Compare commits

..

1277 Commits
0.0.1 ... 0.6.0

Author SHA1 Message Date
Max
1283e3d543 Bump version: 0.5.0 → 0.6.0
Change-Id: I613d09ae0f9f0aa67be1dc6015da1fb9314110fd
2017-08-25 15:51:56 +02:00
Max
b026d38703 Add git-version-gen snippet
Change-Id: Id1732921ecb768b3c3c4872b82b74ccc3d26cf77
Related: OS#1861
2017-08-25 15:41:43 +02:00
Pau Espin Pedrol
8876a507ff osmo-bts-trx: Relax validation to allow TRX data bursts without padding
Original OpenBTS transcievers add 2 bytes of padding to the end of data
bursts, having in total 158 bytes. As those two extra bytes are being
ignored after the initial validation, let's relax this validation a bit
in order to accept transcievers that decide no to send these two extra
bytes.

Change-Id: I94c3cb160bfed0ba9c41ed7ef5f8d8a65b81ad07
2017-08-25 09:34:51 +00:00
Max
aa11997480 osmo-bts-trx: remove global variables from loops
* move TA related globals into phy_link
* move power loop related globals into phy_link
* prefix corresponding vty vars with osmotrx

Change-Id: I01d7c1abad67e51b886a4ecf2de072929d67da27
Related: OS#1848
2017-08-24 19:06:48 +00:00
Max
9a30b77813 osmo-bts-trx: fix 'osmotrx legacy-setbsic'
It was introduced in fe6c75d24a:

* fix typo in config write
* add missing vty help string

Change-Id: Id42359dfbb8ad02f34dd2540db66f3ed69ad5181
2017-08-24 19:06:48 +00:00
Max
01e84be54f OML: use fom_hdr while handling attr. request
Use Obj. Class and TRX# from abis_om_fom_hdr of incoming request instead
of BTS' MO to properly distinguish between BTS-level and TRX-level
attributes.

Change-Id: I8b5a5ab8bd07daf2500b66dec428b89b7f8cd852
Related: OS#2317
2017-08-22 13:29:25 +00:00
Alexander Chemeris
2bbf98afa3 Fix static build of osmo-bts-trx and osmo-bts-virtual.
New libosmocore has some plugin system which requires dlopen(). So we need
to make sure we always link with libdl, even when building statically.

Note that this doesn't fix static build of tests - they are still failing
with some errors.

Change-Id: I8315d6e032e34528def268a49fd88d07bc06ab2e
2017-08-20 19:29:30 +00:00
Harald Welte
4d5df2ebd1 Treat SIGTERM just like SIGINT in our programs
When somebody kills the process, it's best to handle the signal
and to use the opportunity for some cleanup.  We always did this
in the BTS on SIGINT, but never on SIGTERM. Let's change it.

Change-Id: I10009c08b7178988f646e2b6035197b9640ac9b5
2017-08-20 19:23:34 +00:00
Alexander Chemeris
ed662e0799 osmo-bts-trx: Increase a maximum allowed MS power reduction step from 2dB to 4dB.
We tend to start MS with high power to make sure distant phones get good QoS,
but this also means that we need to reduce their power rather quickly. OTOH
we can't make this step too high because this may lead to power output
oscillation. From my (manual, limited) testing 4dB looks like a reasonable
compromise.

Change-Id: I58785513e5739474b881ed7f2a312ecc690e7e60
2017-08-20 01:45:29 +03:00
Alexander Chemeris
b0578dda95 osmo-bts-trx: Remove an unused variable. Resolves a compiler warning.
Change-Id: I2464e872f81021cbc3ccbc4e2e32c394d6afcf70
2017-08-19 22:38:20 +00:00
Alexander Chemeris
d4450051fc osmo-bts-trx: Fix MS power control loop.
The following two commits from 2014-12-06 introduced a new variable to control
MS power - ms_power_ctrl, but kept the old ms_power variable in place. They
have also changed the meaning of the ms_power variable - it now keeps original
RSL configured value. So when much later osmo-trx-bts code was merged to master
the code was compiling fine and this change in the meaning was overlooked.

In osmo-bts:
579651bf30 power/sysmobts: Add a manual ms power level control
In OpenBSC:
f6f86b0eec18da165db136b14bf2db87fde4b4ac osmo-bts: Introduce new struct for a power loop in the BTS code

Change-Id: I713e39b882db32a0d17aa04790d16fa79afa1fb1
2017-08-19 22:35:10 +00:00
Max
b78fc1eeee Simplify jenkins build scripts
* move duplicated code into separate functions in jenkins_common.sh
* use that function in individual builds

Change-Id: I4d09c5f2693b5ac0a4d8f2c840971e13d1ec58cf
2017-08-18 18:08:31 +00:00
Philipp Maier
69ec4a419e octphy: implement support for dynamic timeslots
Implement API functions bts_model_ts_connect() and
bts_model_ts_disconnect() in order to support dynamic timeslot
allocation.

Change-Id: Ia109d4bfade7bc28442127581f4bb0289146ea71
2017-08-15 18:29:21 +00:00
Pau Espin Pedrol
506a7f98b2 osmo-bts-trx: Enable osmotrx tx-attenuation oml by default
There are currently two ways to specify power reductions to be sent to
osmo-trx from osmo-bts-trx:
* osmotrx tx-attenuation oml
* osmotrx tx-attenuation <0-50>

None of them is enabled by default, which means if none of them is
specified in the config file of osmo-bts-trx, SETPOWER cmd won't be sent
to osmo-trx, which in turn won't turn on the transciever.

Let's enable osmo tx-attenuation oml by default and leave it up to the
bsc to decide which power reduction to use. If the user wants to
configure a specific tx-attentuation, it can still do so in exactly the
same way he used to do it.

Change-Id: Ia8640751630ee37e5f5d1f470bad892a08e80654
2017-08-15 14:59:04 +02:00
Harald Welte
fb78397cbd Fix build after recent gsm_bts_alloc() change
In openbsc.git Change-Id I61c18a7f021fcb1ec00d34a745f4e3ab03416c2d
we changed the gsm_bts_alloc() function signature to include
a second argument (the BTS number).  This broke omso-bts, and this
commit is intended to make it build again.

Change-Id: I7ef7654d48c1cfc7e4ecb0b771553ec0740ce2bf
2017-08-14 01:22:12 +02:00
Harald Welte
fe6c75d24a TRX: Remove global variables, move SETBSIC/SETTSC handling into phy_link
Whether or not we are talking to an OpenBTS (SETBSIC) or OsmoTRX
(SETTSC) transceiver is a property of the phy_link, and not a property
of the BTS.  Also, we *really, really* should never use global
variables. I'm very happy this is being cleaned up, finally.

Change-Id: I51aeb17661dfd63ff347f7b2c0d7ffa383ec814c
2017-08-09 13:03:33 +00:00
Harald Welte
bd65b72f91 l1sap/osmo-bts-sysmo: Improve logging
Change-Id: I339db0e5f3fd5e44bac974f2447afc80388802af
2017-08-09 13:02:56 +00:00
Harald Welte
cd1b08b14f TRX: Remove bogus extern global variable declarations
Those global variable declarations for non-existing variables were
introduced in 8a8d73a691, let's remove
them again.  The source / destination IP address is a parameter of the
phy_link, and not a global variable.

Related: OS#1848
Change-Id: I94b5f934fc3bd00b0467d90029d3053b16594186
2017-08-09 11:18:46 +00:00
Harald Welte
bc56094cac GSMTAP: Don't log fill frames via GSMTAP
There's very little point in sending fill frames (such as empty PAGING)
or dummy UI frames via GSMTAP all the time.  They serve no purpose other
than to bloat the log files and make it more difficult for users to find
the interesting bits among all this noise.

Change-Id: Icd18dafb235933c9e6aa9d98ddd8fac1522cc9ac
2017-08-09 10:03:30 +00:00
Harald Welte
de99be4afb L1SAP: Use RSL_CHAN_OSMO_PDCH across L1SAP
So far, L1SAP code is hiding RSL_CHAN_OSMO_PDCH from the bts specific
code below L1SAP.  This is some kind of a hack/workaround, making code
and debug output / logs more difficult to understand.

So let's teach the lower layer how to treat RSL_CHAN_OSMO_PDCH and
remove the "hiding" code from the common l1sap.c code.

Change-Id: Iaaa833febe45b82166d3901f10cc5466a7591c19
2017-08-09 10:03:14 +00:00
Harald Welte
d1f8001cdf VIRT-BTS: Support for GPRS
Change-Id: Id851578c53255866537a16a0be6c3e9268e6ccbc
2017-08-09 10:02:33 +00:00
Pau Espin Pedrol
6fe823a7e1 lc15bts-mgr.service: Prepare dirs and sysctls for the process
Change-Id: I0a0a10ca9498318c48c81fa94faceb2ad4ac1de6
2017-08-07 11:56:11 +02:00
Pau Espin Pedrol
d208132ab9 lc-15, sysmo: l1_if: print name on PH-DATA.ind unknwon sapi
Change-Id: I007e5f0ce9709026331817e55148749e21d8b015
2017-08-01 10:22:55 +00:00
Pau Espin Pedrol
dc469994f3 lc15: Tweak led colors used in service file
service sets led to orange before/while osmo-bts is being started.
osmo-bts-lc15 sets led to green while operating. (unchanged in here)
service sets led to red when osmo-bts stops running.

Change-Id: If351f49d1ead359192d0d80bbc381afd3459c940
2017-07-31 11:55:12 +00:00
Harald Welte
82987f7a7d L1SAP: Print chan_nr and link_id always as hex
The RSL Channel ID is best read / interpreted as hex value, not as
decimal, primarily due to the fact that it is a bit-mask of various
fields.

Change-Id: I9b72a67407870b485e7f7e8a72fa1ad30fc8ed4d
2017-07-30 17:38:37 +02:00
Harald Welte
d6da809d2f TRX / VIRT-PHY: Make check for BCCH/CCCH more specific
In bts_model_l1sap_down() we want to identify BCCH/CCCH channel numbers,
but our check is a bit non-specific.  Let's make the check more specific
to only cover the BCCH, Uplink CCCH and Downlink CCCH C-bits as defined
n 3GPP TS 08.58 Section 9.3.1

Change-Id: Ia20ab09b96c87c0dfbfaf98e5b2a8d36423fac67
2017-07-30 17:38:37 +02:00
Harald Welte
69e0461674 VIRT-PHY: Print NOTICE log message from unimplemented stubs
There are plenty of functions stubbed out in osmo-bts-virtual, let's
print a NOTICE level log message to be able to correlate any kind of
erroneous behavior with the fact that a given function has no actual
implementation.

Change-Id: Ib607d192f90af7fb2d5a8747de5527f39e3cfefa
2017-07-30 17:38:33 +02:00
Pau Espin Pedrol
bbd4d54e46 cosmetic: lc15bts_mgr_vty.c: Fix typos in comments
Change-Id: I46b1cc6e5502829e0c1dc84a184cd2002fbd2b18
2017-07-25 19:21:27 +02:00
Pau Espin Pedrol
8edfe03595 litecell15: Register in vty limits for paX_pwr
Otherwise it fails to read the default config file.

Change-Id: I316a8ea73091c7e76a175314b890e4d86e9c3010
2017-07-25 17:17:25 +00:00
Pau Espin Pedrol
cbb64cffa5 cosmetics: Fix typos and whitespace in lc15bts_mgr_vty.c
Change-Id: I6e35fb9c1a6391e5185a62e9efd2f8ffba13cf0d
2017-07-25 17:17:25 +00:00
Pau Espin Pedrol
824764fa6b lc15bts-mgr.cfg: Set default vswr to a value inside valid range
Valid range is currently set to 1000-200000.

Change-Id: Ibf60ab290acf0423c7617591a86403d63266e5d3
2017-07-25 17:17:24 +00:00
Pau Espin Pedrol
db4ab8e5ce cosmetic: Move error goto path to the end of the function
Change-Id: I3ad15a9edbfe74de3deb7298441d54fd9d0178ad
2017-07-24 22:00:00 +00:00
Pau Espin Pedrol
69de62a573 cosmetic: scheduler_trx.c: Add function to get rid of ugly goto path
Change-Id: I9c2e166e6f182f703ccf49aa883c223e377c8421
2017-07-24 22:00:00 +00:00
Pau Espin Pedrol
9dccaa2064 cosmetic: scheduler_trx: Remove trailing whitespace
Change-Id: Ib057b5e5219ad2acfaee2dcc9ade098daa9ac985
2017-07-24 21:59:59 +00:00
Max
0ebf985492 lc15: port lc15bts-mgr dependency changes
That's mostly changes related to lc15bts-mgr from
https://gitlab.com/nrw_noa/osmo-bts branch nrw/litecell15 based on
eb5b7f80510b603579f7af6d7d5ead296c2fa260 commit:

* adjust comments to simplify further diffs
* add libsystemd dependency to lc15bts-mgr
* add software watchdog which uses it
* ocxo calibration and gps related code

Change-Id: I475a330af771891ba3c897294ce0dd57ec2ba8db
Related: SYS#3732
2017-07-22 09:07:44 +00:00
Max
8785978c37 lc15bts-mgr: separate service file
The sysmobts- and lc15bts- mgr have different semantics for the same
command line option (-n: writing to EEPROM vs writing  to ROM). and
different default value. Hence it make sense to use separate files,
similar to osmo-bts-*.service

Change-Id: I645a81e30d7146ff26720391db763b6d585037e6
Related: SYS#3728
2017-07-21 17:12:17 +02:00
Harald Welte
0e9dadc3d8 scheduler: Fix wrong log subsystem: L1C is L1 *control* not user data
RTS.ind, DATA.* and TCH.* primitives are L1P, not L1C.

Change-Id: I4a32b83225e931ced561fdf457fa962e8ad44bd2
2017-07-19 16:02:25 +02:00
Harald Welte
d7546ed090 VIRT-PHY: Report virtual RACH bursts with plausible burst type
Change-Id: I35b103c512993fc52d4e608f07115a4bb4b21022
2017-07-19 16:02:25 +02:00
Harald Welte
f66d2fc1e6 virt: Don't print NOTICE log message if ARFCN doesn't match
In a larger simulated network with multiple BTSs it is normal that one
BTS will see GSMTAP frames for an ARFCN that is not an ARFCN used by the
local BTS.  This is just normal operation.

Change-Id: Ic68cace9648ccb17500c94b6ede8814674aa9c29
2017-07-19 16:02:25 +02:00
Max
2d2fca4342 lc15: port lc15bts-mgr changes
That's mostly changes related to lc15bts-mgr from
https://gitlab.com/nrw_noa/osmo-bts branch nrw/litecell15 based on
eb5b7f80510b603579f7af6d7d5ead296c2fa260 commit.

I wanted to incorporate vty and hardcoded paths changes so we can use it
from this point without major backward-incompatible changes as a base
for future ports.

Change-Id: Iabbaedc84aaaa594150a4e5445c16dd1f6f89858
Related: SYS#3679
2017-07-19 11:47:47 +02:00
Max
b2bbc81921 lc15: make default config usable
* add trx-calibration path
* change GSM band to 900

Change-Id: I50bc4a4314a8b48e4000de445f4f05795e1a2d8b
Related: SYS#3722
2017-07-18 17:30:07 +00:00
Max
91cecc051a lc15: fix BTS revision and hw options
* remove typo in logging
* add missing return statement
* fix compilation warnings
* add detailed logging for supported GSM band and related errors

Change-Id: I73bccd81ec56845ba11b939937b295eb0f51b4a8
Related: SYS#3728
2017-07-18 19:02:02 +02:00
Max
173a4f1f79 lc15-mgr: update parameter read/write
Better match upstream lc15 code:
* fsync on parameter write
* use permanent storage directly for parameters

Change-Id: Iac150bf2ebffc5fa9544b0f3b19cd647996fc8b6
Related: SYS#3728
2017-07-18 12:49:50 +00:00
Max
f690e5d45c lc15: cleanup board parameters reading
* move common code into separate function
* print error similar to parameter reading code

Change-Id: Icf3285d7bb921d212cb8945e835be2c81189fb87
Related: SYS#3728
2017-07-18 11:41:56 +00:00
Max
a59fb6220b Unify *.service files
* unify description
* provide common BTS-independent aliases

Change-Id: Ia067dc5b0bdef07b90ab57f89e8ba6b2a794eb4a
2017-07-17 17:38:37 +02:00
Max
df07f0a9cb Fix .deb build
Recent introduction of VIRT-PHY broke .deb build. Fix it by installing
osmo-bts-virtual as part of Debian package.

Change-Id: I1ca7eb51019247eb95c6bac752d6e2c4406ce5a2
2017-07-16 21:15:36 +00:00
Harald Welte
3617fd1cb6 Ensure we don't send dummy UI frames on BCCH for TC=5
When no SI 2bis, nor 2ter, nor 2quater is in use, then the code in
bts_sysinfo_get() will return null, causing the transmission of a dummy
frame (0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B) instead of a
system information message. This is - at least - very odd and might not
be backed by the specification. We should simply send any other system
information message instead of sending a frame that does not have a
valid SI header.

While 030301 might be a valid, empty UI frame on a DCCH, it is not a
valid frame for the BCCH, where the header is structured differently.

In fact, bts_sysinfo_get() should never return NULL and always return a
valid BCCH message.

This bug was found while developing
http://git.osmocom.org/osmo-ttcn3-hacks/tree/sysinfo/Test.ttcn

Change-Id: Ifeaed27d1d7ba9994fb8ce67d660648bcc8efece
Closes: OS#2365
2017-07-15 22:36:10 +02:00
Max
e0e2b9e303 Cleanup example config files
* remove deprecated everything log level
* remove copy-pasted sysmobts-mgr.cfg from root directory

Change-Id: I8f392991097267665e9094189d24e7cf94a5d5d2
Related: OS#71
2017-07-14 14:30:01 +02:00
Harald Welte
576408b651 VIRT-PHY: cause BTS to terminate in case of recv()/send() on udp socket returns 0
It is important that we reliably terminate the BTS in case any of the
VirtPHY multicast sockets dies for whatever reason.

Change-Id: I5ae3fdd7cc35fdf235550a3b8362020fdd287c13
2017-07-13 21:35:33 +02:00
Harald Welte
e3b8279f26 VIRT-PHY: Use IPv4 multicast groups for private / local scope
The addresses in the original code make little sense:
* 224.0.0.1 is "All systems on this subnet" and not routed
  outside the local ethernet segment
* 225.0.0.1 is in a RESERVED range that shouldn't be used

Change-Id: Iba1ae69f3f193a33f1da343c6562f67bd8d3557f
2017-07-13 21:35:33 +02:00
Sebastian Stumpf
6feae225eb VIRT-PHY: Added test option for fast hyperframe repeat.
Frame number will restart at 0 after each superframe (approx. 6.1 sec)
if enabled. Can be enabled by preprocessor define.

Change-Id: If3adf14df5fcd8daf53363c27b3772c42d7122e9
2017-07-13 21:35:33 +02:00
Harald Welte
3cda4ff532 VIRT-PHY: Fix handling of default values for vty configuration
The defaults must be set during bts_model_phy_link_set_defaults()
and can then later be overridden by the vty (from the config file).

They should only be written back to the file if they differ from
the default settings.

Change-Id: I5d7f2c1dc8bc3d11db5c607b664730e4dcd58c96
2017-07-13 21:35:33 +02:00
Sebastian Stumpf
1f45db0ff5 VIRT-PHY: Fixed timeslot in gsmtap-msg on downlink which was always 0.
Timeslot is not encoded in the chan_nr accessible in the channel
description but was taken from there and so it was always 0.

Change-Id: I881a1c61ea47399c9b1385fb220cd587e3593e82
2017-07-13 21:35:33 +02:00
Sebastian Stumpf
81335edae3 VIRT-PHY: Added example configurations for openbsc and osmobts.
Change-Id: I368d4a378e20028603b09825eee766abb9195774
2017-07-13 21:35:33 +02:00
Harald Welte
5eb17e28ac VIRT-PHY: Initial check-in of a new virtual BTS
This patch adds a virtual physical layer designed to simulate the
Um air interface between BTS and MS.  It does so by encapsulating MAC
blocks (Layer 2 PDUs) via GSMTAP and sending them through multicast UDP
streams, both in uplink and in downlink.

The purpose of this is enable testing without any radio hardware or
related licenses.

OsmocomBB has recently received as similar patch-set, adding a virty_phy
executable that can be run on a PC instead of the classic 'layer1'
firmware on a real phone.

Using GSMTAP means that one can use unmodified wireshark to decode the
messages exchanged on the virtual Um layer.

This code was originally started by Harald in January 2016, continued
by Sebastian Stumpf in late 2016 and early 2017, and finally completed
by Harald in July 2017.

Change-Id: I1bf7670975b1e367c1c62983020865a043542622
2017-07-13 19:34:17 +00:00
Max
152c2f489c si2q: do not consider count update as error
The number of SI2quater messages might be updated dynamically by
BSC (via 'bts 0 resend-system-information' command for example). Log it
but do not return error.

Related: OS#2357
Change-Id: I9625be879c672e20543cc40af288828143ffb983
2017-07-11 16:22:29 +00:00
Philipp Maier
9a2187e7b1 octphy: remap frame number in MEAS_IND
The octasic phy stamps the SACCH channel that carries the
measurmenet indication with the frame number of the last
SACCH that falls within the measurement period.

The higher layers expect the frame number to be aligned
to the SACCH channel after, which marks also the beginning
of the next measurement period.

Make the octphy code compatible to the higher layers by
remapping the measurement indication frame number.

Change-Id: I8ecb27c018bf4ad5151878a6ad34026fd0f801a1
2017-07-10 16:14:56 +00:00
Philipp Maier
65db0f5c41 measurement: fix measurment report
The end of the measurement reporting period is not aligned with the
SACCH block where the results are reported. The tables that are
used to detect the end of the measurement period are therefore
wrong. The frame number of the SACCH block must be used and not the
TDMA frame number (modulo 104) of the measurement reporing interval.

The tables are oriented to the frame number of the first SACCH block,
at the beginning of an interval. However, when a SACCH block is received
it will always contain the result of the recently passed measurement
reporting period.

To match the tables, introduce another lookup table to remap each
SACCH block that ends to the matching beginning block number.

Change-Id: I1eef894e6f15b4449fc8926bebb118624efc7924
2017-07-10 15:30:59 +00:00
Philipp Maier
9a280eba48 osmo-bts-sysmo: Include frame number in MEAS IND
l1_if.c does not generate struct osmo_phsap_prim l1sap properly.
The frame number is not included in this struct. This renders the
logic that processes the reported measurements non functional,
since the logic (see measurement.c) is not able to detect the
end of the measurement period. This commit fixes the problem by
adding the missing frame number to the l1sap structure.

Change-Id: I09241d6cc2ff09e71a3d723d90e4468108a27ae1
2017-07-10 13:07:30 +00:00
Harald Welte
7887ce7aea jenkins helpers: some minimal documentation/comments + print errors
We should print meaningful error messages in case a user doesn't have
the required local PATH set up, or doesn't specify a required command
line argument.

Change-Id: I30a2935f93ade69222b1e0c3e212ee10e17c1823
2017-07-10 14:55:25 +02:00
Philipp Maier
6a538a0921 octphy: do not send empty frames to phy
ph_data_req() and ph_tch_req() are generating empty (idle)
frames when no data (msg == NULL) is available. Since the
phy is able to generate idle frames internally, there is
no need to waste Host CPU cycles by doing this in software.

Remove the empty frame generation and exit the function
cleanly.

(Patch by Octasic Inc.)

Change-Id: Ib857b7dab490ad426c48d6a9e5e6fa10ef5a0838
2017-07-10 08:45:41 +00:00
Pau Espin Pedrol
390742b3ed Use osmo_dump_gsmtime to log fn across different layers
This commit also fixes a missing end of line in the log output of handle_ph_data_ind

Change-Id: I049f58d51333d3590361db5c0105e6899a862af6
2017-07-10 08:44:03 +00:00
Pau Espin Pedrol
f06ba300c4 Move dump_gsmtime to libosmocore as osmo_dump_gsmtime
Internal l1sap dump_gsmtime has been moved to libosmocore as osmo_dump_gsmtime.
Remove use of internal function and replace with the libosmocore version.

Depends on libosmocore Ib5452e2c20f53006c0f6d197fb055728947125d8

Change-Id: Ia2f89965d970ed5bbb8c0d4f591a043e58c4bd66
2017-07-10 08:44:02 +00:00
Pau Espin Pedrol
ffdc05bc4e l1sap.c: fn_ms_adj: Add err logging and always return GSM_RTP_DURATION
After latest changes, l2 expects to receive an event for every TCH
frame, that is, no TCH frame event should be lost on that layer. We
should now then be safe returning always GSM_RTP_DURATION.

The code which used to calculate the variable duration is left there to
assert that indeed we are not longer having this kind of issues.

Change-Id: I9d112c6db142be138e71393e77129e6d069d9973
2017-07-10 08:44:02 +00:00
Pau Espin Pedrol
c2d3f14bfb l1sap.c: Avoid sending RTP frame with empty payload
Depends on libosmo-abis Id6099372b6231c0a4b6ea0716f46f5daee7049e1

Change-Id: Ie9053674aa4f43aac20dbd5c865d70317360abbc
2017-07-10 08:44:01 +00:00
Pau Espin Pedrol
f588b5f91d Allow passing low link quality buffers to upper layers
We want to always call l1if_tch_rx and l1sap_up in order to avoid losing triggering
events on the upper layer.

With this change, the upper layer will increase correctly seq + ts for
RTP. It will then send an RTP packet with only the header and no payload, which is
not correct but at least we avoid drifting the RTP clock. Upcoming patch
in the series solves this issue.

This patch assumes that we are not lossing data events from the physical
layer and that we receive an event every 20ms, even if the MS is not
transmitting due to DTX.

Depends on libosmocore If4ae20c22b881e94585dad710f17b9e37f77bf82

Change-Id: If5df8940fab833eb4e3ed851880b66987d356031
2017-07-10 08:44:00 +00:00
Max
0bd7a19114 Use release helper from libosmocore
Change-Id: Ib8efd2095fcf759276299b516d495219105c1f2b
Related: OS#1861
2017-07-10 08:24:40 +00:00
Pau Espin Pedrol
aa15504097 sysmo: Remove non longer valid -p option from help
The dsp-trace-flags command line argument was removed
in 9684099ae9

Change-Id: I8dbcdc7080ca3f7d7968aeef24422faa75d925fe
2017-07-05 11:29:12 +02:00
Pau Espin Pedrol
3ae0be0f12 sysmo, litecell15: Make sure all TCH events are triggered
Change-Id: Ie674c7ec40838af36308c6998f227fa452ace4b4
2017-07-04 13:36:53 +00:00
Pau Espin Pedrol
523ae04e5e Fix annoying trailing whitespace
This whitespace keeps being automatically fixed by editor, polluting my
patches.

Change-Id: If0ba1321ed326c1498e3f60b611bd962f2a9484a
2017-07-04 13:36:52 +00:00
Pau Espin Pedrol
171d80a8d6 Use L1P instead of L1C for TCH logging and allocation
L1C is for L1-Control primitives, while TCH channels are L1 Data
channels.

Change-Id: I07ea3a7326bfcb62271d58deb0743311f6d97c8b
2017-07-04 13:36:52 +00:00
Philipp Maier
8baa45a8e3 octphy: complete value strings (octphy_cid_vals)
The value string table octphy_cid_vals lacks the strings for
cOCTVC1_MAIN_MSG_APPLICATION_INFO_CID and cOCTVC1_MAIN_MSG_APPLICATION_INFO_CID

(Patch by Octasic Inc.)

Change-Id: I9843137b55534a29938d5c2308244a6950de788f
2017-07-04 13:36:24 +00:00
Philipp Maier
3902e4d9c4 Revert "osmo-bts-sysmo: Include frame number in MEAS IND"
This reverts commit 3f97e4b1fc.

Change-Id: Ib50c813c470bf6ea740fe6667431eaa1a23fdd8d
2017-07-04 11:53:12 +00:00
Harald Welte
9b97d0f683 TRX: permit transmission of all-zero loopback frames
For some reason, osmo-bts-trx attempted to interpret/validate the
contents of the downlink TCH block that it was about to transmit.  If
such checks are made, they should clearly be in the common part above
L1SAP, and not in the bts-model specific part.

Also, having the checks in place didn't allow us to send an all-zero
downlink block, as is required for detection of uplink FER in a loopback
testing setup, e.g. with CMU-300.

Change-Id: I6388de98e4a7e20843a1be88a58bba8d2c9aa0d5
2017-07-02 07:02:29 +00:00
Harald Welte
a38d34112f l1sap: Don't enqueue PTCCH blocks for loopback
When we're in loopback testing mode for PDTCH, we must make sure to
avoid adding PTCCH blocks to the queue. Only PDTCH blocks must be
enqueued. For the transmit (downlink) side, we already had the PTCCH
check in place.

Change-Id: I7ef40d9bdf74a99375bc6568ed9483499664bf6f
2017-07-01 07:38:40 +00:00
Harald Welte
cc1602f592 TRX: don't free l1h in trx_phy_inst_close()
l1h is allocated in bts_model_phy_instance_set_defaults() and not in
trx_phy_inst_open().  Hence, trx_phy_inst_close() should not free() it!

Change-Id: I0ac4e57a882e5a31143499c1662d8d8e52320938
2017-07-01 07:38:03 +00:00
Harald Welte
f2eaba8869 TRX: merge/simplify l1_if and trx_if code
Related code / function structure still dates back to the pre-phy_link
days.  Let's clean this up to make things less convoluted and reduce the
number of non-static symbols needed between code split over two files.

Change-Id: I1f30ae1f547a5c01c516d4a05032193294c25f2d
2017-07-01 07:38:01 +00:00
Harald Welte
cdf20fec7c TRX: Rename trx_if_data() -> trx_if_send_burst()
The new name makes it clear what the function actually does: Send burst
data via the trx interface.

Change-Id: I5031541d4ae4244a62a18acf71139db2874927fa
2017-07-01 07:38:01 +00:00
Harald Welte
bb71947829 trx_if: Improve error handling
There ware some error conditions that the previous code didn't catch
and/or report, such as unparseable TRX control strings, non-terminated
buffers, ...

Change-Id: I354d0c121880553ce1bd59b7394d52b104b7d6da
2017-07-01 07:38:01 +00:00
Harald Welte
c19ab9ed2f TRX: trx_if: Improve code description / comments
Change-Id: I4e19d68782a12e52ba1d3ba2665060275d04866c
2017-07-01 07:38:00 +00:00
Pau Espin Pedrol
7738f5282f litecell15/tch.c: Clean up use of empty buffer
Make code easier to read and avoid reading first byte of the buffer if size is 0.

Change-Id: Ib9ee967c0f42098b3a0569e9d84f23832eb4f2d5
2017-06-30 08:48:34 +00:00
Pau Espin Pedrol
0ada527bc0 sysmo/tch.c: Clean up use of empty buffer
Make code easier to read and avoid reading first byte of the buffer if size is 0.

Change-Id: I5ecfc4df5a3fcad3d3ad50bf3dd3db65b694481a
2017-06-30 08:47:57 +00:00
Philipp Maier
dd3c7815a5 osmo-bts-litecell15: Fix missing frame number in MEAS IND
The layer 1 interface (l1_if.c) for osmo-bts-litecell15 does not include
the frame number into the measurement indications it forwards
to higher layers. The frame number is required to properly
detect the end of a measurement period.

change process_meas_res() to properly include the frame number into the
l1sap primitive (struct osmo_phsap_prim *l1sap)

Change-Id: Iee9c8f88b05cd5dba9920bb08e079a643e713237
2017-06-29 17:41:01 +02:00
Philipp Maier
b7425f3642 osmo-bts-trx: fix missing frame number in MEAS IND
The layer 1 interface (l1_if.c) for osmo-bts-trx does not include
the frame number into the measurement indications it forwards
to higher layers. The frame number is required to properly
detect the end of a measurement period.

Change-Id: Ife3c791ff50e8a866a97b9783ac7ef3ef2402a70
2017-06-29 17:29:56 +02:00
Philipp Maier
8d645dd0e5 Revert "sysmobts: normalize frame number in measurement indication"
This reverts commit 88b2cc30a6.

Change-Id: I30f37a9feef24a45e254377502615d717dba9765
2017-06-29 13:18:11 +00:00
Harald Welte
250d77f8df Add loopback support for PDTCH
This add support for BTS-side lookback of PDTCH channels.

If lchan-loopback is enabled, We take the uplink frames as received in
PH-DATA.ind and put them into the dl_tch_queue for that lchan.  When we
receive PH-RTS.ind, we dequeue frames from that queue and transmit them
in downlink. If no frame is found in queue, we transmit an empty
(all-zero) frame of 23 bytes (CS-1).

Change-Id: Idd07a3f4a88c38398d3e844333c0104e2de23864
2017-06-28 23:43:28 +00:00
Harald Welte
53ce11ab95 TRX: Use timerfd and CLOCK_MONOTONIC for GSM frame timer
using gettimeofday() is not suitable for the GSM frame timer, as it
relies on the normal 'wall clock' system time, which may be adjusted by
ntp, gps or other means at runtime.

Switching to a different clock source means we cannot use
osmo_timer_list anymore, but timerfd integrates just fine with our
libosmocore select() loop handling.

Change-Id: I51b19adde14ebb7ef3bb863d45e06243c323e22e
Closes: #2325
2017-06-28 23:43:28 +00:00
Philipp Maier
59d0c2cca6 octphy: remove log output
When handle_ph_data_ind() runs BER and RSSI is logged. Remove
this log output by removing the call to dump_meas_res

(Patch by Octasic Inc.)

Change-Id: I5e755465daa3daec2e2b4f61bc8d779c49196e9a
2017-06-28 13:21:51 +00:00
Philipp Maier
5047fbe3b8 octphy: initalize nmsg only when needed
nmsg is initalized every time the function runs, even when it
is not needed. Move the initalization into the if (msg) body
so that nmsg is only initalized when we really need it.

(Patch by Octasic Inc.)

Change-Id: If51dc50a9f4bdb4aba62c0ae5fbfac552806f0c0
2017-06-28 13:21:51 +00:00
Philipp Maier
521ab50dcc octphy: initalize l1msg and only when needed
l1msg is initalized when the variable is declared. This means
the allocation always runs right on the beginning. Even when
the buffer is not needed at all.

do a prober l1msg initalization only when needed and check the
return code.

(Patch by Octasic Inc.)

Change-Id: Ia71d49b9cc109af53d997a687a7fb1b5ed062d1c
2017-06-28 13:21:51 +00:00
Philipp Maier
ae7ece1064 octphy: improve log output
Printing the RX payload size is strictly informative, so the
loglevel LOGL_ERROR is wrong. This commit changes it to
LOGL_DEBUG

(Patch by Octasic Inc.)

Change-Id: I712cdd79cbba93f457705d38871bd8d4b7f4e897
2017-06-28 13:21:51 +00:00
Max
4962ed1811 RSL: receive and send multiple SI2q messages
* change BCCH Info handler to explicitly support multiple SI2quater
  messages sent from BSC
* change SI scheduler to send SI2q in round-robin way

That's resubmission of 340cff51f4 and
186c6bac07 with memory initialization
order change to fix the issue detected by osmo-gsm-tester - see OS#2338.

Change-Id: Ib595733cde108387bc7ee76b1b11ada6a235f13c
Related: OS#1660, OS#2338
2017-06-28 07:56:32 +00:00
Philipp Maier
d0846651a3 measurement: improve log output
The code that receives the uplink measurement data from L1 does not
print the number of already received uplink measurements. Since
this is a valuable information when debugging the log output will
now print this information as well.

(Patch by Octasic Inc.)

Change-Id: I79926f25de088571fcc2c14388c72fc968c2d382
2017-06-26 13:48:10 +00:00
Max
620bd83b12 Add missing include for abis.h header file
This fixes compilation warning:
implicit declaration of function ‘abis_bts_rsl_sendmsg’

Change-Id: I956561b2f953c7d380a26442fad84bc8262ea129
2017-06-26 10:54:28 +00:00
Minh-Quang Nguyen
2a4c5fa2b3 LC15: properly handle BS-AG-BLKS-RES as received from BSC
Closes: OS#2014
Change-Id: Icf437e621d1991f6185e31a0953773309e2bf5ac
2017-06-24 12:56:08 +02:00
Harald Welte
4699ebaa26 l1sap: if lchan is in loopback, don't accept incoming RTP
When the lchan is in loopback mode, we loop back all uplink blocks into
downlink blocks.  We do not processs any RTP frames for that lchan
anymore.  Rather, we discard those RTP frames to avoid mixing
looped-back samples with those received from remote.

Change-Id: I29ef4963e9c491c94c413cbc10436a2388c04d9b
2017-06-24 12:56:08 +02:00
Harald Welte
7a6b178fc0 osmo-bts-sysmo/l1_if.c: PH-DATA.ind belongs to L1P, not L1C
L1C is control, while L1P is data primitive.

Change-Id: I5a0ef08df96a67cd25b11eb23c60934011b01c29
2017-06-24 12:56:08 +02:00
Harald Welte
53216b5d1f l1sap.c: Factor out function to limit message queue
Change-Id: I0fe0fc6b17cefdbf6b2d9f30ed08306998d30687
2017-06-24 12:55:11 +02:00
Harald Welte
50f8165540 measurement: Remove dead code
We used to have trx_meas_check_compute() and call that from the
bts-specific code in order to iterate over all timeslots and all lchans
in the timeslots if we have to send measurement reports.  This was
executed once per frame, and created unequal CPU load over time, which
in turn might increase different per-ts jitter.

Since 2f028c4e2c in April 2017 we have
lchan_meas_check_compute(), which performs this on a per-lchan basis,
and hence CPU load is distributed over all active timeslots.

Change-Id: I6308cefe4a51e55719ea4ed4d613d3782b805c08
2017-06-24 12:55:11 +02:00
Neels Hofmeyr
61f9158eaf Revert "RSL: receive and send multiple SI2q messages"
This reverts commit 340cff51f4.

osmo-gsm-tester detected a regression due to this commit, when running
osmo-bts-trx. The modems timed out when waiting for them to register with the
osmo-bts-trx network. osmo-bts-sysmo is apparently not affected. No further
details on the failure cause are known yet. The failure is shown for example by
http://jenkins.osmocom.org/jenkins/view/osmo-gsm-tester/job/osmo-gsm-tester_run/868/

Change-Id: I15bca30ddc09a7a3044096626016f6130d07636c
2017-06-24 00:49:26 +02:00
Neels Hofmeyr
1ba0cfe9c0 Revert "RSL: check for abnormal SI2q values"
This reverts commit 186c6bac07.

osmo-gsm-tester detected a regression due to commit
340cff51f4, which above commit apparently depends
on. Revert this along to avoid conflicts.

Change-Id: I456e9add788393ca781213cef31b5bc3d48fd531
2017-06-24 00:48:23 +02:00
Max
9d294c9cb1 lc15: fix jenkins build
* use proper fw headers include path
* do not quote $PARALLEL_MAKE variable

Change-Id: Ib67305ae858ce322f7ea4ac6c6ce5007ce8e7ab9
Related: SYS#3682
2017-06-22 19:51:02 +02:00
Max
5466ff9c1b lc15: make jenkins helper executable
Change-Id: Icf06040d77180fb9d877ca52e00171b21b634ef8
Related: SYS#3682
2017-06-22 13:22:43 +02:00
Max
94bdcfd803 OML: move BTS number check into separate function
* move code which checks for BTS number (obtained via OML) validity into
  separate function
* adjust log messages to match the check
* add spec reference and comments

Change-Id: Id5714fbed910696d30e18d1f20f4c9fced4b9230
Related: OS#2317
2017-06-22 10:51:12 +00:00
Max
114293a414 Copy sysmobts.service to osmo-bts-sysmo
This way the name of systemd service file will match the name of the
binary similar to lc15. Add aliases so the user can use both old and new
names regardless of which file is installed. Once the corresponding
changes to OE recipes are applied old file can be removed.

Based on work by Pau Espin Pedrol <pespin@sysmocom.de>

Change-Id: I08615eb625d488603aeb5962ad9f30869c0e77c5
2017-06-22 10:50:00 +00:00
Max
d4806db1e5 Use generic L1 headers helper
Change-Id: I2253df3509595d7393ec6631ef846dbebae73ca4
2017-06-21 20:25:28 +00:00
Max
71ad40c647 lc15: add jenkins helper
Add jenkins build helper for lc15 and separate header with BTS-agnostic
functions.

Change-Id: Ib47f5a6cc88e784c5662b0dab4ddc03ce9a35132
Related: SYS#3682
2017-06-21 20:25:28 +00:00
Max
5b87144f91 Move common steps into common jenkins helper
Move value_string termination check and OpenBSC headers checkout into
shared jenkins helper from BTS' model-specific helpers to get rid of
copy-pasted code. While at it - also remove unnecessary bash
dependency.

Change-Id: Ic48b1f75179b9008d65219dd5a47c1ab3b886408
2017-06-21 20:25:27 +00:00
Max
d5971d0681 Move parameter file opening into separate function
* use talloc for file path allocation
* print detailed error on failures

This simplifies troubleshooting of lc15bts-mgr failures.

Change-Id: I86c93a2a4f080e8ac1517be93f58f6ffd00d248c
Related: SYS#3686
2017-06-19 08:34:41 +00:00
Max
aa5edff477 lc15bts-mgr: use extended config file example
Change-Id: I0ef9d00a031b7d7e59150a28a6972c620ff19e92
Related: SYS#3686
2017-06-19 08:34:23 +00:00
Harald Welte
f4544573f8 OML Add osmocom-specific way to deactivate radio link timeout
In some situations (e.g. when trying to do measurements/testing on the
BTS receiver / uplink) it is useful to have a way to disable the radio
link timeout and keep any channel open until deactivated, irrespective
of whether (valid) data is received or not.

This adds a related feature that can be activated by using an
osmocom-specific value of 0xff for the TS 12.21 Connection Failure
Criterion (9.4.14).

Change-Id: I736f21f6528db5c16fa80cdb905af20673797be5
2017-06-18 10:00:43 +00:00
Max
186c6bac07 RSL: check for abnormal SI2q values
Check for impossible index and count values of SI2q messages. The limit
is defined in 3GPP TS 44.018 Table 10.5.2.33b.1

Change-Id: I351f8e8641a1cb9548154803da70bfde46ee180d
Fixes: CID 170749
2017-06-16 20:17:37 +02:00
Max
340cff51f4 RSL: receive and send multiple SI2q messages
* change BCCH Info handler to explicitly support multiple SI2quater
  messages sent from BSC
* change SI scheduler to send SI2q in round-robin way

Change-Id: I3aeb90804edab1b0325c3eb7347526ae995dbf51
Related: OS#1660
2017-06-15 19:18:47 +00:00
Vadim Yanitskiy
0b7a3e9f62 scheduler_trx.c: strip unused variable
Change-Id: I870dad2a00f68cca1c31a719221fc30a07b30c20
2017-06-15 14:40:21 +00:00
Vadim Yanitskiy
0227e4d04c cosmetic: fix some typos
Change-Id: Ib9172735bc7a05d9d7425a0e66dd90ff2569ee05
2017-06-15 14:40:21 +00:00
Max
61d36212b1 Cleanup SI scheduling
* use GSM_BTS_HAS_SI() from OpenBSC instead of local copy
* arrange GSM_BTS_HAS_SI() checks to improve readability
* constify SI scheduler parameters

Change-Id: If74bc536fe7d2bfbc976c07d882151873ecda4f2
Related: OS#1660
2017-06-15 13:22:12 +00:00
Max
de9357251c Set and report BTS features
Set (possibly incomplete) list of BTS model-specific features and report
them in response to attribute request via OML.

Change-Id: I5f8a6681c3562ec261441e84dde6e085b516d92f
Related: OS#1614
2017-06-15 12:55:16 +00:00
Max
b7793ed8fd Extend Get Attribute responder
* detect if attributes are requested for BTS or TRX and act accordingly
* report TRX phy version

Change-Id: I9f72305bbf1ab74745bffac1bee9f539f5a6de32
Related: OS#1614
2017-06-15 12:55:16 +00:00
Max
1dcbee3420 lc15: add example systemd service file
Change-Id: I923b4220f98bb7bd9ec78a6804bdfa9ad988f473
Related: SYS#3686
2017-06-14 13:15:45 +00:00
Max
78a5073dfb Place *-mgr config examples according to BTS model
* copy sysmobts-mgr.cfg to sysmo/ directory
* add lc15bts-mgr.cfg

The configuration is BTS-specific so it should be located inside
appropriate subdirs.

Note: the old copy of sysmobts-mgr.cfg can be removed once the image
build recipes are adjusted.

Change-Id: Ic81197464809ba508b2572e86dd978a994f4b116
Related: SYS#3686
2017-06-14 13:15:42 +00:00
Max
16b8f51839 Use systemd template specifiers
Use systemd template specifier for config name instead of hardcoding
it. This will allow to specify different config file name depending on
the name of the service file.

By default sysmobts-mgr.cfg will be used preserving compatibilty with
existing installations but if the unit is named lc15bts-mgr.service than
lc15bts-mgr.cfg will be used. This gives us necessary flexibility to use
BTS-specific configuration.

Change-Id: I475df6a06691390120eea0bd8a61fa469df2bd2d
Related: SYS#3686
2017-06-14 13:32:11 +02:00
Philipp Maier
0e7886d379 measurement: Improve log output
The debug log does not print much information about the measured
rxlev and rxqual values. This commit adds debug output to make
measurement debugging simpler

Change-Id: Ic871eed6dcbc7d10aca6cd11dbc803b3e6da449f
2017-06-13 10:06:24 +00:00
Philipp Maier
3e2de526b0 cosmetic: remove unused variable
Tha variable ms_timing_offset in lchan_meas_check_compute is not
used anymore.

Change-Id: I40c393f6864fe72b88a70da265b7775da8fb469c
2017-06-09 16:09:21 +02:00
Philipp Maier
88b2cc30a6 sysmobts: normalize frame number in measurement indication
The higher layers relay on a normalized version of frame number
in order to detect the end of a measurement period.

The frame number on which the measurement reports are sent may
depend on the phy, so we need to normalize the frame number
before we report it to the higher layers.

Change-Id: I90bd01479e41f04a6b0aefe3845d071e3148d0c6
2017-06-09 16:09:21 +02:00
Philipp Maier
67d3b8b136 Revert "measurement: exclude idle channels from uplink measurement"
The offsets used in the lookup tables may be phy dependand. So we
will have to do the alignment in the layer 1 interface of the
phy dependand code before we report the frame number up to the
higher layers.

This reverts commit e0fb3ae52d.

Change-Id: I8acab50cc1bb1cb133831c6a145f4d790e99176c
2017-06-09 16:09:21 +02:00
Philipp Maier
95d2505e57 octphy: fix segfault
The priv pointer of the callback function app_info_compl_cb() is
set to null by the pointer. It should be set to pinst instead.
Besides of that there is a memory violation while accessing
the local variable ver_hdr using osmo_strlcpy(). Both is fixed
with this commit.

Change-Id: I558d78ef29e9a4d8f45f4142611f11289d3ed806
2017-06-09 16:09:21 +02:00
Max
d22b5b84c0 Re-add version to phy_instance
This is resubmission of 9eeb0b1a13 with
errorneous use of talloc_asprintf() removed which should fix OS#2316.

Change-Id: I02ae6fffdc808c1ea14185dbb4a720d27a62d4bb
Related: OS#1614
2017-06-09 09:00:04 +00:00
Philipp Maier
d5fdcfe6d9 measurement: fix measurement computation
Timing advance is currently not taken into account when computing
the measurement results, this commit fixes that

Change-Id: I2e0dfd13b53e8aa2822985f12bf2985e683ab553
2017-06-09 08:54:54 +00:00
Pau Espin Pedrol
e3a3906ee9 trx: Save osmotrx base-port vty properties
Change-Id: I0898a8c4eb3899fc1c0f6b17da33b8c7851b90d6
2017-06-06 19:48:53 +00:00
Pau Espin Pedrol
8a8d73a691 trx: Allow BTS and TRX to be on different IPs
Depends on libosmocore I3c655a4af64fb80497a5aaa811cce8005dba9cd9

Change-Id: I0bd34b7b02c1a9b0c6f6f89f327b486e5620c8d5
2017-06-06 19:23:18 +00:00
Neels Hofmeyr
d36b3a8463 Revert "Add version to phy_instance"
This reverts commit 9eeb0b1a13.

This commit caused osmo-gsm-tester test runs for the sysmoBTS to fail with
SIGABRT consistently. See below redmine issues.

In osmo-bts-sysmo/l1_if.c, it uses talloc_asprintf to write to the char
version[MAX_VERSION_LENGTH]; talloc_asprintf() however is intended to work on
string buffers allocated by talloc, and attempts to reallocate version[].

Furthermore, it is not clear why the patch passes a 'data' arg to
app_info_sys_compl_cb() that is not used.

Hence I will revert this instead of trying to fix. Please resolve issues and
re-submit.

Related: OS#2316 OS#1614
Change-Id: I2c9fd5e6739c1750365c0241476ce4b1aa2df3d4
2017-06-02 22:46:16 +02:00
Max
e91cd2b088 OML: fix Coverity-reported issues
* CID 169803:  Null pointer dereferences
* CID 169802:  Incorrect expression

Change-Id: Ib3f91be97c8bf81a87681814bf81d3a5a9950e54
Related: OS#1614
2017-05-29 21:13:45 +00:00
Max
9eeb0b1a13 Add version to phy_instance
Change-Id: I5b2352b8d15e9b0d8616fcd526b4902d247e4693
Related: OS#1614
2017-05-29 21:13:45 +00:00
Harald Welte
a8bf666a09 sysmobts: Re-order the bit-endianness of every HR codec parameter
The so-called "RTP mode" of the DSP contains a bug on all firmware
versions < 5.3.3 which causes the bit-order within each of the
non-aligned codec parameters to be wrong.  Introduce a function
originally written by Sylvain Munaut during 32C3 in
http://git.osmocom.org/openbsc/commit/?h=sylvain/32c3_codec&id=5b4a16bbe93a7b1ace65cc23d6cce56ecf4f1275
to bring the bits into [the correct] order.

This has never been seen in a "pure sysmoBTS" setup, as all BTSs would
use the same (wrong) bit-ordering and thus interoperate.  This patch now
checks for an affected DSP firmware version and then jumbles (old DSP
firmware version) or does nothing (new DSP firmware version).

Change-Id: Ia0eee4f514fb8fd81c052bb44a4facba898d6afb
Closes: SYS#2452
2017-05-29 21:58:51 +02:00
Harald Welte
cb5a969a45 l1_if: Add inline functions to check dsp/fgpa version at runtime
Change-Id: Iddae9c8de33aca6663dca77908fa4852ad704ce9
2017-05-29 21:58:51 +02:00
Harald Welte
450714b19c vty: Remove command for manual channel activation/deactivation
OsmoBTS won't run without being connected to a BSC.  The BTS wouldn't
start to transmit if the BSC doesn't properly initialize it.  So if we
want to activate some channels manually for testing, we should do so
from the BSC, and not inside the BTS code.  Doing this in the BTS means
that the BSC is not aware of it and might want to use that channel for
something else meanwhile.

Osmo{BSC,NITB} has gained ability to manually activate a channel from
the VTY in Change-Id I44fc3904678eb48bd3ab1a3da8c0c265fa082e0d as can be
seen at https://gerrit.osmocom.org/2759

So let's remove the old/obsoleted code here.

Change-Id: I7ba0301b55cc283aa6a441899f84357e28a97321
2017-05-29 21:58:51 +02:00
Harald Welte
43c763f5af osmo-bts-trx: Remove duplicate parsing of NM_ATT_CONN_FAIL_CRIT
For some reason, osmo-bts-trx did another take at parsing
NM_ATT_CONN_FAIL_CRIT and storing the second octet in
btsb->radio_link_timeout, just like the generic code already does in
oml_rx_set_bts_attr(), but without proper checking and any error
message.  Let's remove it.

Change-Id: Idb0179e1443c0b5a97e59919dba684a001e90192
2017-05-29 19:55:30 +00:00
Harald Welte
440930be44 l1sap.c: Add spec reference to link timeout implementation
Change-Id: Ia95635a4350624b30f2b352e30ee39f856945670
2017-05-29 19:55:30 +00:00
Harald Welte
05ba5c2a10 Consistently check for minimum attribute/TLV length in RSL and OML
Make more use of TLVP_PRES_LEN() instead of plain TLVP_PRESENT() and
implicitly assuming a certain length of the information element.

What this obviously doesn't introduce is some kind of error
generation/reporting in case the minimum length is not fulfilled.  An IE
that's too small is silently ignored by TLVP_PRES_LEN() and treated as
if the IE wouldn't exist in the first place.

Change-Id: If5c4eee65711c49bc8ba4675221b1d5fd16198e9
2017-05-29 19:55:30 +00:00
Philipp Maier
3f97e4b1fc osmo-bts-sysmo: Include frame number in MEAS IND
l1_if.c does not generate struct osmo_phsap_prim l1sap properly.
The (logical) frame number is not included in this struct. This
renders the logic that processes the reported measurements non
functional, since the logic (see measurement.c) is no longer
able to detect the end of the measurement period.

This commit fixes the problem by adding the missing frame number
to the l1sap structure.

Change-Id: I2bab40c30d727395eb3096026810917407419cd7
2017-05-29 18:18:31 +02:00
Philipp Maier
538475259c octphy: remove old event control code
Event handling is done internally in the Octasic BTS. When the TRX is opened,
events are enabled automatically and when TRX is closed events are disabled.

The change is valid for the recent firmware version and for the last couple
of previous releases.

Change-Id: I0652627495f6a9bcb0da2431b8beb839bc22062b
2017-05-29 11:11:36 +00:00
Philipp Maier
524e3e3170 octphy: integrate channel measurement handling
recent octphy firmware versions do support proper channel measurement handling.
The new implementation replaces the old, and for osmo-bts non functional
implementation.

This commit introduces the necessary adjustments. Older firmeware releses will
still work. However, the measurement computation results will still be wrong.

Change-Id: I0f053bb10b1cb112a8814ee591969d607888e686
2017-05-29 11:11:35 +00:00
Harald Welte
ed9e022eb4 rx_tchh_fn(): Avoid copy+pasting formula to determine odd-ness of fn
Change-Id: Ic2a0bdaa70cc28c1ce8237351b0a0c6b998cf0a3
2017-05-27 08:24:05 +00:00
Harald Welte
a493ce9e66 scheduler_trx: Avoid copy+pasting determining CMR from FN
instead, let's introduce a specific function for that.  Also, as this
can be easily determined from the frame number, skip one argument to
tx_tch_common().

Change-Id: Ibbb9b685cf0b6a45339b0874438a500dd6254bc2
2017-05-27 08:24:05 +00:00
Harald Welte
031e8fedac scheduler_trx.c: Avoid code duplication for BER10k computation
Use an (inline) function rather than code copy+pasting

Change-Id: I42e76a4707968e428cbd2e43d5df71ef445efece
2017-05-27 08:24:05 +00:00
Harald Welte
b4c9c8f35d scheduler_trx.c: Fix typos, improve comments, cosmetics
Change-Id: I5e2ce70aea8d62657ce3a7d6c16e5a7f8b76c22f
2017-05-27 08:24:05 +00:00
Harald Welte
ed51c3d145 Remove unusued left-over gsm0503_conv.c
gsm0503_conv.c should have been removed as part of
efbef50efc but somehow was left here. It's
not referenced/compiled by the Makefile anymore, and the gsm053_conv.c
in libosmogsm has superseded it anyway.

Change-Id: Icdcca1bc55a83c76ec47918dc4dd301155210091
2017-05-27 08:24:05 +00:00
Max
72993079ed Implement basic Get Attribute responder
Add 3GPP TS 52.021 §8.11.2 Get Attribute Response handling:
* report OsmoBTS version
* report sysmoBTS sub-model
* report OsmoBTS variant

Requires I7ecb0c4339530d3a8354a2f94b34063dda87e030 in OpenBSC.

Change-Id: I09f95ed995fab5def9dc6e8cc201012fba4db28d
Related: OS#1614
2017-05-27 07:55:41 +00:00
Philipp Maier
e0fb3ae52d measurement: exclude idle channels from uplink measurement
The DATA-IND, received from the physical layer does not only include the actual
uplink data. It also includes the frames which are received when the channel
is idle (which is just noise). This would falsify the measurement results.

Depending on the BTS model, the phy may also filter the idle frames and not
send a DATA-IND at all, when the channel is idle. If this is the case, the
measurement period end can not be detected properly.

The idle frames are located at the very end of each measurement period. In
order to fix the issue, the measurement perioud has to end early. For TCH/F and
TCH/H 1, one frame has to be skipped. For TCH/H 0 two frames are skipped.

Example: For a TCH/F in TS0, the Measurement perioud would end at frame number
103. However, 103 is reserverd as idle frame. So we need to detect the end of
the measurement period at frame number 103 (-1).

Change-Id: I471a767c7974bdacadc3233d0c3e7b7965f6eafa
2017-05-24 22:19:02 +00:00
Pau Espin Pedrol
27b022e0c4 phy_link: Fix typo in state being printed
Change-Id: I312eefa6738f8abdeedd2efb574f3e45cd2e8aa3
2017-05-24 19:26:48 +02:00
Max
3aeb9301f4 Remove redundant test
After switching to libosmocoding there's no need in low-level bursts
test which is part of libosmocoding anyway.

Change-Id: Icb8caf62ac653a39a7a82f2225e8edeab7f5afb5
2017-05-22 09:37:27 +00:00
Max
efbef50efc osmo-bts-trx: use libosmocoding
Remove built-in functions and use libosmocoding instead.

Change-Id: I1b41bb1a8de655639107ec1f3b75afc240fd316f
2017-05-22 09:37:26 +00:00
Philipp Maier
9c1d3f9606 measurement: Compute measurement results on measurement idication
Computing the measurement results on in l1sap_info_time_ind() all
at once may peak the host CPU. On smaller systems (arm based
sysmobts) this might cause a noticable delay of other important
tasks (e.g. passing l2 messages back and forth) It makes more
sense to compute the measurement results continously when
l1sap_info_meas_ind() is executed.

Change-Id: Iecb9a30c0d716bfc88221cd752b1ffdc74269e30
2017-05-17 18:56:51 +02:00
Philipp Maier
2f028c4e2c measurement: make lchan_meas_check_compute() available to l1sap.c
lchan_meas_check_compute() is a static function measurement.c.
In order to distribute the measurement result calculation events,
we need to be able to call lchan_meas_check_compute() from l1sap.c

Change-Id: Ideffe896613e0feda443bc13dac59dcdbbc605aa
2017-05-17 18:56:51 +02:00
Philipp Maier
67d8c72c2e measurement: fix measurement reporting period
The measurement reporting for the MS on a SDCCH lacks some of
the periods, defined in 3GPP TS 45.008, section 8.4.2. This
adds the missing conditions by adding complete lookup tables.

Change-Id: I23fba50f48415314da40cf5bf86fce2ed3e66af6
2017-05-17 18:56:24 +02:00
Philipp Maier
b16eed22c7 octphy: ensure that 11 bit rach flag is not set
The l1 interface does not explicitly set the flag for 11 bit
rach when a rach request is received. Since the current and
previous octphy firmwares do not support 11 bit rach requests,
the flag should be explicitly set to zero.

Change-Id: Ifa165c56e54d272caafa45d1bf0e177848fcdfbd
2017-05-17 16:22:27 +02:00
Philipp Maier
2c841100a9 octphy: align frame number for new firmware versions
Firmware releases OCTSDR-2G-02.07.00-B1314-BETA and newer require
to align the GPRS frame number (fn-3) for ph_data indications.

To preserve compatibility the header version is checked during
compile time and the right method is compiled in.

Change-Id: Ib93d5fb3b34ff92f10021a0e9ce9c8aa3044b7ff
2017-05-17 16:22:27 +02:00
Philipp Maier
17a09507b8 octphy: activate CBCH after all physical channels are activated
CBCH is activated when the SAPI for TS0 is activated. Since the CBCH can be
configured on any physical TS, we wait until all (TS7 is the last) physical
timeslots are configured.

Change-Id: Ie307bf9f370a346686e3bd8c8a8483953a1bc279
2017-05-17 16:22:27 +02:00
Philipp Maier
e3de64cd67 measurement/cosmetic: Fixup source code comment
the function is_meas_complete() uses the *_meas_rep_fn104[]
lookup tables, defined at the beginning of the source file.

These lookup tabels contain a lot of magic numbers. This
commit adds a more elaborated comment with a reference
to the specification/section in order make the values
understandable.

Change-Id: Ic6e4037f965772e6b851c67662d5e7bf64cc04eb
2017-05-17 14:42:00 +02:00
Philipp Maier
22704a88e2 measurement/cosmetic: Fixup source code comment
the function ber10k_to_rxqual() has only a very brief
comment with the spec reference. This commit adds a more
explainatory comment that makes it easier to understand
from where the ber10k constants are taken.

Change-Id: I3d3488c97d0bffa7d449d3675afcc75b2a6a2703
2017-05-17 14:41:52 +02:00
Max
2d848a061e Prepare for BTS attribute reporting via OML
* move BTS model name resolution into separate function
* add convenience wrappers for BTS type and number fo TRX and use then
  in L1 interface

Change-Id: I4649100df8f1b8e095f210fc294567ba014c0b6a
Related: OS#1614
2017-05-15 08:12:15 +00:00
Max
8913b29be2 Set BTS variant while initializing BTS model
This will allow proper BTS attribute reporting via OML in follow-up
patches.

Change-Id: I1c49d6c39fb4dac7a46ee25ceacf4c6ef0f0b736
Related: OS#1614
2017-05-10 07:50:00 +00:00
Vadim Yanitskiy
028820510e osmo-bts-trx/l1_if.c: cosmetic: drop double check
Change-Id: I25a8f85ee65e1c0dd54049ffacc039702ca36c8f
2017-05-09 22:18:19 +00:00
Max
9563039a2a Prepare for extended SI2quater support
SI2quater support as per 3GPP TS 44.018 will require chnages to the way
System Information is stored because it uses 1:n instead of 1:1 mapping
between SI type and generated SI content. This should not affect other
SI types though. To facilitate this transition:

* convert the code to always use GSM_LCHAN_SI helper instead of
  accessing buffer directly
* move duplicated code to inline function
* add logging for buffer truncation and corresponding length values

Requires I74e4e3cb86364cec869a1472a41b4a95af0d50dd in OpenBSC.

Change-Id: Ie97be6ead6ce6d2d425fbfac8429bb90afb95acc
Related: RT#8792
2017-05-09 09:10:45 +00:00
Max
9d5ec1af74 Signal to BSC when PCU disconnects
While at it - do not serialize NULL as a string when delivering OML
Failure Report.

Change-Id: I41a731bd719aee0bbb98d3236405fb3a7f3ddec0
Related: OS#1615
2017-05-08 08:31:52 +00:00
Philipp Maier
91685096f8 bts: revert trx shutdown order
When a new TRX is allocated using gsm_bts_trx_alloc() (see gsm_data_shared.c in
openbsc.git), than it is added to the list in order. When octphy is shutting
down the BTS, it uses llist_for_each_entry() to iterate the tansceiver list to
shut all transceivers down. This means it starts the shut down process with
the primary TRX and then continues with the secondary transceivers in order.

However, octphy does not allow to close primary TRX if the secondary TRX is
open. The shutdown sequence must begin with the secondary transceivers and
finish with the primiary transceiver as last item.

The problem can be easily fixed by iterating the transceiver list in reverse
order using llist_for_each_entry_reverse() instead of llist_for_each_entry()

Since this is a change in the common code, all BTS models (not only octphy)
are affected, but from the logical perspective, this change makes sense
for all other BTS models too.

Change-Id: I18485de586b402610f9e98053d69e92bc9b18dc2
2017-05-08 07:46:25 +00:00
Holger Hans Peter Freyther
40dca8f991 sysmobts: Store a simple network config in the EEPROM as well
Make it possible to store:

	* Static vs. DHCP mode
	* IPv4 address
	* Netmask
	* GW IPv4 address
	* DNS IPv4 address

Add a simple CRC8 and pick 0xFF as initial value so an all
zero EEPROM will not generate a 0 CRC. The code tries to
differentiate exit code between unreadable EEPROM and CRC error.

This is a reference to see if we want to have store it in the
EEPROM or not.

Change-Id: Id8a37fe952ef2a8ef36778729f506f900accf8d1
2017-04-30 21:45:08 +00:00
Holger Hans Peter Freyther
d62a58dbfb sysmobts: Make reservation for mode/netmask/ip and suc
Change-Id: Ib98856356dc296be9e449d35479bc9234c0c4d32
2017-04-29 11:56:29 +00:00
Max
322252d793 osmo-bts-trx: cosmetic log fix
Print actual value causing error and the check range.

Change-Id: Ic36c0558cdbd1790c167f290a40007b42f5de65d
2017-04-28 08:47:21 +00:00
Jean-Francois Dionne
fce5b31b94 Fix RTP duration adjustment not done when speech resumes in DTX mode.
RTP jitter increases continuously because duration is not
updated when speech resumes in DTX mode.

Change-Id: Ib51ed95a449369222c957b3acebd9ce1f66c5435
2017-04-27 10:14:59 +00:00
Max
b4bf603c98 Add MS TO to RSL measurements
Add optional MS timing offset (3GPP TS 45.010 § 1.2) to RSL MEASUREMENT
RESULT (3GPP TS 48.058 § 8.4.8). The value is calculated either directly
from corresponding BTS measurement or from 3GPP TS 48.058 § 9.3.17
Access Delay (for known TA) and is invalidated after RSL report is sent
until new measurement indication or RACH is received.

Change-Id: I4dfe5c48834a083e757d5de3236a02e15a238b28
Related: OS#1574
2017-04-26 12:42:09 +02:00
Philipp Maier
25742a5929 octphy: set tx/rx antenne IDs via VTY
add support for the TX/RX antenna-id feature that has been
introduced with release OCTSDR-2G-02.07.00-B1314-BETA. The
user can now set individual ID numbers for the TX and for
the RX antenna.

Change-Id: I872fe3c4d7b593358a4ce2f02cf0726611b9f3aa
2017-04-13 19:08:47 +02:00
Philipp Maier
e4403464ed octphy: add conditional compilation to support latest octasic header release
With octasics latest release (octsdr-2g-02.07.01-B1351-beta), some struct
members are moved or renamed. This patch adds ifdef-logic and configure
checks to restore compatibilty.

Change-Id: I73287983e8bed8bf64b2ab87e6b810c2c59ea6fd
2017-04-13 19:03:56 +02:00
Philipp Maier
7a21dccec1 octphy: display hint in case of wrongly configured transceiver number
Making use of the multi-trx feature requires to tell osmo-bts that
more than one transceiver are available. Otherwise it will complain
that not enough transceivers are available. This can be quite
confusing, even a correct config file will fail to parse if it
specifies more transcrivers than available.

This patch adds a hint to the error message so that the user knows
that he should check the -t commandline option

Change-Id: Ifbeacd9d43f7c6cd74a1e1b33288e66828fe843f
2017-04-13 19:03:56 +02:00
Philipp Maier
d040bf97de octphy: print log message for multi-trx support
Some header file versions support multi-trx and some do not. After
to compiling it is very difficult to find out if the binary is
multi-trx capable por not. This patch adds a log line that should
rule out any doubts.

Change-Id: I257c0a5e7c5ff5df2f0a603d1ede6db5679382e0
2017-04-13 19:03:44 +02:00
Philipp Maier
1fde15c8bd l1sap: improve log output
Print toa and ra value with the "RACH for packet access" log
message.

Change-Id: I3a2dde95947438aa8348a0a9fc8566cbc177aa2d
2017-04-13 19:02:46 +02:00
Philipp Maier
8e7a51d8c3 octphy: add CBCH support
add Support for CBCH channels in osmo-bts-octphy

Change-Id: Ic5c8363b4dd8ba78ab22bd5527c08d1162331540
2017-04-13 19:02:29 +02:00
Philipp Maier
416ee3ec89 octphy: fix usage of wrong define constant
octphy_hw_get_rf_ant_tx_config() uses define constant
cOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_RX_CONFIG_CID instead of
cOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_TX_CONFIG_CID. This commit
replaces exchanges the wrong constant with the correct one.

Change-Id: Ie4de23daf79bb07ca0c0b818eefe350d18d27e4d
2017-04-13 19:02:07 +02:00
Max
dafb363533 Handle TXT indication from OsmoPCU
* handle OML message
* handle OsmoPCU version message
* show stored PCU version in 'show bts ..' vty command

Requires OpenBSc with I6710d53115f34634a7b70969cc05fd5c72ff8ab2.

Change-Id: I16e73198501487a5b1076bf83390b85538d5af73
Related: OS#1614, 1615
2017-04-10 06:57:39 +00:00
Harald Welte
bbe90fd651 sysmobts: Don't start with 0dBm TRX output power before ramping
In case a system has a high-gain external PA (like a 40dB PA) connected
externally, we cannot simply switch the transceiver to 0 dBm in
trx_init() only to then start the ramping at much lower levels once the
PHJ completes in trx_init_compl_cb().  The result would be a short
0 + 40 dBm spike followed by later ramping.  We want to avoid that
spike, particularly its associated inrush current, so let's bring up the
board with smething very conservative like -50 dBm, and then ramp from
there.

Change-Id: I0ad91fce64f65e0213c9fcfde3390ace519055db
Fixes: SYS#3259
2017-04-06 18:41:01 +02:00
Max
e16b593574 vty: reduce code duplication
Use libosmocore's osmo_str2lower() instead of local equivalent.

Change-Id: I7faced2eaf0f6f87f06081235eea9d4c3ba71a7e
2017-03-23 13:08:39 +01:00
Vadim Yanitskiy
957843959d osmo-bts-trx/l1_if.c: use channel combination III for TCH/H
Currently the channel combination II is used for TCH/H, which
allows only one lchan to be allocated. The reason is that it
saves a bit of CPU by disabling UL burst detection on lchan 1.

There is also the channel combination III, which allows to
increase channel capacity, providing two lchans on a single
TCH/H timeslot.

Ideally we should implement some dynamic II <-> III switching
depending on the network load level. But for now this change
replaces the channel combination of TCH/H by III, until dynamic
switching is implemented.

Fixes issue: https://osmocom.org/issues/1795

Change-Id: I8fd4abb42c153fcd26bcfe22a2554b5c2d02d810
2017-03-23 11:35:05 +00:00
Max
f4816fa577 Sync protocol with OsmoPCU
Copy-paste changes from OsmoPCU commit 0a8fae8d141c2cfa4387ffe9b35402d5b8cc85cd.

Change-Id: I15e6cc86604947a173e8675ba4b41a3bda2d3296
2017-03-23 10:04:38 +00:00
Max
a80c7024f8 osmo-bts-trx: fix scheduling of broken frames
* DTXu: don't set marker for broken frames
* do not attempt to send 0-length bursts to avoid flood of errors after
  bts startup

Change-Id: Icb536f951386b9abe34c0dacbb203f3db1e41bb3
2017-03-23 10:03:27 +00:00
Philipp Maier
b609ee879e l1sap: fix PTCCH detection
The macro L1SAP_IS_PTCCH(fn) only detects a PTCCH channel at fn%52 = 12,
the detection logic has been extended in order to detect PTCCH at fn%52 = 38.

See also 3GPP TS 05.02, Clause 7, Table 6 of 9

Change-Id: Ia6f3333121e5e920c5e1d562a081d0a1b58a1153
2017-03-20 12:36:21 +01:00
Harald Welte
f9eef0ce3e README: update some of the limitations
Change-Id: Ifec983e02ce517d4fe17d595b65312c53b0429b7
2017-03-17 17:49:12 +01:00
Harald Welte
83c4fbc2dc README: Add general project information and convert to markdown
Also, make sure README.md is included in EXTRA_DIST

Change-Id: Icd9192833e1f95758c84cad85f0f0289ff4eb32a
2017-03-17 17:35:27 +01:00
Neels Hofmeyr
f462c87581 jenkins: add value_string termination check
Change-Id: Id4eb92924c03748563921e3f56cc0e5e0ffff502
Depends: libosmocore change-id I2bc93ab4781487e7685cfb63091a489cd126b1a8
2017-03-16 19:00:39 +00:00
Philipp Maier
339b9329ff l1sap: fix rach reason (ra) parsing
The ra parameter indicates the reason for the received rach
request. osmo-bts uses the ra parameter to determine if the
received rach request is packet access related. If yes,
osmo-bts will forward the request to the PCU.

In order to determine if the ra is packet related or not,
the higher 4 bits must be equel to 0x7 and at least one of
the lower 4 bits must be zero.

The current method lacks checking of the lower 4 bits. It
would also accept 0b01111111, which is reserved for future
use. This commit extends the check to take also the last
4 bits into accound.

See also: 3GPP TS 04.08, Table 9.9

Change-Id: I5eb88c42a91e158d9bfa4105ec9636035baf8959
2017-03-15 13:37:55 +00:00
Max
9dfdf54d30 Check for suitable lchan type when detecting HO
Log error when handover RACH is detected on wrong channel: according to
3GPP TS 44.018 it can only be seen on SACCH and DCCH.

Change-Id: Iacbcc8441d6cfbb8f808948a8baddde1ebca488a
Related: OS#1898
2017-03-14 14:17:44 +00:00
Max
6f5e398ccb Handle ctrl cmd allocation failures
Check that ctrl command was successfully allocated before using it.

Fixes: CID163884
Change-Id: Id19e1ce5fae6f936c9ed93f9a6317b57d28d7311
2017-03-14 08:59:19 +00:00
Max
a1b891aab4 Remove code duplication
Use gsm_bts_trx_num() from OpenBSC instead of static function.

Change-Id: Iba80e7a12c85976981a49a9424db069fc4110373
2017-03-07 18:42:27 +01:00
Max
4acc98e68a Use oml-alert CTRL command for temp report
Send temperature reports via OML alert facility exposed by CTRL
protocol.

Change-Id: If29fbd0ab01fefc76e87b90cf1fbc81b2089ba76
Related: OS#1615
2017-02-24 15:03:37 +01:00
Philipp Maier
758522947f octphy: Fix VTY commands
The VTY commands show phy 0 rf-port-stats and show phy 0 clk-sync-stats
do not output their results on the VTY console. If one of those commands
is entered the user is prompted to view the logtext, which is an
uncomfortable solution. This commit adds the missing functionality to
print the information in the VTY as well.

octphy_hw_api.c contains two value_string structs (radio_std_vals and
clocksync_state_vals) which are now exported in octphy_hw_api.h in
order to access them from octphy_vty.c

Change-Id: Iae5aa91fe2ebba7c2874eed88b15ed66e8c9cd61
2017-02-22 10:09:32 +00:00
Ivan Kluchnikov
64d16028eb oml: Fix incorrect usage of const variable abis_nm_att_tlvdef_ipa
This bug was introduced during moving oml definitions from osmo-bts to libosmocore
in libosmocore 0bee65c0d89f81a4b90aa3d484016d9ba680dd46 and
osmo-bts 2cf6b73a42:

The type of abis_nm_att_tlvdef_ipa was changed from struct tlv_definition to
const struct tlv_definition, so:
 * create static abis_nm_att_tlvdef_ipa_local variable for oml attribute
   definitions
 * copy abis_nm_att_tlvdef_ipa to abis_nm_att_tlvdef_ipa_local
 * merge abis_nm_att_tlvdef with abis_nm_att_tlvdef_ipa_local
 * use abis_nm_att_tlvdef_ipa_local in oml_tlv_parse function

Change-Id: Ia9f3c94ab247adeecb26a01c3ccd6f3a8c17ba1c
2017-02-20 13:28:38 +00:00
Ivan Klyuchnikov
70c68853c2 osmo-trx-bts: Fix incorrect bts shutdown procedure in case of clock loss from osmo-trx
This issue occurs in case of osmo-trx restart which leads to losing clock from osmo-trx.
Function bts_shutdown from common/bts.c should be used in this case for proper bts shutdown.

Change-Id: Ie65cf2e8f98cb8bf3314a00048aa53c1f8cd4c25
2017-02-19 08:58:20 +00:00
Harald Welte
6b4c6aa375 sysmobts: fully support trx_power_params
The simplistic approach of sysmobts_get_nominal_power() is insufficient
to cope for devices that have an internal PA.  The Actual transceiver
board is driven to a certain level (0..23 dBm typically), and the
external PA must be handled independent of that.  Increasing the return
value of sysmobts_get_nominal_power() would result in the sysmoBTS
mainboard attempting to reach a higher power, which is wrong.

This change affects sysmoBTS 1020 and 1100.  It causes power-ramping to
be used by default.  For 1002 and 2050, no behavior change is expected.

Change-Id: Ieff75d5becaa80a2097b6e744c75c2d16259c9a4
2017-02-14 17:31:27 +00:00
Ivan Klyuchnikov
c4ac69dcc2 osmo-trx-bts: Fix incorrect bts shutdown procedure in case of abis connection closure
This issue occurs in case of osmo-nitb restart which leads to abis connection closure.
Function bts_shutdown from common/bts.c should be used in this case for proper bts shutdown.

Change-Id: Id025e703dd5c91896d450d200e88e46552f178f0
2017-02-14 16:50:11 +00:00
Max
b390dfb90d Fix typo in TCH/H interleaving table
According to Table 4 in 3GPP TS 45.003 j=11, b=3 case corresponds to
k=91 and not j=12 as was previously used.

Change-Id: Iad3cf545b2f7e16276466cc37dd7a1e7858467e5
2017-02-10 16:43:44 +01:00
Ivan Klyuchnikov
0418ef588c osmo-trx-bts: Fix osmo-bts-trx crash on startup during reading phy instance parameters from config file
pinst->u.osmotrx.hdl should be allocated before reading phy_instance parameters from config file and applying them.
So allocation of pinst->u.osmotrx.hdl should be moved from l1if_open function to bts_model_phy_instance_set_defaults function,
which is proper place for this allocation according to start-up procedure of osmo-bts.

Change-Id: I6e23f92644400acb268818c9373a8fb10c003da1
2017-02-10 13:37:50 +00:00
Ivan Klyuchnikov
e2e0ed5a89 osmo-trx-bts: Fix incorrect setting of RXGAIN and POWER parameters on second channel (TRX1) of osmo-trx
Move rxgain and tx-attenuation (power) parameters from phy_link layer to phy_inst layer.
Rxgain and tx-attenuation parameters should be set for each phy_inst and send for each osmo-trx channel accordingly via control commands.

Change-Id: I4861a59d10d1ef91954e0c6ea265e66dec08844f
2017-02-10 13:35:41 +00:00
Alexander Chemeris
d5414cc30e rsl: Output RTP stats before closing the socket.
It's useful to know RTP statistics (number of packets lost, jitter, etc)
when looking at voice call quality issues. Right now this information is
not avialable anywhere and this looks like the best place to start.

Change-Id: Ife9f27c43157b4a1bf71aba41cd7b0f5f41ac99f
2017-02-10 12:23:38 +00:00
Neels Hofmeyr
ae50f7dac2 cosmetic: lchan_sacch_get: early-exit instead of nested-if
Change-Id: I1fbf7d7f619cc8194c8094cf4a1826b6114f0e11
2017-02-10 12:18:49 +00:00
Neels Hofmeyr
7a18906cfa all models: fix vty write: bts_model_config_write_phy
The vty write for phy/inst is broken, leading to a written-out config being
unparsable; fix all of these:

- in common/vty.c, actually call bts_model_config_write_phy_inst().

- in sysmo and lc15 write the phy instance elements in
  bts_model_config_write_phy_inst() and not in bts_model_config_write_phy(),
  which lead to writing the members above their parent 'instance'.

- sysmo, lc15 and oct omit the bts_model_config_write_phy_inst()
  implementation. This did not cause a compilation problem because it
  was in fact never called.

- sysmo writes 'clock-source None' when clk_src is zero, leading to unparsable
  config (related: OS#1944). Instead omit the 'clock-source' when zero.

- osmo-bts-trx seems to be the only part that lacks nothing, yet it
  also didn't work properly because bts_model_config_write_phy_inst()
  was never called.
  
This problem existed since commit d784e50747
"Introduce new phy_link and phy_instance abstraction"

Change-Id: Icc54fa70045c8fa58e78cf9f788c21a437edfbd4
2017-02-10 07:27:51 +00:00
Neels Hofmeyr
d15dc832c9 SACCH SI: assert that SI enum vals fit in bit mask
In case our SI enums ever move past 31, this static assert will warn us to
enlarge osmo_si_shifted.

Change-Id: I4185d7de590329ff5f523b241721c586ffdbcd8b
2017-02-08 19:34:14 +01:00
Neels Hofmeyr
1631266993 SACCH: fix sending of SI with an enum value > 7
In copy_sacch_si_to_lchan(), the variable to hold the bit mask for SI-is-valid
was chosen as uint8_t, and as a result none of the SIs with an enum value >= 8
would ever be sent. Use int for enum value and uint32_t for the bit mask.

Fixes: #1945
Change-Id: I85fa9a50691601bcd103845c6811caa061a39824
2017-02-08 19:34:06 +01:00
Neels Hofmeyr
3c144069da fix missing ~ in bit logic for lchan->si.valid in rsl_rx_sacch_inf_mod()
Upon rx of a SACCH INFO Modify for an lchan that has no L3 INFO IE, clear only
the si.valid bit in question, instead of clearing all but the one in question.

BTW, It first looked like it could be, but is *not* the cause for OS#1945
(SI5ter never sent to MS).

Change-Id: I0df20b6643b0bfd219ce1df594075838d8406719
2017-02-08 18:00:57 +01:00
Harald Welte
69d297ce75 Add new unit-test for transmit power computation code
This tests the computations of the tx_power.c code using sysmoBTS 1002,
1020, 1100 and 2050 values, as well as the power ramping code.

Change-Id: I1cc88d4c6edff326e2e67d4f869aa02c9b2b1ac5
2017-02-07 20:33:18 +00:00
Harald Welte
df5ac9aa11 tx_power: Change PA calibration tables to use delta vales
It seems more user friendly to look at a calibration table in terms of
the delta (positive or negative) compared to the nominal gain value,
rather than a collection of absolute gain values.  It has the added
benefit that the (API/data model) user doesn't have to specify a gain
value for each ARFCN, but rather can rely on the default nominal gain in
absence of a calibration table for this specific unit.

Change-Id: I7311815902a88d2fc9d211cf4c62fa6fdc5e86ad
2017-02-07 20:17:27 +01:00
Harald Welte
13d0feb404 tx_power: various cosmetic fixes in comments
Change-Id: I542b74d79bc8ffedd7c435b41b042edd5152f61c
2017-02-07 20:17:27 +01:00
Harald Welte
4ba7363286 Revert "sysmobts: Add correct nominal transmit power for sysmoBTS 1020"
This reverts commit 1965b0d880, which was
a premature change.  The 10dB gain are not the power of the TRX board,
but are due to an internal, factory mounted PA, i.e. the
trx_power_params.pa.  This will be introduced after adding a set of
tx_power.c unit tests.

Change-Id: I524b63c51fb0fe1f90ced28486a8e712f2dc50ae
2017-02-07 20:17:26 +01:00
Jean-Francois Dionne
eb4a3392e1 Fix SACCH channel release indication not sent to BSC after location update.
Based on GSM 04.08 3.4.13 RR connection release procedure, after the network
sends a deactivate SACCH it receives DISC from MS which cause BTS to
send RLL release indication to BSC in order to stop T3109 timer. It has been
found that after a location update BSC never receives RLL release indication
which causes a T3109 timeout because no TCH is currently allocated. This fix
ensures RLL release indication to be sent to BSC when no TCH is allocated
in the particular case of a location update.

Change-Id: Ibe2a365641eb8c9a7f0a462b7393ec3fd28cc366
2017-02-03 17:18:04 -05:00
Harald Welte
1beb9bcbe0 sysmobts_eeprom.h: Fix/extend model number definitions
Fix the model number definition for the 1020 and add the one for 1002.

Change-Id: Iba4cfbbda1000d7e34eca614b3a6165d2feb65e1
2017-02-02 18:43:29 +01:00
Harald Welte
1965b0d880 sysmobts: Add correct nominal transmit power for sysmoBTS 1020
The sysmoBTS 1020 is a 2W BTS, hence its nominal transmit powre is
33dBm.  We must handle this correctly based on the model-nr in the
EEPROM.   As a result, proper power ramping will be made during start of
the unit by default.

Change-Id: I91a78dadfd7d2e1bc74c8086808c55effdcdd132
2017-02-02 18:41:02 +01:00
Philipp
67bc885c5d octphy: Improve OML ADM state handling
Improve state handling for for lock/unlock of OC_RADIO_CARRIER obj class. in
bts_model_chg_adm_state()

Change-Id: I034114beca95210169429d8ac1eb8648df12fc6c
2017-02-01 19:16:17 +00:00
Jean-Francois Dionne
a760a043c4 Fix AMR HR DTX FSM logic.
Fix SID_FIRST_INH detection during speech and when SID_FIRST is interrupted by FACCH.
Fix SID_UPDATE_INH detection during silence and when SID_UPDATE is interrupted by FACCH.
Add a delay for SID_FIRST to appear at the right time after FACCH.
Fix extra byte sent in downlink for SID_FIRST and SID_UPDATE.

Change-Id: Ia811305e15541f2376005df736bd610e8b0d2f69
2017-02-01 19:13:16 +00:00
Minh-Quang Nguyen
16b4179fbe rsl: Fix dropping of LAPDm UA message.
In some cases, when successive mobile originated calls are made, the LAPDm UA
message gets lost because the channel is relased to early. Too overcome the
problem we do not send relase indications immediately. Instead a flag will be
set and the message stored and sent on the next TCH-RTS-IND.

This commit adds the functionality to store the release indication msg, to
rsl.c. It also addes the mechanism to forward the release indication to l1sap.c
See also coresponding change in openbsc.git:
Change-Id I15fc1ef8e9e83f009bde96de9a8e95702cffbce6

This patch is is a slightly improved/reformatted version of:
95d1f15ad1

Change-Id: Ie4f70c75f0137b4bd72d579b3a32575bac2fca38
2017-02-01 16:35:42 +00:00
Jean-Francois Dionne
42ffb325f8 DTX: fix "unexpected burst" error
Fix error during FACCH interruption of DTX for AMR HR.

Max's note: added fix for sysmobts.

Change-Id: Ib064952331b4f89676ee68a3d8078b1d9debe570
Related: OS#1801
2017-02-01 14:25:14 +00:00
Philipp Maier
9344080109 cosmetic: remove stray newline in octphy's l1_oml.c
Change-Id: I6b60e5ee03b9afe6595bf44c4a963d23d03a4eb7
2017-01-31 11:14:49 +00:00
Jean-Francois Dionne
8c45ae59f9 sysmo,lc15: fix memory leak at each call placed
Max's note: added same fix for default case and ported it to sysmobts.

Change-Id: Ife1293e3238cfda16eac9c28e7e81ffe5595e031
2017-01-31 11:06:52 +00:00
Philipp Maier
d81e5e963a cosmetic: Remove stray newlines in octphy_vty.c
Change-Id: I33f5c4a3f40c0299a7cdb9c62094f0f914edfc98
2017-01-31 11:02:40 +00:00
Philipp Maier
c1d8f5a490 octphy VTY: fix vty write output for octphy's phy section
Fix invalid configuration generated by VTY 'write' command for the 'phy'
section of osmo-bts-octphy.

The problem was introduced during refactoring
commit d784e50747 (Sat Jan 9 13:13:37
2016 +0100, "Introduce new phy_link and phy_instance abstraction")

Change-Id: Ib018e07e332aa8a6144fb2d87889032bd5fc2533
2017-01-31 10:39:25 +00:00
Max
f65b57a707 Add ctrl command to send OML alert
Change-Id: I228cb71ab945e19e3747843469a52f577ee32f97
Related: OS#1615
2017-01-25 13:29:03 +01:00
Max
871e0bec7e OML: internalize failure reporting
* make oml_tx_failure_event_rep() static and use osmo_signal_dispatch()
  wrapped into oml_fail_rep() to trigger event reports outside of oml.c
  instead of directly calling into OML layer
* remove unnecessary formatting from text messages

Related: OS#1615
Change-Id: I738555c547926e97b325ab53763c0076c42309bc
2017-01-25 13:24:52 +01:00
Holger Hans Peter Freyther
10b11325a7 build: Do not require more headers from OpenBSC
There should be no other OpenBSC headers included and nobody is using
bsc_controlif_setup. Remove the include. This was introduced in
4723a19508.

Change-Id: I581f938e8fe9161b1d7076cedd74ff192cea86b2
2017-01-24 14:56:44 +01:00
Holger Hans Peter Freyther
8be9d7a6fe debian: Use the header files installed by openbsc-dev
Use --with-openbsc= to pick up gsm_data_shared.h coming from the
openbsc-dev package. With the revert of the change
Iec6b0f0eb0b7fffaa814c9769c0ee777d641a07f, packaging could work
now.

Change-Id: Ie0a005315454a6450205ce6fd76242b85405de8d
2017-01-24 13:16:29 +00:00
Holger Freyther
ea5ccfa481 Revert "deb: use gsm_data_shared.* from openbsc-dev"
As the Osmocom project is providing packages and we build them
directly from git we should have native packages. openbsc-dev
should provide files in the same directory structure as the git
repository and then --with-openbsc=/usr/src/osmocom/openbsc/openbsc/include/openbsc
can be used. Follow up patches are coming.

This reverts commit 70b71507c2.

Change-Id: I8bc3a5c2b9446d9e94e362ed5d85a61e3a727f8b
2017-01-24 13:16:21 +00:00
Philipp
2b763cc30c octphy: set tx attenuation via VTY
add code to configure the transmision power via VTY

Change-Id: I76bb8660eb1d8baeb6b8f69da4a6ba9ab7319981
2017-01-23 12:23:17 +00:00
Max
70b71507c2 deb: use gsm_data_shared.* from openbsc-dev
Use gsm_data-shared.* from absolute path where it's installed by
openbsc-dev package instead of relative path to fix OBS package
building.

Change-Id: Iec6b0f0eb0b7fffaa814c9769c0ee777d641a07f
Related: OS#1860
2017-01-20 12:20:14 +01:00
Philipp
c37fd88985 l1sap: fix missing 'else's causing wrong rach frame expiry counts
This bug was introduced in the recently merged
commit 1e399f888e
aka change-id I87f40f5f160a4f6750c4f3d06997fc4f24049303

Fixes: coverity-scan CID#160156 and CID#160155
Change-Id: I88ed1b3e59213acdf97f88eda097b8172b952a5e
2017-01-16 23:38:30 +00:00
Philipp
1e399f888e l1sap: Fix expired rach slot counting
The counting of the expired rach slots in l1sap.c is not correctly
implemented. This commit fixes the implementation. The expired
rach slots are now conted correctly according to the configured
channel combination. If a CCCH and SDCCH are combined, only the
frames related to rach slots are counted.

Change-Id: I87f40f5f160a4f6750c4f3d06997fc4f24049303
2017-01-12 23:36:04 +00:00
Jean-Francois Dionne
0e5b12f981 lc15,sysmobts l1_if: fix memleak in handle_mph_time_ind()
Change-Id: I3061060235a488b114b636b3af9a2253a94de1e8
2017-01-12 11:13:35 +00:00
Max
df75195666 scheduler: log lchan on which prim error occured
Log both lchan and trx_chan_type (using introduced value_string).

Change-Id: I80c581b54eeee371ee524a75a400d1e9ece16c68
2017-01-10 23:29:06 +00:00
Jean-Francois Dionne
b76043e6f4 DTX: fix SID-FIRST detection
Max's note: made similar modification to osmo-bts-sysmo/tch.c

Change-Id: I76e62783b73803dfc0d32693a68020a9d89878b8
Related: OS#1801
2017-01-10 23:28:19 +00:00
Max
de6d25e21d Remove obsolete define TLVP_PRES_LEN
The libosmocore version required by configure.ac already has
TLVP_PRES_LEN anyway.

Change-Id: I3e33d9d1a6160ea17ab0a875c65a98129e3d19c1
2017-01-10 17:18:05 +01:00
Philipp
4723a19508 CTRL: make the CTRL-Interface IP address configurable
Currently the IP address where the control interface is bound
to is hardcoded to 127.0.0.1. This leads to problems with
multiple instances on one and the same machine. This commit
integrates the ctrl interface bind option into the VTY, so
that we can bind the ctrl interface to any IP address, just
like we do it with the VTY already.

Change-Id: If51e0c645c0789a4f4a8c51737fb81fb12f80829
2017-01-10 15:45:59 +00:00
Philipp
962b33ea9d OML: fix possible segfault: add NULL check in oml_ipa_set_attr()
oml_ipa_set_attr() is using gsm_objclass2mo() to determine the
*mo object. However, it is possible that gsm_objclass2mo() returns a
null-pointer. The code following up is using *mo without checking.
Reject instead of dereferencing a NULL *mo.

Fixes: coverity scan CID#159533
Change-Id: Ia2cc9bc504c46ca3843c43d712cd8649bfae9526
2017-01-10 14:14:51 +00:00
Philipp
563b744b38 RSL: add assertions to check args of public API
The public functions in rsl.c do not check for null pointers,
add assertions to catch null pointers early.

Change-Id: I63f127ce70a4127180f90238f564b63e355216ec
2017-01-10 14:13:56 +00:00
Philipp
792573dc97 RSL: drop obsolete NULL check
rsl_rx_paging_cmd() checks if the pointer *trx is NULL, this check
does not make much sense since *trx has already been dereferenced
without checking earlier in the code. Furthermore *trx is also a
mandatory parameter which must not be NULL.

Fixes: coverity scan CID#159534
Change-Id: I17dfb42ff404b2a1e18354fb7a7278089b407a79
2017-01-10 11:53:50 +00:00
Max
ec11a85929 Alarm on various errors
Send OML Failure Report for unsupported BTS attributes and other errors.

Change-Id: Ic163bcfb6361a8ebd39e0bc0f238ef51e2cb214e
Related: OS#1615
2017-01-08 11:09:58 +00:00
Max
c038cb7903 Add Abis OML failure event reporting
Send 3GPP TS 12.21 § 8.8.2 Abis/OML failure event report.

Change-Id: Ib1170edca2207752984a554d7a6a57c224f6d5f5
Related: OS#1615
2017-01-08 11:03:39 +00:00
Max
94dd5060c8 Log socket path on error
Change-Id: If912ac0bc815986de2a231facb5cf317a677be68
2017-01-06 17:30:01 +01:00
Max
2cf6b73a42 Move code to libosmocore
With libosmocore commits I9c3bc15662949654e7bba6aad5488c69ee7d0c45 and
Ieaaaed19da9c069fe451faa53d24c5b84d7d5615 functions to copy and merge
parsed TLV were added as well as abis_nm_att_tlvdef_ipa TLV definition
with related enums. Hence we can remove it from here.

Change-Id: Ia4980062ea88ffe9019b201f84e92e006ae3c2e3
2017-01-06 12:24:42 +01:00
Max
f3763590bd Add copyright for .deb packages
Add debian/copyright in Debian format which should have been added in
c2ecca6b04.

Change-Id: I4c7ef1286ba6d2f3c6aadc8ea1864be513f8cf1d
Related: OS#1694
2017-01-06 10:33:06 +00:00
Neels Hofmeyr
bfd42c2b0a fix: dyn ts: uplink measurement report
Fix pchan value used for uplink measurement decisions for dynamic channels in
TCH mode.

Fixes this error log message flooding the osmo-bts log when a dyn ts is serving
a voice call:

  <0004> ../../../src/common/measurement.c:104 (bts=0,trx=0,ts=3,ss=0) no space for uplink measurement

Change-Id: Id19316701fd8de6f295eeae0272eea0c315ab1b7
2017-01-06 10:32:19 +00:00
Max
f9778b2a26 DTX AMR HR: fix inhibition
* Unlike in AMR FR, in AMR HR incoming ONSET have to be treated
  differently depending on whether we've recently sent SID UPDATE or
  EMPTY frame. Split ST_SID_U FSM state into 2 states to accommodate for
  that and make sure that additional states specific to AMR HR are not
  used for AMR FR.

* Avoid sending E_VOICE and E_SID_U in corresponding states
  as those do not initiate FSM state transitions anyway. This decrease
  extra load from FSM signalling which otherwise would be triggered on
  per-frame basis.

* Introduce separate signal for SID First P1 -> P2 transition to avoid
  confusion with E_COMPL and E_SID_U initiated transitions from P1
  state.

* Don't init DTX FSM for SDCCH channels.

Change-Id: I229ba39a38a223fada4881fc9aca35d3639371f8
Related: OS#1801
2017-01-04 11:25:17 +01:00
Max
c2ecca6b04 Integrate Debian packaging changes
debian/control:
    * restructure to make it easier to incorporate further changes
    * update package descriptions
    * update project URL

debian/rules:
    * use proper hardening syntax
    * restructure to make it easier to incorporate further changes
    * remove useless comment
    * add cleanup and test overrides

debian/compat: update compatibility version

Change-Id: Ibf62448eee1df914d21834f5b54831e3f642b79c
Related: OS#1694
2016-12-22 15:11:05 +01:00
Ruben Undheim
86d7843712 Fix some spelling errors
Change-Id: I5b57102f961f8fd7fb0689ceeaa37dd021535b17
2016-12-22 14:04:22 +00:00
Jean-Francois Dionne
304420ca42 DTX: don't always perform AMR HR specific check
Disable check specific to AMR HR if not DTX is enabled.

Change-Id: I8af1daffbd7e59fef6e671dbd9b820497f82d354
Fixes: OS#1892
2016-12-22 12:55:30 +01:00
Max
fbe655f320 Optionally use adaptive RTP jitter buffering
* add vty option to manually enable adaptive RTP jitter
  buffering (disabled by default) on per-bts level
* use this setting on per-lchan level when setting jitter parameters via
  vty at runtime
* check and log result of osmo_rtp_socket_set_param()
* note: older libosmo-abis will ignore this setting which will be
  properly detected via return value
* if jitter buffer is disabled by configuring "rtp jitter-buffer 0" than
  adaptive buffering is disabled as well but it will be used if jitter
  buffer is set to different value for a givel lchan via vty

Change-Id: I489f3c419039f40b57c2ef0641c176478b8d3566
2016-12-16 14:04:50 +01:00
Max
fed8ce3c5a DTX: fix TS adjustment for ONSET
Previously timestamp was always adjusted according to FN difference. In
case of ONSET event this causes unnecessary TS gap with subsequent
speech packet. Fix this by checking Marker bit before performing
adjustment.

Change-Id: I9bf4b45aa990dd4014334dd846f43f793366056c
Related: OS#1801
2016-12-15 19:57:04 +00:00
Max
2c95ae6a09 osmo-bts-trx: fix lchan deactivation
Use chan_nr for deactivating lchan instead of lchan->nr: chan_nr is the
RSL Channel Number IE value, a bitfield aggregation of lchan type
bits (cbits) and lchan number (lowest three bits). The error was
introduced in 36153239bf.

Change-Id: I6dd7060422ab9d18743c1ff2ab419e3e7299d74d
2016-12-12 12:36:28 +01:00
Max
a1fa955212 Save RTP metadata in Control Buffer
Having RTP metadata is useful for debugging - save Sequence Number and
Timestamp next to Marker bit from RTP header.

Change-Id: I359b3bcb74fbfc071547fe2f9d837829374fe997
2016-12-09 11:54:38 +00:00
Max
55a7b07417 DTX: add explicit check if DTX enabled
Check explicitly if DTX is enabled for AMR before checking if SID frame
repetition is optional.

Change-Id: I660688d56505798cade1495c30338fd6806a3259
Related: OS#1801
2016-12-08 14:44:02 +01:00
Max
960dd993cd TRX: prevent segfault upon phy init
Previously if multiply phy instances were configured but not used
osmo-bts-trx would segfault. Terminate with clear error message instead
so user can correct configuration. Example configuration which caused
problem:
...
phy 0
 instance 0
 instance 1
...
 trx 0
  phy 0 instance 0

Note the 2nd instance of phy 0 which is not used in trx later on.

Change-Id: Id979506731ea92401458f1060e87aeb690901539
2016-12-05 18:55:49 +00:00
Neels Hofmeyr
20363d165e bursts test: test_pdtch: pre-init result mem
Fixes: CID#57943
Change-Id: I4547f47c4150759d5c4ab790e34e91b784b03b39
2016-12-02 12:10:03 +00:00
Max
4a85828462 Fix AGCH/PCH proportional allocation
Do not assume that 1 == BS_AG_BLKS_RES but take that information from
SI3. Note: due to current implementation quirks we activate channels
before SI3 obtained, than we deactivate channels upon receiving SI3 and
activate them again. This might not be necessary once we migrate to
proper OML state machines.

This affects lc15 and sysmo hw.

Change-Id: I11377b12680ac3b2f77f80e742b6f0af63fc9c1e
Related: OS#1575
2016-12-01 15:25:26 +00:00
Neels Hofmeyr
b58aa60d78 cosmetic: vty prompts: add space after '#'
Typically, our VTY prompts have space after the '#', but some of the osmo-bts
VTY prompts don't:

  OsmoBTS# configure terminal
  OsmoBTS(config)# bts 0
  OsmoBTS(bts)#gsmtap-sapi ccch

Add spaces after the '#' to yield e.g.

  OsmoBTS(bts)# gsmtap-sapi ccch

Change-Id: If0591a359e77f01abb76c4113181af7a7733ddd4
2016-12-01 15:21:52 +00:00
Max
36153239bf Remove duplicated code
Remove lchan deactivation related code duplication to facilitate future
use for dynamic CCCH re-activation.

Change-Id: Id0d3b19dbfaa16d1734321a07a6eb0355bfd77c9
2016-12-01 15:20:42 +00:00
Max
aabeb2eae4 DTX DL AMR: rewrite FSM recursion
Add explicit state for recursion (sending the different payload data in
response to the RTS request for same FN) and corresponding
transition. Remove ST_FACCH_V as with new explicit recursion handling it
becomes unreacheable. This makes it easier to maintain
preemption (interruption of current procedure due to FACCH or
Inhibition). This also reduces the number of possible transitions out of
each state thus reducing graph's cyclomatic complexity.

Change-Id: If39b68083d23a4a35f468a5d75f54eb733ebfd14
2016-12-01 14:49:43 +00:00
Alexander Chemeris
f4b238f91e trx: Add "maxdlynb" VTY command to control max TA for Normal Bursts.
Originally `maxdly` command in osmo-trx was contrlling max TA for Normal Bursts.
This was not a proper behaviour, because it was used to "control maximum
distance a handset can attach from" which is controlled by Access Bursts max TA.
Osmo-trx was corrected to apply `maxdly` to Access Bursts and a new command was
introduced to contrl max TA for Normal Bursts - `maxdlynb`. This patch adds
support for this configuration command into osmo-bts-trx.

If you wonder why would you need that - some test equipment (namely R&S CMD57)
has really bad timing sync and can generate signal a few symbols off. That
prevents osmo-trx from properly receiving otherwise perfectly good bursts
generated by CMD57. This configuration is a solution for this.

Change-Id: Ib5d255299668ac1ef9f0ce95e016f55ba3c82277
2016-12-01 14:49:15 +00:00
Neels Hofmeyr
103ddc7155 jenkins: add jenkins_bts_model.sh
Change-Id: Ie7c32e68f789414fdf3c407c0da06cbf983f751a
2016-11-30 04:25:42 +01:00
Neels Hofmeyr
704fba5dc2 add jenkins_oct_and_bts_trx.sh
Change-Id: Ib656d4592f5210e2c180f511a1c955d14397bd03
2016-11-30 03:01:30 +01:00
Neels Hofmeyr
dd8a4a85e4 add jenkins_bts_trx.sh
Change-Id: Ie27ffb72140cb37e6a05bffd90551197f1e9b5fc
2016-11-30 02:46:43 +01:00
Neels Hofmeyr
6f4ce14ed7 osmo-bts-trx: remove obsolete include of netif/rtp.h
Change-Id: Idf364fd7d69446a7a996062f71d701d9c6cca84c
2016-11-29 22:41:59 +01:00
Philipp
8ea93a8a7d octphy: multi-trx support: fix AC_CHECK order
The header file octphy/octvc1/gsm/octvc1_gsm_default.h is not
visible to the configure script when the octphy header files
are referenced via --with-octsdr-2g instead having them
installed in /usr/local/include. This results in a failed
AC_CHECK_MEMBER check for tOCTVC1_GSM_TRX_CONFIG.usCentreArfcn,
even if header files with multi-trx support are used.

The configure.ac script manipulates the CPPFLAGS in order to
make the octphy include files visible to AC_CHECK_ and restores
the original CPPFLAGS when done. This is required when
--with-octsdr-2g is used. AC_CHECK_MEMBER is executed
before the CPPFLAGS are manipulated. This causes no issues
if the headers are properly installed to /usr/local/include,
but does not work when --with-octsdr-2g is used.

This commit moves the AC_CHECK_MEMBER command into the section
where the manipulated CPPFLAGS are valid in order to fix the
problem described above

See also commit: f5494e84e8

Change-Id: I7bdfa4449cd6061c395cce315b372c2833520e37
2016-11-27 18:28:24 +00:00
Harald Welte
ae5405e2a4 vty: Ensure to not use negative (error) sapi value
Change-Id: I282311de8514c1cc0a1b716e97e90ddf48863bb4
Fixes: Coverity CID 57617
Fixes: Coverity CID 57618
2016-11-25 23:50:46 +01:00
Neels Hofmeyr
be671bc61f cosmetic: tweak README
I noticed that the README is prominently shown on github, so it makes sense
to get rid of the worst typos and misinformation there.

Change-Id: I60defef6224a78bb84d7d0b57bc8da17ad7877bb
2016-11-23 00:05:13 +01:00
Alexander Chemeris
f7b559f960 vty: Add commands to manually activate/deactivate a channel.
This is the easiest way I found to make BTS level loopback to work.
Another way to implement this is to have BSC/NITB to send the OML command, but
it's a longer path with no clear benefits.

Note, that the current code hardcodes the channel to be TCH/F with v1 speech,
which is what we need for the basic BER testing. We may want to extend this
later to support more channel types.

Change-Id: Ia2734afeff023e5b3d6b934c7e8b1ed95a071b72
2016-11-16 16:38:51 +00:00
Alexander Chemeris
b2fbdd023b l1sap: Fix use-after-free in loopback mode.
By default l1sap_tch_ind() returns 0 which signals to its caller that message
has been processed and can be freed. In case of loopback we're forwarding
the message to dl_tch_queue who will free it later.  Returning 1 from
l1sap_tch_ind() prevents caller from freeing message.

Change-Id: I1e065075baa51c88fa717f132e1f0a83df68be02
2016-11-14 17:40:34 -08:00
Max
66325aee71 Replace link_id constant with define
Instead of using constant for link_id directly, use shared define value.

Change-Id: Ibf3d439d8893bd994ba089796175b6c635db2cf8
2016-11-11 15:52:49 +01:00
Max
bdf10eb705 Remove duplicated code
Having duplicated code to fill in fn & tn values makes it harder to read
and modify static gsmtap_p* functions. Fix this by removing the
duplication and moving the common code one level up.

Change-Id: I0e67bf7423424cc11435bc0a5a1110297eeee383
2016-11-11 12:22:11 +01:00
Neels Hofmeyr
c43352dbc4 fix 'osmo-bts-* --version' segfault
Call vty_init() before handle_options() to make sure the host.app_info is
populated before --version potentially tries to print it.

Change-Id: Ic87b5498b57b2f0f876171a15e769b74c28348c1
2016-11-09 15:44:30 +01:00
Max
c757272443 dtx_check.gawk: add check for repetitive SID FIRST
Change-Id: Id7acdfae7880fb488b65435ab8d33f2874499967
2016-11-08 16:27:47 +01:00
Max
388a91cbd1 Add libosmocodec for octphy build
Similar to 4582222757 fix build by linking
with libosmocodec explicitly.

Change-Id: Ib52135936ae02d804b60f61088b4bdd227a71aa0
2016-11-08 15:27:29 +01:00
Max
5ee3dba39f DTX: wrap FSM signal dispatching
Make wrapper function which checks that DTX is enabled for lchan before
dispatching any events.

Change-Id: Id8b519c4af6d505ec9a4b9aadd5107bf7af53d66
2016-11-08 12:28:52 +01:00
Max
9f936344ea DTX DL: tighten check for enabled operation
Introduce dtx_dl_amr_enabled() function which checks that DTX is enabled
and FSM is allocated and use it for all corresponding checks.

Change-Id: Ifa68b641265ed14f242765c85e40da2d1021a541
2016-11-08 12:22:40 +01:00
Max
57b5fb8819 Fix tests linking with libosmocodec
Change-Id: I051302f867d70dfbc39bd52d75101eb262f87459
2016-11-08 10:26:40 +00:00
Max
203ea2c209 dtx_check.gawk: Fix false-positives in DTX check
Previously, if ONSET happened exactly at the place where next SID FIRST
or UPDATE should be it was incorrectly detected as error. Similarly,
continuos FACCH was misinterpreted as error.

Change-Id: I43fdbceea0dbdb0833c3b1cf0fc3b825803ed30e
2016-11-08 06:54:36 +00:00
bhargava
38843fbf48 Initialize parameters in osmo-trx for 11bit RACH
The parameters related to support 11bit RACH are initialized in
osmo-trx. These parameter determaine the type of the RACH received
in osmo-pcu.

Change-Id: I164d449303373d0757719d5204f4716975fb517a
2016-11-08 11:56:08 +05:30
Max
acfccb3f02 DTX fix ONSET handling
* re-introduce ST_ONSET_F to guard from repetitive ONSET messages in case
  multiple FACCH occur duriing DTX silence period.
* produce ONSET event after both SID FIRST and UPDATE in case of AMR FR.
* always dispatch E_SID_F (SID FIRST) signal if in talkspurt.
* allow E_SID_* right after ONSET (zero-length talkspurt).
* add missing E_ONSET signal description.
* fix FSM transitions for AMR HR *Inhibited and First P*.
* fix incorrect return from l1if_tch_encode() in ONSET FACCH with
  incoming SID UPDATE

Change-Id: I0e9033c5f169da46aed9a0d1295faff489778dcf
Related: OS#1801
2016-11-03 12:31:37 +00:00
Max
4008ebb925 DTX DL: add AMR HR support to scheduling check
superfemto.sh: Expand log converter to use case-insensitive matching to
accommodate for spelling differences in DSP logs. Add strings/events
specific to AMR HR.

dtx_check.gawk: Remove redundand variables from output. Add checks
specific to AMR HR.

Change-Id: Icce3178605f46bbf3cad15d4eaff18a4d164ad1a
2016-11-03 12:31:37 +00:00
Max
9d102508a8 Remove obsolete define
It was moved to OpenBSC in 582e4f627674f46310a90d9061e82fb342051b42 as
it's used by both projects.

Change-Id: I8aba987e3cdaa840cf3e14913a8455b0ba759889
2016-11-02 09:29:39 +00:00
Max
bce25a60f4 DTX DL: split ONSET state handling
Handle ONSET cause by Voice and FACCH separately. In case of Voice we
have RTP payload which we have to cache and send later on in next
response to L1 RTS. FACCH have higher priority so it preempts both voice
and silence alike - hence we can send ONSET immediately but still have
to track previous state in order to get back to it gracefully.

This affects lc15 and sysmo hw as there's no FSM-based DTX
implementation for other models yet.

Note: this requires patch for OpenBSC which adds FACCH buffer to tch.dtx
struct.

Change-Id: Idba14dcd0cb12cd7aee86391fcc152c49fcd7052
Related: OS#1802
2016-10-28 13:42:29 +00:00
bhargava
efb4a4baeb 11bit RACH support for osmo-bts-litecell15
Based on the indication from L1, number of bits in RACH and burst
type is determined. Appropriate parameters are filled in
osmo-bts-litecell15. These parameters are sent to osmo-pcu for
processing of the RACH.

Change-Id: Ie5207a15424fb287febf74e830297531232accde
2016-10-27 19:54:53 +05:30
Max
64a2bd72f5 Add tools to check DTX operation
* superfemto.sh can parse superfemto-compatible DSP log output to
  properly sort records into MT/MO and DL/UL parts
* dtx_check.gawk can process output of superfemto.sh and check for
  common scheduling errors

This allows to check lc15 and sysmo for errors in DTX DL scheduling. As
dtx_check.gawk is generic it can be used with any other BTS hw (or
virtual BTS) as long as raw logs from this hw can be converted to simple
input format 'FN EVENT' per-line.

Change-Id: Ib1c70c4543b24c2a05a7df8eec5ce3f4eda2c02e
Related: OS#1801
2016-10-26 17:33:55 +02:00
Max
ced9a5d0e2 Fix DTX DL AMR SIDscheduling logic
Previously SID UPDATE was sometimes scheduled incorrectly. Fix this by:
* avoid rounding error when computing scheduling time difference from FN
* properly saving and updating cached SID type and FN

Change-Id: I7acffae4792e7bddc2ae19a2f04ee921dc194c36
Related: OS#1801
2016-10-24 08:55:19 +00:00
Max
5a4f4d12e1 DTX HR - fix array size calculation
Use ARRAY_SIZE macro for each pointer separately.
Fix suggested by Neels Hofmeyr <nhofmeyr@sysmocom.de>.

Change-Id: I68ec1be33fb743977121d654187d85d6b8451e2b
Fixes: Coverity CID 150132
2016-10-24 08:43:30 +00:00
Max
c22da59342 Extend RTP RX callback parameters
Adopt to change in libosmo-abis to accept additional parameters in RTP
RX callback function.

Change-Id: Icf41e568f041e87b38e6192af0be90c42362bfee
2016-10-21 19:53:34 +02:00
Neels Hofmeyr
068918f990 jenkins-oct.sh: fix build: typo in deps path
Change-Id: I05014e25ffc829fa2fc3973471baa28f7f5a62c9
2016-10-18 21:03:20 +02:00
Max
c88a10cece Fix lc15 build
The error seems to be introduced in 21142f7898

Change-Id: I620ac6774fb47479d74bc4470ccc6edd379600ba
2016-10-18 16:40:45 +02:00
Max
ebb483b69a Replace magic number with define
SDCCH occupy lchan 0..3 in combined configuration so for CCCH we've
always used lchan[4] - replace it with CCCH_LCHAN define and add
comment.

Change-Id: Ic5d742c292d638f119c6b4672120c1950adeb7f0
2016-10-18 08:08:25 +00:00
Max
b0c1d21581 DTX AMR - fix buffer length check
Consider AMR-specific prefix in computing max length to avoid triggering
coverity check.

Change-Id: I2fbc468caedf08f26893457db7c7fbacef5b860c
Fixes: Coverity CID 150133
2016-10-17 08:11:01 +00:00
Neels Hofmeyr
21142f7898 msgb ctx: use new msgb_talloc_ctx_init() in various main()s
Change-Id: I31d62d5e1f0b272985fdef5013270d385c4b988a
2016-10-14 01:23:28 +02:00
Max
b058778df1 DTX: fix array size calculation
Compute array size in-place and pass it to function.

Change-Id: I4cd480ceb20efc69df1b00e3c7359fcbd14c19cd
Fixes: coverity CID 1357844.
2016-10-13 11:02:59 +00:00
Max
de9dbe7958 TRX: fix building with latest DTX changes
Bring up-to-speed with latest changes in OpenBSC.

Change-Id: I16b24b2cd09600e215de163e7b5baae329887c9e
2016-10-13 11:45:56 +02:00
Max
babd05661d DTX DL: use FSM for AMR
Use dedicated FSM to handle all DTX DL related events:
- add explicit checks if DTX DL is enabled (fixes regression for non-DTX
setup introduced in 654175f33b)
- fix handling of AMR CMI for SPEECH frames
- add FSM for DTX DL
- sync with corresponding changes in OpenBSC's
- handle FACCH-related DTX ONSET events

This affects both lc15 and sysmobts and requires corresponding change in
OpenBSC (Change-Id: Idac8609faf9b5ced818fde899ccfc6ed0c42e8fd).

Change-Id: I74a0b42cb34d525b8a70d264135e82994ca70d31
2016-10-13 06:58:06 +00:00
Neels Hofmeyr
c09e5a44c3 jenkins.sh: use osmo-build-dep.sh, log test failures
Like in libosmo-abis' and other jenkins.sh

Change-Id: I6ad88bce18677b148af63ae8f6e0ab7e3b38b5a2
2016-10-12 11:29:05 +00:00
Philipp
93f3102da9 rsl: improving the log output
to show more details about the payload type and the connection

Change-Id: Ifaa253e5baed5ca364dfbc046a7cb559f106bfbd
2016-10-12 10:17:43 +00:00
Philipp
b8b939faa9 octphy: prevent mismatch between dsp-firmware and octphy headers
in its current statue l1_oml.c does not check if the version
number in the header files (octvc1_main_version.h) matches up
the version that is reported from the DSP during startip. This
patch ads a check to make sure that the currently loaded
firmware and the headers used during compile time match. If
a mismatch is detected, osmo-bts exits immediately.

Change-Id: Icba5756517d632d53b129c5ce1a1dab4936dab91
2016-10-12 09:57:18 +00:00
Max
4ca5be766c Move copy-pasted array into shared header
Change-Id: I377ece2845830e3defab2d515f44b629ce5aed8e
2016-10-12 09:30:06 +00:00
Max
9f9b96a67b DTX: fix conversion from fn to ms
Previously FN was converted to millisecondss incorrectly due to wrong
conversion between FN and a number of voice samples. The conversion
should be based on following:
* there are 12/13 useful frames for audio in TCH
* there is 1 RTP packet per 4 frame
* there are 160 samples per RTP packet

Fixes: OS#1801
Change-Id: I9cc70cacabde98621aa892cee74f4ac461645093
2016-10-11 18:20:15 +02:00
Yves Godin
c1b86d80d1 DTX: fix 1st RTP packet drop
Use "impossible" dummy value to initialize last_fn to prevent dropping
of 1st RTP frame due to timestamp jump.

Fixes: OS#1803
Change-Id: I485af21f6761048d12dc7f5552fcdd46daf786ed
2016-10-11 15:50:29 +00:00
Philipp
8b39ff8bcf octopy: fixing renamed constant
The constant cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNUSED in header
file octvc1/hw/octvc1_hw_api.h has been renamed to
cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_IDLE. This commit adds an ifdef
decision in to code to ensure that older header files will still work.

Change-Id: I4c0b976d29689ace06741c5943434fc33ee2df14
2016-10-06 10:12:04 +00:00
Philipp
f5494e84e8 octphy: reintroducing multi-trx support
The multi-trx had to be removed because of build conflicts
with octphy header that lack the struct members for needed
to support multi-trx.

For details see the following revert-commits:
ed6b48e4a5
c9a1f284ac

This commit reintroduces multi trx support and ads an ifdef
decision to ensure that header files without multi-trx
support still work.

Change-Id: I7f9b2906cc149c817183745b4c96bcc7f9ebdad0
2016-10-06 09:48:02 +00:00
Neels Hofmeyr
3f192f2291 configure: check for pkg-config presence
Change-Id: Ifee0434dfa275f9faa517c740fd8577930f37188
2016-10-02 13:29:21 +00:00
Neels Hofmeyr
fac02d3d75 build: be robust against install-sh files above the root dir
Explicitly set AC_CONFIG_AUX_DIR.

To reproduce the error avoided by this patch:

  rm install-sh        # in case it was already generated.
  touch ../install-sh  # yes, outside this source tree
  autoreconf -fi

This will produce an error like

  ...
  configure.ac:16: error: required file '../ltmain.sh' not found
  configure.ac:5: installing '../missing'
  src/Makefile.am: installing '../depcomp'
  autoreconf: automake failed with exit status: 1

See also automake (vim `which automake`) and look for 'sub locate_aux_dir'.

Change-Id: I02153ad52faf1465e9f7821378e04118f17352d2
2016-10-02 13:29:21 +00:00
Max
5f2e2de84f DTX: send AMR voice alongside with ONSET
When ONSET event happens (either via Marker bit or due to unmarked
talkspurt) we should first send Onset event to L1 and than send voice
data in response to the same PH-RTS.ind.

Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347
2016-09-30 19:13:08 +02:00
Max
067ef3f1ce DTX: move ONSET detection into separate function
Move code from tch.c (lc15, sysmo) into generic function which:
- check if talkspurt is happening
- cache SID if necessary or invalidate cache
- fill in CMR & CMI prefix

This also fixes the problem when SID FIRST was cached without sending
just like SID UPDATE instead of being sent right away.

Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916
2016-09-30 19:09:04 +02:00
Max
9959f45d90 DTX: further AMR SID cache fixes (lc15, sysmo)
* consolidate AMR CMR and CMI handling in common/amr.c
* use it in save_last_sid()
* remove dead code
* properly compute RTP payload length for AMR
* use save_last_sid() for FR & HR as well
* invalidate cached SID if SPEECH frame is received

Fixes: OS #1800, #1801
Change-Id: I5a1c1ad0b0a295a50e67775a4db85f1d331755ed
2016-09-30 18:57:00 +02:00
Max
7dffd553df DTX: move scheduling check inside repeat_last_sid
Note: this also require changes to properly link against libosmocodec -
see 2bb65be159dfdabf664fec569b343320301701b0 in libosmocore.

Change-Id: I96594cf3aa1013d505bd20069d5bf261d9a2aefb
2016-09-30 16:50:47 +02:00
Max
94fa25295f LC15: Clarify msgb ownership / fix memory leaks
This is similar to 21b020b336 which
changes the way msgb is allocated/freed in sysmobts.

Change-Id: I393828a7b1fb5927453ee25f54d605a5d3ea7087
2016-09-30 11:36:29 +02:00
Max
1559678fa2 DTX: remove misleading comment
There's no SID stored in UL direction so there's nothing to remove.

Change-Id: I3f587a66406bc6a02b859e826f4903641fcc5a15
2016-09-26 16:31:25 +02:00
Max
654175f33b DTX: check Marker bit to send ONSET to L1
If Marker bit is set than it's a talkspurt which we have to explicitly
indicate to L1 by first sending ONSET message and than actual voice
data in a separate message.

This change affect sysmobts and LC15 hw.

Change-Id: I88c41568bcb0d82699f617adc4ad192603dd1bb6
Related: OS#1750
2016-09-24 15:09:31 +02:00
Neels Hofmeyr
eb08a87be5 sysmobts_mgr, lc15bts_mgr: fix tall context for telnet vty
Instead of passing the msgb ctx to telnet_init(), pass the *mgr* ctx.

Change-Id: I213fe52648a1937d8f8c1730ce787e42f0add75f
2016-09-24 03:36:22 +00:00
Philipp
a570e05ec8 octphy: Fixing band selection for ARFCN 0
There is now an exception for ARFCN 0 in osmocom_to_octphy_band to
distingush ARFCN 0 (E-GSM) and 1-124 (P-GSM).

Change-Id: If012f31121e9d0d45b36459807c5f290aa17374f
2016-09-24 03:25:01 +00:00
Philipp
e2069d968c octphy: Fixing missing payload type in ph. chan. activation
in l1_oml.c:ts_connect() the payload type (ulPayloadType) was not
configured to full-rate for PDTCHF PACCHF and PTCCHF. Older octasic
firmwares (below octsdr-2g-02.06.00-B964-alpha) will tolerate this,
newer versions will crash during channel initalitation.

Change-Id: Id2f6a439ceb063b10efc7b9d1d70bb5b29a01033
2016-09-24 03:21:27 +00:00
Max
c77b574d1f lc15, sysmo: Use SID_FIRST_P1 to initiate DTX
Some phone seems to not send SID_FIRST_P2 message which seems like a
different understanding of the DTX spec. L1 accommodates for that by
using P1 to supply data for SID. Hence we should use it to initiate DTX
and ignore P2 message in case of AMR HR.

Change-Id: Iaf993b89caa0ad49b97d1c745dcaf039f867f018
2016-09-23 17:13:14 +02:00
Max
70460814ce DTX: fix SID logic
Previously receiving SID via RTP always caused it's transmission to L1
regardless of the time which might have resulted in excess traffic. Fix
this by only saving SID data and transmitting it later on as necessary
according to 3GPP TS 26.093 A.5.1.1.

Change-Id: Ifcdc5c60d0238b704a94f6778d4e00f2b087b090
Fixes: OS#1801
2016-09-23 17:03:00 +02:00
Max
527dd402c7 DTX: fix SID repeat scheduling
Previously SID retransmission was scheduled incorrectly based on GSM
frames instead of voice frames. Fix this by using GSM Fn only as elapsed
time estimation:

* move saved SID retransmission into generic function from lc15 and sysmo
specific code
* split retransmission time check into separate generic function
* compute estimation for elapsed time since last retransmission using
  GSM Fn

Change-Id: Ib054b458a7345d9ba40dba53754ca59ab099c8e8
Fixes: OS#1799
2016-09-23 16:57:05 +02:00
Max
80473a113d DTX: fix last SID saving
Previously SID was saved explicitly by each BTS model (lc15, sysmo)
instead of relying on generic function. Fix it by using generic function
and propagating necessary parameters for it.

Change-Id: Ie545212cce5ed2b3ea3228597f18a473f5e1deb4
Fixes: OS#1800
2016-09-23 14:53:46 +00:00
Neels Hofmeyr
0a05181603 heed VTY 'line vty'/'bind' command
Like most other osmo-* programs, bind the telnet VTY to the address specified
by the 'line vty'/'bind' command. This is added by vty_init(), so until now the
BTS offered this config but ignored it.

Change-Id: Ic4ab32aee08d8a779adeb9943892de0c828c7b3d
2016-09-22 07:04:54 +02:00
Neels Hofmeyr
b4969cc915 log causing rx event for lchan_lookup errors
Add log_name to lchan_lookup() and pass such from the various RSL rx events
that call it to validate the RSL chan_nr.

Change-Id: I0d9923f47ac655b204169eec302d607412d5754d
2016-09-19 02:12:23 +00:00
Neels Hofmeyr
a91b2d9691 log: sysmo,lc15: tweak log about sapi_cmds queue
The osmo-bts log used to say this a lot:

DL1C <0006> oml.c:758 (bts=0,trx=0,ts=0,ss=1) End of queue encountered. Now empty? 1

- Move this to DEBUG level instead of NOTICE.

- Tweak wording and logic so it says one of:
  [...] End of SAPI cmd queue encountered. Queue is now empty.
  [...] End of SAPI cmd queue encountered. More pending.

Change-Id: I5a46c90d016cee9b50f32db2af568765d3cb74cc
2016-09-17 09:58:27 +00:00
bhargava
ac84afa409 Update parameters in osmo-bts-sysmo for 11bit RACH
Based on the indication from L1, number of bits in RACH and burst
type is determined. Appropriate parameters are filled in osmo-bts-sysmo
These parameters are sent to osmo-pcu for processing of the RACH.

Change-Id: I93831ddfb3f31b637e6a576f23a9bb4557758582
2016-09-14 01:17:33 +00:00
Neels Hofmeyr
d44f0772f9 dyn TS: if PCU is not connected, allow operation as TCH
Before this patch, Osmocom style TCH/F_TCH/H_PDCH dyn TS were paralyzed if no
PCU was running. The state of the dyn TS would lock up in the PDCH activation
phase since the PCU never completed the process.

Make more robust, i.e. don't concern the BSC with PDCH activation failures.
This matches the way plain PDCH TS work: besides declaring the TS as PDCH, the
BSC is not involved and is not told about errors.

During PDCH deactivation, still wait for the PCU to tear down the PDTCH SAPIs,
but in case no PCU is connected, send a rel ack right away.

Thus, the BSC will happily switch Osmocom style dynamic timeslots to and from
PDCH mode, using the dyn TS as voice channels as needed, and not caring about
possible PDCH failures. GPRS starts working right away as soon as a PCU
connects, regardless of dyn TS having been used for voice any number of times,
and without another switchover needed.

In detail:

In rsl_rx_chan_activ(), upon receiving a PDCH activation, send an RSL chan act
ack right away, unconditionally (with an explaining comment). Do not concern
the Abis link with PDCH activation failures.

Since we're acking right away now, drop the chan act ack that would follow
after the PCU activation: as before dyn TS, only send acks and nacks for
rel_act_kind == LCHAN_REL_ACT_RSL (PDCH runs as LCHAN_REL_ACT_PCU).

In dyn_ts_pdch_release, indicate that the PCU is not connected by means of
returning 1. In rsl_rx_rf_chan_rel(), use this indicator to send a rel ack
right away if the PCU is not connected.

Change-Id: I2a0b9730197786b99ff3bc1f08c75f7d279cb1f7
2016-09-09 06:45:27 +00:00
Neels Hofmeyr
3cc91746a3 octphy: fix build with OCTSDR-OPENBSC-02.07.00-B708: name changed
There was an apparent change of name from
 cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_IDLE
to
 cOCTVC1_HW_CLOCK_SYNC_MGR_STATE_ENUM_UNUSED
in:

git://git.osmocom.org/octphy-2g-headers
commit 953a258aadf18c05e8128a339f15b1c5bb377cfd
"Import headers from OCTSDR-OPENBSC-02.07.00-B708.tgz"

In order to build octphy with these headers, apply the same rename in
osmo-bts-octphy/*.

Change-Id: Ic07055860035a7c1b83ab923817423eeb39f33d3
2016-09-06 15:41:10 +02:00
Neels Hofmeyr
c9a1f284ac octphy: fix build: Revert "octphy: add support for multiple trx ids"
This reverts commit c4fc00d851, except: we keep
the part that sets the trx_id in bts_model_phy_instance_set_defaults().

Theoretically, this patch makes a lot of sense, but in order to be able to
build osmo-bts-octphy until the headers version is clarified, revert use of
usCentreArfcn:

Above commit uses an usCentreArfcn member that is never defined in the history
of our octphy-2g-headers.git. This usCentreArfcn does exist in a code snapshot
OCTSDR-2G-02.05.00-B780-DEBUG, which is not (yet?) publicly available.

Also, the current headers version is apparently 02.07, though the octasic
version numbers have been known to cause confusion among osmocom folks.

This along with one other revert fixes this build problem:

make[3]: Entering directory '/n/s/octphy/git/osmo-bts/src/osmo-bts-octphy'
  CC       l1_oml.o
l1_oml.c: In function ‘l1if_trx_open’:
l1_oml.c:1350:13: error: ‘tOCTVC1_GSM_TRX_CONFIG’ has no member named ‘usCentreArfcn’
   oc->Config.usCentreArfcn = plink->u.octphy.center_arfcn;
             ^
l1_oml.c:1352:13: error: ‘tOCTVC1_GSM_TRX_CONFIG’ has no member named ‘usCentreArfcn’
   oc->Config.usCentreArfcn = trx->arfcn;
             ^
In file included from ../../include/osmo-bts/logging.h:5:0,
                 from l1_oml.c:33:
l1_oml.c:1365:13: error: ‘tOCTVC1_GSM_TRX_CONFIG’ has no member named ‘usCentreArfcn’
   oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb,
             ^

Change-Id: Ic643709e8fb3df2d66337190ed1f07fd230d7dca
2016-09-06 15:40:09 +02:00
Neels Hofmeyr
ed6b48e4a5 octphy: fix build: Revert "octphy: fix for multiple trx with more than 1 dsp"
This reverts commit 06968beab9.

Theoretically, this patch makes a lot of sense, but in order to be able to
build osmo-bts-octphy until the headers version is clarified, revert use of
usCentreArfcn:

Above commit uses an usCentreArfcn member that is never defined in the history
of our octphy-2g-headers.git. This usCentreArfcn does exist in a code snapshot
OCTSDR-2G-02.05.00-B780-DEBUG, which is not (yet?) publicly available.

Also, the current headers version is apparently 02.07, though the octasic
version numbers have been known to cause confusion among osmocom folks.

This along with one other revert fixes this build problem:

make[3]: Entering directory '/n/s/octphy/git/osmo-bts/src/osmo-bts-octphy'
  CC       l1_oml.o
l1_oml.c: In function ‘l1if_trx_open’:
l1_oml.c:1350:13: error: ‘tOCTVC1_GSM_TRX_CONFIG’ has no member named ‘usCentreArfcn’
   oc->Config.usCentreArfcn = plink->u.octphy.center_arfcn;
             ^
l1_oml.c:1352:13: error: ‘tOCTVC1_GSM_TRX_CONFIG’ has no member named ‘usCentreArfcn’
   oc->Config.usCentreArfcn = trx->arfcn;
             ^
In file included from ../../include/osmo-bts/logging.h:5:0,
                 from l1_oml.c:33:
l1_oml.c:1365:13: error: ‘tOCTVC1_GSM_TRX_CONFIG’ has no member named ‘usCentreArfcn’
   oc->Config.usCentreArfcn, oc->Config.usTsc, oc->RfConfig.ulRxGainDb,
             ^

Change-Id: I222766f6961f5f35aa3651e2907e3e908fe9a66e
2016-09-06 15:28:44 +02:00
Holger Hans Peter Freyther
8431bbb80f oct: Attempt to enable the Octphy for the osmo-bts-oct build
Change-Id: Ib41dfe35af1ed2ef270a436a8086a3120fe4d7d6
2016-09-06 13:57:54 +02:00
Neels Hofmeyr
bf6bae2b23 common/rsl: move decision whether to chan act ack/nack to common function
Prepare for a dyn TS patch that needs to call rsl_tx_chan_act_ack() directly
without the rel_act_kind decision.

Add function rsl_tx_chan_act_acknack() to wrap rsl_tx_chan_act_ack() and
rsl_tx_chan_act_nack(). Move the decision whether to drop the ack/nack, based
on lchan->rel_act_kind, to the new function, losing some code dup.

Change all callers to use the new function; drop the two older ones from rsl.h
and make them static.

Note: for nack, the exception for dyn TS in PDCH mode was missing
(rsl_tx_chan_act_nack() had only the rel_act_kind != LCHAN_REL_ACT_RSL
condition, but should also have had the dyn TS exception as in
rsl_tx_chan_act_ack()). I already know that this exception will again be
removed in an upcoming commit, but for patch readability it logically makes
sense to add it here. To easily include the nack case, drop the check for which
pchan the dyn TS is operating as, because a rel_act_kind == LCHAN_REL_ACT_PCU
implies that it is either already in or trying to become PDCH mode.

Change-Id: I57ba60c670730c6d7877a6a9b96ece0a7679a0bb
2016-09-02 04:12:16 +02:00
Neels Hofmeyr
8a148613b4 Fix ip.access style dyn PDCH, broken in 37af36e85e
Commit "sysmo,lc15: ts_connect_as(): log error also for pchan_as == TCH/F_PDCH"
introduced a check for TCH/F_PDCH intended only for TCH/F_TCH/H_PDCH. It looked
correct, but TCH/F_PDCH startup was designed differently:

For TCH/F_PDCH, the idea was to look it up in pchan_to_logChComb[] and obtain
the TCH/F channel combination, so that TCH/F_PDCH first initialize as TCH/F.
So pchan was in fact intended to be passed as TCH/F_PDCH.

For Osmocom TCH/F_TCH/H_PDCH, we've in the meantime added a ts_opstart()
function that makes this decision explicitly. So, instead of reverting the
erratic commit, add TCH/F_PDCH to ts_opstart(), for both sysmo and lc15.

In ts_opstart(), move to a switch statement to resolve the actual pchan to use
for ts_connect_as().

Drop TCH/F_PDCH and TCH/F_TCH/H_PDCH from pchan_to_logChComb[] and comment.

Change-Id: I376b92a06f4cbe943c1c913dea7487fac53a7d08
2016-08-30 12:38:04 +00:00
Neels Hofmeyr
4dfc3da96b dyn TS: sysmo,lc15: ph_data_req: fix PDCH mode detection
Though this patch theoretically makes a lot of sense, it is not entirely clear
why dyn TS are working without it. Committing due to common sense, not to fix
any actual breakage.

Change-Id: I6136cb42a4d627ebefc963eb5321fadfe63cca4b
2016-08-30 07:35:48 +00:00
Neels Hofmeyr
9faaf4ecf0 cosmetic: common ts_is_pdch()
Have one common ts_is_pdch(), placed in lchan.c, since this file is pretty
empty and pretty close to ts. Publish in gsm_data.h.

Remove the if-style implementation from l1sap.c, and instead implement in a
switch statement.

This prepares for upcoming ts_is_pdch() usage in ph_data_req() for sysmo and
lc15.

Change-Id: Ib78d663fdbac5a1d7053f1b9d543649b66da00e2
2016-08-30 07:35:47 +00:00
Neels Hofmeyr
3b2e5de3ae dyn TS: measurement: use correct nr of subslots, rm code dup
In measurement.c, fix the number of sublots for TCH/F_TCH/H_PDCH, by using
ts_subslots() from gsm_data_shared.c. The local dup of subslots_per_pchan[] is
no longer needed. (depends on recent commit to openbsc.git for ts_sublots())

Change-Id: I9d9df470c49487bffd56dde42c7bec0da2f50642
2016-08-30 07:35:47 +00:00
Neels Hofmeyr
988f634c97 log: l1sap: add 0x to hex output of chan_nr, 5 times
Change-Id: I187a74fd255dbdfb9bfb1e32786031a66f013efb
2016-08-27 12:31:32 +00:00
bhargava
e77bcaecb6 Change interface in osmo-bts for 11 bit RACH
Interface structure between osmo-bts and osmo-pcu is updated with the
parameters to differentiate the type of RACH and further support 11 bit
RACH. The function prototype and definitions are changed accordingly.
Interface version number is increased.

Change-Id: I4f4c501b2d86d77c78de32a84b1804172ffb6f4d
2016-08-27 01:20:46 +00:00
Max
43d082e6f1 sysmo: ts_connect: log channel combination name instead of number
Change-Id: Ife11cfdb0f83d56ed61e66286a79b7c3a000cce5
2016-08-21 14:02:30 +00:00
Neels Hofmeyr
55c46022e1 sysmo: fix dyn TS: Revert "Activate PTCCH UL" [in sysmobts]
This reverts commit 53d792c3b0.
See http://osmocom.org/issues/1796

The commit caused this error for PDCH TS with SysmoBTS:

DL1P <0007> l1_if.c:164 Tx L1 prim MPH-ACTIVATE.req
DL1C <0006> oml.c:811 Error activating L1 SAPI PTCCH on TS 7: Invalid parameter
DL1C <0006> oml.c:1089 (bts=0,trx=0,ts=7,ss=0) act failed mark broken due status: -4

Plain PDCH TS show this error but continue to function despite the SAPI
activation failure.

As a side effect, the SAPI activation failure breaks dynamic TS. GPRS
initially works, but the broken status prevents transitions to TCH/* modes
in the BSC:

DRLL <0000> chan_alloc.c:355 Failed to allocate TCH_H channel
DRSL <0004> abis_rsl.c:1656 BTS 0 CHAN RQD: no resources for TCH_H 0x45

Since the commit only enabled PTCCH UL in sysmobts, no other BTS models are
affected. Notice that lc15 still has PTCCH UL disabled all the while, before
and after this commit and its revert.

Also note that PTCCH DL is and has been enabled without problems (see
further above in sapi_dir_pdtch_sapis[]). This is only about PTCCH UL.

Related: OS#1796
Change-Id: Ia59d95c75a8a5d3bd596f55cd1dc0906a6a95f7f
2016-08-12 12:07:04 +00:00
Neels Hofmeyr
37af36e85e sysmo,lc15: ts_connect_as(): log error also for pchan_as == TCH/F_PDCH
Change-Id: I76c868a1e70af16268a6fa42dc736cf0b288ecdb
2016-08-10 18:06:20 +02:00
Neels Hofmeyr
63849ebf71 dyn TS: measurement.c: replace fixme with comment
Change-Id: I04668f6f01a48157a98c6326a9ee48982a09ee62
2016-08-10 18:06:20 +02:00
Neels Hofmeyr
67a056c122 dyn TS: complete for TRX
Apply similar fixes as for TCH/F_PDCH also for TCH/F_TCH/H_PDCH:

Detect dyn TS in PDCH mode in ts_is_pdch().

In trx_set_ts(), enhance the "if (TCH_F_PDCH)" to a switch statement including
both dynamic channel types. Adjust the comment to include both kinds.

Change-Id: I6669739cd08780cd9ffb9451cdae9f6b9704c4fe
2016-08-10 18:06:20 +02:00
Mike McTernan
ef8e2ef681 osmo-bts-trx: log decoder bit errors as DEBUG, not NOTICE
It is not an exceptional situation if the air-interface is experiencing
non-recoverable decoding errors.  At bad signal conditions and/or
interference, this is perfectly normal.  Let's use DEBUG instead of
NOTICE log level.

Change-Id: Ifd39c53ec22f57cdb5299e5d76ff6ff1482d3beb
2016-08-08 17:46:34 +00:00
Mike McTernan
b7cdd381d6 osmo-bts-trx: Fix PCS1900 operation
As the ARFCN numbers in DCS (1800) and PCS (1900) are not unique,
we need to specify the band in the upper bits of the ARFCN value before
calling gsm_arfcn2freq10().

Change-Id: I637b76bc1fc749eed8e364412d76606589991c02
2016-08-08 17:45:25 +00:00
Max
4b76a323b3 Fill measurements data for L1SAP
Fill in values for BER, BTO, Link quality in L1SAP and send them to
PCU. Note: this increases the version of BTS <-> PCU protocol. It also
requires corresponding changes in libosmocore.

All BTS models provide measurements data unless direct DSP access for
PCU is enabled. For BTS-specific notes see below.

Octphy: conversion from sSNRDb to Link Quality uses formulae which works
in practice instead of what's documented for sSNRDb value. Subject to
change in future revisions.

TRX: C / I link quality estimator is not computed.

Change-Id: Ic9693a044756fb1c7bd2ff3cfa0db042c3c4e01c
Related: OS#1616
2016-08-08 17:41:27 +00:00
Holger Hans Peter Freyther
b0f8fa8143 ci/spatch: Remove the "static" analysis handling
spatch on Debian 8.0 has already crashed twice and is likely to
crash more and at the same time the value for this static checking
is close to zero (nice idea but never blossomed). So let's remove
it, have a more reliable build and let's coverity find those issues.

Change-Id: Ic1004edf7f0bee8dda30b95554a0aaf0b116b6b8
2016-08-08 14:34:52 +00:00
Harald Welte
44663c17e7 Add .mailmap for mapping mail addresses in shortlog
Change-Id: I4789197e18fba6b1a376dc8645fdffa6120f6698
2016-08-08 11:31:00 +00:00
Tom Tsou
d6920df630 trx: Fix coverity BER calculation NULL dereference
Allow output of encoded bit count or error count on BER calculation
without requiring both pointers to exist.

Change-Id: I2c78fa6a92a3b3da4aad8f70353e5a43451b0aa5
Fixes: Coverity CID 137963
Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-07-28 11:48:25 -07:00
Neels Hofmeyr
af3443385b dyn PDCH: trx l1_if.c: drop fixme, add comment
Change-Id: Ib240f21f4d460524767f4273fc9077617d1ffb43
2016-07-28 17:58:40 +02:00
Neels Hofmeyr
0d4b37d641 dyn PDCH: complete for trx: implement bts_model_ts_[dis]connect()
bts_model_ts_disconnect() has nothing to do.

bts_model_ts_connect() merely sets the new pchan on the ts.

Change-Id: Ieb66935d6efc26854e95d238e810c4f8b16cfa88
2016-07-28 17:58:05 +02:00
Neels Hofmeyr
45d3bbfb44 dyn PDCH: trx l1_if.c: factor out trx_set_ts_as_pchan() from trx_set_ts()
To be able to set a specific pchan type for dynamic channels, have the
trx_set_ts_as_pchan() function with an explicit pchan argument instead of
using ts->pchan.

Keep trx_set_ts() as a thin wrapper to use ts->pchan directly.

Change-Id: I9eeef05d2a6763f86a5b89ee7c3b4211f6736e4d
2016-07-28 17:58:05 +02:00
Neels Hofmeyr
576071d6ca dyn TS, dyn PDCH: common/l1sap.c: properly notice PDCH
In l1sap_ph_rts_ind(), l1sap_ph_data_ind() and to_gsmtap(), the decision
to handle a TS as PDCH was still missing for dynamic TS.

It is not yet clear why this did not impact functionality for dynamic timeslots
on other BTS models. AFAICT they should not work without this patch, but in
fact they do. It would be nice to clarify this some day.

Change-Id: I7b873a089a3de70d980885a7539cb91997464743
2016-07-28 17:58:05 +02:00
Max
5069c1c518 octphy: fix build
The error was introduced in 61372a20de.

Change-Id: I9585eec018b88c5d0548a0a55fa4130bb26aa5b6
2016-07-28 09:52:53 +00:00
Max
108b60faba Fix dsp tracing at phy config
Due to missing runtime cmd patching DSP tracing was not possible at phy
level of config file. No it is possible to specify it as follows:

...
phy 0
 instance 0
  dsp-trace-flag debug
  dsp-trace-flag mph_cnf
...

Change-Id: Ibbbf81d2c4b5d3adbcbc1f08a844d262e603e571
2016-07-28 09:38:04 +00:00
Vadim Yanitskiy
ba656fff91 pcu_sock: use osmo_sock_unix_init() from libosmocore
Since the osmo_unixsock_listen() was moved to libosmocore
it would be better to use the library's implementation
instead of reinventing the wheel again.

Change-Id: Id5828649d44ef11e70946793696b0d689d6b35e3
2016-07-28 09:29:03 +00:00
Neels Hofmeyr
2b34ae32cf fix comment in common/l1sap.c, function name changed
Change was in 334df9441a
"cosmetic: clarify TCH/F_PDCH related naming and comments"

Change-Id: If3e353ea5796ee129bdd95e5f954e6c141cffec8
2016-07-28 06:31:24 +00:00
Max
53d792c3b0 Activate PTCCH UL
So far PTCCH was activated for DL but not for UL. Fix it.

Change-Id: I4fb5ecdfff1a6b8e8d77f561a9cf780f8e116f4d
Related: OS#1545
2016-07-28 06:21:21 +00:00
Tom Tsou
dab54b9178 trx: Enable EGPRS handling through burst lengths
Existing interfaces are coded with the implicit expectation of using
a burst sequence length of 148, which is constant with GSM and GPRS.
That changes with EGPRS, where the burst length may be 444 due to
the use of 8-PSK instead of GMSK modulation.

Setup the interface to accept and return a length value with the
burst sequence. This allows 444 length bit vectors to/from the
EGPRS decoder/encoder. Length is explicitly used as a identifier for
8-PSK vs. GMSK modulated sequences.

Change-Id: I90b46b46b11b6ce280e7f8232d5a2fccec2d4f18
Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-07-28 06:18:12 +00:00
Tom Tsou
9407e644b0 trx: Add EGPRS coding and decoding procedures
Handles uplink decoding and downlink encoding procedures for MCS 1-9.
Includes Type 1, 2, and 3 headers and tables from 3GPP TS 44.060 in
order to independently recover coding and puncturing scheme (CPS)
parameters for each coded message.

Change-Id: I0f059ae34c6f36179553cbc972f8becf8179eb55
Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-07-28 06:18:12 +00:00
Neels Hofmeyr
e07ba54d62 dyn TS: sysmo,lc15: chan_nr_by_sapi(): add missing assertion
Addition of GSM_PCHAN_TCH_F_TCH_H_PDCH should have added these assertions.
They clarify that only 'real' pchan types are expected in this function.

Change-Id: Ifd4b6820861ef716237e7eeed149b2add9e7d485
2016-07-27 16:24:52 +02:00
Neels Hofmeyr
a888e95efa log typo: trx_sched_set_pchan()
Change-Id: Icdb193ec6dbb95cf0c3e441c196b309aa599efe6
2016-07-27 16:24:47 +02:00
Neels Hofmeyr
dd34540ce4 comment typo: common/l1sap.c
Change-Id: I053766452ee01bed6136a9742551c664666a7989
2016-07-27 16:22:46 +02:00
Neels Hofmeyr
7b186adb0a dyn TS: implement litecell15 specifics
For chan_nr_by_sapi(), add GSM_PCHAN_TCH_F_TCH_H_PDCH to pick_pchan().

Add GSM_PCHAN_TCH_F_TCH_H_PDCH to pchan_to_logChComb[] for first pchan
initialization.

In ts_connect_as(), make sure that callers pass proper "real world" pchan
types, i.e. reject the "meta" GSM_PCHAN_TCH_F_TCH_H_PDCH pchan constant.

In ts_opstart(), connect as PCHAN_NONE since we will only know the desired
pchan when the first RSL chan activ is received.

Add GSM_PCHAN_TCH_F_TCH_H_PDCH to lchan_to_GsmL1_SubCh_t(), by using its
current "real" pchan mode.

Call cb_ts_[dis]connected() unconditionally, i.e. not only for TCH_F_PDCH when
a pending flag is set. The cb_ts_[dis]connected() will be a no-op if the pchan
type is not dynamic.

Change-Id: Ie30323f968da25027045c42a7ae7f1e70ca711ae
2016-07-25 22:13:44 +02:00
Neels Hofmeyr
b0f77ce685 lc15/oml.c: rename ts_connect() to ts_opstart()
ts_connect() is only called during OPSTART. Name it such because a special
case for OPSTART will be added there for dyn TS.

Change-Id: Iba6880d94142096a8371b08f7404035912cadbb0
2016-07-25 22:13:44 +02:00
Neels Hofmeyr
090a41f897 dyn TS: implement SysmoBTS specifics
For chan_nr_by_sapi(), add GSM_PCHAN_TCH_F_TCH_H_PDCH to pick_pchan().

Add GSM_PCHAN_TCH_F_TCH_H_PDCH to pchan_to_logChComb[] for first pchan
initialization.

In ts_connect_as(), make sure that callers pass proper "real world" pchan
types, i.e. reject the "meta" GSM_PCHAN_TCH_F_TCH_H_PDCH pchan constant.

In ts_opstart(), connect as PCHAN_NONE since we will only know the desired
pchan when the first RSL chan activ is received.

Add GSM_PCHAN_TCH_F_TCH_H_PDCH to lchan_to_GsmL1_SubCh_t(), by using its
current "real" pchan mode.

Call cb_ts_[dis]connected() unconditionally, i.e. not only for TCH_F_PDCH when
a pending flag is set. The cb_ts_[dis]connected() will be a no-op if the pchan
type is not dynamic.

Change-Id: Iaffd2fc0aa9fc6c4a2acbc534ce6384392e0635b
2016-07-25 22:13:44 +02:00
Neels Hofmeyr
78458a3811 sysmo/oml.c: rename ts_connect() to ts_opstart()
ts_connect() is only called during OPSTART. Name it such because a special
case for OPSTART will be added there for dyn TS.

Change-Id: I09cc81e79661e8084aeebf8132435c207b2cf422
2016-07-25 22:13:44 +02:00
Neels Hofmeyr
21ffe07894 dyn TS: common TCH/F_TCH/H_PDCH implementation
common/l1sap: For dyn TS, the BSC will issue RSL Chan Activ requests with a
non-standard chan_nr. While the rest of the code now understands that, the L1
phy will not. Translate to standard PDCH (== TCH/F).

common/oml: use dyn TS' current pchan mode for lchans config.

common/pcu_sock: detect desired PDCH mode of dyn TS.

common/rsl: implement reconnection chain of a TS for changing its pchan:

* rsl_rx_chan_activ():
** Add dyn_pchan_from_chan_nr() to derive the requested pchan from the RSL
   chan_nr IE.
** Notice the need for a pchan change and invoke dyn_ts_l1_reconnect() (s.b.)
** Make Chan Mode IE presence optional, because the non-standard PDCH
   activation message is simpler and does not require it.
** Do PDCH activation via PCU.

* Add dyn_ts_l1_reconnect(): store state and disconnect the L1 channel;
  then wait for cb_ts_disconnected().

* Add osmo_dyn_ts_disconnected() to cb_ts_disconnected():
  verify state and connect with the new pchan type; then wait for
  cb_ts_connected().

* Add osmo_dyn_ts_connected() to cb_ts_connected(), which re-issues
  the cached chan activation message from before disconnecting the L1 channel.

* Also send an rf chan rel/act ack for dyn TS upon PDCH de/act via PCU.

* Add dyn_ts_pdch_release(): on channel release of a dyn TS in PDCH mode,
  release via the PCU. Call from rsl_rx_rd_chan_rel().

Change-Id: I463bb6b4e57674f091c3badba9257374961c52c7
2016-07-25 22:13:44 +02:00
Neels Hofmeyr
6e656748b7 code dup: join [rsl_]lchan_lookup() from libbsc and osmo-bts
lchan_lookup in openbsc abis_rsl.c and rsl_lchan_lookup() rsl.c are the
same code, except for the log context, which is only set in abis_rsl.c.
The common code was factored out to gsm_data_shared.c in openbsc.git.

Use the *rc return code argument to keep the logging part in the newly
introduced thin wrapper lchan_lookup() in common/rsl.c. This also removes code
dup for logging

The rsl_lchan_lookup() implementation is removed from osmo-bts, so a recent
openbsc is needed to build this.

Change-Id: Ibc469b75e31560271be8633d524366442d27e6fb
2016-07-25 22:13:44 +02:00
Tom Tsou
73cb583e51 trx: Add EGPRS tables, sequences, and mappings
Includes EGPRS specific convolutional codes, interleaving tables
and functions, burst mappings, training sequences, and parity
checks from 3GPP TS 44.060 needed to handle MCS codings 1-9.

Change-Id: Ie270398dd7a72f282ba53e646853d8de1eabee93
Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
2016-07-25 18:36:29 +00:00
Neels Hofmeyr
c9582ac2d7 prepare dyn TS: split/replace conf_lchans_for_pchan()
Move the actual switch from static conf_lchans_for_pchan() into new 'public'
function conf_lchans_as_pchan(), adding an explicit pchan argument. This allows
passing a non-trivial pchan, for dynamic TS.

conf_lchans_as_pchan() now takes a pchan argument, so distinguish the naming
and drop the 'for_pchan' from conf_lchans_for_pchan(), which takes only a ts
argument.

Change-Id: I8e458501fff5503c243512aeb3469c12b1f2bbc4
2016-07-25 15:22:06 +00:00
Neels Hofmeyr
c57304b65e dyn PDCH: code dup: use conf_lchans_as_pchan()
For ip.access dyn PDCH, call conf_lchans_as_pchan() instead of dup'ing the
pchan-to-lchan switch.

Change-Id: I979828e08953e83ae579a347334536f52939faf0
2016-07-25 15:22:06 +00:00
Neels Hofmeyr
9ab51522da error log: rsl.c: typo x2
Change-Id: I285fdff8260f008d856b9cda811e9fbb936893eb
2016-07-25 15:22:06 +00:00
Neels Hofmeyr
8e22ac3d1a info log: l1sap.c: add '0x' to hex output
Change-Id: If29895de238e586b8298d84b6f0b41e08bea8c91
2016-07-25 15:22:06 +00:00
Neels Hofmeyr
ee2299c8fa fix compiler warning: msg_utils.c: fn_chk() constify arg
The only caller dtx_sched_optional() passes const arrays and a warning was
issued.

Change-Id: I18e0788ef96489d2116a60cae57bd516fe6eae8e
2016-07-25 15:22:06 +00:00
Neels Hofmeyr
95dec9ff4a cosmetic: pcu_sock.c: rename ts_is_pdch() to ts_should_be_pdch()
The function checks whether to switch a TS to/from PDCH, not whether it already
is PDCH.

Change-Id: Ib4036445d09792636bb2f1a8a665b6b28f32e1a0
2016-07-25 15:22:06 +00:00
Neels Hofmeyr
334df9441a cosmetic: clarify TCH/F_PDCH related naming and comments
We're about to introduce a new kind of dynamic channel, which will also use
parts of the ip.access mode dyn PDCH code paths. Make sure the general parts
have general names and mark ip.access specific parts as such.

Rename dyn_pdch_ts_[dis]connected() to cb_ts_[dis]connected().
Rename dyn_pdch_complete to ipacc_dyn_pdch_complete().
From cb_ts_[dis]connected(), factor out the current code into static
functions ipacc_dyn_pdch_[dis]connected() -- this will make sense once the
new dynamic kind is added to cb_ts_[dis]connected().

Change-Id: I7da5b7cb7b48572671f50e0dec97d9eec3083df1
2016-07-25 16:38:18 +02:00
Neels Hofmeyr
290c7d954f cosmetic: pcu_sock.c: rename ts_is_pdch() to ts_should_be_pdch()
The function checks whether to switch a TS to/from PDCH, not whether it already
is PDCH.

Change-Id: Ib4036445d09792636bb2f1a8a665b6b28f32e1a0
2016-07-25 16:38:18 +02:00
Neels Hofmeyr
7f1365c05e fix compiler warning: msg_utils.c: fn_chk() constify arg
The only caller dtx_sched_optional() passes const arrays and a warning was
issued.

Change-Id: I18e0788ef96489d2116a60cae57bd516fe6eae8e
2016-07-25 16:38:18 +02:00
Neels Hofmeyr
2479ef4133 info log: l1sap.c: add '0x' to hex output
Change-Id: If29895de238e586b8298d84b6f0b41e08bea8c91
2016-07-25 16:38:18 +02:00
Neels Hofmeyr
ae65ccd0b2 error log: rsl.c: typo x2
Change-Id: I285fdff8260f008d856b9cda811e9fbb936893eb
2016-07-25 16:38:18 +02:00
Neels Hofmeyr
8a2f026cf0 doc: move dyn_pdch.msc to osmo-gsm-manuals.git
Also remove related cruft: .gitignore, msc-README and adjust an in-code
comment that referenced dyn_pdch.msc.

Change-Id: Ie41a453bb5070c1f18793f646dc053a978f43fba
2016-07-25 16:35:53 +02:00
Max
4355021b8a sysmobts: dump PRACH and PTCCH parameters
Change-Id: I6b833b21d2bbbd45dfed6a094a674359762d02b7
Related: OS#1545
2016-07-16 21:00:53 +00:00
Neels Hofmeyr
2ed03cd640 osmo-bts-trx: init OML only once by sending AVSTATE_OK with OPSTATE_ENABLED
When receiving an OPSTART for the BTS object, also set the availability state
to OK.

Before, the availability would remain at NM_AVSTATE_DEPENDENCY, which caused an
unfortunate chain reaction resulting in osmo-bts-trx going through the
initialization sequence twice:

  BTS    BSC
   |<-----|   SITE_MANAGER OPSTART
 n |----->|   BTS state change: OPSTATE_DISABLED, AVSTATE_DEPENDENCY
 o |      |     This signals to nm_statechg_event() in bts_ipaccess_nanobts.c
 r |      |     to (a) Set BTS Attributes and (b) send BTS OPSTART
 m |<-----|   Set BTS Attributes (a)
 a |      |     When osmo-bts-trx receives a Set BTS Attributes, it sends
 l |----->|   CHANNEL state change: OPSTATE_DISABLED  x8
   |      |     This signals the BSC to Set CHANNEL Attributes and OPSTART
 i |<-----|   Set CHANNEL Attributes  x8
 n |<-----|   CHANNEL OPSTART  x8
 i |----->|   CHANNEL state change: OPSTATE_ENABLED, AVSTATE_OK  x8
 t |      |
   |<-----|   BTS OPSTART (b)
   |      |     osmo-bts-trx immediately replies with:
   |----->|   BTS state change: OPSTATE_ENABLED, AVSTATE_DEPENDENCY
   |      |     Unfortunately, availability is left at DEPENDENCY,
   |      |     and the NM_OC_BTS case in nm_statechg_event() only
   |      |     checks for availability, not for the opstate.
   |      |     Hence nm_statechg_event() again feels inclined to
   |      |     to (a) Set BTS Attributes and (b) send BTS OPSTART,
   |      |
 --+------+----- This is where the second round starts
   |      |
 s |<-----|   Set BTS Attributes (a)
 e |      |     When osmo-bts-trx receives a Set BTS Attributes, it sends
 c |----->|   CHANNEL state change: OPSTATE_DISABLED  x8
 o |      |     All channels are disabled again, and then re-launched:
 n |<-----|   Set CHANNEL Attributes  x8
 d |<-----|   CHANNEL OPSTART  x8
   |----->|   CHANNEL state change: OPSTATE_ENABLED, AVSTATE_OK  x8
   |      |
 i |<-----|   BTS OPSTART (b)
 n |      |     osmo-bts-trx again sets the OPSTATE_ENABLED, but since
 i |      |     this time it was already enabled, no further state change
 t |      |     is sent back to the BSC.

This nightmare pivots on two hinges:

1. osmo-bts-trx fails to set BTS availability to AVSTATE_OK.
2. nm_statechg_event() fails to heed the OPSTATE_ENABLED of the BTS state
   change.

Note, the configured channels from the first round were not actually taken
down, only the OML OPSTATE_DISABLED were sent.

In this commit, fix the osmo-bts-trx side: send AVSTATE_OK for the BTS object
upon sending OPSTATE_ENABLED, so that only the part marked "normal init" above
is run.

This change applies the same fix to other OML objects, which should make sense
in the same manner, within the current hackish OML implementation:
* NM_OC_BTS
* NM_OC_SITE_MANAGER
* NM_OC_BASEB_TRANSC
* NM_OC_GPRS_NSE
* NM_OC_GPRS_CELL
* NM_OC_GPRS_NSVC

This means that the NM_OC_CHANNEL case just above is identical, and thus
collapse NM_OC_CHANNEL onto the other cases. Drop the comments from
NM_OC_CHANNEL since they merely rephrase the commands themselves.

See OS#1770 for BTS and NITB logs.

Fixes: OS#1770

Change-Id: I08aa861f6100568c79750f4fbc9a32e1557b9304
2016-07-14 03:40:50 +02:00
Neels Hofmeyr
cff0d44e53 log: osmo-bts-trx: change PDTCH block logs to DEBUG level
Many erratic PDTCH blocks are expected. To not bloat the log,
notifications for this should be on debug level.

See http://lists.osmocom.org/pipermail/openbsc/2016-June/009457.html
(Thu, 30 Jun 2016 01:49:33 +0300 / Alexander Chemeris
<alexander.chemeris@gmail.com> / Re: GPRS on osmo-trx not working)

Change-Id: Ie318248aa2b8de455174e72a63c602c7aeae312c
2016-07-09 19:52:18 +00:00
Neels Hofmeyr
b8f5f4e176 log: osmo-bts-trx: change access burst logs to DEBUG level
Many erratic bursts are expected. To not bloat the log, notifications for this
should be on debug level.

See http://lists.osmocom.org/pipermail/openbsc/2016-July/009482.html
(Tue, 5 Jul 2016 15:38:27 -0700 / Tom Tsou <tom@tsou.cc>
/ Re: osmo-bts-trx error logs -- was: GPRS on osmo-trx not working)

Change-Id: If591c087ba8fd48564139e32930050ee8ab07001
2016-07-09 19:50:50 +00:00
Neels Hofmeyr
b151301c6c cosmetic: osmo-bts-trx: add comment, fix comment typo
Change-Id: Iea62bd98954d0219ba597613cea6db63f7a6b396
2016-07-09 19:50:50 +00:00
Holger Hans Peter Freyther
1c1b0e843d sysmobts: Fix eeprom padding before gpg key
Correct the too short padding I introduced in the commit
a55b166c6c. The result needs to
be 121 and not 120. Add static asserts to make sure it does
not happen again.

Change-Id: I3da7f3b8d3c8e12deb8b805cd15ff52a103d4e56
2016-07-07 13:51:00 +00:00
Max
e3edc17426 Mark array as static const
Change-Id: Ia70519c8f10d55084b53acb68e57debc70549246
2016-07-05 14:48:26 +02:00
Harald Welte
7267a0d37e sysmobts: screnrc/systemd-service: Use osmo-bts-sysmo instead of sysmobts
Back in January in commit 634c3e4648 we
changed the executable name from 'sysmobts' to 'osmo-bts-sysmo', which
is a change that has not been propagated to the contributed screenrc and
systemd init files.

Change-Id: I875a0ce4f470226e1b06ed1b7c74ca9471ebb574
2016-06-27 13:50:25 +02:00
Max
d5f95c308b TRX: add Uplink DTX support for FR/HR
* detect SID and set RTP Marker accordingly (emulate ONSET events)
* set proper FN in TCH_IND
* detect speech pause and do not send dummy 'bad' frames during that
  time

Change-Id: Id518e5c667df7773c281effb9e75b66bf898f6fc
Related: OS#1750
2016-06-27 09:37:11 +00:00
Max
bb1e3b089b Remove duplicated nibble shift code
Those functions are now part of libosmocore.

Change-Id: Iab3206e3b41caff23f656a727605032df9798953
2016-06-24 10:47:59 +02:00
Max
c03d3ae7af DTXu: move copy-pasted code to common part
Abstract code for checking/setting lchan's UL SID flag and RTP Marker
into generic function and use it for LC15 and sysmoBTS.

Change-Id: Ica5392e92bab29164711163e7b01adb174272883
Related: OS#1750
2016-06-23 20:01:02 +00:00
Max
5c0d88e69d Make get_lchan_by_chan_nr globally available
* Remove static qualifier
* Remove duplicated code - use generic function instead

Change-Id: I37a312648771f58d3087471083cfcebbd97ccf1d
2016-06-23 20:00:44 +00:00
Neels Hofmeyr
4fa641d7b2 fix compiler warning: remove unused variable 'i' in calib_verify()
Change-Id: Iea6bc47182d021523285aea8d3f6a93ee4eec0eb
2016-06-23 19:58:47 +00:00
Neels Hofmeyr
64e3813b06 fix compiler warning: remove useless 'static' storage class for struct decl
Change-Id: I4d5d11dd89449e4c9315f963576265bccad7e68c
2016-06-23 19:58:47 +00:00
Neels Hofmeyr
9797a72cd7 fix compiler warnings: include bts_model.h in phy_link.c
The file calls bts_model_* API which was yet undeclared.

Change-Id: Ib6b30d125906c3abae518fb76da3a158885e3354
2016-06-23 19:58:47 +00:00
Neels Hofmeyr
99642656a0 vty: install orphaned trx nominal power command
The cfg_trx_nominal_power_cmd added 12 days ago in
58e4e18206 was floating.
Actually add it to the TRX_NODE.

Change-Id: I89d638b2e2bb1fb9baeabe566035ff171f4bfad0
2016-06-22 23:33:36 +00:00
Neels Hofmeyr
c2874c4360 dyn PDCH: safeguard: exit if nothing pending in dyn_pdch_ts_disconnected()
The function would currently only be called in cases where one of the if
branches catches on, but for safety's and clarity's sake, don't ts_connect
using as_pchan if no reconnect is pending.

Change-Id: I52c34065254e902bb80662fc04540901b36cb4c3
2016-06-22 23:31:06 +00:00
Neels Hofmeyr
3f919171ef dyn PDCH: lc15: complete for litecell15-bts: implement bts_model_ts_*()
Analogous to 63b296bdd9 on osmo-bts-sysmo.

Implement bts_model_ts_disconnect() by sending an MphDisconnect message to L1.
Pass a disconnect callback to invoke dyn_pdch_ts_disconnected() in
common/rsl.c.

Implement bts_model_ts_connect() by calling ts_connect_as(). Pass a connect cb
to invoke dyn_pdch_connected() in common/rsl.c.

Change-Id: I8c8c3244c726fd6055cedb22ee11706994ff9cd4
2016-06-22 23:26:15 +00:00
Neels Hofmeyr
a4c6802315 dyn PDCH: lc15: handle TCH/F_PDCH init like TCH/F
Analogous to 57fc1124e1 on osmo-bts-sysmo.

Change-Id: If65c5a86cbc1b5556b71de8a6744d92113fbbcba
2016-06-22 23:26:07 +00:00
Neels Hofmeyr
0eaa27a6be dyn PDCH: lc15: add ts_connect_as(), absorbing ts_connect() guts
Analogous to 294fbe104b on osmo-bts-sysmo.

For upcoming dyn PDCH switching, I want to be able to set the pchan dynamically
upon ts_connect() and not continue with OPSTART ACK, but with the dyn PDCH.

Thus recoin ts_connect(ts) to ts_connect_as(ts, pchan, cb) and leave
ts_connect() as a thin wrapper to leave init code unchanged.

Change-Id: I7a27193168f83e8c40b6e54d1842f4502d0475e5
2016-06-22 23:26:01 +00:00
Neels Hofmeyr
037dcfe981 dyn PDCH: lc15: chan_nr_by_sapi(): handle TCH/F_PDCH according to ts->flags
Analogous to 0d10f0e482 on osmo-bts-sysmo.

According to the PDCH Active flag, handle a TS as TCH/F or PDCH.

Change-Id: I0c97b360136f76bdae8d70d06af9a31fdf75c1ba
2016-06-22 23:25:54 +00:00
Neels Hofmeyr
380a2e6d90 lc15: add L3 handle to l1prim messages
Analogous to 7158c2ed08 in osmo-bts-sysmo.

Place a layer 3 handle into GSM L1 messages to better match up confirmations to
respective requests. This handle is a uint32_t transparently returned in the
confirmation messages, so a match-up is easy to add.

So far, a GSM L1 confirmation message received for a preceding L1 Request was
matched only by the prim_id. That meant that only one instance of the same
primitive could be waiting for a confirmation at any given time, or the
responses would get mixed up: the struct wait_l1_conf instances entered into
the fl1h->wlc_list queue would be returned to a possibly mismatching
confirmation handler. (Seen during testing of dyn pdch switching.)

Send the hLayer3 handle out via prim_init(), using new static functions to
produce handles on different scopes:

* l1p_handle_for_trx()
* l1p_handle_for_ts()
* l1p_handle_for_lchan()

(These could possibly move to a more general .h/.c file later.)

Remember the hLayer3 handle in

* struct wait_l1_conf.

Match the incoming confirmations' and stored hLayer3 handles up in, and remove
a now obsolete comment from:

* is_prim_compat()

Since the hLayer3 members are at different byte offsets in
GsmL1_Prim_t.u.*, use large switch statements to set/get the value:

* In prim_init(), extend existing switch statement to set in GsmL1_Prim_t.
* Add l1p_get_hLayer3() to retrieve from GsmL1_Prim_t (could possibly move to a
more general .h/.c file later).

Note that some messages are already using the hLayer3 handle, and will
overwrite it after calling prim_init(), so those are not affected.

Change-Id: I17f95ba744c3e944a2241809106506f8dd1b24f0
2016-06-22 23:25:43 +00:00
Neels Hofmeyr
ccb1148717 fix lc15 build: put src/common/libbts.a left of -losmogsm
When switching to the gsm_chan_t_names string list from libosmogsm,
libosmogsm actually became a dependency of the local libbts.a.

The breaking change is in openbsc.git 29048b2a80b5865ffc41fa4401113c5826227e23
and came in here because gsm_data_shared.h is included from openbsc.

Change-Id: I70e5735fc2a212305182d46a7e8485d0199ade7b
2016-06-22 23:25:27 +00:00
Max
724412a49a Clarify logging message
Change-Id: I3c7be592f4cbdd553f07c4a7084478706a7bd644
Related: OS#1648
2016-06-22 23:24:43 +00:00
Max
f0d6d6ba02 Use error values instead of number for RSL error
Change-Id: I0aa695c42a4399828fb8e9c08c905870175b7149
2016-06-21 17:52:01 +02:00
Max
dd084e6e57 Use libosmocodec functions for AMR
Switch to using libosmocodec functions as a preparation step for DTX
support as they expose necessary bits.

Change-Id: Ie7423032fd06779d78876182ee63538d98906328
Related: OS#1750
2016-06-21 17:24:50 +02:00
Max
61372a20de Move copy-pasted code into common part
Related: OS#1750
Change-Id: Ic4342eaf7e32a0e9a5f2b16dd196a1f5f03152a9
2016-06-18 11:35:12 +00:00
Max
c3fb0dcc8c DTX: add support for AMR/HR
Change-Id: Id744b67904011eb328b24c46a645b3eb53525c04
Fixes: OS#1562
2016-06-18 11:34:51 +00:00
Neels Hofmeyr
274d29bedd debug log: log TS pchan type on connect
A whitespace error is fixed along the way.

Change-Id: Iff373ba934937435a175ed3a5d9cfb6f2514735d
2016-06-17 15:50:48 +00:00
Neels Hofmeyr
7efc2f3c5b debug log: log lchan state transitions
Change-Id: Id20f61ef535f4ea049da6579e41eb98f31238d23
2016-06-17 15:50:48 +00:00
Neels Hofmeyr
b231e0f6cd error log: two minor clarifications
Change-Id: I95e4331f51f650d5077eb3a8f897f754d5d2b779
2016-06-17 15:50:48 +00:00
Neels Hofmeyr
63b296bdd9 dyn PDCH: complete for sysmo-bts: implement bts_model_ts_*()
Implement bts_model_ts_disconnect() by sending an MphDisconnect message to L1.
Pass a disconnect callback to invoke dyn_pdch_ts_disconnected() in
common/rsl.c.

Implement bts_model_ts_connect() by calling ts_connect_as(). Pass a connect cb
to invoke dyn_pdch_connected() in common/rsl.c.

Change-Id: I61709fdf6b093689a6d3a046f67db6d02f1296ae
2016-06-17 15:50:48 +00:00
Neels Hofmeyr
57fc1124e1 dyn PDCH: sysmo: handle TCH/F_PDCH init like TCH/F
Change-Id: Ic62921e17c55aeb26235b70a8325d6fea1716cef
2016-06-17 15:50:48 +00:00
Neels Hofmeyr
294fbe104b dyn PDCH: sysmo-bts/oml.c: add ts_connect_as(), absorbing ts_connect() guts
For upcoming dyn PDCH switching, I want to be able to set the pchan dynamically
upon ts_connect() and not continue with OPSTART ACK, but with the dyn PDCH.

Thus recoin ts_connect(ts) to ts_connect_as(ts, pchan, cb) and leave
ts_connect() as a thin wrapper to leave init code unchanged.

Change-Id: I09cc794cb424e17411e608c65f2b68e2f2544e07
2016-06-17 15:50:48 +00:00
Neels Hofmeyr
24a31cfe43 dyn PDCH: implement main dyn PDCH logic in common/
React on IPAC PDCH ACT and DEACT messages and invoke the PCU and bts_model_ts_*
APIs to effect switchover. The dyn PDCH interaction is described in the comment
to rsl_rx_dyn_pdch(), the main entry point for PDCH switchover.

In case the bts_model_ts_* are not implemented (or return other errors),
reply with an IPAC PDCH ACT/DEACT NACK.

Add callbacks that mark steps in the PDCH switchover process,
dyn_pdch_ts_disconnected(), dyn_pdch_ts_connected() and dyn_pdch_complete().

Add hooks in l1sap.c on channel activation and release confirmation, to call
dyn PDCH callbacks.

BTS dyn PDCH implementations should invoke dyn_pdch_ts_disconnected() and
dyn_pdch_ts_connected() when bts_model_ts_disconnect() or
bts_model_ts_connect() are called, respectively. (upcoming for sysmoBTS)

Change-Id: Id2f5f77121a65d6c14eac127b3d4fb50e97a77ab
2016-06-17 15:50:48 +00:00
Neels Hofmeyr
0d10f0e482 dyn PDCH: chan_nr_by_sapi(): handle TCH/F_PDCH according to ts->flags
According to the PDCH Active flag, handle a TS as TCH/F or PDCH.

Change-Id: I06ca26a99f052c6a2ae953fe355fd1196f66e501
2016-06-17 15:50:47 +00:00
Neels Hofmeyr
f8bf95fa6b dyn PDCH: pcu_tx_info_ind(): handle TCH/F_PDCH in PDCH mode
Introduce a static function to encapsulate the decision whether a TS is
used for PDCH. Depending on the ts->flags, handle a TCH/F_PDCH TS exactly like
a standard PDCH TS.

Change-Id: Ic72fd06ecc99609823efa3edcf773007cc514b5b
2016-06-17 15:50:47 +00:00
Neels Hofmeyr
e6cc04827a dyn PDCH: conf_lchans_for_pchan(): handle TCH/F_PDCH
Depending on the PDCH active flag, handle a TCH/F_PDCH like TCH/F or PDCH.

Change-Id: Ifc5561f8e2db172bb692ba26bdeae2fd675d6ec5
2016-06-17 15:50:47 +00:00
Neels Hofmeyr
9375aa9a68 dyn PDCH: add bts_model_ts_connect() and _disconnect() stubs
Enhance bts_model_ API in preparation of dyn PDCH switching. These will be used
to re-connect a TCH/F_PDCH TS in a different mode: either as TCH/F or as PDCH.

All implementations so far return -ENOTSUP, and thus will cause a IPAC PDCH ACT
or DEACT *NACK* to be sent to the BSC as soon as these messages are handled.

Also add stubs in tests.

Change-Id: I21e60c028a1333431c3ed000f788b654d1170b0d
2016-06-17 15:50:47 +00:00
Neels Hofmeyr
bfc9ff3118 fix two compiler warnings: add two opaque struct declarations
Change-Id: Ie12eeff753e399b28a816893ac4d23e1cd391025
2016-06-17 15:34:57 +00:00
Neels Hofmeyr
6b60611a4d fix compiler warning: add missing case (PHY_LINK_CONNECTING)
Change-Id: I7979e10551023c1f52f04b4e93ea1706cf0bef39
2016-06-17 15:34:48 +00:00
Neels Hofmeyr
bc9c42663d fix compiler warning: printf format for sizeof()
Change-Id: Id600c5a34ab261736f7595ab2e36e3a30d434175
2016-06-17 15:34:42 +00:00
Max
8a75e60d0c Add .gitreview
Similar to other projects, add helper file for "git review"
command. More information:
https://www.mediawiki.org/wiki/Gerrit/git-review

Change-Id: If3406fafa5778e94ab53e858ddda4a4d55651879
2016-06-17 15:33:01 +00:00
Max
ae2a8b75f9 TRX: add configuration example
Related: OS#1648
Change-Id: Icc7d15eceee8ee667fd6a29e758a38668c4946ef
2016-06-17 15:32:28 +00:00
Neels Hofmeyr
3686005180 add missing DSUM entry to bts_log_info_cat
This allows setting the 'sum' log level to debug in osmo-bts.cfg.

Change-Id: I1fe1a483f07f0384815f01877f86ffc192052f72
2016-06-17 15:32:03 +00:00
Neels Hofmeyr
ea40bd60e7 doc: add ladder diagram on dynamic PDCH, add msc-README
Adjust .gitignore for dyn_pdch.svg and .png.

Change-Id: I532f896b1b528c4d1764bb5042a7f42c3c60f617
2016-06-17 02:46:12 +00:00
Neels Hofmeyr
a8168271eb dyn PDCH: cosmetic: lchan_to_GsmL1_SubCh_t(): add case for TCH_F_PDCH
It is cosmetic since the 'default:' case already caught TCH_F_PDCH, but it's
good to mention all expected pchans explicitly.

Change-Id: I5aef84209e46c9288f6adf0730178fe08f26764f
2016-06-17 04:26:20 +02:00
Neels Hofmeyr
e951042475 dyn PDCH: rsl rx dchan: also log ip.access message names
Before, only standard ABIS RSL message names were logged, add ip.access
specific ones.

The IPAC_PDCH_ACT and _DEACT msgs are received with an ABIS_RSL_MDISC_DED_CHAN
discriminator, and not with _MDISC_IPACCESS like the others. Thus rsl_rx_dchan()
should be able to log ip.access message types properly.

Change-Id: I9db6826b515bf565fc7ae24fc0760b60928cc89f
2016-06-17 04:24:57 +02:00
Neels Hofmeyr
65efa691f8 oml, Set Chan Attr: treat unknown PCHAN types as error
Change-Id: Id79585993df15362ba0e1271d03302597182ceff
2016-06-17 01:31:03 +00:00
Neels Hofmeyr
6ab1ed580d fix typo in error message ('at lEast')
Change-Id: I6ac3606157dc6c81ed17cd6d26227da8ae26c49f
2016-06-17 01:30:08 +00:00
Neels Hofmeyr
213db32e30 tests/stubs.c: remove unused stubs
Change-Id: I53a839a332980bca67ae0b7d3e36b97afe406e5b
2016-06-17 01:30:00 +00:00
Neels Hofmeyr
703c2d6eb8 pcu_sock: add pcu_connected() to query PCU availability
Will be used in upcoming dyn PDCH switching.

Change-Id: I8031089ad5e9cb9690ca7e22facc53438f28e12a
2016-06-17 01:24:25 +00:00
Max
ecd5bc2aef TRX: Add vty command to power on/off transceiver
Add vty command (under "phy X instance Y" hierarchy) to manually send
POWERON or POWEROFF command. It's useful for debugging issues related to
BTS/TRX initialization.

Change-Id: I6dfebaf118cdf5ad144516b2b839b17350a73ce4
Related: OS#1648
2016-06-16 13:39:42 +00:00
Max
7cc3c3156e Fix OML activation
Previously software activation could have been reported multiple times
which broke proper BTS init. Introduce guard variable to ensure
reporting happens only once.

Note: this is just minimal workaround - ideally proper OML state machine
should be implemented.

Change-Id: Ifffbdb756bc5d2864f985c01a3299b839c4de7af
Related: OS#1648
2016-06-16 12:43:44 +02:00
Minh-Quang Nguyen
58e4e18206 LC15: TRX nominal TX power can be used from EEPROM or from BTS configuration
Change-Id: I173f4126cea41959d48def07bff25fcd29894b7e
2016-06-15 09:45:02 +00:00
Minh-Quang Nguyen
cbbce0be09 LC15: Hardware changes:
- Change system devices path
- Remove obsoleted sensors and add new sensors
- Change TRX and sensors numbering to 0,1 instead of 1,2 (JFD)

Change-Id: I5172daf68d3145a6398e37df87df21b0e5affe42
2016-06-15 09:44:58 +00:00
Minh-Quang Nguyen
d0d2c9217a LC15: Bring back DSP trace argument
Change-Id: I822651d9ba4959ce5885a2c0362f1ea583b724da
2016-06-15 09:44:51 +00:00
Neels Hofmeyr
7158c2ed08 sysmo: add L3 handle to l1prim messages
Place a layer 3 handle into GSM L1 messages to better match up confirmations to
respective requests. This handle is a uint32_t transparently returned in the
confirmation messages, so a match-up is easy to add.

So far, a GSM L1 confirmation message received for a preceding L1 Request was
matched only by the prim_id. That meant that only one instance of the same
primitive could be waiting for a confirmation at any given time, or the
responses would get mixed up: the struct wait_l1_conf instances entered into
the fl1h->wlc_list queue would be returned to a possibly mismatching
confirmation handler. (Seen during testing of dyn pdch switching.)

Send the hLayer3 handle out via prim_init(), using new static functions to
produce handles on different scopes:

* l1p_handle_for_trx()
* l1p_handle_for_ts()
* l1p_handle_for_lchan()

(These could possibly move to a more general .h/.c file later.)

Remember the hLayer3 handle in

* struct wait_l1_conf.

Match the incoming confirmations' and stored hLayer3 handles up in, and remove
a now obsolete comment from:

* is_prim_compat()

Since the hLayer3 members are at different byte offsets in
GsmL1_Prim_t.u.*, use large switch statements to set/get the value:

* In prim_init(), extend existing switch statement to set in GsmL1_Prim_t.
* Add l1p_get_hLayer3() to retrieve from GsmL1_Prim_t (could possibly move to a
  more general .h/.c file later).

Change-Id: Ie4533c6cbc160318917e7a672ab6f9a848f01d1b
2016-06-15 09:30:24 +00:00
Holger Hans Peter Freyther
a55b166c6c sysmobts: Add the barebox boot state reservation
We are using up to 48 (actually only 8) bytes to manage the boot
state of the device. Add it to the eeprom reservation. It turns out
the current padding was too large (37 + 84 don't end at 120).

Change-Id: I4c1de5925577f1d0b7b5cc08529642ffa333d7de
2016-06-15 09:33:23 +02:00
Minh-Quang Nguyen
3f3f34ba52 common/abis.c: fix 100% CPU usage after disconnecting OML/RSL link (Bug #1703)
Change-Id: I24605b8a6d4e778a3280ffba8bc1fc7a284ce12d
2016-06-14 21:57:57 +00:00
Minh-Quang Nguyen
495fed9f43 l1sap.h: fix wrong L1SAP_FN2PTCCHBLOCK calculation according to TS 45.002 Table 6
We have seen that the DSP time to time rejects PTCCH message from BTS due to invalid block number.
As a result, we patched FN2PTCCHBLOCK calculation according TS 45.0002 Table 6.


Change-Id: I8be1c8b9159c94788857c6de5440a418739f1212
2016-06-14 21:57:06 +00:00
Max
a10ac248c6 DTXu: mark beginning of speech burst in RTP
Set Marker bit in RTP header to mark the beginning of talkspurt.

Change-Id: I3dd70ad8ff94356e3c3cc5458255f6c23534783e
Related: OS#1562
2016-06-14 10:19:13 +00:00
Max
60970056c8 DTXd: store/repeat last SID
Store last SID received over RTP and repeat is if necessary (no new SID
or SPEECH frames) according to codec-specific scheduling rules.

Related: OS#1563
Copy-paster from I4d23846a27d3dbd2a6e75e481c1efcdb2a85f305 for LC15.

Change-Id: I29acea6e8bbf426330ce52554a48afb5d2ef1679
2016-06-14 10:18:59 +00:00
Max
8ecadc66ce DTXd: store/repeat last SID
Store last SID received over RTP and repeat is if necessary (no new SID
or SPEECH frames) according to codec-specific scheduling rules.

Change-Id: I4d23846a27d3dbd2a6e75e481c1efcdb2a85f305
Related: OS#1563
2016-06-14 10:18:59 +00:00
Max
9302abe054 Fix debug output
Previously frame number was not saved in case of PRIM_TCH rendering many
debug statements with g_time useless.

Copy-paste from ef30f50d5d.

Change-Id: I952b39458d921622d5964cbdcc2f4e45ff9ea951
2016-06-14 10:18:59 +00:00
Jason DSouza
45e97ac59a Close TRX session before opening new one
This fixes the unstable behavior (BTS loosing subscribers after some
time) in case previous run of osmo-bts was interrupted (with ctrl+c for
example).

Change-Id: Ie2119b0b566d01f0e70b38c8a149fecb47def38d
2016-06-14 10:18:43 +00:00
Max
3a1f1b8e91 octphy: Use the app. info. defaults as base
Similar to 91565b2d51 use default
initializers.

Change-Id: Ib813249f4295b034eb65658e3f43b4fe86862cf0
Fixes: Os#1642
2016-06-13 14:56:44 +02:00
Max
4582222757 Use libosmocodec for AMR RTP
Use libosmocodec function to parse RTP with AMR payload in sysmoBTS and
LC15. This replaces "manual" parsing of AMR frame with function covered
by test suite and makes adding DTXd support easier.

Related: OS#1563
Change-Id: I1464f9a12e3f92926d03d5dd5d18e8f0f7206dd9
Reviewed-on: https://gerrit.osmocom.org/204
Tested-by: Jenkins Builder
Reviewed-by: Harald Welte <laforge@gnumonks.org>
2016-06-12 15:43:19 +00:00
Max
c1586388dc Add DTXd support for sysmoBTS and LC15
* set/clear DTXd activity indicator for measurement reporting
* set DTXd status based on information from RSL

Related: OS#1563
Change-Id: I148a75725c4e5089b6f2da6e9adcbe94170d3257
Depends-On: I4a033b03fcd0deb4db7a38273b5407511dbf1d6c
Reviewed-on: https://gerrit.osmocom.org/220
Tested-by: Jenkins Builder
Reviewed-by: Harald Welte <laforge@gnumonks.org>
2016-06-12 15:42:34 +00:00
Max
51bfebec39 Fix RTP timestamps in case of DTX
Compute RTP user_ts adjustment based on the difference between current
and previous FN instead of hard-coded value.

Change-Id: If1677ddcf754b29990ff7cd846e11c32e3d30b33
Related: OS#1562
Reviewed-on: https://gerrit.osmocom.org/196
Tested-by: Jenkins Builder
Reviewed-by: Harald Welte <laforge@gnumonks.org>
2016-06-07 15:32:39 +00:00
Max
ef30f50d5d Fix debug output
Previously frame number was not saved in case of PRIM_TCH rendering many
debug statements with g_time useless.

Change-Id: Ib8d8c919862d0de8e2ebf7753c2592e0d91b09c5
Reviewed-on: https://gerrit.osmocom.org/195
Tested-by: Jenkins Builder
Reviewed-by: Harald Welte <laforge@gnumonks.org>
2016-06-05 09:35:23 +00:00
Max
201b424b73 Use libosmocore function for uplink measurements
Related: OS#1563
Change-Id: Ide47e8e69e0d2d5859c5249b22f4bad22c18aa57
Reviewed-on: https://gerrit.osmocom.org/108
Tested-by: Jenkins Builder
Reviewed-by: Harald Welte <laforge@gnumonks.org>
2016-05-31 11:58:08 +00:00
Daniel Laszlo Sitzer
0778cd488a octphy: Update outdated config param name in error message.
Change-Id: I45b8bc09c9aabacc5b908450fe574b5802b88be8
Reviewed-on: https://gerrit.osmocom.org/129
Tested-by: Jenkins Builder
Reviewed-by: Holger Freyther <holger@freyther.de>
2016-05-31 09:30:55 +00:00
Max
ed494443cc Ensure TRX invariant
There is implicit invariant in trx_phy_instance() which is actively used
by various hw-specific implementations to get TRX's phy instance. Let's
make sure there's explicit assertion for this because there's been
segfaults in the past related to it.
2016-04-29 13:03:35 +02:00
Holger Hans Peter Freyther
b61850248a jenkins: Add the build script from jenkins here
This can be used to replicate a build issue more easily.
Build specific to the Octphy.
2016-04-13 19:35:32 -04:00
Holger Hans Peter Freyther
c8da1ac9a6 jenkins: Add the build script from jenkins here
This can be used to replicate a build issue more easily.
2016-04-13 19:08:07 -04:00
Holger Hans Peter Freyther
227015e52e misc: Ignore files generated by a debian packaging build 2016-04-01 17:02:11 +02:00
Holger Hans Peter Freyther
460e1b7387 debian: Create initial packaging for the osmo-bts-trx
This is only with osmo-bts-trx as others require headers that are
not packaged yet.
2016-04-01 17:01:54 +02:00
Max
21fc6e45fb LC15: properly initialize unmapped phy instances
Fixes: OS#1665
2016-03-22 19:38:39 +01:00
Max
925fcf48ed LC15: add stubs for phy link/instance defaults 2016-03-22 19:37:03 +01:00
Max
0fe3b215b9 LC15: ignore build byproducts 2016-03-22 19:37:02 +01:00
Max
06968beab9 octphy: fix for multiple trx with more than 1 dsp
Explicitly store and use "center" arfcn used by each dsp (1 dsp
corresponds to 1 phy link).
2016-03-21 17:20:11 +01:00
Max
ae5a737c18 octphy: add example configuration with 2 trx 2016-03-18 15:43:56 +01:00
Max
c4fc00d851 octphy: add support for multiple trx ids 2016-03-18 15:30:30 +01:00
Max
3044a26d71 octphy: use octasic's routines for debug output 2016-03-18 15:29:54 +01:00
Max
b857f27704 Fix typo in error message 2016-03-17 18:23:55 +01:00
Max
9591b6c253 octphy: add missing include to fix the build 2016-03-17 16:23:07 +01:00
Max
bb0cc685f1 Add utility to check proper scheduling of SI
There are several types of System Information messages with tricky
scheduling rules described in 3GPP TS 05.02 § 6.3.1.3. This GNU Awk
script takes in .csv file with sequence of scheduled SI messages (for
example generated using tshark from GSMTAP capture - see usage note
inside the script) and check the scheduling rules compliance.
2016-03-17 13:51:09 +01:00
Max
6044785a22 Ignore binary and backup files
Add missing entries to .gitignore
2016-03-17 13:50:51 +01:00
Max
b2b1112a6e Add explicit check for SI2quater index and count
Right now we do not support multiple SI2quater messages, so return error
if either index or count is non-zero.
2016-03-17 13:50:31 +01:00
Max
f3ee66207d Fix SI2ter scheduling
According to 3GPP TS 05.02 § 6.3.1.3 SI2ter messages should be scheduled
in FN with TC=4 only if SI2bis messages are also available.
2016-03-17 13:48:16 +01:00
Holger Hans Peter Freyther
0be80aa2d1 octphy: Enable TCH/H mode and begin testing
Upcoming releases will support TCH/H and we should start to test
the DSP->RTP code.
2016-03-16 09:17:04 +01:00
Holger Hans Peter Freyther
710e99c2e3 misc: Attempt to fix make distcheck and dumping docs
The file has been renamed, attempt to catch up
2016-03-15 20:09:49 +01:00
Harald Welte
40e8365854 Update configuration examples
Add SysmoBTS-specific example.
Remove outdated generic example which is no longer working.
2016-03-14 18:36:11 +01:00
Max
d5c658b22e Fix copy-paste issue
This issue prevented scheduling of SI 2quater messages.
2016-03-11 22:10:21 +07:00
Holger Hans Peter Freyther
91565b2d51 octphy: Use the event defaults as base
Bad parameters are passed to the event structure and the default
initialization should happen.
2016-03-10 16:15:51 +01:00
Holger Hans Peter Freyther
2278fdc580 pcuif: Do not bump the PCU_IF version
I had accidently bumped the version as I thought that osmo_ph_pres_info_type
was part of the ABI. It is not an only internal to the BTS. Revert
this part of the change.
2016-03-10 16:10:11 +01:00
Max
cb20c83323 Fix ocmo-bts-octphy interaction with OsmoPCU
Previously osmo-bts-octphy have not provided in-band presence
information which cause off-by-one errors and misinterpretation of
ph_data_ind by PCU. This fixed now by adding support for explicitly
passing PH-DATA presence info. Corresponding check and in-band passing
of presence information are removed.

Note: this requires libosmocore version with osmo_ph_pres_info_type
support integrated.

[hfreyther/max: Remove + 1 from the decoded length]
2016-02-22 13:57:54 +01:00
Harald Welte
94bb3769f3 scheduler: Fix ARRAY_SIZE() in trx_sched_init()
We want the size of the array, not of the pointer to the array.

Found by coverity (CID 1351422).
2016-02-15 20:16:07 +01:00
Harald Welte
e81cc6a158 use unsigned int to compare wih ARRAY_SIZE
This is not really an issue, but makes coverity happy (CID 1351422).
2016-02-15 20:13:04 +01:00
Harald Welte
69b959e557 sysmobts_vty: Fix null-check for pinst
There was a copy+paste error, checking for plink but we should check for
pinst.

This was found by coverity (CID 1351424).
2016-02-15 20:11:43 +01:00
Harald Welte
ad7f7a7117 Merge branch 'laforge/litecell15' 2016-02-15 14:28:50 +01:00
Harald Welte
81cc8cdba5 LC15: remove bogus check_for_ciph_cmd() copy 2016-02-15 14:28:19 +01:00
Harald Welte
e634fd256b LC15: set nominal transmit power of 37dBm for all TRX 2016-02-15 14:28:05 +01:00
Harald Welte
433863e4c9 LC15: Fix 'make dist' (missing include files) 2016-02-15 14:28:00 +01:00
Harald Welte
634c3e4648 Use consistent naming of binaries accross BTS models
Let's use one systematic naming schemes for all BTS models.

osmobts-trx -> osmo-bts-trx
sysmobts -> osmo-bts-sysmo
lc15bts -> osmo-bts-lc15
2016-02-15 14:27:57 +01:00
Harald Welte
a9a7120c82 make PCU socket and telnet port configurable
In some cases we'd like to run multiple instances of osmo-bts on a
single machine.  This is the case where we a multi-TRX PHY is to be used
for several BTSs, or in case osmo-bts-trx has multple SDRs attached.

This wa currently prevented by having a hard-coded PCU socket path
and telnet port, which are now configurable via VTY / config file
itself.
2016-02-15 14:27:52 +01:00
Harald Welte
5dfb115eaf declare pcu_direct in pcu_if.h 2016-02-15 14:27:47 +01:00
Harald Welte
c6723c8206 move auto-band configuration commands to common/vty.c
It remains up to the individual BTS hardware models to decide
whether or not to register those commands (depending on whether they
support the feature) via cfg_bts_auto_band_cmd / cfg_bts_no_auto_band_cmd
2016-02-15 14:27:43 +01:00
Harald Welte
3b4d9e7c07 LC15: Call l1if_reset() after l1if_open()
We want to start talking to the L1 from the point the PHY link has
been opened, and not only once an OML connection has been established.
2016-02-15 14:27:36 +01:00
Harald Welte
53e0291df6 LC15: Remove clk_cal (another unused struct member) 2016-02-15 14:27:32 +01:00
Harald Welte
e9a17292e8 LC15/sysmobts: Don't try to refer to fl1h from PHY config
At the time the phy link / phy instance level VTY configuration
commands are parsed, we did not yet call l1if_open() and thus
pinst->u.{lc15,sysmobts}.hdl == NULL.

PHY or PHY instance specific configuration must thus be stored inside
the phy_link or phy_instance itself, and not inside the (not yet
existing) handle.

We solve this by moving around some parameters:
* clk_use_eeprom/clk_cal/clk_src/calib_path get replicated in
  phy_instance
* min_qual_{rach,norm} are moved into the generic part (which means
  that osmo-bts-octphy and osmo-bts-trx should also implement them)
2016-02-15 14:27:29 +01:00
Harald Welte
9b5cff87ec LC15: Remove unused clk_use_eeprom and clk_src fields
this is part of the copy+paste legacy from sysmobts and can be removed
as it is not used.
2016-02-15 14:27:25 +01:00
Harald Welte
9684099ae9 sysmobts/LC15: Fix startup-time DSP trace flage configuration
Due to the changes introduced by the phy_link API, it's not easy to set
the default DSP trace flags via a command line argument anymore.  We now
rather introduce a persitent VTY configuration command, by which the
default DSP tracing configuration can be set (for each PHY).

The persistent trace flags are stored in the phy_instance, while the
current operational run-time flags are in fl1h->phy_instance.
2016-02-15 14:27:20 +01:00
Harald Welte
38933afdd9 introduce + use new generic vty_get_phy_instance()
this function is intended to be used by VTY commands that need to
resolve a given PHY interface.
2016-02-15 14:27:16 +01:00
Harald Welte
6a0f0f9e21 LC15: fix compiler warning against more recent libosmovty 2016-02-15 14:27:12 +01:00
Harald Welte
4dd8bd84a4 LC15: Fix printed msgq file names in error messages 2016-02-15 14:27:08 +01:00
Harald Welte
8f0266b885 LC15: cosmetic whitespace fixes 2016-02-15 14:27:04 +01:00
Harald Welte
234309878e LC15: Add example configuration file for Litecell 1.5 2016-02-15 14:26:58 +01:00
Harald Welte
1dcb97eaa3 LC15: port litecell 1.5 support to recent osmo-bts master
This includes changes required for
* shared main() function accross all BTS models
* use of the new phy_link / phy_instance infrastructure as the basis
  for true multi-TRX operation
2016-02-15 14:26:55 +01:00
Harald Welte
29a0197ead LC15: configure.ac: Allow specifying an alternate include-dir
The user can now use ./configure --with-litecell15=/my/local/path
2016-02-15 14:26:51 +01:00
Harald Welte
ccc7a1bf46 LC15: configure.ac: use --enable-litecell15 insteda of --enable-litecell15-bts 2016-02-15 14:26:47 +01:00
Yves Godin
b936bd7162 LC15: use talloc pool for msgb and ortp library
by using a talloc pool, we avoid having to go back to the libc
malloc pool all the time.  The msgb allocations and libortp allocations
happen quite frequently during processing and show up as one of the
high priority items in osmo-bts profiles on sysmoBTS with 14 concurrent
TCH/H calls (highest load scenario).

talloc still consumes significant CPU, this is mostly due to the
zero-initialization of all the associated buffers.  Strictly speaking
we shouldn't need this, but any change there would require lots of
testing, as there might be hidden assumptions in the code?

In some percentage of cases, talloc still seems to fall back on malloc
for msgb allocations, which is currently a bit of a mystery.  The pools
certainly are large enough, talloc_reprt() rarely reports more than a
few tens of kilobytes used by the msgb pool.

From 2ecbf87130
2016-02-15 14:26:44 +01:00
Yves Godin
6e1aed4b23 LC15: Disable DSP trace flags by default 2016-02-15 14:26:38 +01:00
Yves Godin
2a711887b7 LC15: Add initial support for the NuRAN Wireless Litecell 1.5
This commit adds basic support for the Litecell 1.5. Multi-TRX is not
supported yet. Instead, multiple instances of the BTS can be launched
using command line parameter -n <HW_TRX_NR> to specify if TRX 1 or
2 must be used by the bts. Note that only TRX 1 opens a connection to
the PCU. Full support for GPRS on both TRX will come at the same time
than the multi-TRX support.

The BTS manager has been adapted to match the new hardware but otherwise
it has not been improved or changed compared to the one used on the
SuperFemto/Litecell (sysmobts).
2016-02-15 14:26:33 +01:00
Harald Welte
5a945dad0c sysmobts: make clock calibration eeprom default (again?) 2016-02-15 14:23:57 +01:00
Harald Welte
b1d2dd316f abis.c: Fix segfault on OML link loss
When the OML signalling link is lost, first set bts->oml_link = NULL,
then iterate over the RSL links and close them.  Closing the RSL link
will cause a OML state change message to be sent, which in turn tries
to use the no-longer-existing OML link.

The code should be cleaned up further to distinguish which signalling
link was lost, and actually communicate a RSL(only) loss to OML.

But for now, it's best to simply close down all links and terminate
osmo-bts to ensure all state is properly reset and recovered.
2016-02-15 14:23:18 +01:00
Harald Welte
f5b42c3421 Merge branch 'laforge/phy-link'
this introduces the new phy_link / phy_instance interface, which is the
basis of clean support for all kinds of multi-trx configurations with
various BTS modules.

WARNING: This breaks configuration file compatibility.  You will need to
introduce config nodes for 'phy' and 'instance', as well as the link
from the 'trx' nodes towards the phy instance.
2016-02-15 14:19:46 +01:00
Harald Welte
a02bf125ac port sysmobts to phy_link/phy_instance abstraction 2016-02-15 14:18:59 +01:00
Harald Welte
fcef6b2b52 don't touch OML MO when PHY link is established
It seems the right thing to do: Once we know a PHY link is established,
the associated OML managed objects should change their state
accordingly.  However, given all the hackery we do with MO states, this
actually breaks things, rather than helping.  So I'm disabling that part
for now, but this needs to be re-visited at some point.
2016-02-15 14:18:59 +01:00
Harald Welte
d784e50747 Introduce new phy_link and phy_instance abstraction
This way we can model a flexible mapping between any number of PHYs,
each having multiple instances, and then map BTSs with TRXx on top of
those PHYs.
2016-02-15 14:18:59 +01:00
Harald Welte
f58542899a Merge branch 'laforge/trx-split'
This splits the TRX scheduler into a generic part and an osmo-bts-trx
specific part.  It is the basis for re-using the scheduler from other
bts modules such as the upcoming osmo-bts-virtual.
2016-02-15 14:18:06 +01:00
Harald Welte
1a5b00ebe2 TRX: Move scheduler to src/common
This is the final step to make the L1 scheduler generally available
to other BTS models than OsmoTRX.
2016-02-15 14:17:55 +01:00
Harald Welte
48726242ad TRX: scheduler: Remove dependency to trx_if.[ch] 2016-02-15 14:17:55 +01:00
Harald Welte
67311cc1f2 TRX: scheduler: Move trx_sched_clock() to scheduler_trx.c
This funciton (and associated static functions) are TRX specific,
and scheduler.c should only contain generic code.
2016-02-15 14:17:55 +01:00
Harald Welte
b6b42d150d TRX: scheduler: don't access l1h->config from scheduler 2016-02-15 14:17:55 +01:00
Harald Welte
11db925f15 TRX: call trx_loop_sacch_clock from TRX scheduler backend
this removes the dependency of scheduler.c on loops.h
2016-02-15 14:17:55 +01:00
Harald Welte
2b0e209029 TRX: split scheduler in generic part and backend part
the backend is performing the actual encoding and decoding functions,
while the generic part constsits of the TDMA structures and generating
the RTS.ind
2016-02-15 14:17:55 +01:00
Harald Welte
5538f5cff8 TRX: factor out the scheduler from remaining code
The L1 scheduler is a generally useful component that is unfortunately
tied quite a bit into the OsmoTRX support.  Let's try to separate it out
by having separate per-trx/per-ts/per-chan data structures pre-fixed
with l1sched_

Using this patch it should be one step easier to use the scheduler for
other BTS models, such as the intended upcoming virtual BTS.
2016-02-15 14:17:55 +01:00
Harald Welte
5f17720fcd fix migration of check_for_ciph_cmd() from sysmobts to l1sap
During the L1SAP related changes, somehow an old version of
check_for_ciph_cmd() was re-introduced, which didn't store the N(s) as
part of the lchan.  To make things worse, the old code was still present
in the sysmobts specific part, but never executed.
2016-02-09 13:59:55 +01:00
Harald Welte
5d212055b7 L1SAP: Ensure we don't process MPH-TIME.indication on TRX != C0 2016-02-03 18:45:39 +01:00
Harald Welte
6f9beedc48 fix compile warnings 2016-02-03 18:45:39 +01:00
Harald Welte
131ab36e3a abis: Add a queue of OML messages
When the oml_link is down or not yet established, we currently lost
any OML messages that were scheduled for transmission to the BSC.  Let's
prevent that by keeping a queue of OML messages, which is drained at the
time the OML link comes up again.
2016-02-03 18:45:39 +01:00
Harald Welte
2ed116efec Revert "oml: temporary debug hack"
This reverts commit c623c4e589.

That's a commit from 2012, and it was never needed ever since.
2016-02-03 18:45:39 +01:00
Holger Hans Peter Freyther
5f8c85bf9c octphy: Look-up the right timeslot and then the logical chan
Use the right identifier for the timeslot and not the trx number
which would always use ts==0 on the first trx. This should fix
ciphering issues for TS>0 (e.g. SDCCH8 on TS==1)
2016-02-03 18:29:00 +01:00
Harald Welte
3ca59512d2 OML: Ignore T200 settings by BSC for now
It seems that once we start to respect the T200 values as specified by
the BSC, we run into all kinds of issues with LAPDm re-transmissions,
REJ frames, unexpected supervisory frames and the like.

The libosmogsm LAPDm T200 defaults of 1s/2s are proven to "work" (i.e.
not expose the above behavior), so let's revert to them until the root
cause of this problem is determined.
2016-01-25 20:46:56 +01:00
Harald Welte
111a02f214 lapdm: Add DEBUGP statement about T200 values being set for lchan 2016-01-25 20:46:53 +01:00
Harald Welte
0d19e48487 Fix T200 default values
The T200 default values should be in milli-seconds (as the variable name
indicates).  They are not expected to be divided by the TS 12.21 OML
dividers for T200.

This change doesn't really make a difference with OpenBSC, as the BSC
always sets its own T200 values via OML, overwriting the defaults here.
2016-01-25 20:46:51 +01:00
Holger Hans Peter Freyther
728448a7f1 main: Return something from the method
Fixes: CID#59923
2016-01-23 10:25:24 +01:00
Harald Welte
0db18d030d OCTPHY: fix 'make dist' (missing header files) 2016-01-22 09:44:17 +01:00
Harald Welte
0048a788dd Merge branch 'laforge/common-main' 2016-01-22 09:33:54 +01:00
Harald Welte
611ef23700 merge bts-specific main function into common/main.c:bts_main()
This removes a lot of copy+paste duplication between different BTS
models.
2016-01-22 09:09:09 +01:00
Harald Welte
a0192b859b Add new bts_model_ctrl_cmds_install()
This is one step in making the main() functions of different
BTS models more similar, so we can share one code rather than multiple
copies of it.
2016-01-22 09:09:09 +01:00
Harald Welte
ec3be11ec6 common/support.c: Remove unused file 2016-01-22 09:09:08 +01:00
Andreas Eversberg
69fc57b028 ABIS: Support for multiple RSL connections 2016-01-22 09:09:02 +01:00
Harald Welte
32d681ab98 OCTPHY: Don't have files in EXTRA_DIST that don't exist (anymore)
This fixes a 'make dist' issue.
2016-01-21 16:32:14 +01:00
Harald Welte
e60b9d1de6 Make T200 default initialization even more robust
There's no need to use memcpy(), which adds the risk that the types of
source and destination are not the same (see previous commit). Iterating
over the array and assigning each element is more robust.
2016-01-17 21:10:13 +01:00
Harald Welte
3d431bb4eb Fix T200 default values
t200_ms is an unsigned int [7] array, while the oml_default_t200_ms was
an uint8_t[7] array, which we memcpy() to the former as default
initializer.  Fix this by turning oml_default_t200_ms into unsigned int,
too.
2016-01-17 21:10:09 +01:00
Harald Welte
5e8d8a1e75 Merge branch 'laforge/cleanup' 2016-01-16 17:51:16 +01:00
Harald Welte
f9de18ea15 TRX: the L1SAP queue contains mac blocks, not bursts (cosmetic) 2016-01-16 17:49:13 +01:00
Harald Welte
97cb71971a TRX: Don't hard-code 23 bytes, use GSM_MACBLOCK_LEN 2016-01-16 17:49:08 +01:00
Harald Welte
dd562d84ba TRX: Don't use magic numbers when we have #defines 2016-01-16 17:49:04 +01:00
Harald Welte
773ab8b2c5 TRX: replace some more 2715648 magic numbers with GSM_HYPERFRAME 2016-01-16 17:48:57 +01:00
Harald Welte
69ace680dd TRX: scheduler: whitespace cleanup 2016-01-16 17:48:53 +01:00
Harald Welte
1bdd08d07d TRX: schedule: remove dead code
the check whether or not to send a dummy burst is done already in
trx_sched_dl_burst(), so no need to have commented-out code doing that
again.
2016-01-16 17:48:45 +01:00
Harald Welte
519a639cf3 TRX: make trx_chan_desc static, it is not used externally 2016-01-16 17:48:40 +01:00
Harald Welte
6323d2e617 use existing #define for FR/EFR frame length (33/31) 2016-01-16 17:48:26 +01:00
Harald Welte
601781f463 move 'GSM_FR_BYTES' and related definitiions to common part 2016-01-16 17:48:20 +01:00
Harald Welte
695d8eb277 TRX: Reduce magic numbers, introduce GSM_HYPERFRAME for 2715648 2016-01-16 17:48:15 +01:00
Harald Welte
5b500f5d8f TRX: use const for dummy and fcch burst definitions 2016-01-16 17:48:04 +01:00
Harald Welte
2bf00d7729 TRX: mark scheduler data structures as 'const'
Those are read-only tables which should end up in the text segment
and not in writable data.
2016-01-16 17:47:59 +01:00
Harald Welte
12992d86dc TRX: some comments dscribing the scheduler.[ch] API 2016-01-16 17:47:54 +01:00
Harald Welte
d93bd21185 sysmoBTS: port 'press Ctrl+C twice for immediate exit' from osmo-bts-trx 2016-01-16 17:47:40 +01:00
Harald Welte
8250800d3b TRX: Add stub bts_model_change_power() function
This just fixes linking. It still needs to be properly implemented
2016-01-16 17:47:34 +01:00
Harald Welte
6d101a79a8 TRX: remove obsolete get_mac() function 2016-01-16 17:47:13 +01:00
Harald Welte
20e8770df0 Merge branch 'sysmocom/octphy' 2016-01-16 17:28:25 +01:00
Harald Welte
866f9b979d OCTPHY: Obtain information from PHY and expose it in VTY
This adds 'show trx 0 system-information' command to the VTY indicating
various version information obtained from the DSP/PHY.
2016-01-16 17:26:26 +01:00
Harald Welte
3e98f942e5 OCTPHY: Implement command re-transmission after message loss
We re-use the 'wait_l1_conf' structure for implementing the
unacknowledge command window towards the PHY.  This means that thre will
unconditionally be a 'wait_l1_conf' now, even for requests where the
caller didn't provide a call-back.
2016-01-16 17:26:25 +01:00
Harald Welte
7bd2251dcb OCTPHY: Print NOTICE message if we receive supervisory frame 2016-01-16 17:26:24 +01:00
Harald Welte
0c017618cd OCTPHY: Block PHY indications until it is confirmed open
When re-starting OsmoBTS after unclean shutdown, the PHY is already
sending notifications (PH-DATA.ind, PH-TIME.ind, etc.) for the previous
physical channel / timeslot configuration.  At the point those messages
are received, OsmoBTS might not even have A-bis OML up yet, and thus has
no clue how to process such messages (and subsequently likely crashes).

Let's block such primitives from passing further up the code until we
have received the TRX-OPEN response.
2016-01-16 17:26:22 +01:00
Harald Welte
8d198f3598 OCTPHY: Fix various memory leaks and add comments on msgb ownership 2016-01-16 17:26:21 +01:00
Harald Welte
bca8d3b8f8 OCTPHY: Exit gracefully if config file specifies no phy-netdev 2016-01-16 17:26:20 +01:00
Harald Welte
a9003acb1c OCTPHY: Ensure we write the phy-netdev parameter
When writing the config file from the command line, we must not forget
to write the phy-netdev parameter, otherwise the program will fail to
re-start later :/
2016-01-16 17:26:19 +01:00
Harald Welte
dad89e50a2 OCTPHY: Replace '-lortp' with the proper pkg-config/autofoo version 2016-01-16 17:26:06 +01:00
Harald Welte
b92100ad36 Add support for Octasic OCTSDR-2G GSM PHY
This adds support for a new PHY to OsmoBTS, the Octasic OCTSDR-2G
PHY. This is a proprietary GSM PHY running on a familty of Octasic DSPs.
2016-01-16 17:23:10 +01:00
Harald Welte
e9f12acbeb LAPDm: Use T200 settings from OML rather than libosmocore defaults 2016-01-16 16:25:52 +01:00
Harald Welte
7d6860b114 print a NOTICE message if lchan not activ in get_active_lchan_by_chan_nr() 2016-01-16 16:25:52 +01:00
Alexander Huemer
056c267b89 fix some format specifiers 2016-01-15 15:33:46 +01:00
Holger Hans Peter Freyther
2b7728cd9d sysmobts-calib: Warn about firmware and header mismatch
sysmobts-calib might be easily patched by a user that does not know
that firmware and firmware headers form a contract that should be
matched. Compare the version numbers and print a warning if it does
not look correct. This should be enough for a user to see that something
is not right. Continue anyway as the firmware might still be compatible
(because the ABI has not changed).

Fixes: SYS#1172
2016-01-11 20:47:36 +01:00
Holger Hans Peter Freyther
65b4a7ba2b sysmobts-v2/eepromreader: Add userspace program to read EEPROM
If using a too old kernel on newer devices the eeprom reading will
fail and maybe it is not possible to update the kernel after the
unit has been deployed.

Add a utility to read the EEPROM of revD+ from userspace to be used
to fix up the thing.
2016-01-11 17:29:24 +01:00
Harald Welte
74269054a6 sysmobts: add missing break statement in l1if_handle_ind()
this was introduced in 21b020b336 and
luckily spotted by coverity (CID 1347446)
2016-01-08 14:19:23 +01:00
Alexander Chemeris
a62e3221b6 l1sap: Whitespace fixes. 2016-01-08 13:07:14 +01:00
Harald Welte
085569df55 fix large amount of compiler warnings in common and sysmobts code 2016-01-04 20:29:24 +01:00
Harald Welte
21b020b336 sysmobts: Clarify msgb ownership / fix memory leaks 2016-01-04 20:17:32 +01:00
Holger Hans Peter Freyther
e28a20a2d9 sysmobts: Catch up with the API changes and specify the version
API revision 5.1 allows us to pass a version number for the rx/tx
calibration and the DSP/FPGA will inform us about clock errors.
2015-12-07 11:23:36 +01:00
Minh-Quang Nguyen
2da932c7a0 sysmobts: support eeprom map version 2
[hfreyther: Accept the mixing of whitespace to ease future
merges]
2015-12-07 11:10:57 +01:00
Harald Welte
2ecbf87130 use talloc pool for msgb and ortp library
by using a talloc pool, we avoid having to go back to the libc
malloc pool all the time.  The msgb allocations and libortp allocations
happen quite frequently during processing and show up as one of the
high priority items in osmo-bts profiles on sysmoBTS with 14 concurrent
TCH/H calls (highest load scenario).

talloc still consumes significant CPU, this is mostly due to the
zero-initialization of all the associated buffers.  Strictly speaking
we shouldn't need this, but any change there would require lots of
testing, as there might be hidden assumptions in the code?

In some percentage of cases, talloc still seems to fall back on malloc
for msgb allocations, which is currently a bit of a mystery.  The pools
certainly are large enough, talloc_reprt() rarely reports more than a
few tens of kilobytes used by the msgb pool.
2015-12-06 21:31:39 +01:00
Harald Welte
62d7502b82 osmo-bts-sysmo: Disable DSP trace flags by default 2015-12-05 15:57:09 +01:00
Harald Welte
2d5481da27 l1sap: Ensure we only pass PHY primitives of active lchans
In some situations, a PHY might send us a primitive for a logical
channel that is not (or no longer) active.  Passing such primitives
higher up the stack is asking for trouble.  Specifically, LAPDm
instances cannot accept messages once their instance has been released.

We introduce two new helper functions: get_lchan_by_chan_nr() as well as
get_active_lchan_by_chan_nr().  The former just centralizes the look-up
of the lchan by timeslot number and sub-slot number.  The latter also
checks to ensure the lchan is active, which is used for PH-DATA / PH-RTS
primitives.  To the contrary, MPH primitives generally don't require the
cahnnel to be active for processing.
2015-12-05 11:54:08 +01:00
Harald Welte
44bc9408b1 common/rsl.c: The presence of a valied measurement result is DEBUG
we shouldn't consider the presence of a valid measurement result
as something NOTICEable
2015-12-03 19:54:38 +01:00
Harald Welte
02337e1d1d sysmobts: Dont recycle PHY primitive for L1SAP in PH-DATA.ind 2015-11-20 21:35:07 +01:00
Harald Welte
437deb5f3a sysmobts: fix ph_data_req() msgb handling + alignment
The way we recycle the msgb with a l1sap header when transforming a
PH-DATA.req L1SAP primitive into a PHY/L1 primitive was flawed in
several ways:

1) the way the L1SAP header was stored in the buffer didn't provide
   sufficient tailroom for the L1 primitive
2) the alignment of the data in L1SAP is at a 32bit bounadry, but not
   in the L1 primitive, causing unaligned accesses.
2015-11-20 18:05:51 +01:00
Harald Welte
48e99fd05a cope with 'struct gsm_bts' without a tsc member
This was introduced in openbsc.git a2bbc5ec0e6481bb5b65da7bdbde03a424437af4
2015-11-20 10:54:09 +01:00
Harald Welte
3c161bb7df tests/Makefile.am: Don't use sysmobts SUBDIRS twice
probably a git merge artefact of some sort...
2015-11-05 23:05:20 +01:00
Harald Welte
bbcf703be8 TRX: catch up with trhe amr_mode naming changes
OpenBSC introduced a naming change in
615ed46a6ab25f71a7ab0d8201d33b4dbf8fc5b0 but osmo-bts fixes were only
about osmo-bts-sysmo, not osmo-bts-trx.  This updates osmo-bts-trx
accordingly.
2015-11-05 23:02:55 +01:00
Harald Welte
94da045be5 Don't blindly link against '-lortp' but use pkg-config for that
This also ensures that a missing ortp library dependency is discovered
at configure time already
2015-11-05 22:52:50 +01:00
Harald Welte
33f234f278 Revert "configure.ac: Add subdir-objects to suppress warnings"
This reverts commit 94a05abb98.

The tests don't work well with subdir-objects, so we have to live with
the warnings meanwhile until somebody finds time to find the magic spell
to solve the autotools quest.
2015-11-05 22:48:24 +01:00
Harald Welte
55d89d17b2 configure.ac: Better description for --enable-sysmocom-bts and --enable-trx 2015-10-12 12:15:49 +02:00
Harald Welte
94a05abb98 configure.ac: Add subdir-objects to suppress warnings
automake: warning: possible forward-incompatibility.
automake: At least a source file is in a subdirectory, but the 'subdir-objects'
automake: automake option hasn't been enabled.  For now, the corresponding output
automake: object file(s) will be placed in the top-level directory.  However,
automake: this behaviour will change in future Automake versions: they will
automake: unconditionally cause object files to be placed in the same subdirectory
automake: of the corresponding sources.
automake: You are advised to start using 'subdir-objects' option throughout your
automake: project, to avoid future incompatibilities.
2015-10-12 12:13:13 +02:00
Harald Welte
45e597cc16 configure.ac: Depend on libosmotrau 0.3.2 (ortp statistics) 2015-10-12 12:12:29 +02:00
Harald Welte
9a9ddc1203 configure.ac: Only require libgps if building for sysmoBTS 2015-10-12 12:12:22 +02:00
Holger Hans Peter Freyther
13947b3408 amr: Catch-up for the non-RTP mode after amr rename 2015-10-03 22:45:52 +02:00
Holger Hans Peter Freyther
1009a87f3c amr: Catch up with the amr_mode changes
Use the bts_modes for all the types. As there are two instances
know. One for the ms and one for the bts.

Manual compile fix and not tested on HW
2015-10-03 22:34:37 +02:00
Harald Welte
f1fb0fa3af Merge branch '201509-trx-rebase' 2015-09-22 16:41:54 +02:00
Harald Welte
caa648d92e TRX: Add missing call to abis_init()
This somehow got lost during the latest rebase.
2015-09-22 16:41:32 +02:00
Harald Welte
88a31e2a99 make osmo-bts-trx provide bts_model_adjst_ms_pwr() 2015-09-22 16:41:32 +02:00
Harald Welte
307bfc81c1 fixup tests after bts_model_adjst_ms_pwr 2015-09-22 16:41:32 +02:00
Alexander Chemeris
5becc4613a tests: Update busrsts_test build.
We've added logging calls to the bursts processing. Add logging facility
initializatoin to the test code.
2015-09-22 16:41:31 +02:00
Alexander Chemeris
b812839dfa trx: fix potential use of uninitialized toa variable.
Not really a bug, as we're smart about it down the stream, but it's better to
be strict here as well.
2015-09-22 16:41:31 +02:00
Alexander Chemeris
ae525a8761 trx: Send POWERON/OFF commands to osmo-bts only for the first channel.
osmo-trx never supported separate power control for trx's, but now it started
to be more strict about it.
2015-09-22 16:41:31 +02:00
Alexander Chemeris
29ea40f538 trx: Assume 100% BER if total decoded bits is 0 in l1if_process_meas_res() 2015-09-22 16:41:31 +02:00
Alexander Chemeris
e9abc5a4f3 trx: Cleanup unused parts of loops.c 2015-09-22 16:41:31 +02:00
Alexander Chemeris
17be7fa73b trx: Remove unused variables. 2015-09-22 16:41:31 +02:00
Alexander Chemeris
68e8b2b1d5 trx: Fix typo in a log message. 2015-09-22 16:41:31 +02:00
Alexander Chemeris
391ff14977 trx: More logging for voice frame decoding functions. 2015-09-22 16:41:31 +02:00
Alexander Chemeris
cf18dcd5fd tests: Update bursts_test to accommodate BER calculations. 2015-09-22 16:41:31 +02:00
Alexander Chemeris
6fceaca584 trx: Implement BER calculations.
A known issue with this code is that BER is not updated for lost TCH frames,
because osmo-trx doesn't send any indication for them and we don't have
a callback to handle this.

Otherwise the code seem to work fine.
2015-09-22 16:41:31 +02:00
Thomas Tsou
ddc0bf14d5 TRX: Remove extra TCH/HS puncturing value
3GPP TS 05.03 "Channel coding" specifies the puncturing matrix (1,0,1)
for class 1 information bits and tail bits valued u(0) to u(103) for a
maximum puncturing index of 311. The puncturing index 313 exceeds the
maximum index and causes osmo_conv_get_output_length() to output the
improper length of 210 instead of 211.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
2015-09-22 16:41:31 +02:00
Andreas Eversberg
deb01a2652 TRX: Check if Transceiver indicates an out of range clock
If frame number is out of range (>= 2715648), the scheduler's process
would end up in an infinite loop. This is because the loop would schedule
bursts until the indicated frame number is reached, which would not be
possible.

The openbts, calypso-bts and osmo-trx might send out out of range clock
indications every 3.5 hour.
2015-09-22 16:41:30 +02:00
Andreas Eversberg
3cfc9d5fa3 TRX: Show which TRX does not respond or rejects a command 2015-09-22 16:41:30 +02:00
Andreas Eversberg
a7d0c5ef5a trx: Set lchan inactive, only if the dedicated channel is deactivated 2015-09-22 16:41:30 +02:00
Andreas Eversberg
f39c739bd6 TRX: Activate LCHAN of CCCH when CCCH is configured on time slot 2015-09-22 16:41:30 +02:00
Andreas Eversberg
f66f5b3ddc TRX: Free bust buffer memory to when changing lchan type 2015-09-22 16:41:30 +02:00
Andreas Eversberg
c241afa87c TRX: Add VTY option to allow setting RTS advance in frames
RTS (ready-to-send) must be issued in advance, so BTS core and especially
osmo-pcu can provide downlink data frames early enough. In some cases PCU
might provide frames too late, so they must be dropped. If PCU provides
frames too late, due to high system load, this "RTS advance" setting must
be increased.
2015-09-22 16:41:30 +02:00
Martin Hauke
178d618d5a TRX: fix some typos in comments 2015-09-22 16:41:30 +02:00
Martin Hauke
c9ddb2ba22 build: Use AM_CPPFLAGS in Makefile.am
Since automake 1.13 INCLUDES is depricated and causes a warning
Inspired from similar patches by Alexander Huemer for other osmocom
projects.
2015-09-22 16:41:30 +02:00
Martin Hauke
73d3f46994 tests: make tests for sysmobts conditional 2015-09-22 16:41:30 +02:00
Andreas Eversberg
b2482a8574 Allow TRX 0..254 at VTY, even if less TRX are available
Instead of limiting the number of TRX at VTY to the actual number of
supported TRX, VTY allows to configure any possible number of TRX. If a
TRX is configured, which is not supported by BTS model, an error message is
returned, which states that the given TRX is not supported.
2015-09-22 16:41:30 +02:00
Andreas Eversberg
812fdd92c7 TRX: Changed logging of unserved primitives from LOGL_NOTICE to LOGL_INFO 2015-09-22 16:41:30 +02:00
Andreas Eversberg
ec6225e3e0 TRX: Fixed chan_nr for SACCH/8(7) at scheduler 2015-09-22 16:41:29 +02:00
Andreas Eversberg
ef6eb5442c trx: Add option to set transmit power reduction via OML (BSC) 2015-09-22 16:41:29 +02:00
Andreas Eversberg
f0072a8de8 TRX: Do not send burst on IDLE channels at TRX != C0
This is required, so the transceiver transmits no power.
2015-09-22 16:41:29 +02:00
Andreas Eversberg
3cf28aa924 TRX: Close TRX (shutdown all active channels) on ABIS link failure 2015-09-22 16:41:29 +02:00
Andreas Eversberg
578340c7a7 TRX: Add bts_model_trx_close to TRX implementation 2015-09-22 16:41:29 +02:00
Andreas Eversberg
3caf3b7c45 TRX: Fixup ciphering state names after rebasing 2015-09-22 16:41:29 +02:00
Andreas Eversberg
ee47913389 TRX: No need to set mode and cipher for PDCH 2015-09-22 16:41:29 +02:00
Andreas Eversberg
f5aaf523c5 TRX: If no cipher algorithm is given, or if it is a5/0, reset cipher state 2015-09-22 16:41:29 +02:00
Andreas Eversberg
8c8998e551 TRX: Set ciphering to an initial state when activating channel
Handover and assignment may activate channels with ciphering already set,
so we need to tell scheduler to enable/disable ciphering and set the
correct cipher state.
2015-09-22 16:41:29 +02:00
Andreas Eversberg
da0c44a9db Add test case for successful handover and unsuccessful handover 2015-09-22 16:41:29 +02:00
Andreas Eversberg
798c1bba9d TRX: Process real time scheduling option is now similar to sysmobts 2015-09-22 16:41:29 +02:00
Andreas Eversberg
db0b93ac39 TRX: Disable handover burst detection when closing channel during detection 2015-09-22 16:41:29 +02:00
Andreas Eversberg
86c936cbb1 TRX: Use correct slot type for GSM_PHCAN_BCCH 2015-09-22 16:41:28 +02:00
Andreas Eversberg
b9a917a138 TRX: Handover access burst support 2015-09-22 16:41:28 +02:00
Andreas Eversberg
6527dffc94 TRX: Clear lchan state when resetting TRX 2015-09-22 16:41:28 +02:00
Andreas Eversberg
fb04746bce TRX: Report measurements 2015-09-22 16:41:28 +02:00
Andreas Eversberg
05597a7ddb TRX: Fixed typos tranceiver -> transceiver 2015-09-22 16:41:28 +02:00
Andreas Eversberg
82676c13ee TRX: Fix: Cleanly free TRX instances during initialization in case of an error 2015-09-22 16:41:28 +02:00
Andreas Eversberg
c2ee307fd4 Allow one or more TRX to configure via VTY 2015-09-22 16:41:28 +02:00
Andreas Eversberg
2e4a26a0e9 TRX: Add VTY options to enable and disable SETTSC and SETBSIC 2015-09-22 16:41:28 +02:00
Andreas Eversberg
6508f21130 TRX: Reset ciphering state when closing channel 2015-09-22 16:41:28 +02:00
Andreas Eversberg
c5241c3aa4 TRX: Support for AMR half speech 2015-09-22 16:41:28 +02:00
Andreas Eversberg
c910a332b2 TRX: Support for TCH/H and GSM half rate transcoding 2015-09-22 16:41:27 +02:00
Andreas Eversberg
f62a64e440 TRX: Add AMR Payload handling 2015-09-22 16:41:27 +02:00
Andreas Eversberg
a7f5e07712 TRX: Support for AMR full speech 2015-09-22 16:41:27 +02:00
Andreas Eversberg
5e2341411f Get RSSI from received uplink data and send to PCU 2015-09-22 16:41:27 +02:00
Andreas Eversberg
917cf7018b TRX: Add support for EFR transcoding 2015-09-22 16:41:27 +02:00
Andreas Eversberg
84b9a44535 TRX: Code cleanup, prepare for other codecs than GSM full rate 2015-09-22 16:41:27 +02:00
Andreas Eversberg
7ff22823ca TRX: Use link timeout value from BSC via OML attribute. 2015-09-22 16:41:27 +02:00
Andreas Eversberg
9855e8bd48 TRX: Out of range primitives found in downlink queue are not an error 2015-09-22 16:41:27 +02:00
Andreas Eversberg
219ece83a3 TRX: Implementation of MS power and timing advance loops 2015-09-22 16:41:27 +02:00
Andreas Eversberg
889890da43 TRX: Improved handling of clock indications.
If no clock is received, a POWEROFF is sent until clock is detected.
2015-09-22 16:41:27 +02:00
Andreas Eversberg
23a5183767 TRX: Fixes to TRX interface
Ignore false response to uncritical commands.
2015-09-22 16:41:27 +02:00
Andreas Eversberg
ce0f20b597 TRX: Fix of SCH burst data 2015-09-22 16:41:26 +02:00
Andreas Eversberg
7bd6e8b89b TRX: Ciphering 2015-09-22 16:41:26 +02:00
Andreas Eversberg
d692b6e054 TRX: Replaced GSM 06.10 ordering table by table in libosmocodec 2015-09-22 16:41:26 +02:00
Andreas Eversberg
89e36c0e64 TRX: Cleanup of channel transcoding 2015-09-22 16:41:26 +02:00
Andreas Eversberg
801c182c02 TRX: By default, send 20 frames in advance to tranceiver 2015-09-22 16:41:26 +02:00
Andreas Eversberg
7451ce29a7 TRX: Detect missing received bursts and fill them with zero-sbits 2015-09-22 16:41:26 +02:00
Andreas Eversberg
450d32919a TRX: Add test code for PDTCH transcoding 2015-09-22 16:41:26 +02:00
Andreas Eversberg
78b2080027 TRX: PDTCH (GPRS) works now
Detection and transcoding of all four coding schemes are supported.
2015-09-22 16:41:26 +02:00
Andreas Eversberg
9de67ca962 TRX: Lost TCH frame detection of omitted bursts from tranceiver 2015-09-22 16:41:26 +02:00
Andreas Eversberg
b9880bc812 TRX: Allow transcoding of TCH FR with MSB first (RTP) or LSB first (E1) 2015-09-22 16:41:26 +02:00
Andreas Eversberg
d10eaee4cc TRX: Completed TCH/F full rate support
Full rate is now tested and working.
2015-09-22 16:41:25 +02:00
Andreas Eversberg
b104aed5ec TRX: Fixed swapped stealing bits
Thanx to Sylvain for pointing to this bug.
2015-09-22 16:41:25 +02:00
Andreas Eversberg
cd463dd72a TRX: Minor fixes, especially handle TOA of RACH correctly 2015-09-22 16:41:25 +02:00
Andreas Eversberg
7d684d6866 TRX: Fix, never send confirm for DEACT SACCH request (TS 05.08 4.6)
Sending it would cause BSC to change to a state, where it does not release
rf channel.
2015-09-22 16:41:25 +02:00
Andreas Eversberg
e0959e7929 TRX: Use received TRX clocks to determine availablility of tranceiver
Only if transceiver becomes available, control commands are sent. If
tranceiver is gone, reset scheduler.

The current availability state is sent to BSC via OML state change
commands.
2015-09-22 16:41:25 +02:00
Andreas Eversberg
2ea68e2b7b TRX: Fixes and improvements of scheduler 2015-09-22 16:41:25 +02:00
Andreas Eversberg
2c8787224f Fix: Check right result on bursts_test 2015-09-22 16:41:25 +02:00
Andreas Eversberg
74d63b7212 Add test routing to test transcoding of TCH FR / FACCH frames 2015-09-22 16:41:25 +02:00
Andreas Eversberg
d0603d96e9 TRX: Completed transcoding of TCH with reordering Table 2 of TS 05.03 2015-09-22 16:41:25 +02:00
Andreas Eversberg
414faaca19 TRX: Power down tranceiver and reset scheduler, if abis link is lost
If BTS is gone, TRX is powered down, due to loss of abis link. If link is
esablished again, tranceiver and scheduler are provisioned again by BTS.
2015-09-22 16:41:25 +02:00
Andreas Eversberg
7a0d11dd68 ABIS: Introduce bts_model_abis_close to indicate ABIS link failure.
sysmocom-bts model shuts down on link loss, but other models may not want
this, so shutdown is moved tor bts_model_abis_close of osmo-bts-sysmo.
2015-09-22 16:41:25 +02:00
Andreas Eversberg
cd0581d815 TRX: On negative response of critical commands, shutdown BTS 2015-09-22 16:41:24 +02:00
Andreas Eversberg
1de7085d31 Add test code for testing GSM burst transcoding 2015-09-22 16:41:24 +02:00
Andreas Eversberg
acc71ffb4b TRX: Introduce osmobts-trx, a layer 1 implementation for OpenBTS tranceivers
The code is quite complete, TCH and PDCH channels are not yet tested.
2015-09-22 16:41:24 +02:00
Andreas Eversberg
c64fa4f888 Change to new structure of multirate at gsm_data_shared.h 2015-09-22 16:41:24 +02:00
Andreas Eversberg
79bc80102c Fix: Call e1inp_vty_init() before reading config file 2015-09-22 16:41:24 +02:00
Andreas Eversberg
5fa388c366 Fix: Process all TRX on GSM Time indication, not only C0 2015-09-22 16:41:24 +02:00
Andreas Eversberg
75f105bbb5 Fix: Retrieve ARFCN (from OML) for TRX other than C0 2015-09-22 16:41:24 +02:00
Ivan Kluchnikov
2340b88ede fix: make sysmobts tests only when sysmobts is enabled 2015-09-22 16:41:24 +02:00
Harald Welte
329085a8ff Merge branch '201509-l1sap' 2015-09-22 16:39:55 +02:00
Harald Welte
819b50e1a7 move MS power control handling from sysmobts to common part
MS uplink power control is required in pretty much any BTS, and we
cannot assume that they PHY / L1 will always take care of it by
itself.   So the correspondign code is moved to common/power_control.c
and called from the generic part of L1SAP.

The corresponding VTY paramter has been moved from the sysmobts-specific
trx VTY node to the common BTS VTY node.
2015-09-22 16:39:05 +02:00
Andreas Eversberg
f449842053 Move detection of handover frames from sysmo-bts code to common code 2015-09-22 16:39:05 +02:00
Andreas Eversberg
9cfbf27d4c Remove obsolete gsmtap handling from osmo-bts-sysmo part. 2015-09-22 16:39:05 +02:00
Andreas Eversberg
a450ef73ed Add gsmtap option to command line to main.c of osmo-bts-sysmo 2015-09-22 16:39:04 +02:00
Andreas Eversberg
04b5d65575 Move gsmtap VTY commands from osmo-bts-sysmo to common part 2015-09-22 16:39:04 +02:00
Andreas Eversberg
90e543bd83 Send primitives at PH-/MPH-/TCH-SAP interface via GSMTAP 2015-09-22 16:39:04 +02:00
Andreas Eversberg
75caaf2949 sysmobts: Clean up transitions for lchan cipher state
There are three transitions:

1. LCHAN_CIPH_NONE -> LCHAN_CIPH_RX_REQ -> LCHAN_CIPH_RX_CONF

It is used to enable ciphering in RX (uplink) direction only.

2. LCHAN_CIPH_RX_CONF -> LCHAN_CIPH_RX_CONF_TX_REQ -> LCHAN_CIPH_RXTX_CONF

It is used to additionally enable ciphering in TX (downlink) direction.

3. LCHAN_CIPH_NONE -> LCHAN_CIPH_RXTX_REQ -> LCHAN_CIPH_RX_CONF_TX_REQ
   -> LCHAN_CIPH_RXTX_CONF

It is used to enable ciphering in both TX and RX directions. This is used
when the channel is activated with encryption already enabled. (assignment
or handover)

In order to follow the order of these transitions, the RX direction must
always be set before the TX direction.

If no cipher key is set (A5/0), ciphering is set to ALG 0, but lchan cipher
state remains at LCHAN_CIPH_NONE.
2015-09-22 16:39:04 +02:00
Andreas Eversberg
5027e122a8 Add MEAS (MPH_INFO) IND message to PH-/MPH-/TCH-SAP interface
This part moves processing of measurement infos from osmo-bts-sysmo to
common part.
2015-09-22 16:39:04 +02:00
Harald Welte
a313bb0a47 l1sap: Port code to new ciphering handling
... introduced in 2cc37035d7
2015-09-22 16:39:04 +02:00
Harald Welte
923e324abc sysmobts/l1_if: Sacch/Sdcc/Facch are handled in l1sap/core 2015-09-22 16:39:04 +02:00
Andreas Eversberg
bac087c207 Add SDCCH/SACCH/FACCH messages to PH-/MPH-/TCH-SAP interface
This part moves control channel message primitives from osmo-bts-sysmo to
common part.

In order to control ciphering fo BTS model, CIPHER (MPH_INFO) messages are
used.
2015-09-22 16:39:04 +02:00
Harald Welte
80f039973e l1sap: Avoid compiler warnings regarding uninitialized nmsg 2015-09-22 16:39:04 +02:00
Harald Welte
3a381367a6 l1sap: Use {data,empty}_req_from_l1sap() and avoid code duplication 2015-09-22 16:39:04 +02:00
Andreas Eversberg
12472df8f0 Add TCH messages to PH-/MPH-/TCH-SAP interface
This part moves TCH handling from osmo-bts-sysmo to common part. The RTP
handling is done at the common part, so they can be used by other BTS
models.
2015-09-22 16:39:04 +02:00
Harald Welte
7cc199ea95 l1sap: re-introduce a comment that was lost during l1sap merge 2015-09-22 16:39:03 +02:00
Andreas Eversberg
793e713c4b Move chan act/rel/modify from bts_model to PH-/MPH-/TCH-SAP interface
This part replaces channel activation/deactivation/modification routines
by MPH_INFO messages.
2015-09-22 16:39:03 +02:00
Andreas Eversberg
faba84b9b7 Relace bts_model_get_time() by get_time() at common part 2015-09-22 16:39:03 +02:00
Harald Welte
7cf313c75b l1sap: Re-introduce more correct RACH slot counting
The original code handled both the fact where a TIME indication would be
missed (and thus the frame number be higher than previous + 1), as well
as the two cases for combined / non-combined CCCH.

The L1SAP code removed some of those bits, which I'm re-introducing
here.
2015-09-22 16:39:03 +02:00
Andreas Eversberg
21b5e6318e Add TIME (MPH_INFO) IND messages to PH-/MPH-/TCH-SAP interface
This part moves GSM time handling from osmo-bts-sysmo part to common part.
2015-09-22 16:39:03 +02:00
Harald Welte
4fe00da9f8 l1sap: additional comments explaining l1sap changes in l1_if.c 2015-09-22 16:39:03 +02:00
Andreas Eversberg
75be092b99 Add PDCH messages to PH-/MPH-/TCH-SAP interface
This part moves PDTCH, PACCH and PTCCH message primitives from
osmo-bts-sysmo to common part.
2015-09-22 16:39:03 +02:00
Harald Welte
c9441b3c0b l1sap: Add a warning about assuming BS_AG_BLKS_RES=1
This is a regression of the code compared to the existing
sysmoBTS code, where the L1 tells us whether its AGCH or
PCH.  However, it was not used even in the old code, so
we can afford to simply put a #warning here.
2015-09-22 16:39:03 +02:00
Andreas Eversberg
ace9a8742f Add PCH/AGCH message to PH-/MPH-/TCH-SAP interface
This part moves PCH and AGCH message primitives from osmo-bts-sysmo to
common part.
2015-09-22 16:39:03 +02:00
Harald Welte
54eceac257 l1sap: sysmobts: remove obsolete get_lapdm_chan_by_hl2() 2015-09-22 16:39:03 +02:00
Harald Welte
d410eb9787 l1sap: correctly set chan_nr on PRIM_PH_RACH / INDICATION
In case of a RACH INDICATION on CCCH, we need to set CHAN_NR to
0x88 (RSL_CHAN_RACH).  In other cases, chan_nr needs to reflect
the actual logical channel (TCH/SDCCH) on whcih the handover happened.
2015-09-22 16:39:02 +02:00
Harald Welte
9ae5b50d78 l1sap: RACH: Detect hand-over even on TRX0
I don't understand why we would detect handover only on TRX1-n,
but not on TRX0.  It is perfectly valid for a handover to occur
on TRX0.
2015-09-22 16:39:02 +02:00
Harald Welte
52476fc1d4 l1sap: fix missing include file and resulting compiler warning 2015-09-22 16:39:02 +02:00
Harald Welte
e969f08892 l1sap: fix coding style 2015-09-22 16:39:02 +02:00
Harald Welte
7b1b832618 l1sap: Use L1SAP_IS_CHAN_RACH instead of magic number 0x88 2015-09-22 16:39:02 +02:00
Andreas Eversberg
e0146997a6 Add RACH message to PH-/MPH-/TCH-SAP interface
This part moves RACH message primitives from osmo-bts-sysmo to common
part.
2015-09-22 16:39:02 +02:00
Harald Welte
a391d3691a l1sap: Split ph_data_req() into smaller parts
... in an effort to avoid introducing new/more spaghetti code

Also, use offsetof() instead of pointer calculation to determine
the start of GsmL1_Prim_t.u.phDataReq.msgUnitParam.u8Buffer
2015-09-22 16:39:02 +02:00
Andreas Eversberg
5e90f2a809 Add BCCH message to PH-/MPH-/TCH-SAP interface
This first part moves BCCH message primitives from osmo-bts-sysmo to common
part. A new file "common/l1sap.c" is introduced to implement handling of
layer 1 messages from/to BTS model.
2015-09-22 16:39:02 +02:00
Holger Hans Peter Freyther
1eaa3d72ea audio/rsl: Honor the speech mode and don't send anything
Spotted by Ciaby while debugging an audio issue. Do not
send anything to port==0 to the BSC/NITB. Look at the
upper bits of the speech_mode to determine if sending is
allowed. 0x1 means recv_only and all other modes allow us
to send.

Manually verified with a single phone call with LCR bridge
mode to send a CRCX early but a MDCX sendrecv later. The
audio starts to flow after the MDCX message. Virtual Addr
space didn't increase over 10 calls. The l1p_msg is freed
by the caller.

The code might not re-set speech_mode from one call to
another but if it is ever != 0 it can be expected that
the BSC will always set it. This is because we do not
(and don't want to) allocate the lchan dynamically on
every usage.

Fixes: SYS#2111
2015-09-21 14:34:22 +02:00
Holger Hans Peter Freyther
668f8df3be audio/rsl: Include statistics for one call
Use the new libosmo-abis API to query the session for the
statistics and then send it as a TLV element to the BSC.
This can be used to do post processing about the call. E.g
to figure out if no audio arrived at all.
2015-09-21 14:34:07 +02:00
Holger Hans Peter Freyther
cc4a08bdc7 audio/rsl: Include the connection identifier in the DLCX ind
I have traces that include the connection identifier in the
DLCX indication.
2015-09-21 10:14:11 +02:00
Harald Welte
862807504b update README to bring it more in sync with reality. 2015-08-21 02:30:24 +02:00
Holger Hans Peter Freyther
a7c276b72b meas: Do not send incomplete measurement reports
The RSL_IE_MEAS_RES_NR is mandatory element with a minimum
of 5 octets (two for TL and three for the value). When we
establish a new channel we might not have had enough time
in a TDMA frame to calculate the average. The issue is not
easy to reproduce. At the point we receive the measurement
report we have two uplink measurements queued. As it is not
easy to reproduce and only occurs when a channel is new
I have decided to drop the message instead of sending made
up uplink measurement reports.

As of now lchan_build_rsl_ul_meas will always return 3 and
the condition will never be false.

Avoids: SYS#1781
2015-07-14 09:55:56 +02:00
Holger Hans Peter Freyther
f869a95f3b write_queue: Check the result of osmo_wqueue_enqueue and free
The write_queue is designed to have a maximum amount of pending
messages and will refuse to take new messages when it has been
reached. The caller can decide if it wants to flush the queue
and add the message again, create a log. But in all cases the
ownership of the msgb has not been transferred. Fix the potential
memory leak in the failure situation.
2015-03-28 18:31:10 +01:00
Andreas Eversberg
0ddd4b6c25 Add header file of PH-/MPH-/TCH-SAP interface to common part of osmo-bts
Instead of handling primitives directly at layer 1 specific code,
osmo-bts handles primitives at common code.

When all primitive are moved, the l1sap interface will:
- receive PH-DATA indications and forward them to layer 2.
- check for RF link loss and notify BSC.
- receive TCH indications and forward them via RTP.
- receive PH-RTS indications and send PH-DATA requests with content
  according to its logical channel.
- receive TCH-RTS indications and send TCH requests with content
  received via RTP or loopback from TCH indications.
- send MPH-INFO requests to activate, deactivate and modify logical
  channels and handle their confirms.
- receive MPH-INFO indications with measurements from tranceiver.
- forward received and transmitted PH-DATA to GSMTAP.
2015-03-25 23:22:00 +01:00
Andreas Eversberg
24839068f5 sysmo-bts: Use correct boundaries of L1 msg when forwarding to L1 proxy
In case of a headroom in a message, the 'head' pointer will not point to
the actual data.
2015-03-25 23:19:58 +01:00
Holger Hans Peter Freyther
b631bd21d2 power: Make it possible to force a power level
Use the standard RSL commands to order a logical channel
to use a fixed power level.

The code is not fully verified and there was a last minute
change to invoke bts_model_adjst_ms_pwr.
2015-02-05 22:32:53 +01:00
Holger Hans Peter Freyther
579651bf30 power/sysmobts: Add a manual ms power level control
Currently the DSP is instructed to achieve a given uplink
power target but there are circumstances (e.g. EMV testing)
where we need more control over it. The "manual/software/osmo"
power control can only be implemented per TRX and not per
lchan. Add a very very basic control that checks the MS Power
used by the phone, the actual receive level and then adjust
the power.

The code doesn't take the history into account, if the phone
can not reach the requested power level the code will be stuck
(e.g. no timeout based on multiframes). It has a mode for a
fixed power control but no way to set it yet.

The change of the mode requires a restart of the software.
2015-02-05 22:32:47 +01:00
Holger Hans Peter Freyther
0d6946741c sysmobts: Check mgr->calib.bts_conn for NULL
Check the right variable for NULL.

Fixes: CID 1262214
2015-01-10 18:06:29 +01:00
Holger Hans Peter Freyther
7e10bd6401 misc: Fix up testcase after 5a03e129a6
In 5a03e129a6 we generalized the
structural parser so we need to update the expected behavior of
that routine.
2015-01-10 13:07:49 +01:00
Holger Hans Peter Freyther
84e4dd92d4 sysmobts: Improve some log messages for calib control
* Print the GPS FD that was opened (e.g. to see if it was
  closed again)
* Print the state changes/expectations
* Print the correct to be applied. I wondered if I shouldo do
  a cor = cor * -1.. cor = -cor.. or add CLOCK_CORR(err) macro
  to use it inside the printf and correction and decided the
  gain is not worth the risk.
2015-01-10 09:15:27 +01:00
Holger Hans Peter Freyther
55da9874c0 sysmobts: Create a calibration loop that will be run
Continously run the calibration process. Everytime we call the
reset function classify the outcome. In case of a failure schedule
the next command soon and otherwise wait several hours.

Remember if the process was started through the VTY or the run
loop. In case it can't be started immediately reset and schedule
a new run.
2015-01-09 21:57:13 +01:00
Holger Hans Peter Freyther
d8d5f5904f sysmobts: Start the calibration the first time the link is up
After a reboot the system might have been off for a long time
and the currently used value might be wrong. Remember that we
never ran the calibration and execute it on start.
2015-01-09 21:57:13 +01:00
Holger Hans Peter Freyther
9acc82ce4a sysmobts: Initial version to use libgps to determine FIX state
We should only calibrate the clock if there is a GPS fix. Start
gpsd to determine if there is a fix or not. Work around trimble
decoding issues (sent an email upstream). We need to gain some
more experience to see if there memory leaks. We also need to
re-schedule the calibration depending on the outcome.
2015-01-09 21:57:13 +01:00
Holger Hans Peter Freyther
c017e309c4 sysmobts: The correction for GPS is in the reverse direction
Change the sign before passing it as correction value. The error
is the difference between the TCXO and GPS. We need to correct by
the reverse of the error. This seems to be different depending on
the clock source we have.

This is a last minute untested change.
2015-01-09 21:57:13 +01:00
Holger Hans Peter Freyther
2e59b20204 sysmobts: Use the ctrl interface for calibration
This runs the entire procedure for calibration with reasonable
error and success checking. It can be triggered from the VTY
of the sysmobts-mgr right now.

What is missing is to hook up with GPSD to check if the system
has a fix and provide a mode that will continously run the
calibration command.
2015-01-09 21:57:13 +01:00
Holger Hans Peter Freyther
fd425b1484 sysmobts: Copy more of l1if_rf_clock_info_reset into the CTRL code
The CTRL code should have used/extended the l1_if calibration
code. The sysmobts-mgr code first needs to determine if the
clock adjustment is necessary at all. This is done by first
resetting the counters, then waiting, then asking for the diff
and then applying the correction value. But the reference clock
is only set by the application comand.

Copy more code of l1if_rf_clock_info_reset to set the reference
clock as value. This is leaving some todos inside the code that
will be resolved as part of SYS#835.

Related: SYS#835
2015-01-09 21:57:13 +01:00
Holger Hans Peter Freyther
50131c125e sysmobts: Begin with calib control from the sysmobts manager
In the long run we will connect to GPSD and wait for a fix and
then run the calibration. The first step is to open (and re-open)
the control connection to the BTS.

As the connection is on localhost there should not be a computation
overhead to always have the connection open. When connecting assume
that the ASYNC connect worked directly as otherwise we get no
notification of the failure.

This looks like a "bug" of libosmo-abis that should check if the
socket has been connected or not.
2015-01-09 21:57:13 +01:00
Holger Hans Peter Freyther
5a03e129a6 msg: Generalize the message structure test
This was taken out of LaF0rge's OML router branch and is now
used by the extended calibration feature.
2015-01-09 21:57:13 +01:00
Holger Hans Peter Freyther
b7ebf545e6 cbch: Speculative change to not change CHAN ACK for CBCH
Use the rel_act_kind to not send RSL channel acks for the
CBCH to the BSC. This is similar to what we do for the BCCH
a couple of lines above.
2015-01-06 19:23:02 +01:00
Harald Welte
8fc2630dd4 SMS-CB: Clean up + centralize generation of NULL block 2014-12-30 13:45:02 +01:00
Harald Welte
bd988f6ad3 SMS-CB: Use GSM412_SEQ_NULL_MSG rather than 0xf 2014-12-30 13:34:57 +01:00
Harald Welte
1e245336ec SMS-CB: use gsm412_block_type from libosmocore
.. and not our own local re-definition of the structure.
2014-12-30 13:33:54 +01:00
Harald Welte
4457c0d9ba SMS-CB: Use GSM412_ #defines from libosmocore rather than our own 2014-12-30 13:32:52 +01:00
Harald Welte
660116fb9d CBCH: Implement CBCH block segmentation and RSL_MT_SMS_BC_CMD
* CBCH load indications are not yet sent
* The queue length is not yet limited!
2014-12-30 00:32:13 +01:00
Harald Welte
b15d2c9d2f Initial CBCH support
This should handle OML channel combinations with CBCH and activate the
CBCH SAPI towards the DSP correspondingly.  What is still missing is
sending any actual information over the CBCH in respons to the
PH-RTS.ind coming up from L1.
2014-12-30 00:28:31 +01:00
Holger Hans Peter Freyther
50dc96507c sysmobts: Include the serial number in the find response
Read the serial number once and format it as a string. In
case no serial number is present -1 will be returned.

Manually tested with a slightly modified version. serial_nr
was the expected one.
2014-12-26 01:46:24 +01:00
Holger Hans Peter Freyther
c265bef48c sysmobts: Add slave on/off action for the sysmoBTS2050
Add new power actions for the sysmoBTS2050. This allows to
switch off the secondary/slave when the system temperature
is too high and back on when the normal level is reached.

Do not allow to switch off the master (so remove the enum
value), do not check if the slave is switching itself off.
2014-12-16 20:22:28 +01:00
Holger Hans Peter Freyther
02a2afa962 sysmobts: Comment out the varpoware options that are not implemented 2014-12-16 20:22:28 +01:00
Holger Hans Peter Freyther
ffc193443c sysmobts: Add "normal" actions to execute
Instead of keeping state to remember what was done and needs
to be undone this patch introduces actions that will be executed
when the system is back to normal.

By design the system is considered to be in the normal state
and these actions will be only executed after the system is
coming back to the normal state.

One advantage of this scheme is that an operator can decide
that an overheated systems hould be off duty and requires manual
interaction to be allowed back in service.

The change has only been smoke tested

Fixes: SYS#833
2014-12-16 20:22:28 +01:00
Holger Hans Peter Freyther
8968b48643 sysmobts: Remove unused global variables
We do not need to have these variables anymore. Just remove them.
2014-12-16 15:12:56 +01:00
Holger Hans Peter Freyther
641a934931 sysmobts: Read the clock calibration from another place
Read the clock calibration from the place that will be read by
the BTS process. Use the standard eeprom code for doing that.
The code assumes that this and the other eeprom code don't
write/invlidate the others reason. If that assumption would not
be true calls to eeprom_free_resources should be added.
2014-12-16 15:12:55 +01:00
Holger Hans Peter Freyther
69897d7eed sysmobts: Don't list non integer parameters in the help
The command can only read integer parameters. Don't offer
buffers as this will lead to error 22.
2014-12-16 15:09:22 +01:00
Holger Hans Peter Freyther
0d09e75f9c eeprom: Fix brown paper bag introduced a long while ago
91d204e2db while adding checks
to resolve coverity issues. We simply had no one writing to
the eeprom so this was unnoticed for a long time.
2014-12-16 15:09:22 +01:00
Holger Hans Peter Freyther
42cc96e2c1 sysmobts: Add an option to stop the systemd sysmobts.service
For systems without direct access to the PA the best option
is to simply switch off the bts service. This will stop the
transmission which will take load from the DSP/FPGA/RF circuit
and indirectly from the PA as well.

We should introduce "pa-on and bts-on" that can be executed
as "normal" action.
2014-12-12 14:53:23 +01:00
Holger Hans Peter Freyther
8381a6a483 sysmobts: Actions can be executed in all levels
Somebody could decide to switch off the PA in the warning level
already. Support this mode of operation. This means we could have
a config that:

* Enables the PA in the normal level
* Disables it in the critical level

With kdbus or better IPC we could even have the PA and other
parts be represented as service that talk to a bts manager and
then simply execute start/stop requests. This would make the
entire TODO entry irrelevant as state would be managed by
systemd and one can see the time the service was executed.
2014-12-12 14:40:25 +01:00
Holger Hans Peter Freyther
4d4dc26742 bts: Move BTS and children into the enabled state after opstart
With "show bts 0" all objects were still listed as dependency.
Once the BTS has been started.. move all the other objects into
the enabled state. Our OpenBSC OML code doesn't care but people
using the VTY to inspect state will be more happy.

One day... we will create proper statemachines inside the BTS
and the BSC instead of changing the state in the BTS impl.

Fixes: ONW#1330
2014-11-10 15:16:16 +01:00
Holger Hans Peter Freyther
48eb374a96 bts: Start with the site manager being enabled and available
We would never transition the sitemanager to anything. Our SW
does not support SW activation's so we are always ready.

Related: ONW#1330
2014-11-10 15:12:38 +01:00
Holger Hans Peter Freyther
2fa6ef2687 bts: Mark NSVC1 as offline. We do not expose a second NSVC
OsmoBSC> show bts 0
  ...
  GPRS NSVC1: Oper 'Disabled', Admin 'unknown 0x0', Avail 'Off line'
2014-11-10 13:18:59 +01:00
Holger Hans Peter Freyther
6d8bcbd192 bts: Fix typo in OML comment 2014-11-10 13:01:33 +01:00
Holger Hans Peter Freyther
b89a5fa55d bts: In case the line isn't created do not exit with code 1
The service file will prevent a re-launch of the sysmobts.service
in case the main process exits with '1'. In case the ethernet is
not available yet the routine would fail and the sysmobts process
will not be restarted.

unable to connect/bind socket: Network is unreachable
<000f> input/ipaccess.c:885 cannot open OML BTS link: Network is unreachable
unable to connect to BSC
root@sysmobts-v2:~# echo $?
2

Fixes: SYS#736
2014-11-10 12:53:22 +01:00
Holger Hans Peter Freyther
9f0002b52b ctrl: Fix compiler warning
bts_ctrl_lookup.c: In function 'bts_controlif_setup':
bts_ctrl_lookup.c:97:2: warning: implicit declaration of function 'bts_ctrl_cmds_install' [-Wimplicit-function-declaration]
  rc = bts_ctrl_cmds_install(bts);
  ^
2014-11-10 12:04:48 +01:00
Holger Hans Peter Freyther
1cce69364d abis: Fix compiler warning and remove const from syntax
libosmo-abis doesn't make it easy to have these parameters
as const.. just declare it non-const in the api. We pass
a static string but we know it will not be modified.
2014-11-10 12:02:45 +01:00
Holger Hans Peter Freyther
8332e29c9f tch: Avoid compiler warnings when using the direct RTP mode
tch.c: In function 'l1_to_rtppayload_amr':
tch.c:247:29: warning: unused variable 'amr_mrc' [-Wunused-variable]
  struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr;
                             ^
tch.c: In function 'rtppayload_to_l1_amr':
tch.c:335:10: warning: unused variable 'amr_if2_core_len' [-Wunused-variable]
  uint8_t amr_if2_core_len = payload_len - 2;
2014-11-10 11:59:53 +01:00
Holger Hans Peter Freyther
be63f03254 sysmobts: Call the routine send and receive instead of get 2014-11-10 11:58:21 +01:00
Andreas Eversberg
9f22fcfd36 Correctly fill system information messages from BSC
SI 5*/6 require L2 header of 0x03,0x03. All SI might be less than 23
octets, so they need to be filled with 0x2b.
2014-08-27 23:45:47 +02:00
Harald Welte
11b14fd662 tx_power: Check actual TRX output power against intended value
We use the completion call-back from L1 to compare the instructed
TRX board output power with the actual value as reported  back from
L1.

Right now we only print an error message in case the values disagree.

In the future we might want to either use that value as part of our
calculation or send an OML alarm report to the BSC.
2014-08-25 19:01:24 +02:00
Harald Welte
9e873335ec Revert "add nominal transmit power for upcoming sysmoBTS 1020 and 1100"
This reverts commit d0866fe477, as it
was a bit premature.  We need to address this more properly.
2014-08-25 18:06:29 +02:00
Holger Hans Peter Freyther
04585dd90a tx: Generate a working configuration file on "write"
We do not have the vty test script to do roundtrip testing. There
is no max-initinal-pout, then there was a typo inside 'initial' and
for the relative step size the unit is dB/mdB. Fix both of that.
2014-08-25 16:06:56 +02:00
Holger Hans Peter Freyther
645cba8532 tx: Fix another typo i found today morning 2014-08-25 16:01:29 +02:00
Holger Hans Peter Freyther
adddb65f46 sysmobts: Remove left-over from non-generic power control 2014-08-25 16:01:23 +02:00
Holger Hans Peter Freyther
fbf04438b7 ctrl: Use msgb_free to free message 2014-08-25 16:01:23 +02:00
Harald Welte
e0e9b30f5c tx_power.c: fix potential array out-of-bounds access 2014-08-25 10:05:55 +02:00
Harald Welte
68b9b376cf make use of libosmocore 'gsm_meas_rep_unidir'
Back in March 2013, some structures and defines related to decoded
measurement reports have been moved from openbsc to libosmocore
(libosmocore e128f4663104ed64e33e362cff2566f36d65e658) so that they can
be used also from osmo-bts.  This finally follows up on that.

You need openbsc 7ff4f0e0fc692bfab829da50edb104e58b271e7e or later.
2014-08-25 09:22:00 +02:00
Harald Welte
d0866fe477 add nominal transmit power for upcoming sysmoBTS 1020 and 1100 2014-08-25 08:48:37 +02:00
Harald Welte
913044ecc5 tx_power.c: Fix typos in comments 2014-08-25 08:46:48 +02:00
Harald Welte
3dd6ebe0b8 add information on unit (milli-dB) to control interface doc 2014-08-25 08:42:08 +02:00
Harald Welte
1fb66c8e6a disable clock control interface on HW_SYSMOBTS_V1 2014-08-24 18:16:45 +02:00
Harald Welte
ab09e27d72 add control_if.h to Makefile.am 2014-08-24 17:42:47 +02:00
Harald Welte
c0a3030277 add a small document describing the use of the control interface 2014-08-24 17:19:59 +02:00
Harald Welte
be18984959 ctrl: Add sysmobts control interface
This sysmobts specific control interface allows for clock calibration
from an external program by means of the "trx.0.clock-info" and
"trx.0.clock-correction" values.
2014-08-24 17:07:02 +02:00
Harald Welte
9d0fd073e9 l1_if: pass private 'void *data' from call to callback
When enqueueing a command towards the L1, we can now pass along
a private data pointer, which then gets passed to the call-back
upon completion.
2014-08-24 17:05:23 +02:00
Harald Welte
8e4cc1cbb8 fix build problem introduced with control interface 2014-08-24 17:04:54 +02:00
Harald Welte
993575bcd8 use libocmocore #defines for VTY port numbers 2014-08-24 16:59:07 +02:00
Harald Welte
0ff0f2d00f ctrl_if: Move control interface to port 4238
... which is now defined in libosmocore
2014-08-24 16:59:05 +02:00
Harald Welte
d9a2aa8d99 add control interface to common BTS (for thermal attenuation)
Using this control interface, an external program can request
attentuation of the transmitter for thermal management reasons. The
external application doesn't have to know anthing about the actual
transmit power, but it can just configure a certian value of milli-dB
(1/10000 bel) and update (increase/decrease) that value depending on
the thermal environment.
2014-08-24 16:42:02 +02:00
Harald Welte
e43feaf231 New generic transmit power handling
In order to support transmit power reduction by thermal management
as well as the variety of new internal / external PA configurations
of BTSs, we need a slightly more complex system.

Also, as at high power a single dB can be quite a big difference,
we are now doing all computations in milli-dB(m), i.e. 1/10000 bel.

Ramping is now used both for up and down ramping, as that is useful in
cases where you want to gracefully shut down a cell by shrinking its
radius, gradually handing over subscribers to neighboring cells.

Furthermore, this code is becoming part of the 'common' codebase, as it
is not really specific to how sysmobts is working.

The user can specify a single aggregate value for external system
gain/attenuation.  Let's say you have 1dB loss of antenna cable, so you
can put that as 'user-gain -1' into the config, which means that a
'transmit power of 20dBm' will be compensatet for that and the TRX is
instructed to output 21dBm to compensate the cable loss.  Similarly,
external PAs can be described by a positive user-gain.

One of the next steps will be to communicate those values and the
nominal power capability of the specific BTS to the BSC, so the BSC will
automatically show correct signal levels in the VTY and log files.

The code includes provisions for future extensions regarding
* an external and an internal PA with calibration tables
* a thermal attenuation setting to be controlled by the site manager
2014-08-24 10:46:21 +02:00
Harald Welte
fcca2e8218 remove copy of gsm_bts_num()
... which is now available from gsm_data_shared.[ch] of openbsc
2014-08-24 10:46:21 +02:00
Holger Hans Peter Freyther
15f899f89e sysmobts: Use the uc connection on both slave and master
We can use this on both slave and master. But only have the
master switch on the PA.
2014-08-22 00:06:01 +02:00
Holger Hans Peter Freyther
3a54b7aa30 Merge branch 'sysmocom/features/sysmobts-mgr-temp'
Implement the first round of temperature control and actions. Only
the PA can be switched off, it will never be switched on again, in
case the microcontroller doesn't respond we will do nothing as well.
These todos need to be addressed in the near future.
2014-08-21 23:55:37 +02:00
Holger Hans Peter Freyther
1f8053e366 sysmobts: Enable the PA on start and disable it as first action
The PA will be unconditionally turned. This makes it possible
that in case of a crash, the PA will be turned on and then we
will do the temperature measurement and turn it off again. There
are no known crashes with the sysmobts-mgr right now so the risk
seems to be okay. In case we can't switch off the PA we have no
way to escalate it right now. We have not seen a dead uc either
so the risk is okay as well.

We can't switch the PA back on once we reach the normal level
as the BTS might transmit with full power and we would need more
current than the power supply/rails can carry. So leave the
system off right now.

What is missing is to use the OML router to actually inform
the BSC that something bad has happened at the BTS.
2014-08-21 23:55:27 +02:00
Holger Hans Peter Freyther
e02d7796c3 sysmobts: Show the current temperature controls state int he VTY 2014-08-21 23:55:27 +02:00
Holger Hans Peter Freyther
714ccb9992 sysmobts: Provide information about the state transitions 2014-08-21 23:55:27 +02:00
Holger Hans Peter Freyther
b0674e9636 sysmobts: Implement a small state machine for temp control
Check the temperature and move between "NORMAL", "WARNING"
and "CRITICAL" state. We will only return from CRITICAL to
WARNING when the temperature has significantly changed, and
when being in state "WARNING" we enter an intermediate state
to allow an easy hysteris.
2014-08-21 23:55:27 +02:00
Holger Hans Peter Freyther
d036cce744 sysmobts: Remove the sbt2050 timer and move defines back
We haven't done anything with the result of the micro controller
query and querying every six hours for the temperature of the
system will not help us. We need to query the temperatures more
frequently but avoid writing to the eeprom too frequently so we
will start another timer for that.
2014-08-21 23:55:27 +02:00
Holger Hans Peter Freyther
c42bf5fdf5 sysmobts: Simplify some includes/dependencies 2014-08-21 23:55:27 +02:00
Holger Hans Peter Freyther
ca71d07e44 sysmobts: Begin to add various limits and actions
The idea is that for different parts of the system we can define
thresholds for warning and critical (severe) temperate thresholds.
And once any of these temperatures is reached we will execute an
action. When crossing from NORMAL to WARNING or WARNING to SEVERE
we will need to apply some hysteris before switching back to the
lower level. E.g. when being SEVERE mode, at least wait until we
are below the warning level again. Besides being able to switch
off things we could start reducing the transmit power of the system
until the system is cold enough again.

No action is implemented so far, everything is varpoware!
2014-08-21 23:55:27 +02:00
Holger Hans Peter Freyther
c7ee5acba9 sysmobts: Fix the temperature log message alignment 2014-08-21 23:55:27 +02:00
Holger Hans Peter Freyther
9698570d47 sysmobts: Move ipaccess-find counterpart to a dedicated source file 2014-08-21 23:55:27 +02:00
Holger Hans Peter Freyther
7be58a173a sysmobts: Fix the build when no 2050 uc header file was found
Fix the build (provide empty stubs) when the header file is not
present.
2014-08-21 18:03:25 +02:00
Holger Hans Peter Freyther
631945a367 Merge branch 'sysmocom/features/sysmobts-mgr'
Add some VTY code to show the temperature on all devices and to
query the external micro controller for voltage/current and the
temperature in the "show manager" command. It should probably be
a "show system" command though.
2014-08-21 16:25:22 +02:00
Holger Hans Peter Freyther
5e1363071f sysmobts: Fix the power request result
We want to know which componets are enabled and the voltage and
current used by the components.
2014-08-21 16:25:07 +02:00
Holger Hans Peter Freyther
4059e29a29 sysmobts: Read the temperature sensors on the device
Read the sensors that are always present and the ones that
are only present on the sysmoBTS 2050.
2014-08-21 16:25:07 +02:00
Holger Hans Peter Freyther
46c085d794 sysmobts: Add is_sbts2050_master 2014-08-21 16:25:07 +02:00
Holger Hans Peter Freyther
b1ceb40363 sysmobts: Read the model number and trx once from the device
Use it for the ipaccess-find response and for the sysmobts
classification code. This can be used by the vty in a second.
2014-08-21 16:25:07 +02:00
Holger Hans Peter Freyther
3ecb2bb604 sysmobts: Initialize fd with an invalid fd
Initialize the ucinfo with an invalid fd to prevent writing
on fd=0 by accident.
2014-08-21 16:25:07 +02:00
Holger Hans Peter Freyther
ffe1d2e1e0 Merge commit 'sysmocom/features/sysmobts-mgr-vty'
Some re-factorings. Still a very long way to go. It should
work with haralds re-based but that wasn't verified due my
toolchain not having the most recent libosmocore. The service
file and screenrc change has not been verified either.
2014-08-21 15:50:40 +02:00
Holger Hans Peter Freyther
575f633483 sysmobts: Use another logp region as it is mostly related to remp 2014-08-21 15:49:06 +02:00
Holger Hans Peter Freyther
54a8b313b4 sysmobts: There is only one uc make it a singleton
Move the init and polling into the sysmoBTS related part. In the
future we should have _one_ temperature control.
2014-08-21 15:49:06 +02:00
Holger Hans Peter Freyther
c84ca8c82f sysmobts: Clean-up the parsing routines 2014-08-21 15:49:06 +02:00
Holger Hans Peter Freyther
035187b44e sysmobts: Move the sysmoBTS 2050 controller handling
Move the code to a separate file to keep things nicely apart
of each other.
2014-08-21 15:49:06 +02:00
Holger Hans Peter Freyther
013df51ca8 sysmobts: Add VTY support to the sysmobts-mgr
Add VTY support to the manager. This way we can interactively
inspect the state of the system and trigger events.
2014-08-21 15:49:06 +02:00
Harald Welte
07198750b2 adopt to recent libosmocore ipa rename 2014-08-20 23:30:28 +02:00
Harald Welte
ac76388c77 TLVP_PRES_LEN is now in libosmocore, avoid redefining it 2014-08-18 20:48:56 +02:00
Harald Welte
bc82b0189a replace oml_{osmo,ipa}_magic[] with abis_nm_{osmo,ipa}_magic
the latter is now in libosmogsm.
2014-08-18 20:48:56 +02:00
Harald Welte
fcd5c367d1 Migrate to osmo_get_macaddr() in recent libosmocore
get_mac_addr() is generally useful and shouldn't be hidden in
the osmo-bts/abis.c file
2014-08-18 20:48:56 +02:00
Holger Hans Peter Freyther
88d60a1f86 sysmobts: Add a unit test that checks of the behavior
We need to build a lot more code to be able to test these two
new routines. I didn't want to move the code to a utils file
as the check is called from a hot path. Add accessors to the
inlined variant to be used by the unit test.

While writing the unit tests I noticed that a re-transmission
of the ciphering command would lead to an attempt to enable
ciphering again. I am not sure that this MphConfig is idempotent.
2014-08-09 09:42:56 +02:00
Holger Hans Peter Freyther
2cc37035d7 sysmobts: Deal with ciphering when we have a transport clash
The network is configured with early classmark sending. This means
that the phone might send a "classmark change" message at the same
time we send a ciphering mode command. When we received the CM
message we assumed we have just received the first ciphered message
and enabled ciphering for tx as well.

When we snoop the Ciphering Mode Command extract the N(S) variable
and when we receive an I frame from the MS see if it handled our
message by comparing the MS N(R) to BTS N(S) + 1.
2014-08-09 09:42:56 +02:00
Holger Hans Peter Freyther
6cf49380cd Merge branch 'sysmocom/features/oml-router' 2014-07-31 17:49:08 +02:00
Holger Hans Peter Freyther
caca1899ce sysmobts: Make sure that the omlrouter is in a FHS path
I wondered if I should use the 'abstract namespace' feature
of Linux but just put the router into /var/run/ to make it
work out of the box. Change the signature to provide a sane
error message.
2014-07-31 17:43:08 +02:00
Holger Hans Peter Freyther
fcdfb690ca sysmobts: Add testcase for ETSI/12.21 message 2014-07-31 16:59:06 +02:00
Holger Hans Peter Freyther
dbc2731887 sysmobts: Extend the testcase for a Osmo message as well 2014-07-31 16:58:48 +02:00
Holger Hans Peter Freyther
0655cac6f1 sysmobts: Verify the structure of IPA and OML messages
Extend the router to verify that the message received is
properly encoded. The code can deal with the basic structure
of ETSI OML and vendor specific messages for ip.access and
the osmocom project.
2014-07-31 16:58:26 +02:00
Holger Hans Peter Freyther
9e1dbf532e sysmobts: Remove debug left over from enabling the RTP mode 2014-07-31 16:57:39 +02:00
Holger Hans Peter Freyther
b05d72d21b sysmobts: Begin with an OML router that will be used by the manager
Begin with the basics of a OML Router. This is currently only
capable of accepting a connection and read messages but it will
evolve into a router in multiple stages. The first usage will
be by the sysmobts-mgr. An OML Error Indication will be sent by
the sysmobts-mgr and it will be forwarded to the BSC. In the
second step we will set a relative power reduction from the
sysmobts-mgr.

In the long-term this code will be used to communicate with a
second TRX.
2014-07-31 16:57:39 +02:00
Holger Hans Peter Freyther
b3d1779b96 tests: Move the "pcu_direct" symbol into the stubs to be shared 2014-07-31 14:55:03 +02:00
Holger Hans Peter Freyther
bc8de14671 oml: Make it possible to include the file directly
Fixes:
../../include/osmo-bts/oml.h:8:42: warning: ‘struct gsm_bts’ declared inside parameter list [enabled by default]
 int down_oml(struct gsm_bts *bts, struct msgb *msg);
                                          ^
../../include/osmo-bts/oml.h:8:42: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
../../include/osmo-bts/oml.h:12:52: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
 int oml_mo_send_msg(struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_type);
                                                    ^
../../include/osmo-bts/oml.h:13:31: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
 int oml_mo_opstart_ack(struct gsm_abis_mo *mo);
                               ^
../../include/osmo-bts/oml.h:14:32: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
 int oml_mo_opstart_nack(struct gsm_abis_mo *mo, uint8_t nack_cause);
                                ^
../../include/osmo-bts/oml.h:15:32: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
 int oml_mo_statechg_ack(struct gsm_abis_mo *mo);
                                ^
../../include/osmo-bts/oml.h:16:33: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
 int oml_mo_statechg_nack(struct gsm_abis_mo *mo, uint8_t nack_cause);
                                 ^
../../include/osmo-bts/oml.h:19:29: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
 int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state);
                             ^
../../include/osmo-bts/oml.h:22:31: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
 void oml_mo_state_init(struct gsm_abis_mo *mo, int op_state, int avail_state);
                               ^
../../include/osmo-bts/oml.h:26:10: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
          int success);
          ^
../../include/osmo-bts/oml.h:29:33: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
 int oml_tx_state_changed(struct gsm_abis_mo *mo);
                                 ^
../../include/osmo-bts/oml.h:31:33: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
 int oml_mo_tx_sw_act_rep(struct gsm_abis_mo *mo);
                                 ^
../../include/osmo-bts/oml.h:36:4: warning: ‘struct gsm_abis_mo’ declared inside parameter list [enabled by default]
    uint8_t cause);
2014-07-31 14:54:51 +02:00
Holger Hans Peter Freyther
a19912db34 sysmobts: Enable the direct RTP mode for firmware >= 3.11
We need to patch the CMR due wanting to support systems that still
have Audiocodes hardware in their chain. I have manually tested
and could listen to my own voice on:

TCH/H	&	AMR 5.9		& PTSN			& BSC
TCH/F	&	FR1		& Other subscriber	& NITB
TCH/F	&	EFR		& Other subscriber	& NITB
TCH/H	&	HR1		& Other subscriber	& NITB
TCH/H	&	AMR 5.9		& Other subscriber	& NITB

The tests were done using the Nokia E71, a Blackberry curve and
for the PTSN a HTC 8S were used.
2014-07-31 14:39:32 +02:00
Holger Hans Peter Freyther
eececf5fa9 sysmobts: Make it possible to slowly ramp up the output power
For systems with a bigger PA enabling the full output power at
once might draw more current than a power supply can provide. This
code will step up the output power in smaller steps to avoid this
situation.
2014-07-30 18:22:12 +02:00
Holger Hans Peter Freyther
bc24955e91 sysmobts: Provide VTY routines to do clock calibrations
The sysmoBTS2050 does not have a OCXO and we should not rely
on the GPS module to always have a fix. Instead use the TCXO
by default and from time to time (and we know we have a fix
calibrate the TCXO). This can be done by:

  trx 0 rf-clock-info reset
  wait...
  trx 0 rf-clock-info correct
  write

The output is currently only written to the log as the VTY
connection might go away during the operation. The reset will
set the approriate reference clock and the correct will attempt
to determine and apply the correction. The write terminal will
make sure that next on start a known good value will be used.
2014-07-25 14:45:52 +02:00
Holger Hans Peter Freyther
bac0ff7f6d sysmobts: Free the message on older firmware releases
Seen while implementing a new functionality in the code.
2014-07-25 13:23:00 +02:00
Holger Hans Peter Freyther
94a63851b7 sysmobts: Include the model and master/slave in the unitid
Make it more easy to find the right BTS model and know what is
the master/slave.
2014-07-25 10:48:14 +02:00
Holger Hans Peter Freyther
3674645e20 amr: Avoid toggling the CMR from none and a set one
For LCR and other systems without out-of-band information we need
to indicate the CMR. Not every air message will include the mode
and we sent a stream that had the CMR set and not-set. This lead
to the AudioCodes MGW only playing every second frame.

Remember the last used mode and initialize it to _NONE when we
receive the multirate config. In case of a real error we will
still use AMR_CMR_NONE.

The initial patch is from Harald. I have added the initialization
and moving of the defines to amr.h.

Manually verified by enabling AMR5.9 and looking at two RTP
packages in sequence. In both cases the CMR was 2. I have looked
at "amr.nb.cmr != 2" in wireshark and only found the MGCP dummy
packet.
2014-07-25 09:22:29 +02:00
Holger Hans Peter Freyther
a2b806c375 sysmobts: Fix typo in the comment 2014-06-22 16:23:59 +02:00
Holger Hans Peter Freyther
a7f9b58e44 sysmobts: Fix the initialization of the BTS manager code
The code should only run for the sysmoBTS 2050 and TRX 0.
If the device is not marked as 2050 the code would attempt
to open /dev/ttyS0 and block forever.
2014-05-30 15:29:01 +02:00
Holger Hans Peter Freyther
0e2b624418 sysmobts: Revert all sysmobts-mgr related changes
Harald is right and that the code is generally not ready
for inclusion. I fell victim of trying to finish it while
the code is not ready at all. It is better to re-introduce
the patches in a smaller and more tested way.

The right way would have been a branch were ready things
are split-off the main/wip commit until everything is ready.

Revert "sysmobts: Have a common prefix for the enum"
This reverts commit 44980347f3.

Revert "utils: Used the enum manuf_type_id in the parameter of add_manufacturer_id_label"
This reverts commit 7d36e5ed46.

Revert "utils: Classify the OML message using the return type"
This reverts commit afee0b7929.

Revert "sysmobts: Do not access out of bound string"
This reverts commit f5f41e8051.

Revert "sysmobts: Separate IPA and OML check into two methods"
This reverts commit 13a224063d.

Revert "screenrc: osmobts-mgr now needs a config file"
This reverts commit 0a1699ff8a.

Revert "make sure osmobts-mgr.cfg file is included in tarballs"
This reverts commit 14c60b425f.

Revert "sysmobts-mgr: Add VTY support for configuring it"
This reverts commit c5fedd24c9.

Revert "sysmobts: Add beginnings of an OML router and create Failure Messages in the sysmobts-manager"
This reverts commit c6ab90b270.
2014-05-25 13:48:33 +02:00
Holger Hans Peter Freyther
7996134d2a common: Ignore "si.valid" outside of _MAX_SYSINFO_TYPE
Limit the range from 0 to (_MAX_SYSINFO_TYPE - 1) instead of
0 to 31. This way we will never access the lchan->si.buf[] out
of bounds. This is only a theoretical issue though as the code
filling the lchan->si.buf for the SACCH will not have valid
>= _MAX_SYSINFO_TYPE. Add a small regression test to check we
still schedule all SIs.

Fixes: CID 1040765
2014-05-22 21:17:49 +02:00
Holger Hans Peter Freyther
ac26607fe4 common: Remove unused gsm_time parameter from lchan_sacch_get 2014-05-22 20:42:33 +02:00
Holger Hans Peter Freyther
9d8aeab0b6 sysmobts: Avoid memleak when multiple -c arguments are passed
Rely on optarg pointing to an address that will be valid for
the run of the entire application.

Fixes: CID 1206578
2014-05-22 19:50:39 +02:00
Holger Hans Peter Freyther
44980347f3 sysmobts: Have a common prefix for the enum
Make the manuf_type_id enum have a common prefix for the
symbols.
2014-05-20 09:47:02 +02:00
Álvaro Neira Ayuso
7d36e5ed46 utils: Used the enum manuf_type_id in the parameter of add_manufacturer_id_label
Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-05-20 09:47:02 +02:00
Álvaro Neira Ayuso
afee0b7929 utils: Classify the OML message using the return type
Classify the OML message and return the manufacturer type
or an error. Currently ETSI, ip.access and Osmocom are known.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-05-20 09:45:36 +02:00
Álvaro Neira Ayuso
f5f41e8051 sysmobts: Do not access out of bound string
One can either use "strlen(str) + 1" but not add one to the
result of the sizeof.
2014-05-20 09:43:38 +02:00
Álvaro Neira Ayuso
13a224063d sysmobts: Separate IPA and OML check into two methods
I have split the function check_oml_msg, in two functions. One for
checking if the ipa header is well-formed and in check_oml_msg,

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-05-20 09:37:30 +02:00
Harald Welte
0a1699ff8a screenrc: osmobts-mgr now needs a config file 2014-05-19 13:01:20 +02:00
Harald Welte
14c60b425f make sure osmobts-mgr.cfg file is included in tarballs 2014-05-19 12:58:31 +02:00
Harald Welte
b4280963c0 Revert "sysmobts: Add support for changing the transmit power in sbts2050"
This reverts commit c64d425738.

There are unfrtunately still too many problems with this patch to be
merged at this point.
2014-05-19 11:22:38 +02:00
Harald Welte
76c309e9f7 sysmoBTS TCH: Set CMR in AMR RTP frames
Enable the previously commented-out logic to set the CMR (Codec Mode
Request) in AMR RTP frames based on the CMI (CMR Index) of the AMR
speech frame on the Um interface.

This is of course anyway the right thing to do, but also required for an
AMR receiver which doesn't have out-of-band information on the codec
mode, and which also doesn't determine the AMR codec mode based on the
size of the AMR frame (such as lcr as of current master).

We also move the entire CMR generation into the #ifdef section
which is only compiled-in if we do _not_ use the RTP mode of L1.
2014-05-18 22:31:45 +02:00
Álvaro Neira Ayuso
c64d425738 sysmobts: Add support for changing the transmit power in sbts2050
Make the sysmobts-mgr send a manufacturer O&M message with the power
reduction we want the sysmobts to apply. The sysmobts will handle
this message and set the new tx output power. An ACK/NACK will be
send as a response to the power reduction.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-05-18 09:42:49 +02:00
Álvaro Neira Ayuso
c5fedd24c9 sysmobts-mgr: Add VTY support for configuring it
This patch allows to configure the warning temperature threshold,
the severe temperature threshold of the board and the PA and the
actions like the relative value power that we want to reduce the
transmit power to and the part that we want to switch off or not.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-05-18 09:42:08 +02:00
Álvaro Neira Ayuso
c6ab90b270 sysmobts: Add beginnings of an OML router and create Failure Messages in the sysmobts-manager
Make the sysmobts listen for OML messages on a Unix Domain Socket.
Messages passing a sanity check will be forwarded to the BSC.

In case the sysmobts-mgr detects a temperature above or below
temperature threshold an OML failure message will be sent
to the BTS.

[moved confinfo into the #ifdef BUILD_SBTS2050]

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-05-18 09:41:29 +02:00
Harald Welte
73d9d3af6c sysmobts: Support DSP API >= 3.8.1 (u8MaxCellSize) 2014-05-17 10:04:44 +02:00
Holger Hans Peter Freyther
d75c648871 abis: Separate initialization from connect for Abis
Initialize the libosmo-abis VTY nodes more early so we can parse
the config file that was created by "write". Introduce abis_init
to initialize the libosmo-abis and modify abis_open to re-use an
existing line. Update the comments. This has only been tried with
the sysmobts-remote on x86. A TCP connection is opened toward the
configured BSC.

Fixes: SYS#285
2014-05-15 14:18:26 +02:00
Álvaro Neira Ayuso
8b5b993d29 sysmobts: Fix compiler warning about missing declaration
Include utils.h to have a declaration of sysmobts_get_nominal_power,

l1_if.c: In function 'l1if_activate_rf':
l1_if.c:1144:6: warning: implicit declaration of function
'sysmobts_get_nominal_power' [-Wimplicit-function-declaration]

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-05-15 10:21:43 +02:00
Álvaro Neira Ayuso
9ed6b95c90 osmo-bts-sysmo/utils.c: Added a function for calculate the power transmitter
Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-04-29 12:08:28 +02:00
Holger Hans Peter Freyther
3e5b6db2d2 handover: Call the right function and avoid recursion
Fix a brown paper bag bug and call the right method. The above was
an infinite recursion. The stack didn't overflow as the compiler
optimized the tail-recursion and coverity didn't complain either.

The issue was introduced in the last minutes before the merge
when I renamed "reset_handover" to "handover_reset" to follow
the object_verb approach throughout the handover.c code. While
doing that I sadly replaced reset_handover with handover_frame
and not handover_reset.
2014-04-19 19:22:22 +02:00
Holger Hans Peter Freyther
d59bbd16a7 sysmobts: Add log message in case the channel activation fails 2014-04-07 20:33:04 +02:00
Holger Hans Peter Freyther
f547bee878 rsl: Use unique values for the call to rsl_tx_chan_act_nack
This way we can easily find the place in the code that is responsible
for the NACK.
2014-04-07 20:30:12 +02:00
Jacob Erlbeck
57a4d121c4 oml: Pass all valid state change requests to the model
Currently ADM state change request that tries to set the
administrative state to the current value are immediately ACK'ed.
Beside the caching problem, this could lead the protocol
inconsistencies if two such requests are sent one after the other and
the second arrives before the procedure of the first has finished.

This patch removes the shortcut in oml_rx_chg_adm_state() which
immediately called oml_mo_statechg_ack(mo).

Ticket: OW#1132
Sponsored-by: On-Waves ehf
2014-04-03 12:46:03 +02:00
Holger Hans Peter Freyther
0859795878 sysmobts: Fix build for the v1 of the sysmobts 2014-03-29 19:27:54 +01:00
Holger Hans Peter Freyther
14ff925555 agch/pcu: Fix crash for AGCH commands queued by the PCU
The dequeue code assumed that msg->l3h is a valid pointer but in
the case of the PCU socket it was a null pointer. This lead to
memcpy copying a lot more than 23 bytes which ultimately lead to
a crash. The issue was introduced in the git commits
37c332e5bf and the commit
d290ee029a.

use msg->l3h = msgb_put(msg, len) to make sure that there is a
valid L3 pointer for the message.

 (gdb) bt
 #0  0x419d6384 in memcpy () from /tmp/ow/lib/libc.so.6
 #1  0x0001894c in bts_ccch_copy_msg (bts=0x62248, out_buf=0x62248 "p\025\003", gt=0x1,
    is_ag_res=100684) at bts.c:572
 #2  0x0000c958 in handle_ph_readytosend_ind (rts_ind=<optimized out>, fl1=0x62e78)
     at l1_if.c:515
 #3  l1if_handle_ind (fl1=0x62e78, msg=0x8bb08) at l1_if.c:920
 #4  0x000147e8 in read_dispatch_one (queue=<optimized out>, msg=0x8bb08, fl1h=<optimized out>)
    at l1_transp_hw.c:190
 #5  l1if_fd_cb (ofd=0x62f04, what=<optimized out>) at l1_transp_hw.c:224
 #6  0x41b9d028 in osmo_select_main (polling=<optimized out>) at select.c:158
 #7  0x0000b204 in main (argc=<optimized out>, argv=<optimized out>) at main.c:384

(gdb) p *msg
$12 = {list = {next = 0x100100, prev = 0x200200}, {dst = 0x0, trx = 0x0}, lchan = 0x0,
  l1h = 0x0, l2h = 0x0, l3h = 0x0, l4h = 0x0, cb = {0, 0, 0, 0, 0}, data_len = 23, len = 23,
  head = 0x8572c "-\006?\020\r\340*q\224#", tail = 0x85743 "",
  data = 0x8572c "-\006?\020\r\340*q\224#", _data = 0x8572c "-\006?\020\r\340*q\224#"}
2014-03-27 09:19:24 +01:00
Holger Hans Peter Freyther
64a4327c34 sysmobts: Apply the potentially new max_power_red on the TRX
In case the max power reduction has been changed through OML,
let us call the l1if_set_txpower routine to update the nominal
power. This has been manually verified with both BTS #1 and #57.

./bsc_control.py -d localhost -p 4249 -s bts.0.trx.0.max-power-reduction 0

The above command and GNUradio have been used to determine if
the power level has changed at all.

Fixes: SYS#268
2014-03-26 18:05:41 +01:00
Holger Hans Peter Freyther
a276b98236 oml: Indicate the kind of object passed as the void*
These routines do not pass the gsm_abis_mo and parsing the FOM
header of the msg does not seem to be a good idea either. Pass
in the OML object so that the model code can determine what the
void pointer is.
2014-03-26 18:01:55 +01:00
Holger Hans Peter Freyther
71d98050f3 sysmobts: Honor power reduction on older sysmoBTSv2 hardware
Older hardware didn't have the external attentuator that was used
to control the wanted output power. So starting from the git commit
3c8ff3c70b older hardware was always
transmitting with 23 dBm regardless of the power reduction.

Remember the hardware revision returned by the SystemInformation
primitive, postpone the call to l1if_activate_rf until we know
the board revision.

Manually verified on BTS #1 and #57. On BTS#1 the external
attenuator has not been configured and on BTS#57 it was.
2014-03-26 17:49:06 +01:00
Holger Hans Peter Freyther
83dc54fb95 systemd: Provide the pcu direct mode 2014-03-21 19:28:13 +01:00
Holger Hans Peter Freyther
ae2473c2ca systemd: Do not restart with a broken config file or such
Only restart in case of a crash or the exit(42) when the OML/RSL
link is going down.
2014-03-21 18:10:12 +01:00
Holger Hans Peter Freyther
fb067905d5 sysmobts: Add a magic number to the hLayer2 to differentiate it
The DSP/FPGA appears to report bogus PhDataInd with hlayer2 == 0.
Currently this would match the TRX==0,TS==0 and SS=0 and then we
report bad measurement reports. Add a magic number to the lower
eight bit of the hLayer2 to differentiate valid numbers.

Addresses:
<0004> measurement.c:97 (bts=0,trx=0,ts=0,ss=0) measurement during state: NONE
<0004> measurement.c:102 (bts=0,trx=0,ts=0,ss=0) no space for uplink measurement
2014-03-16 14:23:37 +01:00
Holger Hans Peter Freyther
3e317ea4f0 sysmobts: Change the order to follow the RX handling code 2014-03-16 14:21:41 +01:00
Holger Hans Peter Freyther
b45c8a6b6c sysmobts: Improve the log message and print the hLayer2 we don't know 2014-03-16 14:21:41 +01:00
Álvaro Neira Ayuso
2dca8f37e5 misc/sysmobts_misc: function for switching off/on and requesting status power
I have extended the principal function that we use for requesting
information to the microcontroller for switching off/on the board
and the PA. And I have extended it for requesting the power status
information of the board and the PA.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-03-16 14:21:41 +01:00
Álvaro Neira Ayuso
4b614a0246 misc/sysmobts_mgr: Added new header created in the configure
Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-03-12 21:38:18 +01:00
Holger Hans Peter Freyther
bd26784362 misc: Ignore some of the new configure and test files 2014-03-12 16:54:19 +01:00
Holger Hans Peter Freyther
4e3aa93681 misc/sysmobts: Another small change to help in finding the header
We could have a dedicated configure/cflag for the header files
but for now search in the standard directories.
2014-03-12 16:51:27 +01:00
Holger Hans Peter Freyther
06387d89e8 misc: Fix the build breakage now that we have btsconfig.h
Include the btsconfig.h for the PACKAGE_VERSION variable.
2014-03-12 16:40:07 +01:00
Álvaro Neira Ayuso
e030dfd443 misc/sysmobts_misc.c: Read temperature from microcontroller
Add function for requesting the temperature information to the
microcontroller. I have added a function that we can extend
for requesting more information but in this case we only need to
know the temperature.
I have added to a microcontroller temperature handling function
in the manager for monitoring this information.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-03-12 16:27:38 +01:00
Jacob Erlbeck
21104720f7 agch: Remove obsolete comment
Use of configuration variables has already been implemented here, so
the TODO comment is removed.

Sponsored-by: On-Waves ehf
2014-03-10 14:04:29 +01:00
Holger Hans Peter Freyther
b26b8fc776 sysmobts: Do a RF mute at initialization when the RC is locked
Currently a locked cell is actively broadcasting when it is being
bootstrapped after the lock.

This patch adds an initial update of the RF mute state when the TRX
is initialized.

Ticket: OW#1131
Sponsored-by: On-Waves ehf
2014-03-10 14:00:21 +01:00
Holger Hans Peter Freyther
9c4a524444 handover,sysmobts: Handle handover in the sysmobts code
When the lchan was activated for handover configure it to wait
for a RACH burst. On release make sure to always release the
RACH SAPI (in case it has been allocated). On the first frame
inform handover.c about it and forward the received access burst
to the handover layer.

Using an E71 it was possible to make a handover for SDCCH and
TCH/F from a nanoBTS but also from itself to itself. The vty
commands of OpenBSC and the silent-call have been used for that.
I didn't verify audio handling so far.
2014-03-10 13:38:07 +01:00
Holger Hans Peter Freyther
bb76d816da handover,sysmobts: Handle idle needed for preparation of rach handling 2014-03-10 13:38:07 +01:00
Holger Hans Peter Freyther
cfce4d65f2 handover,sysmobts: Refactor the parsing/handling of the access delay 2014-03-10 13:38:07 +01:00
Andreas Eversberg
00b4e064ff handover: Add generic handling for handover
The BTS layer needs to inform the handover code when an access
burst has been received. In turn the handover layer will ask the
bts to modify the channel, it will schedule the physical information
inform the BSC with the HANDOVER DETECTION and waits for the BTS
layer to inform it about the first received frame to stop a timer.
2014-03-10 13:38:07 +01:00
Andreas Eversberg
8ade45e795 handover: Set basic values for handover, remember the activation reason
Introduce the handover.h/handover.c and initialize handover parameters
in OML and remember the activation through RSL.
2014-03-10 13:38:07 +01:00
Andreas Eversberg
3058854535 handover: Implement generating HANDOVER DETECTION in rsl_tx_hando_det 2014-03-10 13:38:07 +01:00
Andreas Eversberg
a37e239961 handover: Introduce debug area for handover related items 2014-03-10 13:38:07 +01:00
Holger Hans Peter Freyther
d863f9cbea Merge branch 'jerlbeck/agch-queue' 2014-03-10 13:33:26 +01:00
Jacob Erlbeck
4fcda92d7b agch: Merge IMM.ASS.REJ if possible when enqueueing
This patch implements merging of IMMEDIATE ASSIGN REJECT messages as
suggested in GSM 08.58, 5.7. When a new IMM.ASS.REJ is to be appended
to the AGCH queue and the last message in that queue is of the same
type, the individual entries (up to 4 per message) of both messages
are extracted, combined and stored back. If there are less than 5
entries, all entries fit into the old message and the new one is
discarded. Otherwise, the old message will contain 4 entries and the
remaining ones are stored into the new one which is then appended to
the queue.

Ticket: SYS#224
Sponsored-by: On-Waves ehf
2014-03-10 13:07:35 +01:00
Jacob Erlbeck
0148d4e7d5 agch: Add VTY queue management configuration
This patch adds the following VTY commands to tune AGCH queue
handling:

  agch-queue-management default
  agch-queue-management threshold THRES low LOW high HIGH

Examples:
  agch-queue-management default
    Resets queue management to default parameters.
  agch-queue-management threshold 0 low 25 high 75
    Start dropping at 25%, drop all messages above 75% queue length
    (relative to max queue length corresponding to T3126). Between
    low and high, drop with a probability interpolated linearly
    between 0 (low) and 1 (high).
  agch-queue-management threshold 50 low 0 high 0
    Start dropping at 50% and continue until all IMM.ASS.REJ have
    been removed from the front (output) of the queue

Sponsored-by: On-Waves ehf
2014-03-10 09:40:20 +01:00
Jacob Erlbeck
fae0149260 agch: Manage AGCH queue length
Currently, the AGCH queue length is not limited. This can lead to
large delays and network malfunction if there are many IMM.ASS.REJ
messages.

This patch adds two features:
- Don't accept msgs from the RSL layer when the queue is way too
  full (safety measure, mainly if bts_ccch_copy_msg() is not being
  called by the L1 layer, currently hard coded to 1000 messages)
- Selectively drop IMM.ASS.REJ from the queue output depending on the
  queue length

Ticket: SYS#224
Sponsored-by: On-Waves ehf
2014-03-10 09:40:04 +01:00
Jacob Erlbeck
7503540959 agch/pch: Use PCH for AGCH msgs
This patch extends paging_gen_msg() by adding an output parameter
is_empty that is true, if only a paging message with dummy entries
has been placed into buffer. This feature is then used by
bts_ccch_copy_msg() to insert an AGCH message if is_empty is true.

Ticket: SYS#224
Sponsored-by: On-Waves ehf
2014-03-10 09:22:24 +01:00
Jacob Erlbeck
2d725e77f7 agch/test: Add test for AGCH queue handling
The first test checks the AGCH may queue length computation.

The second test fills the queue by calling bts_agch_enqueue() with a
mix of IMM.ASS and IMM.ASS.REJ. Then it drains the queue by calling
bts_ccch_copy_msg(). After each of both steps, statistics are printed
out.

Sponsored-by: On-Waves ehf
2014-03-10 08:57:38 +01:00
Jacob Erlbeck
35a8144e41 agch: Add simple counters
Counters are added for the following events (use VTY show to query):

  - Dropped IMMEDIATE ASSIGN REJECT messages
  - Merged IMMEDIATE ASSIGN REJECT messages
  - Rejected AGCH messages
  - Use of PCH (non-reserved) for AGCH messages
  - Use of AGCH (reserved) for AGCH messages

Sponsored-by: On-Waves ehf
2014-03-10 08:55:02 +01:00
Jacob Erlbeck
4fbe06b3f2 agch: Recalculate length limit of AGCH queue
This patch adds a function bts_update_agch_max_queue_length()
to compute a limit of the AGCH queue. This is based on the idea,
that the AGCH queue has a limited drain rate and that CHANNEL
REQUESTs must be answered within a certain time frame, given
by the minimum value of T3126 (see GSM 04.08). When the AGCH queue
reaches that limit, the last message would be delivered in time if
there were no other delays involved (which is not the case).

The calculation is based on the ratio of the number RACH slots and
CCCH blocks per time:
  Lmax = (T + 2*S) / R_RACH * R_CCCH
where
  T3126_min = (T + 2*S) / R_RACH
  R_RACH is the RACH slot rate (e.g. RACHs per multiframe)
  R_CCCH is the CCCH block rate (same time base like R_RACH)

The value depends control_channel_desc.ccch_conf and
rach_control.tx_integer (both from SYSINFO_TYPE_3) and should
therefore by called at least each time after one of these is changed.
For this reason, a signal callback is registered under
SS_GLOBAL/S_NEW_SYSINFO which invokes bts_update_agch_max_queue_length().

Sponsored-by: On-Waves ehf
Based-On: "bts: Calculate length of agch queue" by Ivan Kluchnikov
  <kluchnikovi@gmail.com>
2014-03-10 08:54:54 +01:00
Álvaro Neira Ayuso
20f5422803 src/misc/sysmobts_misc: Fixed wrong TEMP_PATH
Before, this patch the program tried to read the info
of the temperature sensor from a wrong location.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
2014-03-05 15:03:05 +01:00
Holger Hans Peter Freyther
e5bda88c9d sysmobts: Do not generate RF Conn failure for CCCH and PDCH
This could lead to a BSC attempting to release the BCCH or a
PDCH. In the case of the BCCH this lead to a funny crash.

Log:
<0000> rsl.c:605 (bts=0,trx=0,ts=0,ss=4) Sending Connection Failure: cause = 0x01
<0000> rsl.c:1720 (bts=0,trx=0,ts=0,ss=0) Rx RSL DEACTIVATE_SACCH

Backtrace:
 Program received signal SIGSEGV, Segmentation fault.
msgb_dequeue (queue=0x4007d2d8) at msgb.c:102
102        llist_del(lh);
(gdb) bt
 #0  msgb_dequeue (queue=0x4007d2d8) at msgb.c:102
 #1  0x4002ed28 in lapd_dl_flush_tx (dl=0x4007d220) at lapd_core.c:173
 #2  0x40030cb4 in lapd_dl_reset (dl=0x4007d220) at lapd_core.c:307
 #3  0x40030d00 in lapd_dl_exit (dl=0x4007d220) at lapd_core.c:321
 #4  0x40033d80 in lapdm_entity_exit (le=<optimized out>) at lapdm.c:169
 #5  0x40033d9c in lapdm_channel_exit (lc=0x4007d214) at lapdm.c:180
 #6  0x0001a334 in rsl_tx_rf_rel_ack (lchan=0x4007d180) at rsl.c:505
 #7  0x0000e908 in lchan_deactivate_sapis (lchan=0x4007d180) at oml.c:1427
 #8  sapi_queue_exeute (lchan=0x4007d180) at oml.c:547
 #9  0x0000ead0 in sapi_queue_send (lchan=<optimized out>) at oml.c:571
 #10 queue_sapi_command (lchan=<optimized out>, cmd=<optimized out>)
    at oml.c:609
 #11 queue_sapi_command (lchan=0x4007d180, cmd=<optimized out>) at oml.c:601
 #12 0x0000faf0 in enqueue_rel_marker (lchan=0x4007d180) at oml.c:1440
 #13 lchan_deactivate (lchan=0x4007d180) at oml.c:1447
 #14 0x0001004c in bts_model_rsl_chan_rel (lchan=<optimized out>) at oml.c:1647
 #15 0x0001b948 in rsl_rx_rf_chan_rel (lchan=0x4007d180) at rsl.c:844
 #16 rsl_rx_dchan (msg=0x75a88, trx=0x4007b038) at rsl.c:1727
 #17 down_rsl (trx=0x4007b038, msg=0x75a88) at rsl.c:1853
 #18 0x000154d4 in sign_link_cb (msg=<optimized out>) at abis.c:132
 #19 0x400701c0 in ?? () from /usr/lib/libosmoabis.so.2
 #20 0x400701c0 in ?? () from /usr/lib/libosmoabis.so.2
 Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Fixes: OW#1133
2014-03-03 16:28:53 +01:00
Holger Hans Peter Freyther
5030972316 pcu: Avoid crash when closing the PCU socket
When closing the PCU socket all channels will be closed. In that case
the LAPDm structures might not have been allocated. Mark the channel
as LCHAN_REL_ACT_PCU to avoid going through the RSL code for sending
the message. This avoids a crash when "gprs none" is selected but one
still configures a PDCH and then connects/disconnects the pcu.

 #0  llist_del (entry=0x0) at ../include/osmocom/core/linuxlist.h:119
 #1  msgb_dequeue (queue=0x400bbc58) at msgb.c:102
 #2  0x40110d28 in lapd_dl_flush_tx (dl=0x400bbba0) at lapd_core.c:173
 #3  0x40112cb4 in lapd_dl_reset (dl=0x400bbba0) at lapd_core.c:307
 #4  0x40112d00 in lapd_dl_exit (dl=0x400bbba0) at lapd_core.c:321
 #5  0x40115d80 in lapdm_entity_exit (le=<optimized out>) at lapdm.c:169
 #6  0x40115d9c in lapdm_channel_exit (lc=0x400bbb94) at lapdm.c:180
 #7  0x0001a334 in rsl_tx_rf_rel_ack (lchan=0x400bbb00) at rsl.c:505
 #8  0x0000e908 in lchan_deactivate_sapis (lchan=0x400bbb00) at oml.c:1427
 #9  sapi_queue_exeute (lchan=0x400bbb00) at oml.c:547
 #10 0x0000ead0 in sapi_queue_send (lchan=<optimized out>) at oml.c:571
 #11 queue_sapi_command (lchan=<optimized out>, cmd=<optimized out>) at oml.c:609
 #12 queue_sapi_command (lchan=0x400bbb00, cmd=<optimized out>) at oml.c:601
 #13 0x0000faf0 in enqueue_rel_marker (lchan=0x400bbb00) at oml.c:1440
 #14 lchan_deactivate (lchan=0x400bbb00) at oml.c:1447
 #15 0x0001004c in bts_model_rsl_chan_rel (lchan=<optimized out>) at oml.c:1647
 #16 0x0001de30 in pcu_sock_close (state=0x62788) at pcu_sock.c:654
 #17 0x0001e150 in pcu_sock_read (bfd=0x627a8) at pcu_sock.c:698
 #18 pcu_sock_cb (bfd=0x627a8, flags=1) at pcu_sock.c:755
2014-02-24 13:51:30 +01:00
Holger Hans Peter Freyther
fcd4026e7b Revert "bts/vty: Use new vty_install_default() function, adjust prompts"
This reverts commit bbfd21a36c.
2014-02-24 13:03:33 +01:00
Jacob Erlbeck
f550a6a574 agch: Log error if BS_AG_BLKS_RES is != 1 in SI3
Currently, the DSP is always configured with u8NbrOfAgch = 1 before
SYSINFO type 3 is received. Thus using a different value for
BS_AG_BLKS_RES may lead to inconsistencies and MS failing to receive
paging messages properly.

This patch adds a warning and error logging and should be reverted
when initialisation is done in proper order.

Sponsored-by: On-Waves ehf
2014-02-24 12:55:38 +01:00
Jacob Erlbeck
d290ee029a agch/pch: Put CCCH message generation into common
This patch adds a common function bts_ccch_copy_msg() that provides
and schedules AGCH and PCH messages. It is basically a frontend to
paging_gen_msg() and bts_agch_dequeue() and contains refactored code
from l1_if.c.

Sponsored-by: On-Waves ehf
2014-02-22 08:45:56 +01:00
Jacob Erlbeck
d242ec2ed9 agch: Keep track of AGCH queue length
This patch adds and updates btsb->agch_queue_length to keep track of
the queue length.

Sponsored-by: On-Waves ehf
2014-02-22 08:44:29 +01:00
Jacob Erlbeck
37c332e5bf agch/rsl: Fix msgb handling for IMMEDIATE ASSIGN
Currently, the msg->data pointer is just set to the IMMEDIATE ASSIGN
message and the len is adjusted accordingly. Unfortunately, this
leaves l2h (pointing to the RSL header) and l3h (pointing to the
FULL_IMM_ASS_INFO IE) in an undefined state (outside of [data, tail]).
The code in bts.c accesses the message via msg->data.

This patch sets l3h and l2h correctly.  msgb_l3() will point to the
start of the IMM ASS message and should be used instead of msg->data.

Sponsored-by: On-Waves ehf
2014-02-22 08:41:02 +01:00
Jacob Erlbeck
bbfd21a36c bts/vty: Use new vty_install_default() function, adjust prompts
This patch removes the local 'end' and 'exit' implementations (which
aren't used anyway) and uses the generic ones provided by libosmocore
instead, which are enabled automatically when vty_install_default()
is used.

The prompt strings are modified to match those in
libosmocore/openbsc.

Ticket: OW#952
Sponsored-by: On-Waves ehf
2014-02-22 08:40:48 +01:00
Holger Hans Peter Freyther
4160e3d0f8 sysmobts: Remove debug left over from the SACCH fixes we made 2014-02-20 10:48:35 +01:00
Holger Hans Peter Freyther
2755f6e5b4 rsl: Do not allow IPA CRCX on non traffic channels
Use 0x52 as error cause as the nanoBTS is doing the same under the
situation. This has been spotted while testing handover using the
VTY command for handover.
2014-02-19 18:09:35 +01:00
Jacob Erlbeck
572ed461b6 rsl/si: Fix resetting bits in bts->si_valid
Use  'var &= ~(1 << x)' to reset bits instead of 'var &= (1 << x)'.

Sponsored-by: On-Waves ehf
2014-02-19 18:07:43 +01:00
Holger Hans Peter Freyther
1375a4b153 systemd: Disable colors in the stdout log
For journald we should not output escape sequences as it is
confusing the output.
2014-02-04 13:31:04 +01:00
Holger Hans Peter Freyther
f91799eecf l1fwd-proxy: Bind to the bts VTY port to block another process
Today we had the problem that multiple l1fwd-proxy instances ran
at the same time and not everything working all the time (some
packets were sent to a different host).

Another approach is to use flock on the message queues. This appears
to work fine as well.
2014-01-28 16:36:34 +01:00
Holger Hans Peter Freyther
023739fc94 sysmobts: Add the requested TA to the field ACCH header
Write the requested timing advance into the header. We are currently
using the u8AutoTA mode so the value will be overwritten by the DSP
before the bursts are sent to the MS.
2014-01-27 14:46:58 +01:00
Holger Hans Peter Freyther
1817447c24 sysmobts: Correct sending of LAPDm frames on the SACCH
When a frame is sent on the SACCH the LAPDm code will already
prepend two bytes for the tx_power and the ta. In the BTS we want
to use the values that were set by the BSC though. They currently
come from the RSL CHAN ACT but could also be set through the
RSL MS power control command. Update the comment as the space is
not empty.

At the 30C3 we had a NITB crash because of a RLL timeout on a
TCH/F. Jacob analyzed the problem and tracked it down to the
mismatch of LAPDm and the l1 interface to the DSP.
2014-01-27 14:46:52 +01:00
Harald Welte
2e93a8683c bts_model_rsl_chan_act(): Handle tp==NULL case gracefully
The PCU may call this function without a valid 'tp' (tlv parsed)
pointer, we need to make sure we take this into consideration...
2014-01-23 17:09:10 +01:00
Harald Welte
bc7d6fbdbb sysmoBTS OML: Don't permit TSC != BSIC
The sysmoBTS L1 has the TSC as a global value, we cannot have individual
per-timestamp or even per-lchan TSC, as the GSM specification would
suggest (and other BTSs support).

Rather than fail silently, write an error message to the log and
return NM_NACK_PARAM_RANGE or RSL_ERR_SERV_OPT_UNIMPL back to the BSC.
2014-01-21 23:39:00 +01:00
Harald Welte
bc48e26fc9 common/rsl.c: Allow bts_model_rsl_chan_act() to return negative cause
If the channel couldn't be activated, the function can simply return
a negated RSL_ERR_* constant which will then be propagated towards
the BSC in an CHAN_ACT_NACK RSL message.
2014-01-21 23:38:59 +01:00
Harald Welte
8196de46ad common/oml.c: Send OML NACK if bts_model_check_oml() returns negative
This way, bts_model_check_oml() can return a negated NM_NACK_* constant
which will then be sent as cause value in the corresponding
SET_ATTR_NACK back to the BSC.
2014-01-21 23:38:59 +01:00
Harald Welte
3c8ff3c70b sysmobts: Specify TRX nominal maximum tx power as fMaxTxPower
In the MPH ACTIVATE-RF.req, we need to specify the nominal maximum
transmit power, i.e. >= what we later request during MPH-INIT.req.

This field was first introduced in API version 2.2, but we never used
it so far.  It may help fixing a bug related to excessive power
consumption of the sysmoBTS 2050.
2014-01-21 23:38:47 +01:00
Holger Hans Peter Freyther
15bc64c6cd sysmobts: Honor the LDFLAGS when building the sysmobts-calib utility
Address warning during system builds.

Addresses:
  WARNING: QA Issue: No GNU_HASH in the elf binary...
2014-01-21 18:07:28 +01:00
Holger Hans Peter Freyther
06c098e2cb sysmobts: Launch the sysmobts-mgr in the screen and add service file
Launch the sysmobts-mgr as well. It will monitor the temperature
but it will not update the eeprom or act on any of the data. On
top of that it will respond to ipaccess-find messages making it
more easy to find the device.
2014-01-21 17:08:35 +01:00
Holger Hans Peter Freyther
d76211dc3b sysmobts-mgr: Check the return value of the sendto
Fixes: Coverity CID 1157379
2014-01-17 17:59:12 +01:00
Holger Hans Peter Freyther
5899b2d346 sysmobts-mgr: Respond to ipaccess-find broadcast messages
Bind to port 3006 and listen to incoming IPA requests. Currently
we unconditionally respond with the MAC and IP Address of the unit.
To determine the IP Address the kernel is asked for thesource
address of the route for the destination. In contrast to a nanoBTS
we will reply to the port the initial request came from.
2014-01-17 09:32:05 +01:00
Holger Hans Peter Freyther
1881e46cb9 sysmobts-mgr: Parse the daemonize option
Parse the daemonize option and daemonize after the full
set-up of the code.
2014-01-17 09:30:19 +01:00
Holger Hans Peter Freyther
810fbff380 sysmobts-mgr: Parse logging related commands, re-order init function 2014-01-17 09:30:03 +01:00
Holger Hans Peter Freyther
19224b4b9b sysmobts-mgr: Make it possible to not write to the EEPROM
For testing/trial it is better to not write to the EEPROM
but it is still good to see how the logic is working.
2014-01-16 13:49:50 +01:00
Holger Hans Peter Freyther
3e110ae141 misc: Allow to cross-execute the testsuite using qemu
When cross-compiling osmo-bts/osmo-pcu one can not easily
execute the testsuite. By adding the OSMO_QEMU variable in
front of the normal execution we can execute the tests. This
should work for native and cross builds.

$ OSMO_QEMU="qemu-arm -L /opt/poky/1.1.2/sysroots/armv5te-poky-linux-gnueabi/" make check
2014-01-15 11:59:28 +01:00
Holger Hans Peter Freyther
a4ffc44eac sysmobts: Specify the parameters that can be read from the EEPROM
When using the utility it is not clear which parameters can be
read or written. Make that more obvious.
2014-01-03 12:07:15 +01:00
Holger Hans Peter Freyther
c28a5b0b25 sysmobts: Specify the constant as a float and not a double 2013-12-29 10:14:20 +01:00
Holger Hans Peter Freyther
623d97a0d3 tch: Do not log every single RTP packet and air frame
The sysmoBTS takes quite a bit of CPU time for the vfprintf that
is used by osmo_hexdump. Do not dump every single frame to improve
the performance a bit.
2013-12-28 17:25:23 +01:00
Holger Hans Peter Freyther
9c279945a1 misc: Avoid using double numbers on our ARM
In the perf the ARM EABI ddiv operation showed up in the most
of expensive symbols. It doesn't really make much sense as the
calls should only be done on configuration.
2013-12-28 11:11:17 +01:00
Holger Hans Peter Freyther
19e87d332f measurement: Speculative performance change
Most timeslots do not have eight lchan. Use the subslots_per_lchan
map to reduce the number of iterations. Looking at the ARM assembly
showed that no loop-unrolling was done so this could be a speed up.
2013-12-28 09:37:59 +01:00
Holger Hans Peter Freyther
cdc6e3028c contrib: Remove the stray "FIVE" print it doesn't make any sense 2013-12-20 11:28:13 +01:00
Holger Hans Peter Freyther
540f608c2c sysmobts: Fix compiler warning by including utils.h
calib_file.c: In function 'next_calib_file_idx':
calib_file.c:126:3: warning: implicit declaration of function 'band_femto2osmo' [-Wimplicit-function-declaration]
2013-12-12 17:34:20 +01:00
Holger Hans Peter Freyther
0a51e1a337 sysmobts: Change the ARRAY_SIZE to a constant number
The parameter "uint8_t mute_state[8]" is actually a "uint8_t *mute_state"
so the ARRAY_SIZE is not what we think it is.

Fixes: Coverity CID 1125885
2013-12-12 17:31:02 +01:00
Holger Hans Peter Freyther
ef852ae86e sysmobts: Fix resource leak in the error condition
Fixes: Coverity CID 1047336
2013-12-12 17:28:52 +01:00
Holger Hans Peter Freyther
96264b6dd9 sysmobts: Remove stray semicolon from the PCU band filtering code.
The information from band_mask has never been used as the return
was executed unconditionally.

Fixes: Coverity CID 1113473
2013-12-12 17:26:15 +01:00
Holger Hans Peter Freyther
2800b347e9 bts: Fix crash of receiving data during the release process
Release/Free the lapdm resources _after_ the channel has
been fully released. Do not forward data unless the lchan
is in the active state.

Reading this code again, there is probably a memory leak for
everytime the PCU will re-connect to the BTS.

 (gdb) p lchan->state
 $4 = LCHAN_S_REL_REQ
 (gdb) bt
 #0  lapd_dl_flush_hist (dl=0x40454894) at lapd_core.c:164
 #1  0x44873b54 in lapd_rx_u (lctx=0xbe9bd5a8, msg=0x92f90) at lapd_core.c:1040
 #2  lapd_ph_data_ind (msg=0x92f90, lctx=0xbe9bd5a8) at lapd_core.c:1644
 #3  0x44876d50 in l2_ph_data_ind (link_id=<optimized out>, chan_nr=<optimized out>,
     le=<optimized out>, msg=0x92f90) at lapdm.c:637
 #4  lapdm_phsap_up (oph=<optimized out>, le=<optimized out>) at lapdm.c:707
 #5  0x0000c504 in handle_ph_data_ind (l1p_msg=0x97358, data_ind=0x97420, fl1=<optimized out>)
     at l1_if.c:774
 #6  l1if_handle_ind (fl1=<optimized out>, msg=0x97358) at l1_if.c:892
2013-11-27 14:29:50 +01:00
Holger Hans Peter Freyther
f56d56c439 sysmobts: Activate the BCCH silently have have state set to active
Use the lchan->rel_act_kind field for the BCCH activatiob by OML.
The lchan's should be marked as active but no event should be sent to
the BSC. This is mostly like the PCU. We can now remove the secnd
argument from lchan_activate.
2013-11-27 14:26:39 +01:00
Holger Hans Peter Freyther
ed9d643036 sysmobts: Make the eeprom/nominal power reading backward compatible
There are existing deployments where the EEPROM either contains a
wrong value and/or the kernel can not be updated to support the
different EEPROM of revD. Revert to the old behavior that if no
nominal can be derived from the model_nr we assume that it is 23.
2013-11-27 13:28:59 +01:00
Holger Hans Peter Freyther
e14ddaf204 sysmobts: Print the model number that is not supported.
When using an old kernel on revD hardware we will read garabge
from the EEPROM and it is nice for debugging to see which model
number has been picked.
2013-11-27 11:46:45 +01:00
Holger Hans Peter Freyther
e968c4224d bts: Fix typos in the log messages 2013-11-27 10:43:01 +01:00
Holger Hans Peter Freyther
082e21dbb5 bts: Fix a typo in the log message 2013-11-27 10:40:31 +01:00
Holger Hans Peter Freyther
a82cc5321e rsl: Rename abis_rsl_sendmsg to avoid symbol clash with libosmo-abis
Nicolas ended up with linker issues due abis_rsl_sendmsg being
defined twice. Rename our version of the function and update the
code.

Patched with:
 @i@
 expression E;
 @@

 - abis_rsl_sendmsg(E)
 + abis_bts_rsl_sendmsg(E)
2013-11-14 10:41:18 +01:00
Jacob Erlbeck
897f97f632 sysmobts: Notify the BSC about all muted lchans
Currently it takes some time (around 30s) until it is detected that
the radio link is down after mute. Not till then the BSC is informed
and the call terminated.

This patch modifies this behaviour by sending a RSL_MT_CONN_FAIL
message with cause RSL_ERR_RADIO_LINK_FAIL for each muted and active
lchan immediately after the corresponding Change Administrative State
Request has been acknowledged.

Ticket: OW#976
Sponsored-by: On-Waves ehf
2013-11-05 16:11:07 +01:00
Jacob Erlbeck
5eef61414a sysmobts: Only set RC state to LOCK if all channels are muted
Currently only mute_state[0] (refers to ts[0]) is inspected to
determine, whether the Radio Carrier's state is set to LOCK.

This patch changes this by looking at all channels and using LOCK
if (and only if) all channels have been muted successfully.

Sponsored-by: On-Waves ehf
2013-11-05 15:51:19 +01:00
Jacob Erlbeck
5b69ec3e72 sysmobts: Use status flags instead of direct LED access
Currently the LEDs are being accessed directly from within the
l1_if.c file. So the handling of rf mute and activate/deactivate both
access LED_RF_ACTIVE directly. This may lead to an inconsistent LED
status.

This patch replaces these calls to sysmobts_led_set() by an abstract
equivalent bts_update_status(), that uses a set of independant status
ids. The associated values can than be combined into a visible LED
status. Currently LED_RF_ACTIVE is on iff BTS_STATUS_RF_ACTIVE is set
and BTS_STATUS_RF_MUTE is not set.

Sponsored-by: On-Waves ehf
2013-11-05 15:51:19 +01:00
Jacob Erlbeck
08571b1588 sysmobts: Do a RF mute when Radio Carrier is locked
Currently a Change Administrative State Request is just applied
unconditionally to the object's state object and then acknowledged.

This patch implements the special handling of setting the Radio
Carriers state to LOCK or UNLOCK. This is done by passing the
appropriate mute command to the L1 layer. Always all radio channels
are affected, it is not possible to lock single radio channels.
On success, an ACK is sent back to the bsc with the new state (based
on the state passed in the callback by the L1 layer). If something
went wrong or the firmware doesn't support RF mute, a NACK
(REQ_NOT_GRANTED) is sent instead.

Note that a NACK for such a request hasn't been sent by the BTS to
the BSC yet, so (albeit it's spec conformant to do so) the BSC must
be prepared to handle this correctly.

Ticket: OW#976
Sponsored-by: On-Waves ehf
2013-11-05 15:46:30 +01:00
Jacob Erlbeck
9ef742f5e7 sysmobts: Add L1 support for the new RF mute request
This adds a new function

  l1if_mute_rf(femtol1_hdl, ch_mute[8])

to set the mute state for each radio channel. On completion and iff
l1if_mute_rf() returned 0 the callback

  oml_mo_rf_lock_chg(mo, ch_mute_state[8], success)

is invoked when the response from the superfemto DSP is received.

Ticket: OW#976
Sponsored-by: On-Waves ehf
2013-11-05 15:46:22 +01:00
Jacob Erlbeck
f3108fafab sysmobts: Add mappings for MuteRfReq/MuteRfCnf
This add the mappings for SuperFemto_PrimId_MuteRfReq and
SuperFemto_PrimId_MuteRfCnf to the arrays femtobts_sysprim_type,
femtobts_sysprim_names, and femtobts_sysprim_req2conf.

Sponsored-by: On-Waves ehf
2013-11-05 15:39:05 +01:00
Jacob Erlbeck
0133ff3866 sysmobts: Add L1P_T_INVALID to l1prim_type
Currently uninitialized elements of the femtobts_sysprim_type array
are mistaken as L1P_T_REQ (which is accidently the first element and
thus 0).

This patch adds a new element to the enum that has the value 0 to
detect uninitialized elements of the femtobts_sysprim_type array.
Those will then show up in the log as 'SYS Prim XXX is not a
Request!'.

This patch also adds missing definitions of the CalibTbl messages
in the femtobts_sysprim_type mapping so that the requests can still
be identified as such.

Sponsored-by: On-Waves ehf
2013-11-05 15:38:57 +01:00
Holger Hans Peter Freyther
f9dd260ee5 pcu: Exit the PCU in case of loss of the sysmobts connection
The PCU is not capable of cleaning up properly. For now simply
exit the PCU in case the sysmobts has exited. This requires
osmo-pcu a30f47613abb7c22a26d534d66e478265a8c2c09 or later.
2013-10-31 15:27:19 +01:00
Harald Welte
99fb43f41a sysmobts calibration: Load further tables even if one fails
Even if one calibration table cannot be loaded, continue to try to
load the other tables, instead of aborting very early.
2013-10-28 10:15:48 +01:00
Harald Welte
b8687024ea sysmobts calibration: skip bands not supported by L1
If L1 tells us that a certain band is not supported, then there is no
point in even trying to read+load calibration tables from EEPROM or
files.
2013-10-28 10:15:47 +01:00
Harald Welte
501673fcf3 sysmbts calibration: print error if we fail to read from EEPROM 2013-10-28 10:15:47 +01:00
Holger Hans Peter Freyther
6321c72522 rsl/pcu: Do not send a CHAN ACT to the BSC on PCU usage
The PCU is forcing the activation of a PDCH. Currently the BSC
will receive a channel act ack for a channel that was not
activated at all. Use the "release_reason" flag of the lchan
to see if we have requested a normal activation or a silent
one.

It feels a bit odd to do it in the TX function but it is the
most easy solution right now. I have added logging so it will
not be totally silent.
2013-10-25 19:14:44 +02:00
Holger Hans Peter Freyther
e851e13413 lchan: Print the name of the channel already in release request 2013-10-25 16:57:02 +02:00
Holger Hans Peter Freyther
d57e67e8da sysmobts: Fix the unit test after the internal band changes 2013-10-10 21:28:35 +02:00
Holger Hans Peter Freyther
ac3fc27257 sysmobts: Attempt to fix the compilation for the v1 hardware 2013-10-10 21:12:39 +02:00
Holger Hans Peter Freyther
ad142f84b3 misc: Fix resource leak when the ioctl is failing
Fixes: Coverity CID 1040759
2013-10-10 21:07:04 +02:00
Harald Welte
b2a8a642d6 sysmobts: Permit local override of transmit power above 23 dBm
This is used in the sysmoBTS 2050, where the maximum power is 40 dBm

We might want to add a safeguard of some kind to prevent people from
overdriving their transmitters.
2013-10-09 23:05:38 +02:00
Harald Welte
5c0e7b1f2c sysmobts: don't call sysmobts_get_nominal_power() twice
... no need for that
2013-10-09 22:35:46 +02:00
Harald Welte
e843f80832 sysmobts: make L1 power configurable
The TRX nominal output power (as seen by OML) is the aggregate power
of any gain internal to the sysmoBTS (and managed by L1) and any
external PA.  This is what is used in trx->nominal_power;

fl1h->l1_power is the transmit power to which we configure the sysmoBTS
L1.  This is 23 dBm (200mW) by default in the sysmoBTS 1002, and 40 dBm
(5W) in the sysmoBTS 2050.  However, if sysmoBTS 2050 is used in
single-TRX configuration, it may be used with higher power, which we can
now configure in the config file / vty.

TODO: A separate, additional field that keeps track of any gain added by
an external PA, e.g. if the sysmoBTS 1002 is used with a sysmoAMP.
2013-10-09 22:35:27 +02:00
Harald Welte
cfa54328e2 sysmobts: Don't use the clock calibration value on external clocks
If the clock is provided by an external (like GPS) clock, we should not
use the calibration value.  The latter is only used in context of the
OCXO or VCTCXO.
2013-10-09 16:06:41 +02:00
Harald Welte
50e63fa9e7 sysmobts: Set nominal transmit power depending on sysmoBTS model
This enables the use of up to 5W for each TRX in a sysmoBTS 2050.
2013-10-09 15:38:33 +02:00
Harald Welte
19009f2d7a Do not attempt to initialize L1 with a band unsupported by hardware
If the EEPROM tells us that a given unit doesn't support a given band,
we shouldn't try to use it, even if the BSC tells us to use an ARFCN in
such an unsupported band.

The reason is simple:  The given BTS unit might have band specific
filter / duplexer / PA.
2013-10-09 15:38:33 +02:00
Harald Welte
de0ca823f1 sysmobts: Read supported bands from EEPROM
...rather than assuming that any v2 hardware supports all bands.
2013-10-09 15:38:32 +02:00
Holger Hans Peter Freyther
6d76c1c701 Merge branch 'shared/libosmo-abis-late-init' 2013-10-06 15:51:56 +02:00
Harald Welte
d92774b4ac abis: delay l1if_reset() until OML link is established 2013-10-06 15:50:36 +02:00
Harald Welte
359fb8caf4 abis: Use OML remote (BSC) address if RSL CONNECT contains no IP
This introduces a new get_signlink_remote_ip() function whcih we also
use in the RSL code to determine the RTP remote address if the CRCX/MDCX
contains no remote IP address IE.
2013-10-06 15:50:36 +02:00
Harald Welte
b77ae3bc60 Call e1inp_vty_init() to make abis interface accessible from VTY
It might not be particularly useful, but then there's no disadvantage
either...
2013-10-06 15:50:36 +02:00
Harald Welte
6d5dc060ea migrate away from our own abis.c code to libosmoabis
libosmoabis has a BTS-side implementation of the IPA protocol for years,
and osmo-bts should have used that all the time.  Unfortunately it had
its own local hack, this patch is migrating to the libosmocore
implementation.
2013-10-06 15:50:36 +02:00
Harald Welte
b469e73148 Use GPS as default clock source on sysmoBTS 2050 2013-10-04 19:58:14 +02:00
Harald Welte
33fe4ca97b add sysmobts-util command-line utility to read/write EEPROM parameters 2013-10-04 18:29:54 +02:00
Harald Welte
870f1f1f84 sysmobts_par: add value_string definitions for parameters 2013-10-04 18:29:25 +02:00
Harald Welte
7410bc3020 sysmobts_par: Implement new EEPROM parameters (trx_nr, model_nr, model_flags) 2013-10-04 18:28:46 +02:00
Harald Welte
ff41a47c65 sysmobts_par: support for negative parameters
by splitting the rerutn code/status from the actual value, we support
negative values to be stored in the EEPROM
2013-10-04 18:27:16 +02:00
Harald Welte
ad89cd978a EEPROM: add model_nr, model_flags and trx_nr to EEPROM 2013-10-04 18:24:34 +02:00
Andreas Eversberg
971a95d259 Remove obsolete osmo-bts-bb code 2013-09-03 17:47:26 +02:00
Holger Hans Peter Freyther
ac98b545a8 sysmobts-calib: For gps the sign/difference appears to be different
For the sysmoBTS 2050 this appears to have a different sign. We can't
test this with NWL right now so we will need to see if this is a case
of ping/pong.
2013-07-26 21:24:37 +02:00
Nicolas J. Bouliane
ad10f0f533 sysmobts: Set the clock calibration to the value read from the eeprom
By default read the clock calibration from the EEPROM. It is
still possible to set it using the cli.

Signed-off-by: Nicolas J. Bouliane <nicolas.bouliane@nutaq.com>
2013-07-16 19:13:46 +02:00
Holger Hans Peter Freyther
fbf97e35eb calib: The call to fscanf can fail and we should check the return value
Coverity wants us to check that fscanf has scanned the amount of
variables we want to have. Initialize the scan result to 0/0.0f
and warn if the scan has failed.

Fixes: Coverity CID 1040774, CID 1040773
2013-07-16 18:36:44 +02:00
Holger Hans Peter Freyther
91d204e2db eeprom: Check the return value of the fseek in all calls
Coverity insists that we should check the return value of the
calls to fseek. In general this is a good idea.

Fixes: Coverity CID 1040770, CID 1040771, CID 1040772
2013-07-16 18:36:44 +02:00
Holger Hans Peter Freyther
f333387748 eeprom: After eeprom_write g_file could point to a closed file
Calling eeprom_write would either re-use g_file or newly open the
file and set g_file but it will close the file as well. This will
lead to other code using fseek/fread on a closed file.

On top of that the general rule for the eeprom code now is that
read and write may not be mixed (due caching and other bits).
2013-07-16 18:36:44 +02:00
Holger Hans Peter Freyther
95c6eed436 oml: Remove the unused nofh variable from oml_mo_tx_sw_act_rep
The variable was assigned but nothing was done with it, just
remove it for now.

Fixes: Coverity CID 1040758
2013-07-16 18:36:44 +02:00
Holger Hans Peter Freyther
612f387fc9 rsl: Fix the audio handling after the 'alignment' handling fix
The issue got introduced in fcdba6bfac
when moving from the uint32_t pointer to a plain int. The code
was now like this:

if (connect_ip > 0) {
   if (connect_ip == 0)
       lookup_ip_based_on_rsl
...

Coverity detected this as logically dead code and it was breaking
audio handling for the osmo-bsc case. Remove the tristate handling,
the RSL behavior is that leaving out port/ip is like specifying it
as zero.

Fixes: Coverity CID 1040769
2013-07-09 18:18:45 +02:00
Holger Hans Peter Freyther
ed966f0428 sysmobts: The code allowed a out of bounds access to temp_type_str
The array has three elements but check was for > _NUM_TEMP_TYPES (3)
so an access at array[3] was possible. It is unlikely to have
happened due the usage of enums. Use ARRAY_SIZE and >= on the real
array to avoid this problem.

Fixes: Coverity CID 1040760
2013-07-09 15:46:50 +02:00
Holger Hans Peter Freyther
481f14d87f sysmobts: Cache the eeprom_Cfg_t for reading tx/rx calib data
The current code has 26 fseek/fread. Only the minority really results
in a call to read. Nevertheless the time for reading during the bootstrap
can take up to 7.82 seconds. Caching the header (which is already done
by fopen/fread) will result in one call to fseek/fread and only
consumes 0.784 seconds.
2013-07-04 17:38:15 +02:00
Holger Hans Peter Freyther
89582f7e77 sysmobts: Add a method to free cached epprom resources
Close the cached file descriptor once the calibration data is
loaded and applied.
2013-07-04 17:38:15 +02:00
Holger Hans Peter Freyther
270cf418fc sysmobts: Read the mac and determine fixup only once during start 2013-07-04 17:38:15 +02:00
Holger Hans Peter Freyther
eebdfb8e6f sysmobts: Fix a typo that broke the ciphering with A5/0 > 0
Commit 5643130664 by Daniel changed
the ciphering to go through the command queue. In this commit the
direction for the ciphering got turned around and was not spotted
by review. It worked in testing due the usage of A5/0 and in that
case the direction did not matter.
2013-07-04 17:37:39 +02:00
Holger Hans Peter Freyther
2523cdbc7f misc: Fix various warnings in the code
sysmobts_vty.c: In function 'activate_lchan':
sysmobts_vty.c:373:3: warning: implicit declaration of function 'lchan_activate' [-Wimplicit-function-declaration]
sysmobts_vty.c:375:3: warning: implicit declaration of function 'lchan_deactivate' [-Wimplicit-function-declaration]

eeprom.c: In function 'eeprom_ReadEthAddr':
eeprom.c:305:5: warning: pointer targets in passing argument 3 of 'eeprom_read' differ in signedness [-Wpointer-sign]
eeprom.c:260:12: note: expected 'char *' but argument is of type 'uint8_t *'
2013-07-01 09:30:02 +02:00
Harald Welte
6404a76661 make oml_mo_state_init() a void function
... so we don't get warnings about not returning anything
2013-06-30 15:29:26 +02:00
Harald Welte
48eca2524c Don't send OML STATE CHANGE before OML is connected
Instead of calling oml_mo_state_chg() [which transmits OML STATE CHG]
during bts_init(), we use a new oml_mo_state_init() function which
simply sets the state.
2013-06-30 15:09:35 +02:00
Holger Hans Peter Freyther
0089ce4178 sysmobts.service: Use multi-user.target as target to fix ordering 2013-06-26 18:03:41 +02:00
Holger Hans Peter Freyther
123caa3c83 calib: Attempt to fix the build for v2.7 of the api headers
This should fix:
calib_file.c: In function 'calib_eeprom_read':
calib_file.c:262: error: 'SuperFemto_SetRxCalibTblReq_t' undeclared (first use in this function)
calib_file.c:262: error: (Each undeclared identifier is reported only once
calib_file.c:262: error: for each function it appears in.)
2013-06-24 11:18:54 +02:00
Holger Hans Peter Freyther
593080ebab calib: Attempt to fix the build for v2.7 of the api headers
This should fix:
calib_file.c: In function 'calib_fixup_rx':
calib_file.c:148: error: 'SuperFemto_SetRxCalibTblReq_t' undeclared (first use in this function)
calib_file.c:148: error: (Each undeclared identifier is reported only once
2013-06-24 11:11:16 +02:00
Holger Hans Peter Freyther
f169a75fc4 sysmobts: Introduce an auto-band config to ease DCS/DCS, PCS/PCS changes
During development one switches from GSM900 to GSM1800 and GSM850 to
GSM1900. This commit attempts to make this switch more easy.

GSM1800 and GSM1900 have overlapping ARFCNs. This means that the
mapping from bands to arfcn is not injective. Because of that I
removed the code to deduce the band from the ARFCN. This was done
in commit 8c3d807b3f. The auto-band
option allows to move between GSM900/GSM1800 and GSM850/GSM1900.

Add a simple testcase with these auto-band configurations.
2013-06-24 08:17:12 +02:00
Holger Hans Peter Freyther
43b4176f0e sysmobts.service: Reset the firmware after the service exited
These should have been ExecStopPost from the beginning. Currently
they reset the firmware while the software is starting. Reload
the DSP and FPGA firmware.
2013-06-24 08:17:12 +02:00
Holger Hans Peter Freyther
266af543e3 sysmobts: Make sure we receive every SACCH frame to count S properly
In case there is no transmitter the S counter might never be decreased.
This means that no radio link timeout will not be sent and the lchan will
remain open forever. There are several ways to resolve this.

The first would be to use the MphTimeInd and after each multiframe check
if there has been a SACCH message for the open lchan's. This could be
similar to the trx_meas_check_compute.

I decided to change fBFILevel to always receive SACCH frames and move
the code down to the PDTCH/PACCH handling and update the comment.
2013-06-24 08:17:05 +02:00
Holger Hans Peter Freyther
718cc9dcac sysmobts: Read multiple primitives at once but only up to 3
In most cases there are multiple messages ready to be read from
the queue and it is more efficient to read them in one go instead
of going through the select again.
2013-06-24 08:02:34 +02:00
Holger Hans Peter Freyther
44eec601bc sysmobts: Use writev for the outgoing data of the write queue
Attempt to write multiple primitives at the same time instead of
the select/write, select/write that is currently done. The queue
size is big enough to hold several entries at the same time and it
is unlikely we get the -EAGAIN from the kernel driver.

The writev code works by assuming that each element in the queue
has the same size. This is not verified by the code and if this
assumption breaks at some point the code will drop primitives or
send some twice.
2013-06-24 08:02:34 +02:00
Holger Hans Peter Freyther
25346fe0d7 sysmobts: Fix potential memory leaks in the prim callback handling
Make sure the l1msg is always freed in the callback. There were
several error conditions were the msgb would not have been freed,
in the case of the calib data and the system information the message
was not freed even in normal condition.

I will modify this code to __use a msgb. This allows to re-use
the allocated msgb across read operations.
2013-06-24 08:02:34 +02:00
Holger Hans Peter Freyther
a7e7537776 lapd: Fix a +ptrsize memory leak for each opened lchan
The lapdm/lapd_core code needs to keep a history of messages sent.
This history is not freed when lapdm_channel_reset is called and
the init code will just allocate a new array. This means there is
a memory leak on every released channel every time it is released.
2013-06-24 08:02:20 +02:00
Harald Welte
ee43f46cb0 calib: Fix for new EEPROM Mode; better log msgs 2013-06-22 19:30:59 +02:00
Harald Welte
40ca16766d calib: Add fixup for incompatible calib data / firmware version
For certain sysmoBTS units, a fixup to the calibration table is needed,
if the firmware is >= 3.3.0.
2013-06-22 19:30:55 +02:00
Harald Welte
2563267757 calib: Read calibration data from EEPROM, not just files
On v2D (and later) hardware, the calibration data can be read directly
from the EEPROM and doesn't have to be read from files.

If there is no trx-calib-path set in the VTY, we will read from EEPROM.
2013-06-22 19:27:13 +02:00
Harald Welte
a899146aea eeprom: wrap DISP_ERROR #ifdef/endif in PERROR() macro
This has the advantage that an user application might simply re-define
the PERROR() macro rather than patching the code all over the place.
2013-06-22 19:22:45 +02:00
Harald Welte
6002d17c24 eeprom: cache the file descriptor instead of fopen/fclose all the time 2013-06-22 19:22:45 +02:00
Harald Welte
d675de9c23 initial import of EEPROM calibration read routines 2013-06-22 19:22:45 +02:00
Holger Hans Peter Freyther
6ebabb560e sysmobts: Do not write "trx-calibration-path (null)" in the config file
When not specifying a config path, then saving the running config
it would end up as "(null)" and then leads to an error like this:

 <0006> calib_file.c:147 Failed to open '(null)/calib_rxu_850.cfg' for calibration data.

Add a NULL check to avoid this issue when writing the config file.
2013-06-20 18:17:34 +02:00
Holger Hans Peter Freyther
d98f2f35ec misc: Please ignore the commit. It is done to test a jenkins trigger 2013-06-20 17:24:32 +02:00
Nicolas J. Bouliane
fcdba6bfac rsl: fix the unaligned memory access
the armv5 can do 32bit/16bit reads only from the aligned address
use tlv.h macro to copy data to local variable

Signed-off-by: Nicolas J. Bouliane <nicolas.bouliane@nutaq.com>
2013-06-20 13:50:44 +02:00
Holger Hans Peter Freyther
19cefb0097 sysmobts: Fix a crash when the DSP2ARM queue runs full
When not reading quick enough from the queue we will get a bogus
response which will lead to marking the lchan as broken and to
clear the sapi queue. The sapi_queue_dispatch was checking if the
queue was empty before calling the callback but not taking into
account that it might have been flushed.

Stop processing if the queue was empty before calling the callback
or if it is empty after the callback.

Backtrace:
 #0  0x4eb1f1cc in raise () from /lib/libc.so.6
 #1  0x4eb22f48 in abort () from /lib/libc.so.6
 #2  0x4ecc2cb8 in talloc_abort (reason=<optimized out>) at talloc.c:167
 #3  0x4ecbc854 in talloc_abort_unknown_value () at talloc.c:180
 #4  0x4ecc6bc8 in talloc_chunk_from_ptr (ptr=0x4ec2d494) at talloc.c:192
 #5  _talloc_free (ptr=0x4ec2d494) at talloc.c:517
 #6  talloc_free (ptr=0x4ec2d494) at talloc.c:990
 #7  0x0000f294 in sapi_queue_exeute (lchan=0x402414a0) at oml.c:528
 #8  0x0000f2d4 in sapi_queue_send (lchan=0x402414a0) at oml.c:542
 #9  0x0000f3e0 in sapi_queue_dispatch (lchan=0x402414a0, status=-4) at oml.c:565
 #10 0x000114d0 in lchan_deact_compl_cb (trx=0x4021e038, l1_msg=0x7e690) at oml.c:1269
 #11 0x0000d70c in l1if_handle_l1prim (wq=1, fl1h=0x607c8, msg=0x7e690) at l1_if.c:938
2013-06-20 13:50:44 +02:00
Alexander Huemer
d07ee75fc6 Makefile.am: Use AM_CPPFLAGS
Since automake 1.13 INCLUDES is depricates and causes a warning
2013-06-12 08:01:00 +02:00
Holger Hans Peter Freyther
c03fe5af31 sysmobts: Allow to enable realtime priority for the BTS process
The latency to respond to a PH-READY_TO_SEND.ind may not be higher
than 18ms. Currently we are using nice to increase our priority but
for a heavily loaded cell this is not enough. Add an option to enable
realtime scheduling and use it in the screenrc.

Linux offers two realtime scheduling classes these are SCHED_FIFO
and SCHED_RR. For SCHED_FIFO the process is running as long as possible
(potentially taking all the CPU and never yielding it), for SCHED_RR
the process can still be pre-empted at the end of the timeslice.

Using SCHED_RR appears to be the more safe option as a run-a-way
sysmobts process will not be able to take all the CPU time.

For a very loaded cell we also require to use readv/writev to allow
writing multiple primitives in one syscall.
2013-05-11 08:34:36 +02:00
Holger Hans Peter Freyther
9be5f8c9c0 measurement: Mark the internal functions as internal
In terms of assembly code this only removes the ".global FN" from
the code. GCC does not attempt to inline it right now.
2013-05-04 13:12:20 +02:00
Holger Hans Peter Freyther
0d194268fb sysmobts: Use msgb_free instead of talloc_free to free the message
Currently msgb_free is calling talloc_free but we might introduce
a msgb pool in the future. So make sure to use the designated free
method for the msgb.
2013-05-01 19:03:43 +02:00
Holger Hans Peter Freyther
bd3250a456 sysmobts: Print the lchan name for the S counter. 2013-05-01 19:03:30 +02:00
Holger Hans Peter Freyther
3a6220cae2 rsl: Add the channel name to the act nack and conn fail message 2013-04-30 21:56:50 +02:00
Nicolas J. Bouliane
6a4c8a8596 osmo-bts: fix linking order in Makefile.am
On some system (e.g. ubuntu) libosmovty must precede libosmocore
otherwise we get undefined reference errors while linking.

Signed-off-by: Nicolas J. Bouliane <nicolas.bouliane@nutaq.com>
2013-04-18 20:32:23 +02:00
Holger Hans Peter Freyther
17dd79a3ae sysmobts.service: Install the sysmobts.service at the default target 2013-04-07 11:53:16 +02:00
Holger Hans Peter Freyther
636cad95a7 sysmobts: Document the known MphConfig conflict in the code
Right now changing the TxPower through the VTY could conflict with
a channel activation.
2013-03-24 09:05:05 +01:00
Holger Hans Peter Freyther
0809ae6941 sysmobts: Do not re-configure the channel on non-active channels
In case the channel is not active we can omit the external requests
to modify it. For the channel modification the higher level is already
acking it and for the ciphering it is probably too late to do anything.
2013-03-24 09:05:05 +01:00
Holger Hans Peter Freyther
4c4fd284ae oml: Use the queue for the release handling of a channel
There are three new commands. There are two markers and a deactivate
command. The markers are used to wait until all previous commands are
executed and then to decide if the SAPI needs to be released at all.

When asked to release the SACCH the marker will be queued, then on
execution of the marker the SACCH in Up-/Downlink will be released.

For the RF Channel Release we use another marker, when the marker is
executed we check all the SAPIs we want to release. It is possible that
the queue looks like this:
   (SACCH_REL_MARKER is done) REL_MARKER, SACCH DEACT, SACCH DEACT

This could happen if a BSC sends SACCH Deactivate and RF Channel Release
at the same time. We deal with issue by changing the SAPI state to the
REL_REQ state and check_sapi_release will not ask for another release. So
after the execution the queue will look like this:

  SACCH DEACT, FACCH DEACT, TCHF DEACT..

This code does not check that all allocated SAPIs are released. The
lchan_deactivate_sapis could be changed to go through all sapis_dl
and sapis_ul to fix that.

The normal flow should now be:
1.)  lchan_deactivate
2.)  Check if the queue is empty then go to 4
3.)  REL_MARKER is executed and lchan_deactivate_sapis is called
4.)  For all SAPIs to be released, check if they are allocated and
     then schedule a CMD_DEACTIVATE. If there is an error remember
     something went wrong but continue.
5.)  Once all commands are executed send the channel release ack.

For the release markers we need to be careful as they might not schedule
any work. E.g. if the BSC sends two SACCH DEACTIVATE the second marker
will not generate any release requests and we should proceed with the
next command. Make sapi_queue_command return 1 in case the command has
been directly executed. So a queue like SACCH_REL_MARKER, LOGCH will
result in LOGCH, SACCH DEACT Rx, SACCH DEACT Tx but a 0 will be returned
and the sapi_queue_next will then call sapi_queue_exeute again.

NITB has been modified to trigger these corner cases more easily.
* Do not send IMM.ASSIGNMENT for some timeslots to go through the
error path
* Issue multile SACCH deactivates in the normal release mode
* Send rsl_chan_mode_modify_req before the SACCH DEACT and also when
the RLL is being released.
2013-03-24 09:05:05 +01:00
Daniel Willmann
42cc93efb6 oml: Print out power setting in txpower completion callback 2013-03-24 09:05:05 +01:00
Daniel Willmann
4e46cb8961 oml: Use sapi command queue for setting the logical channel params 2013-03-24 09:05:05 +01:00
Daniel Willmann
5643130664 oml: Enqueue ciphering message through sapi cmd queue as well 2013-03-24 09:05:05 +01:00
Daniel Willmann
376183fcf0 oml: Introduce a SAPI queue for activation and deactivation of SAPIs
Put all SAPI requests into a queue and handle them one after another.
Begin with the channel activation. Once the queue is empty the channel
activate will be sent. For the BCCH activation we do not want to send
a channel activation message and this is why we set the lchan->state
to NONE.

One change is that we do not attempt to call the ciphering routines on
the BCCH anymore.

This change is necessary to fix issues with LCHANs staying open and being
marked as broken by the BSC and will help in implementing handover support
as this requires a re-configuration of the lchan on the fly.
2013-03-24 09:05:04 +01:00
Holger Hans Peter Freyther
fb0c9f0613 measurement: Add debug helper when we have a report for an inactive channel 2013-03-24 09:05:04 +01:00
Holger Hans Peter Freyther
9d91c60875 sysmobts: Prepare to address the documented limitation of this code 2013-03-24 09:05:04 +01:00
Holger Hans Peter Freyther
470a6ced9a oml: Only shut the bts down once
If the shutdown timer is already running do not deactivate the RF and
do not close the trx. This is addressing another instance of the following
warning:

[ERROR] : DeviceMng_ValidateL1Handle() => Invalid layer 1 handle
2013-03-23 11:39:32 +01:00
Andreas Eversberg
118eb43ba5 fixup e2cde1f48379657402332b5a95d4ce242d63069a 2013-03-18 18:05:24 +01:00
Andreas Eversberg
cdc5a4dc38 Add VTY option to define minimum C/I level for RACH and normal burst 2013-03-17 17:43:02 +01:00
Andreas Eversberg
5cbc7e9167 Get RSSI from received uplink data and send to PCU
This bumps the PCU API version and thus requires a new version of the
code on the sysmoBTS side!
2013-03-17 17:43:02 +01:00
Holger Hans Peter Freyther
4ad8d4d3c0 sysmobts: Name the screen and use '-X quit' to shut it down
Use "kill -2 0" for the PCU as SIGTERM is not handled yet. With
the current set of code the stop function will stop both the PCU
and the BTS.
2013-03-16 23:29:59 +01:00
Holger Hans Peter Freyther
e45fc86359 respawn: Adjust the oom score for the supervisor and bts/pcu, increase sleep
Make the script mostly unkillable due to OOM and make sure that the
process has a score of zero. Wait 10 seconds before re-launching.

The combination of ( && exec ) & appears to save one sub-process. The
script has been tested with bash and busybox's ash.
2013-03-16 14:15:50 +01:00
Andreas Eversberg
54dd949e62 Fix: Stop RADIO LINK TIMEOUT couter S from counting, if it has reached 0
In case that the counter S reached 0, it will stay 0. Subsequent received
good and bad SACCH frames must not cause to trigger radio link failure
again. Once the BSC has been indicated about link failure, it will release
channel.

The counting of S has been moved to a seperate function.

This patch will ensure that the link failure is indicated only once. But
even if the link failure would be sent multiple times, the BSC should
ignore it. The BSC releases the channel and may only reuse it after confirm
from BTS. (There cannot be any link failure indications after confirm of
channel release.)

The allowed timeout value range is 4..64, as defined in TS 05.08, so if the
BSC sends an attribute with value out of range or other failure criterion,
the Set BTS Attributes message is NACKed.
2013-03-15 21:41:27 +01:00
Harald Welte
620be0bbed OML: fix broken curly braces while parsing SET BTS ATTR
Looking at the problem, it's a surprise that the old code was working at
all...  (Thanks to jolly for pointing this out)
2013-03-14 11:20:09 +01:00
Harald Welte
f0bdc1e562 RSL: Fix Channel Number IE in Common Channel RSL messages
As per Chapter 9.3 of TS 08.58, we have to use RSL_IE_CHAN_NR instead
of the zero we were implicitly using so far.
2013-03-13 12:42:01 +01:00
Andreas Eversberg
294fd1b650 Added radio link timeout procedure according to TS 05.08 Chapter 5.2
Chapter 5.2 applies to MS procedure, but 5.3 (BSS procedure) defines no
exact criterion, so I decided to use the procedure equivalent to MS.

The criterion is based on a counter S, which is initialized to a preset
RADIO_LINK_TIMEOUT, which can be configured via VTY. Whenever a received
SACCH block is bad, S is counted down by one. If SACCH block is
successfully decoded, S is counted up by two, but never above initial
RADIO_LINK_TIMEOUT value. If S reaches 0, an RSL Connection Failure
Indication with cause RF Radio Link Failure is sent to BSC, which then
aborts channel.

Use link timeout value from BSC via OML attribute.

How to test:
- Set "debug" for "meas" logging.
- Start silent call to an attached mobile.
- Remove battery from mobile or shield mobile.
- Watch S count down.
2013-03-11 11:47:41 +01:00
Harald Welte
19f212951a l1_if: if ul_power_target==0, hard-code MS power to what RSL says
RSL CHAN ACT contains a MS_POWER IE which is intended to be used as the
initial power level for the MS, before the UL power control loop is
starting.

In our case, if ul_power_target != 0, then the DSP takes care of power
control.  If ul_power_target == 0, then we instruct the phone to
constantly use the value specified by the BSC in the MS_POWER IE.

FIXME: Actually implement a proper power control algoritihm inside
osmo-bts so we don't have to rely on the DSP implementation.
2013-03-07 10:07:18 +00:00
Harald Welte
cf4e3501a1 gsmtap: Put the RxLevel and RxQual in uplink GSMTAP 2013-03-06 19:58:26 +00:00
Holger Hans Peter Freyther
d9da7813a6 doc: Remove the rtp bind-ip from the example
This option is not needed anymore, let's remove it.
2013-03-02 18:12:22 +01:00
Holger Hans Peter Freyther
b7eb9865df calib: Use 2.4.0 as cut-off for the firmware, log errors
In case opening a calibration file is failing an error will will be
logged, the caller and implementation were inconsistent about the API
version that is supported for the calibration data, attempt to make
the cut-off at 2.4.0.
2013-02-27 11:10:33 +01:00
Holger Hans Peter Freyther
dd2a51ed32 tests: Share the stub between the paging and ciphering tests 2013-02-27 10:44:43 +01:00
Holger Hans Peter Freyther
faba73a812 sysmobts: Improve the shutdown of the DSP on exit
Issue the RfDeactivate.REQ before sending the MphClose.REQ. Ideally
we would issue MphClose.REQ after the RfDeactivate.CNF but this is
not possible right now.

The current approach makes the following warning of the DSP go away
on shutdown. This was tested with my E71 and an active silent-call
using a SDCCH.

DSP Warning:
[ERROR] : DeviceMng_ValidateL1Handle() => Invalid layer 1 handle
2013-02-27 10:44:01 +01:00
Holger Hans Peter Freyther
305d8314bc Merge branch 'zecke/request-queuing'
* Simplify the callback signature. The trx is now the first argument.
* Embed the calibration data into the femtol1_hdl.

Tests:
* All commits are compile tested
* All commits bring up the radio (without using calibration data)
* Calibration data loading has been tested with the merge
* All commits allow a IMSI Attach and a MO Call (to an invalid unknown
  number). All channels are freed after this. It has been tested with
  the E71.
2013-02-27 10:31:30 +01:00
Holger Hans Peter Freyther
5e46e4b488 sysmobts: Fix a memory leak when no callback is set
The TxPower handled used to call the requestion function without
a callback. In that case the msgb is leaked. The code still allows
the callback to be NULL so we will just delete the message in that
case.
2013-02-27 09:07:18 +01:00
Holger Hans Peter Freyther
3d383c22c7 sysmobts: Remove the is_system_primitive from l1if_req_compl
All users (but the gsm_compl) of the l1if_req_compl use it with
is_system_primitive=1. We can now remove this parameter from the
method. Introduce _l1if_req_compl that will insert the item into
the queue for us.
2013-02-27 09:07:18 +01:00
Holger Hans Peter Freyther
654fe73b78 sysmobts: We can now pass the trx to the callback change the signatures 2013-02-27 09:07:18 +01:00
Holger Hans Peter Freyther
6142f9262a sysmobts: Remove the trx parameter from the signature
l1if_gsm_req_compl everyone is passing the trx as data pointer right
now, remove it from the request procedure right now as it can be
deducted from the femtol1_hdl.
2013-02-27 09:07:17 +01:00
Holger Hans Peter Freyther
64c5e3a19c sysmobts: Embed the calib state in the femtol1_hdl and use hdl->priv 2013-02-27 09:07:17 +01:00
Holger Hans Peter Freyther
b6942ffeb9 sysmobts: Use the hdl->priv in l1if_req_compl for all callers 2013-02-27 09:07:17 +01:00
Holger Hans Peter Freyther
ff4f789249 sysmobts: Remove the data parameter from the l1if_gsm_req_compl
Pass in the trx argument at the lower level as everyone is using
the fl1h->priv now.
2013-02-27 09:07:17 +01:00
Holger Hans Peter Freyther
0890e274b1 sysmobts: Use the fl1h->priv and get the ts back from the response 2013-02-27 09:07:17 +01:00
Holger Hans Peter Freyther
60b090ac53 sysmobts: Use the fl1h->priv to get the trx instead of using the lchan
I am working toward killing the last argument of the l1if_gsm_req_compl
and just have the trx inside the callback signature.
2013-02-27 09:07:17 +01:00
Holger Hans Peter Freyther
dc9148d035 Merge branch 'zecke/calib-pch-agch-follow'
Introduce bcch_ccch to scan the PCH on top of the BCCH. The AGCH is
included in the PCH. CBCH/NCH are not included at this point.
2013-02-13 17:19:19 +01:00
Holger Hans Peter Freyther
1897f03d4c calib: Attempt to follow the PCH as well and print the SAPI..
AGCH is reported as part of the PCH because we are not searching
for the BS-AG-BLKS-RES inside the SI3 and do not use MphConfigReq
to change this setting.
2013-02-13 17:17:59 +01:00
Holger Hans Peter Freyther
6ac2e68467 calib: Print the frame number decoded as t1/t2/t3 2013-02-13 10:34:40 +01:00
Holger Hans Peter Freyther
225cf82290 calib: Provide the fn and block number for each frame 2013-02-13 10:34:40 +01:00
Harald Welte
18708dd3b6 RSL: further rtp local bind related fixes
If the CRCX does not indicate the remote IP address, then we still were
binding to 0.0.0.0 and used that address successively in the CRCX_ACK.

As a workaround, we now use the source IP address of the RTP socket,
assuming that the outbound routes to BSC and the MGW are identical.
This is of course not always true, but I don't think there are any
better alternatives...
2013-02-09 14:17:01 +01:00
Harald Welte
98407bd457 rsl: Fix compiler warning in use of osmo_rtp_get_bound_ip_port()
for whatever reason i decided that a port number in
osmo_rtp_get_bound_ip_port() needs to be a int * and not a uint16_t * at
the time, so we have to deal with this here rather than breaking the
ABI.
2013-02-09 11:44:07 +01:00
Harald Welte
0bb2974b37 Fix determination of locally bound IP for RTP sockets
After we create a socket and bind it to INADDR_ANY, we cannot yet use
getsockname() to resolve the locally bound IP.  This only works after
the socket has been connected to the remote IP.  So we have to move the
osmo_rtp_get_bound_ip_port() to a code section after
osmo_rtp_socket_connect() has already happened.

With the code prior to this commit, unless "rtp bind-ip" was used in the
config file, we reported "0.0.0.0" as the "Source IP AddresS" in the IPA
CRCX ACK to the BSC.   This is of course wrong, as the BSC will then use
this "0.0.0.0" as destination address for the incoming RTP stream :(

Please note that for this fix to work, you also need a libosmoabis.git
with commit d426d458ca96ba29793e35b1b2a73fbcb3b2c888 which actually
causes osmo_rtp_socket_connect() to actually issue connect() on the
socket at all.
2013-02-09 11:38:30 +01:00
Harald Welte
550d22be5b Deprecate the "rtp bind-ip" configuration directive
Instead of explicitly having to specify the local IP address for RTP
sockets in the BTS, we just use "0.0.0.0" instead, which gets
translated to INADDR_ANY.

We still accept the configuration directive in old config files, but
when we write, the line will no longer be re-written to the file.

TODO: IMHO, the IPA RSL CRCX/MDCX actually permit the BSC to specify the
IP address on the BTS side, and we probably simply ignore this at this
point.
2013-02-04 22:16:23 +01:00
Harald Welte
6a2d89f48d Make sure SACCH fill frame is correctly aligned for L1 header
When we send a fill frame on SACCH, we need to have two bytes for the L1
header at the beginning (inserted by the DSP).

Thanks for Andreas Eversberg for pointing it out.
2013-02-04 22:16:23 +01:00
Harald Welte
3ff2fc4378 RSL: don't store MS power in lchan->bs_power but lchan->ms_power
As we currently don't use any BSC-based MS power control in either
OpenBSC nor in OsmoBTS, this bug has never shown up so far.

Thanks to Andreas Eversberg for spotting this.
2013-01-25 16:00:20 +01:00
Daniel Willmann
bcd50d3219 oml: Create mph_send_activate_req for sending the activation request
Move the channel activation out of the loop into a dedicated function.
This is done in preparation of separating the decision to activate
something and sending the request.
2013-01-24 12:15:10 +01:00
Holger Hans Peter Freyther
f0c5a424af sysmobts: Send GSM requests using the l1if_gsm_req_compl method
Prepare to change the queue and callback handling. For the TX power
VTY command it is still possible that it will conflict with other
callbacks and the easiest way is to beging with sending these requests
through another method that allows us a more strict test.
2013-01-23 18:23:58 +01:00
Holger Hans Peter Freyther
76a1bf6136 sysmobts: Help in calling the right callback for l1if_req_compl
The wait list code has a limitation that for two requests of the
same kind it does not know where the confirmation belongs to. This
limitation is triggered when two lchan's get activated/deactivated
at the same time and is noticed once we start to count the SAPIs.

Set the hLayer3 to the lchan identifier, use the trx as closure for
the callback and resolve the lchan in the callback using these two
bits of information.
2013-01-23 18:23:58 +01:00
Holger Hans Peter Freyther
e210f1a864 sysmobts: Rename the hLayer2<->lchan to hLayer<->lchan
We are using this conversion for both hLayer2 and hLayer3. Make the
function name more generic to indicate that this function can be used
with the hLayer3.

The functions that call the methods were updated using spatch and
@rule1@
expression E;
expression F;
@@
- l1if_hLayer2_to_lchan(E, F)
+ l1if_hLayer_to_lchan(E, F)
@rule2@
expression E;
expression F;
@@
- l1if_lchan_to_hLayer2(E)
+ l1if_lchan_to_hLayer(E)
2013-01-23 18:23:58 +01:00
Holger Hans Peter Freyther
61e739912f sysmobts: Ignore too short messages on the FACCH (but also the SDCCH)
During call testing using an E71 and dialing a number of an expired (lac
set to 0) subscribe the CC Release and other messages are sent after or
during the channel modification. This appears to lead to some reception
issues in the DSP code and giving use empty (u8size == 0) FACCH frames.
The real issue might be inside the MNCC code of NITB and the lack of a
size check inside the LAPDm code (our msgb has enough data though).
Passing the empty FACCH frame into the LAPDm code lead to the generation
of RSL ERROR INDICATION with cause FRAME_UNIMPL as some bits were zero.

Add a check for 0 into the FACCH code. As the code path is shared with
SDCCH it is also discarding zero sized SDCCH frames. These have not been
observed during my testing. The lacking size check in LAPDm will be
addressed separately.

During call testing the IPA CRCX was also failing due the BTS trying
to bind to an unassigned IP address.
2013-01-23 18:22:11 +01:00
Holger Hans Peter Freyther
4a303c7c38 oml: Fix memory leak in the callback 2013-01-23 18:22:11 +01:00
Harald Welte
8597a278d6 l1_if: don't print measurements a second time in case of error 2013-01-23 17:42:17 +01:00
Holger Hans Peter Freyther
6ddd632adf sysmobts: Use a newline at the end of the SACCH u8Size < 2 message
The other message in this method is using a \n as well and the line
is generally now followed with a LOGPC.

It looked like this:
<0006> l1_if.c:672 SACCH with size 0<2 !?!<0006> tch.c:540 (bts=0,trx=0,ts=2,ss=0) Rx Payload size 0
2013-01-17 21:14:40 +01:00
Holger Hans Peter Freyther
0903001d9b calibration: The clock error is absolute for anything but the netlisten
We only need to run this once and we know the clock error. In case it
is 0/0 we know that we didn't receive one of the two clocks. This could
be because the GPS doesn't have a fix. I accidently pushed this code into
the master branch and it is too late to rebase.
2013-01-15 22:47:38 +01:00
Harald Welte
c2371cc011 fix message: the PCU is not a call control application 2013-01-15 18:57:59 +01:00
Daniel Willmann
91816acfb8 paging: De-duplicate paging lifetime and max queue length variables
These attributes are saved in paging_state, we don't need to save them a
second time in struct gsm_bts_role_bts. Add get and set methods for
these attributes and use them consitently in the VTY code.
2013-01-13 17:24:45 +01:00
Holger Hans Peter Freyther
fad5b08625 WIP... use gps for calibration.. 2013-01-12 21:44:48 +01:00
Harald Welte
24b2128e29 add PCU respawning to contrib screenrc and respawn scripts 2013-01-11 17:36:56 +01:00
Holger Hans Peter Freyther
3177f2b42f sysmobts: Fix the comment referring to the value of the timeout
Right now it is 30 seconds and not 10.
2013-01-03 16:39:41 +01:00
Holger Hans Peter Freyther
552989ad57 common: Fix faulty memcpy statement in the paging code
This was experienced by Daniel on his 64bit machine. The paging
expiration time was too high and not set by the code at all. Using
gdb watchpoints he found the place where the memory is written. The
issue is that the size of the pointer (8) and not the size of the
data structure was copied (3).

Fix the issue by assigning the de-referenced value. gcc generates
the same code as if we had written:
 memcpy(&ps->chan_desc, chan_desc, sizeof(*chan_desc));
2013-01-01 21:33:18 +01:00
Holger Hans Peter Freyther
222a6a5e23 l1_if: Fix typo... call it femtobts 2012-12-29 12:23:09 +01:00
Holger Hans Peter Freyther
0670138ffc tch: Do not print that there is no audio data on a TCH/H
When only signalling is used on the TCH/H it is normal that there
is no TCH data. Save CPU time by not printing the message. This
needs to be moved to be edge triggered.
2012-12-26 19:50:10 +01:00
Holger Hans Peter Freyther
19cf0e81b3 ciphering: Handle ciphering support for A5/3 correctly
This was found and debugged by Sylvain. The BTS will always support
A5/0 so we do not keep track of that, the first bit of the flags is
used for A5/1, second for A5/2... but for RSL there is an offset to
go from RSL to A5(x). Add a testcase and change the code.
2012-12-26 18:55:54 +01:00
Daniel Willmann
5f408f934c tests: Don't delete atconfig in clean
This file is created in ./configure so we shouldn't remove it with make.

Otherwise ./configure && make clean && make check fails
with:

make[3]: *** No rule to make target `atconfig', needed by `check-local'.
Stop.
2012-12-26 11:31:30 +01:00
Holger Hans Peter Freyther
fc9920830e misc: Package the configuration and contrib directory 2012-12-22 16:05:10 +01:00
Holger Hans Peter Freyther
c559dde69d misc: Package our version of the gsm_data.h to make the code compilable
The sharing with OpenBSC is not complete yet. We will need to include
our version of gsm_data.h instead of the normal OpenBSC version.
2012-12-22 16:02:05 +01:00
Holger Hans Peter Freyther
3bcf3a5fd0 sysmobts: Add all header files to the EXTRA_DIST to fix make distcheck 2012-12-22 15:03:19 +01:00
Holger Hans Peter Freyther
359b2cf469 misc: Fix the make distcheck of the osmo-bts code
* Comment out the osmo-bts-bb/Makefile as we have removed it from
  the SUBDIRS and are not packaging the code right now
* Add missing include files for the build
2012-12-22 14:59:12 +01:00
Holger Hans Peter Freyther
20c5702e0f paging: Update the test output to make the test pass 2012-12-22 14:44:00 +01:00
Holger Hans Peter Freyther
ce7559fbec misc: Fix compilation on debian stable with GCC 4.4.5
l1_transp_hw.c:89: error: redefinition of typedef 'dummyprim'
l1_transp_hw.c:88: note: previous declaration of 'dummyprim' was here
2012-12-22 14:37:30 +01:00
Holger Hans Peter Freyther
0d30b5d818 Merge branch 'zecke/openbsc-incdir'
Allow to have the OpenBSC directory somewhere else. This is required
to build osmo-bts on the public jenkins installation. The default is
the old behavior to look for OpenBSC next to the osmo-bts code.
2012-12-20 19:23:01 +01:00
Holger Hans Peter Freyther
56698b84e0 openbsc: Check for the presence of the gsm_data_shared.h header file 2012-12-20 19:18:13 +01:00
Holger Hans Peter Freyther
db51f0d73e openbsc: Introduce autoconf support to set the OpenBSC include directory
Add autoconf support to set the path to the OpenBSC include directory
so that openbsc/gsm_data_shared.h can be found there.
2012-12-20 19:02:37 +01:00
Holger Hans Peter Freyther
bcae2abff8 openbsc: Prepare to allow to have the OpenBSC directory somewhere else
Right now osmo-bts requires access to one OpenBSC header file and
this requires that openbsc and osmo-bts git are in the same directory.
Begin with making the location of the OpenBSC sourcecode configurable.

This approach will allow to build osmo-bts on our Jenkins installation
but now has the risk of more code including the openbsc/*.h header files.
2012-12-20 19:02:37 +01:00
Holger Hans Peter Freyther
d1ffab96ca misc: Forward declare calib_load to address a compiler warning 2012-12-20 19:01:27 +01:00
Holger Hans Peter Freyther
61a1f99680 misc: Forward declare l1if_set_ciphering to avoid a compiler warning 2012-12-20 19:01:27 +01:00
Holger Hans Peter Freyther
4fd0a84cf8 misc: Change the method to return void instead of int and garbage
The method was not returning anything and the callers did not use
the result. Change it to void for now.
2012-12-20 19:01:27 +01:00
Holger Hans Peter Freyther
9bd5afa014 misc: Include pcu_if.h for pcu_tx_pag_req in rsl.c and make it const
The rsl.c code was calling the paging request with a const pointer,
change the signature to make the code const.
2012-12-20 19:01:27 +01:00
Holger Hans Peter Freyther
8d8ff80890 misc: Forward declare the load_timer_start to address compiler warning 2012-12-20 19:01:27 +01:00
Holger Hans Peter Freyther
6f93861cfc misc: load_ind_period is uint8_t and 60*100 is bigger than that.
Address the compiler warning and truncate the value by hand.
2012-12-20 19:01:27 +01:00
Holger Hans Peter Freyther
6ae49691af sysmobts: Transmit the UI idle frame as a LAPDm Command
When transmitting an idle frame the BTS should transmit it as a
command and not a response. This is unbreaking the mobile application
of osmocomBB.
2012-11-26 01:33:52 +01:00
Harald Welte
2bad1363e9 Add VTY configuration of paging queue size and lifetime of paging records
This may be adding bells and whistles that nobody wants to touch, but at
least for current analysis/optimiziation they are useful to have.  Later
on they should probably be removed again and/or obsoleted by OML
messages for configuration of paging behaviour by the BSC.
2012-11-24 22:28:44 +01:00
Harald Welte
9858a7defe paging: send CCCH load indications even if paging load below threshold
This is mainly as OpenBSC is adjusting the amount of paging commands it
sends based on this magic value 0xffff.
2012-11-24 22:28:44 +01:00
Andreas Eversberg
a57fac59c6 Use tlvp_val16_unal() / tlvp_val32_unal() to align 16 and 32 bit values
This is required for CPUs < armv6, to access 16 and 32 values at right
memory locations.
2012-11-20 11:37:10 +01:00
Harald Welte
36e73dd7ed Ensure osmo-bts builds agsainst sysmobts-v1 headers (again) 2012-11-18 10:38:32 +01:00
Harald Welte
17dd7fad72 VTY: print length/depth of paging queue in 'show bts' 2012-11-10 18:33:12 +01:00
Harald Welte
ce826f3fc4 VTY: make target uplink Rx level VTY-configurable
We used to have -75 dBm as the target value for the uplink receive
level.  Now this is configurable.

The parameter is used as input into the power control loop that adjusts
the MS transmit power in order to achieve the target rx value on the
BTS Rx input.
2012-11-10 18:15:53 +01:00
Harald Welte
7350736054 l1_if: Dump measurement data in case we receive SACCH without data
On the uplink SACCH, we should at least receive the two bytes SACCH
uplink header from the phone.  But sometimes we don't.  Log this more
verbosely.
2012-11-10 18:06:02 +01:00
Harald Welte
fffbfd9890 l1_if: add 'log level' to dump_meas_res() function 2012-11-10 18:04:54 +01:00
Harald Welte
a066e334dd Measurement: Correctly report L1 SACCH uplink header in RSL
For whatever reason, the order of fields in the L1 SACCH header is
different from 04.04 (Um) and 08.58 (A-bis).  Please note that it's not
just a different bit order, but actually logically re-ordering the
fields within the byte, while keeping the bit-order/-endian.

We now correctly report the L1 transmit power up the stack.
2012-11-10 18:02:13 +01:00
Holger Hans Peter Freyther
dd4b8a2507 systemd: Use realtime scheduling for the BTS to read msg queues
We need to read the Layer1 message queues fast enough, switch on
realtime processing for that. Move the firmware init after the
process execution to have some time for the firmware to reload
before the application sysmobts is restarted.
2012-11-02 11:16:21 +01:00
Harald Welte
d1335d878b sysmobts: Add support for reading calibration tables
'trx-calibration-path' is the new VTY command indicating the path
name where the calibration files can be found.

Calibration is only implemented for SUPERFEMTO API version 2.4.0 or
later.
2012-10-28 10:58:41 +01:00
Harald Welte
98a4404279 l1_transp_fw: don't use printf() and dont print things twice 2012-10-28 10:17:42 +01:00
Harald Welte
5705cfaebc properly display the header file versions 2012-10-28 10:01:21 +01:00
Harald Welte
c3646a80a7 sysmobts: Add code to read calibration files
... and convert them to L1 primitives.  The code is not yet used.
2012-10-27 21:44:18 +02:00
Harald Welte
8debeeeeea make it build against sysmobts v2 APO 0.1, 0.2, 1.0, 2.0, 2.1, 2.2, 2.4 and 3.0 2012-10-27 18:06:03 +02:00
Andreas Eversberg
255343db4b Fix: Remove Bad frame Indicator from PDCH blocks before sending via GSMTAP 2012-10-22 10:34:08 +02:00
Harald Welte
4fe622cf9c OML: TA is a 8bit value, not 16bit
... as jolly correctly pointed out.
2012-10-04 18:13:19 +02:00
Andreas Eversberg
4168d885cf Fix: Set correct paging group for IMM.ASS on PCH 2012-09-29 20:32:00 +02:00
Andreas Eversberg
c1ad2ac20f PCU: Add PCH confirm, raise PCU interface version to 4
The confirm is required, so PCU knows when an IMMEDIATE ASSIGN message has
has been sent on PCH. The PCU will start packet flow after that confirm.
2012-09-29 20:31:40 +02:00
Andreas Eversberg
0efca9a1f9 Set correct GSMTAP channel type for PDTCH/PACCH 2012-09-29 20:31:15 +02:00
Holger Hans Peter Freyther
ef2cb5ab7f misc: Disable the color in the default setting
When forwarding the log messages to logger or systemd the ansi
escape sequence can confuse the app collecting the data.
2012-09-20 15:27:35 +02:00
Holger Hans Peter Freyther
4d197c96d8 systemd: Add a service for the sysmobts
Migrate the LED and firmware reloading into a systemd service. This
makes the respawn and screen obsolete as it will be done with systemd
and the journal script.
2012-09-20 15:24:50 +02:00
Holger Hans Peter Freyther
d127ddbfcc sysmobts: Fix the init script for systemd.
The rcS file is not part of the lsb. There is little need to
include this file.
2012-09-13 19:46:18 +02:00
Harald Welte
f91924bb18 sysmobts VTY: update to new libosmocore
libosmocore 40832fcfb58c8c97c66e098c5705352ac5beea8e and later contain
the vty_cmd_string_from_valstr() function, so we shouldn't have
a local / deprecated copy anymore.
2012-08-17 12:40:52 +02:00
Holger Hans Peter Freyther
8c3d807b3f sysmobts: Do not ignore the band configuration of the BTS.
The band was derived from the ARFCN but this does not work for
PCS1900/DCS1800 due overlapping ARFCNs. Use the already existing
band configuration to select the band for the MphInitReq. The
dsp firmware will complain if the band/arfcn do not match.
2012-08-09 12:15:41 +02:00
Andreas Eversberg
7daa093df7 PCU: Removed -P option, so GPRS support is always enabled 2012-07-26 21:14:02 +02:00
Holger Hans Peter Freyther
b86bf060d3 sysmobts: Support older firmware on the RevB hardware
For the firmware used on RevB the GsmL1_Prim_t was bigger than
the femtobts control structure. Solve it by introducing a macro
that will select the biggest size and use this macro. This is a
follow up fix for 08fce19cfc.
2012-07-26 20:18:53 +02:00
Holger Hans Peter Freyther
fde8e6dc0c vty: Remove TS_NODE and LCHAN_NODE as they are not used. 2012-07-25 14:34:22 +02:00
Holger Hans Peter Freyther
a9dee426d7 misc: Ignore some of the auto generated files 2012-07-25 14:16:51 +02:00
Holger Hans Peter Freyther
d777a19bb8 contrib: Add a python script to start sysmobts-remote and dump docs
This starts sysmobts-remote and dumps the documentation about the
VTY to the doc/ directory.

$ ./contrib/dump_docs.py
this writes doc/vty_reference.xml
2012-07-25 14:14:05 +02:00
Holger Hans Peter Freyther
e5a04ea35d vty: Document the gsmtap SAPI and the dsp trace flags parameters
Introduce femtobts_tracef_docs with some more information about
the traceflags, add parameters to the vty_cmd_string_from_valstr
for specifying the separator, the suffix and if the name should
be lowered.
2012-07-25 13:18:28 +02:00
Holger Hans Peter Freyther
1c74191ff0 vty: Document parameters of the unit-id and the band selection 2012-07-25 13:15:34 +02:00
Holger Hans Peter Freyther
93c087892c tests: Use the right name for the struct (not that it matters) 2012-07-25 12:03:52 +02:00
Harald Welte
7c2427c020 l1_if: indicate against which api header files we were compiled 2012-07-22 22:47:06 +02:00
Harald Welte
678321d013 determine (and use) the API version as indicated in the header files
From our header files v2.4 onwards, we include some macros that allow us
to do compile-time checks for the API header version.  As older headers
don't have those macros, we have to fall back to assume it will be v2.2
2012-07-22 22:42:36 +02:00
Harald Welte
e729a3d595 add missing stub functions to ensure paging_test compiles
FIXME: hlayer1 and l1if function calls are not acceptable in src/common !
2012-07-22 22:19:56 +02:00
Andreas Eversberg
1195148fc6 Send RR paging requests to PCU, in order to page on PACCH 2012-07-21 13:19:43 +02:00
Andreas Eversberg
1ddb183736 Enable direct access to PDTCH queue of DSP by PCU
Use "-P -M" to enable PCU and direct access.
2012-07-21 13:18:45 +02:00
Holger Hans Peter Freyther
c2d3e45571 sysmobts: The array size for the clocksources has increased to 10. 2012-07-20 15:30:06 +02:00
Holger Hans Peter Freyther
27baa4c3de sysmobts-calib: Add support for pre-production revb hardware
The board version wasn't exposed in the revb DSP interface.
2012-07-20 15:30:06 +02:00
Holger Hans Peter Freyther
b3eb6da2db misc: Quote the warning to avoid additional warning 2012-07-20 15:30:06 +02:00
Andreas Eversberg
d40d4d6071 Allow L1 forward proxy to provide all 4 queues to seperate applications
Different applications can now connect to L1 forward proxy or access DSP
directly, if they use different message queues.
2012-07-19 20:33:37 +02:00
Andreas Eversberg
08fce19cfc Allocate correct message size for L1 primitives
This is required for using firmware v2.4
2012-07-19 20:29:56 +02:00
Andreas Eversberg
0390d54ade logging: Fixed order of logging categories in enum list
The enum list must have the same order as the logging description
structure. Otherwiese libosmocore will crash when writing loglevels at
VTY.
2012-07-16 18:50:55 +02:00
Andreas Eversberg
0c470759da PCU: Add verion number of PCU interface to PCU INFO IND message
The client (PCU) can check if it is compiled with a different version.
2012-07-16 18:50:26 +02:00
Andreas Eversberg
5a53eff4cb sysmobts L1: fix memory leaks for GPRS
we have to hand off the PH-RTS.ind to the PCU interface _before_
we allocate a response msgb/primitive.
2012-07-16 18:48:55 +02:00
Andreas Eversberg
990d1da8a4 PCU interface: fix memory leaks in error paths 2012-07-16 18:48:37 +02:00
Holger Hans Peter Freyther
65d4d5108a calib: Create a new header file and move it. 2012-07-12 09:08:13 +02:00
Holger Hans Peter Freyther
0cfefa0e12 calib: Add code to change the BSIC/TSC before following the BCCH. 2012-07-12 09:08:13 +02:00
Holger Hans Peter Freyther
4253150bab calib: Use base 16 encoding for the dsp trace flags 2012-07-11 23:14:35 +02:00
Harald Welte
38420fb951 add new sysmobst-mgr daemon
This daemon is taking care of counting the number of hours in operation
and to watch the system temperature as determined by internal
temperature sensors.

Later, it will export an external interface for firmware reload, as well
as a way to raise OML ALARMs in case of temperature issues or other
problems.
2012-07-11 01:32:42 +02:00
Harald Welte
3696c6946d OML: add missing ntohs() for UL/DL_TBF_EXT
Thanks to Andreas for spotting this.
2012-07-11 01:26:32 +02:00
Harald Welte
438a28714d l1_if: skip processing of measurement results on PDTCH
In case of PDTCH, the PCU has to process measurements, not the BTS.
2012-07-09 15:51:42 +02:00
Harald Welte
c1368d4ebe PCU: remove german warnings from the code 2012-07-08 23:53:32 +02:00
Andreas Eversberg
744f745d7a PCU: Add PCU socket interface to BTS.
A special command line option "-P" is used to enable socket interface
and signal available GPRS MO object to BSC.
2012-07-08 20:50:02 +02:00
Andreas Eversberg
8169b0bd85 Add BTS to list at the beginning of bts_init()
During init process, signals might be sent. PCU receives these signals and
requires that BTS instance is already in the list.
2012-07-08 20:20:51 +02:00
Andreas Eversberg
07b37853a4 PCU: Add PCU socket interface prototype header file 2012-07-08 19:59:41 +02:00
Andreas Eversberg
bf2a18e623 debug: Add new debugging class for PCU interface (DPCU) 2012-07-08 19:41:41 +02:00
Andreas Eversberg
66f1fe15e9 signal: Add signals for setting/change of GPRS MO attributes 2012-07-08 19:38:39 +02:00
Andreas Eversberg
07891a0908 paging: Alow to store CCCH messages in paging records
This is required for PCU to send IMMEDIATE ASSIGNMENT messages on PCH.
A message in a paging record is sent only once.
2012-07-08 18:55:45 +02:00
Andreas Eversberg
343cae60b6 lchan: Activate PTCCH/PRACH/PDTCH/PACCH when activating PDCH 2012-07-08 18:48:58 +02:00
Andreas Eversberg
ea15101896 Fixed check for RACH (random access) delay 2012-07-08 18:44:40 +02:00
Andreas Eversberg
b57e17394b Fixes for handling of GPRS NSE/NSVC/CELL MO 2012-07-08 18:03:04 +02:00
Holger Hans Peter Freyther
b19592f713 paging: Update the unit test that would have caused the previous
The unit test created and used the paging request in the same
second and was passing because of that. Add a second test with
a delay to force now to not be equal to the expiration time.
2012-07-05 23:31:18 +02:00
Holger Hans Peter Freyther
cb7697074e paging: Expire paging requests after the expiration time
The paging needs to expire when the expiration time is smaller
than the current time.
2012-07-05 23:15:02 +02:00
Harald Welte
71b216d995 l1_if: don't enable any GSMTAP by default
the user has to explicitly enable it in the VTY
2012-07-05 15:31:06 +02:00
Harald Welte
d53ae2d0f1 sysmobts_vty: Fix setting GSMTAP sapi, as well as save/restore in cfg 2012-07-05 15:31:05 +02:00
Harald Welte
5f8a3149fe sysmobts: avoid sending duplicate RSL CHAN ACT ACK
This is just an intermediary hack, until we get proper lchan manager
threads...
2012-07-05 15:31:05 +02:00
Holger Hans Peter Freyther
eda6c26360 calib: Add a mode to follow the BCCH of a given cell. 2012-07-05 00:17:02 +02:00
Harald Welte
6b561bb7ba Add 12.21 handling for GPRS NSE/NSVC/CELL MO
We now bring the GPRS related MO up in DEPENDENCY state and parse
the various NS, BSSGP and RLC parameters as set by the BSC via 12.21/OML.
2012-06-28 08:59:48 +02:00
Harald Welte
fa8014f181 make sure we don't send CCCH LOAD IND before we have an Abis link 2012-06-21 16:46:05 +02:00
Harald Welte
61fb64d252 rsl: use correct headroom size for load indications 2012-06-18 22:17:28 +08:00
Harald Welte
54b8af0f64 use default value of 63 for maximum timing advance
As the careful commitlog reader Andreas points out:  When the BSC does
not sent NM_ATT_MAX_TA, then it would be zero instead of the specified
default value of 63.
2012-06-15 23:24:55 +08:00
Holger Hans Peter Freyther
9fdefc6ffe respawn: The BTS should not be nice, make sure the BTS is the most favorable 2012-06-15 14:53:15 +02:00
Harald Welte
13e92be8bf Implement NM_ATT_MAX_TA in sysmobts backend 2012-06-15 14:54:33 +08:00
Harald Welte
e01a47aad4 Update README and reflect that we now have CCCH LOAD IND 2012-06-15 11:17:15 +08:00
Harald Welte
babbbbf6ee CCCH LOAD IND: Avoid divide-by-zero
The total count of RACH or PCH slots should never be zero, as they
constantly increment.  However, just as a safeguard, we introduce
an explicit handign to avoid divide-by-zero situations
2012-06-15 11:15:11 +08:00
Harald Welte
821bf067e4 RSL: Add CCCH LOAD INDICATION for RACH
We now count the total number of RACH slots, the number with rx level
above the busy threshold, and the number of valid access bursts.

This data is used to generate RSL CCCH LOAD INDICATION for the RACH.
2012-06-15 11:07:03 +08:00
Harald Welte
c882b85d8c system information: avoid modulo 0 / SIGFPE
As Holger pointed out, it may well be the case that there are no system
information messages to be sent at TC=4, and we should avoid a modulo by
0.  I'm simply sending SI2 instead now, as it isn't forbidden to send it
more often than the minimum at TC=2...
2012-06-14 11:51:16 +08:00
Harald Welte
565cf0d8ab attempt to make CCCH Load Indications for PCH work 2012-06-14 11:48:24 +08:00
Holger Hans Peter Freyther
a540332df3 sysmobts-calib: Add a utility to calibrate the sysmobts v2 hardware
It has been tested with the OCXO and the network listen mode of the
firmware. For other sources we are not required to synchronize to
the network and the tool needs to be adjusted.
2012-06-12 18:17:11 +02:00
Holger Hans Peter Freyther
ad3e31dc4b sysmobts: The meaning of the clock value changed from v1 to v2
In v2 the calibration value is the clock error in ppb that needs
to be compensated. Create a V2 specific implementation. Write the
clock value unconditionally as it is initialized to 0 by default
and not 0xffff.
2012-06-05 09:34:33 +02:00
Holger Hans Peter Freyther
1c069cd0a0 sysmobts-v1: Fix compilation by using the right define 2012-06-05 09:17:26 +02:00
Harald Welte
0455e51cd5 Use git-generated PACKAGE_VERSION in IPA IDTAG_SWVERSION
We previously used to send the bogus string "0815" which was a hack
from early development time, but is obviously not a generally useful
idea.
2012-06-03 11:47:42 +02:00
Harald Welte
ad09615acb add known limitations 2012-06-03 11:01:31 +02:00
Harald Welte
2100a2e16f sysinfo: Make our SI scheduling more complete
We now implement the fairly complex rules for schedulign of
SI 2bis/2ter/2quater, 13 and 9 on TC=4 and TC=5 of the BCCH Norm.

The patch is currently untested.
2012-06-03 07:37:52 +02:00
Harald Welte
c58968be02 sysinfo: Schedule SI 2bis and 2ter
In case we have neighbor cells in different bands, we should send those
SI...
2012-06-02 22:20:58 +02:00
Harald Welte
799ea59c2f sysmobts: set the RF ACTIVE LED when we bring RF up
Once we get RF-ACTIVATE.conf from L1, we now enable the corresponding
LED.  We also switch it off on RF-DEACTIVATE.conf.  We do _not_ switch
it off when osmo-bts crashes or terminates before RF-DEACTIVATE.conf.

The latter is intentional, as RF may very well still be active at that
point.  The re-spawning script will re-set the DSP and therby turn off
the RF and then disable the LED.

A better solution might be to do all this in the kernel driver for the
DSP.
2012-06-01 00:06:58 +02:00
Harald Welte
700c645478 add /var/lock/bts_rf_lock and /var/run/osmo-bts.pid for rf control
an external application can create /var/lock/bts_rf_lock and then kill
the pid in /var/run/osmo-bts.pid in order to shut down the BTS.  Any
re-spawning scripts will trigger, but osmo-bts will refuse to start up
until /var/lock/bts_rf_lock is removed again.
2012-05-31 21:02:18 +02:00
Harald Welte
346e531222 sysmobts: fix double-free if msgq cannot be opened 2012-05-31 20:58:57 +02:00
Holger Hans Peter Freyther
b18f00f162 contrib: Re-load the firmware before restarting the main application
More recent firmware appears to have issues even after a clean shutdown,
make sure to fully reset the DSP before starting the BTS software.
2012-05-14 22:29:45 +02:00
Harald Welte
268c7f02fd sysmobts l1: make sure to read messages of arbitrary size
... and warn if the size is not what we expect.

This is required to work with sysmobts-v2 firmware >= v2.1, as the
SuperFemto_Prim_t is now larger than the GsmL1_Prim_t.
2012-05-13 15:25:27 +02:00
Harald Welte
388b9d0a35 Adapt to L1 firmware/API version 2.1 2012-05-13 14:16:28 +02:00
Holger Hans Peter Freyther
9de1e9f914 sysmobts: Document the values of the clock-source in the vty command
We need to have a documentation for each possible value, add some simple
ones for the available clock sources.
2012-05-12 08:49:35 +02:00
Holger Hans Peter Freyther
7fe0838588 sysmobts: Save the clock-source to the config file
Make the clock names lower case to match with the vty command.
2012-05-12 08:49:35 +02:00
Holger Hans Peter Freyther
3af5426d71 sysmobts: Add Network Listen as clock source for the bts 2012-05-12 08:49:35 +02:00
Harald Welte
e6ed814dc3 update the readme 2012-05-05 14:44:29 +02:00
Holger Hans Peter Freyther
f7fd2e4798 sysmo-bts: Use HW_SYSMOBTS_V1 to select the development hardware 2012-04-28 17:05:03 +02:00
Holger Hans Peter Freyther
36a3b0d85b sysmo-bts: Move the payload setting into a new method
Make this code a bit easier to read by moving the payload setting
into a new method.
2012-04-28 17:04:56 +02:00
Harald Welte
36179bbcdf RSL / SI: Make sure to have correct LAPDm header in SI5/SI6 on SACCH
SI5/SI6 and other messages on SACCH need the C/R and the EA bit set in
the LAPDm header.  Most devices accept a broken header, but especially
the Wavecom Q2686 responds with tons of RR STATUS messages if there is
any invalid bit.
2012-04-27 15:12:46 +02:00
Harald Welte
227c57728a fix the idle filling to comply with 04.06 5.4.2.3 (UI frame 0 byte len)
We used to send some crap before, which most phones happily accepted but
some (particularly the Wavecom Q2686) didn't really like at all.
2012-04-26 21:00:18 +02:00
Holger Hans Peter Freyther
baa88d542c lchan: I forgot to handle TchH in my recent lchan fixes, add it to another place
Harald fixed the issue for the activation by adding TchH, but this
needs to be added for de-activation as well.
2012-04-20 10:44:43 +02:00
Harald Welte
d28b9940b9 sach_deact -> sacch_deact (follow spelling fix in openbsc) 2012-04-19 23:51:50 +02:00
Harald Welte
2b7aace0b5 add vty-configurable loopback mode
this allows the BTS to loop-back any incoming data on a TCH
2012-04-19 22:29:07 +02:00
Harald Welte
b1644b22d0 Fix TCH/H channel activation after zecke's recent lchan fixes 2012-04-19 22:27:55 +02:00
Harald Welte
bcd08888f9 add VTY command to manually alter transmit power
this allows for quick manual tx power changes from the VTY, particularly
useful in type approval or other measurements.
2012-04-19 20:19:21 +02:00
Harald Welte
9aa6d9496b l1_if: allow for l1prim or sysprim without a completion callback 2012-04-19 20:18:53 +02:00
Harald Welte
ff9e904926 fix VTY help strings related to TRX 2012-04-19 19:47:55 +02:00
Harald Welte
f19ee66096 add a VTY command for activating PDCH channels (in EGPRS mode)
This allows us to do RF measurements (EDGE EVM and the like) even
without having any PCU/RLC/MAC code as of now.

To use it, configure PDCH type timeslots (e.g. TS 7) in the BSC and then
use "trx 0 7 activate 0" to manually activate the PDTCH lchan on top
of that timeslot.  The BTS will now happily transmit EDGE/8PSK data.
2012-04-19 19:22:53 +02:00
Harald Welte
4301b09137 delete dead code 2012-04-19 17:22:38 +02:00
Harald Welte
f5a0a439e9 ciphering: Make sure to initialize lchan to no ciphering when activating
The ciphering parameters in L1 are persistent accross MPH
deactivate/activate, so we need to make sure to always initialize them
cleanly at RSL CHAN ACT time.  This has the added benefit that we can
also activate channels that have encryption enabled from the very
beginning (required for encrypted handover).
2012-04-19 10:06:00 +02:00
Harald Welte
bf91f06eca Improve logging of L1 MPH request by printing the direction
where previously we would only see
<0006> oml.c:931 (bts=0,trx=0,ts=1,ss=0) MPH-DEACTIVATE.req (FACCH/F)
we now get
<0006> oml.c:931 (bts=0,trx=0,ts=1,ss=0) MPH-DEACTIVATE.req (FACCH/F RxUL)

to notice it is modifying the receive path in the uplink direction.
2012-04-19 09:50:02 +02:00
Holger Hans Peter Freyther
b0150b7ad4 lchan: Refuse to activate a non-idle lchan. 2012-04-19 09:39:54 +02:00
Holger Hans Peter Freyther
d7718280c9 lchan: Send the ACT ACK/NACK after the Layer1 has handled act/deact
Send the RSL ACT ACK/NACK after the Layer1 firmware has acked the
activation/deactivation. In case the channel can not be activated
we will send a NACK. In case the channel can not be deactivated we
will send an ACK and the next time the channel is activated we will
send a NACK. The release ack will be sent once the TxDownlink of the
TCH/SDCCH is closed.

Change the rsl_tx_chan_nack method to create a new msgb to be used
by the hardware layer, change the return value to ask the caller to
delete the msgb.
2012-04-19 09:39:54 +02:00
Holger Hans Peter Freyther
1e2b3259b9 lchan: Separate the Uplink/Downlink in activate/deactivate 2012-04-19 09:39:53 +02:00
Holger Hans Peter Freyther
29e1fdd994 lchan: Deactivate the SACCH only once, use the sach_deact flag for that
Use the deact_sach (renamed to deact_sacch in master) to remember if the
SACCH has been disabled. This should fix the case of lchan errors due releasing
the lchan twice.
2012-04-19 09:39:52 +02:00
Holger Hans Peter Freyther
af02387183 lchan: rsl_tx_chan_nack will re-use the msgb, do not msgb_free
Do not msgb_free the msg as it will be re-used inside the nack
method and return 1 so the caller does not free the msgb. This
ownership model needs some consideration but the usage of ref
counts will not yield good results.
2012-04-19 09:39:52 +02:00
Holger Hans Peter Freyther
f78f35880f lchan: Fix crashes when the specified lchan can not be found
gsm_lchan_name will crash if the lchan is NULL. Introduce an error_report
method that will do the right thing in the future and report the error.
2012-04-19 09:39:51 +02:00
Holger Hans Peter Freyther
eac221b4ea lchan: Fix the state transition in the deactivate handler
If the deactivation is failing the channel needs to be moved into
and error state, if the deactivation completed the channel needs to
be set to the none state and set the state to release reqeust on
the deactivation.
2012-04-19 09:39:51 +02:00
Holger Hans Peter Freyther
f4f69ee6fc lchan: Similar to OpenBSC use a set method to change the state
By making all modifications through lchan_set_state we can easily
add code to verify the state transition.
2012-04-19 09:39:15 +02:00
Holger Hans Peter Freyther
f1052b812d sysmobts: Add an option to query the hardware version. 2012-04-19 09:38:30 +02:00
Holger Hans Peter Freyther
0be33e3add common: Add the copyright text to the vty_app_info
This will make app -V print the copyright information like the other
applications of our universe. An BTS integration that want to list
additionaly copyright holders needs to access the vty_app_info and create
a new copyright string.
2012-04-19 09:38:30 +02:00
Harald Welte
b03f8ae4f0 ciphering: Better state tracking and HACK around L1 race condition
We now check if the received message is an LAPDm I frame in order to
determine if we have received the first valid encrypted message on the
radio link.  This relates to the fact that we often see 'old' UI frames
coming up from L1, even after it has confirmed decryption has been
enabled.
2012-04-19 09:35:03 +02:00
Harald Welte
d9ab45d1aa Support for ciphering
When the RR CIPH MODE CMD is transmitted to the MS, we need to tell the
L1 to enable decryption on RX.  After the first received frame has been
decrypted successfully, we will enable encryption also on transmit.

This has been tested with A5/1 so far, but A5/2 and A5/3 should work
exactly identical.
2012-04-19 08:22:29 +02:00
Harald Welte
51f9693ba6 make HR channels work for voice, not only signalling
without this, we would set a FR_V1 codec on a TCH/H channel, which
the L1 is obviously not happy with.
2012-04-19 08:21:41 +02:00
Harald Welte
b34faf6f8c TCH: Add support for the L1 RTP mode
In L1 RTP mode, the L1 already does all the bit-shifting and re-ordering
required for the RTP formats (which have different bit/nibble order than
the ETSI/3GPP encodings, for some odd reason).

We don't enable it by default yet, as only HR/FR/EFR work with it, but
AMR has some yet to be debugged problem.

Enabling USE_L1_RTP_MODE would save some CPU cycles on the ARM side.
2012-04-18 20:03:18 +02:00
Holger Hans Peter Freyther
bc74b7f432 femtobts: The separate pdch/tch queues are not available in the old firmware
The old firmware does not expose separate queues for PDCH and TCH. The change
appears to be too intrusive and I will try to find a more elegant solution.
2012-04-14 14:56:58 +02:00
Holger Hans Peter Freyther
f4a5bd2dd2 sysmobts: Handle options before allocating the bts
This way -h/--version will always work, even when the underlying
hardware is not available.
2012-04-14 14:36:23 +02:00
Holger Hans Peter Freyther
58f419c7ce misc: Use sizeof(uint32_t) instead of simply using 32 bit
This code would break in case we shrink the bitmap, use sizeof instead.
2012-04-14 01:03:28 +02:00
Holger Hans Peter Freyther
11a787df24 femtobts: Use HW_FEMTOBTS instead of HW_VERSION_1 to select femtobts
Our header files use HW_FEMTOBTS guards to select the older femtobts
design. Use the same macro in the bts code.
2012-04-14 00:54:40 +02:00
Holger Hans Peter Freyther
caaa7e9d7b misc: Address a compiler warning and add an assert to a branch
The compiler can not know that the "int priv_nr" will hold the
enum values of the write queue, add a default branch and add a
warning and an assert there.

l1_transp_hw.c:108:1: warning: control reaches end of non-void function [-Wreturn-type]
2012-04-12 22:31:06 +02:00
Holger Hans Peter Freyther
666fec7ff2 misc: Fix compiler warning about printing a ptrdiff
Use 't' modifier for pointer diff in the printf statement.

oml.c: In function ‘oml_rx_set_bts_attr’:
oml.c:403:3: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 9 has type ‘int’ [-Wformat]
2012-04-12 21:54:48 +02:00
Holger Hans Peter Freyther
76aa95453f misc: Fix compiler warning of the femtobts_clksrc_names
femtobts.c:249:2: warning: excess elements in array initializer [enabled by default]
femtobts.c:249:2: warning: (near initialization for ‘femtobts_clksrc_names’) [enabled by default]
2012-04-12 21:52:22 +02:00
Harald Welte
c623c4e589 oml: temporary debug hack 2012-04-05 02:48:16 +02:00
Harald Welte
2ed209c758 Increase head-room in IPA messages received
Without that headroom, I ran into an abort due to insufficient headroom
in the LAPDm code.
2012-04-05 01:16:46 +02:00
Harald Welte
a0970249bf osmo-bts-sysmo: Add gsmtap for uplink 2012-04-05 00:41:35 +02:00
Harald Welte
f4d14b3f2e set the default log mask for the L1 a bit more reasonable 2012-03-18 23:27:27 +01:00
Harald Welte
d25b6a752b osmo-bts-sysmo: Add GSMTAP support for transmit (DL) path
there are VTY commands that can be used to filter which particular
L1 sapis (channel types) should be sent in GSMTAP.
2012-03-18 23:24:12 +01:00
Harald Welte
3cf942792a correctly print SAPI in log file on MPH-ACTIVATE.req 2012-03-18 21:46:44 +01:00
Harald Welte
21724bbaed Fix debug print of MPH-CONFIG.req 2012-03-18 21:35:15 +01:00
Harald Welte
12b95405ff print human-readable SAPI name on MPH-[DE]ACT.{req,conf} 2012-03-18 21:34:05 +01:00
Harald Welte
452112e823 Ensure that ADM_STATE IE is presnent when sending NM_MT_CHG_ADM_STATE_ACK 2012-03-18 21:25:45 +01:00
Harald Welte
d0e6749327 Issue MPH-CLOSE.req during shutdown
If we don't do this on recent L1, the L1 will refuse the open after
re-starting osmo-bts.

There still is an issue in case osmo-bts crashes.  We should have a
respawn loop that re-loads the DSP firmware before re-starting osmo-bts,
just to make sure...
2012-03-17 14:25:34 +01:00
Harald Welte
b81c5d4699 introduce a command that permits setting the clock source via vty
the default source is the OCXO
2012-03-17 14:08:51 +01:00
Harald Welte
fe0c13f8bd OML: when allocating merged tlvp arrays for MO, use bts context
'ts' is not a talloc-managed pointer but an offset into the bts
structure.  As such, we cannot pass it to talloc as context!
2012-03-15 23:39:53 +01:00
Harald Welte
3525f2c038 we currently run the board alwasy in clock master mode 2012-03-15 23:39:37 +01:00
Harald Welte
20d73555a2 update to new "superfemto.h" header file naming 2012-03-15 21:27:21 +01:00
Harald Welte
47589f10a4 Introduce a HW_VERSION_1 #define
This #define helps us to distinguish the subtle API differences between
the earlier v1 (2011) hardware and the later v2 (2012) model.
2012-03-07 18:05:57 +01:00
Harald Welte
f1cbd81984 prepare for splitting L1 queue into signalling/tch/pdtch
We don't use multiple queues yet, but we very well might end up using
them soon.
2012-03-07 18:05:18 +01:00
Harald Welte
818cb2d314 update config file to parse correctly 2012-02-10 13:32:58 +01:00
Holger Hans Peter Freyther
6dd7c4fb57 misc: Check return value of msgb _alloc functions
Attempt to catch all functions that allocate a msgb and didn't
check the return value of the allocation.
2012-01-23 10:22:09 +01:00
Holger Hans Peter Freyther
bb9647f651 ipa: Send the DLCX Indication with the right message discriminator
The IPA messages for RTP should use the IPA vendor as message
discriminator.
2012-01-15 18:09:40 +01:00
Holger Hans Peter Freyther
2e677958d2 efr: Add efr to the femtobts_tch_pl_names array
Parts of the code check if GsmL1_TchPlType_Efr is defined, others
parts don't. Follow the easy route and assume it is defined.
2012-01-14 21:47:59 +01:00
Holger Hans Peter Freyther
771e77dff0 oml: Use talloc_free(ptr) instead of talloc_free(ptr_to_ptr)
tp_merged points to memory allocated by talloc_zero, no need to
hand the address of that to talloc itself.
2012-01-14 21:47:49 +01:00
Holger Hans Peter Freyther
62579c7a34 oml: Mention the SAPI that is activated in the log message
I was wondering why the channel was activated twice but it needs
to be activated for each SAPI.
2012-01-14 21:47:41 +01:00
Holger Hans Peter Freyther
4cd68dc4d7 bts: Use msgb_dequeue and msgb_enqueue for the AGCH queue
The TODO item still applies to somehow limit the queue of incoming
messages and drop older ones first. A sane limit would be the number
of channels (+ or * 2).
2012-01-14 21:47:30 +01:00
Holger Hans Peter Freyther
eab71534ef sysmo: handle_ph_data_ind has paths rc is not initialized
rc might not be initialized when going through the default
statement but also hitting a break inside the switch case
statement for GsmL1_Sapi_Sacch.

l1_if.c:530:2: warning: Undefined or garbage value returned to caller
        return rc;
2012-01-14 21:47:19 +01:00
Harald Welte
6e121417a5 RSL: fix typo in comment 2012-01-14 12:35:40 +01:00
Harald Welte
7a44e47ed6 OML SET CHAN ATTR: merge TS attributes (not BTS) and fix mem leak
We have to
 * merge the new attributes with the exiting TS (not BTS) attributes
 * in case of success, attach the new merged attributes to our state
 * in case of success, free the old attributes

Thanks to Holger for pointing this out.
2012-01-14 12:28:17 +01:00
Holger Hans Peter Freyther
6aa2a574fb sysmo-bts: The code is not used (and built), remove it.
The BTS is using the LAPDm code in polling mode, there will be no
callbacks (e.g. a BTS does not transmit RACH bursts). Remove the code.
2012-01-11 19:27:54 +01:00
Holger Hans Peter Freyther
fd58d925a8 bts.h: lchan_init_lapdm is listed twice, remove one 2011-12-11 12:57:36 +01:00
Holger Hans Peter Freyther
b0985e3fa5 test: Introduce a very simple test for the paging subsystem
Check that adding a paging command works, check that it is expired
after the first call to paging_gen_msg. The test will be extended
to test the scheduling and selection of the various paging messages.
2011-12-01 09:14:32 +01:00
Holger Hans Peter Freyther
467e149763 paging: Provide functions to check the internal state of the paging system 2011-12-01 09:09:18 +01:00
Holger Hans Peter Freyther
127ec05b4e paging: Do not crash if we get called for the wrong frame/t1/t2/t3
If someone wants to have paging for a wrong frame, gracefully return
and do not fill the output buffer. Because we are on the wrong frame
I think it is best to not fill the frame, this is why I did not add a
check to l1_if.c to generate an empty frame.
2011-12-01 08:47:53 +01:00
Holger Hans Peter Freyther
79da6f3283 misc: Move the cmr_index into the #if 0 block as it is only used there 2011-11-29 21:55:12 +01:00
Harald Welte
143bb812dc LAPDm: Use lapdm_channel_exit() and avoid copy+paste bug
We have to either lapdm_exit() both DCCH and ACCH (not 2x ACCH) or
rather call lapdm_channel_exit() which does that for us.

Thanks to Holger Freyther for spotting this bug.
2011-11-29 12:15:16 +01:00
Harald Welte
fe4893e625 RSL: Actually check if BSC-requested cipher is supported 2011-11-24 17:46:22 +01:00
Holger Hans Peter Freyther
2660812084 audio: Make bts_model_rtp_rx_cb compatible with the prototype 2011-11-07 14:26:48 +01:00
Holger Hans Peter Freyther
5cdcf8a837 sysmo-bts: Include bts.h for bts_shutdown, remove unused variable 2011-11-07 14:13:29 +01:00
Holger Hans Peter Freyther
efdb45d5d0 common: Include bts.h for bts_shutdown 2011-11-07 14:09:53 +01:00
Holger Hans Peter Freyther
477f35e78c sysmo-bts: Use the z modifier to print the result of sizeof 2011-11-07 14:08:46 +01:00
Holger Hans Peter Freyther
187871e2ca sysmobts-vty: Fix compiler warnings about the clock value
The first one just sets the val to 0xffff, the second converted
the value to integer twice.

sysmobts_vty.c: In function ‘cfg_trx_clkcal_def’:
sysmobts_vty.c:109:15: warning: unused variable ‘clkcal’ [-Wunused-variable]
sysmobts_vty.c: In function ‘cfg_trx_clkcal’:
sysmobts_vty.c:122:15: warning: unused variable ‘clkcal’ [-Wunused-variable]
2011-11-07 14:02:02 +01:00
Holger Hans Peter Freyther
b10d74d821 config: Rename llapdm -> llapd in the example configuration 2011-11-07 13:48:02 +01:00
Harald Welte
9582883235 add VTY based way to set clock calibration of sysmobts L1 2011-10-12 13:36:22 +02:00
Harald Welte
c373448e03 fix various compiler warnings across the code
this deals with unused cocde, unused variables and undeclared symbols in
various places.
2011-09-19 20:46:51 +02:00
Harald Welte
7899dc5fcf sysmobts: fix initial codec mode computation
There is no off-by-one between osmocom and L1 definitions...
2011-09-09 23:55:39 +02:00
Harald Welte
215d9eecdd sysmobts: channel activation changes for v2.4 L1 DSP firmware
We now have to explicitly indicate the tchPlType at channel activation
type, so L1 knows which channel decoder to use (FR, EFR, AMR, ...)

Also, we properly implement the initial codec mode selection as per TS
05.09
2011-09-09 23:30:46 +02:00
Harald Welte
06636b6155 AMR: change definition of amr_get_initial_mode() return value
AMR: return AMR_CODEC_MODE (0..3) instead of full range
2011-09-09 23:29:27 +02:00
Harald Welte
9508fb80a4 Introduce new amr.[ch] for AMR related functions 2011-09-09 22:32:45 +02:00
Harald Welte
4ccca1ce36 OML: make sure max_power_red is scaled by 2 to convert from 12.21 to dBm 2011-09-09 22:04:09 +02:00
Harald Welte
a4a3574b1d update osmo-bts to conform to L1 v2.4 API changes 2011-09-09 15:12:52 +02:00
Harald Welte
2c40d02f27 Inquire DSP/FPGA version at BTS boot and check band compatibility 2011-09-09 14:10:57 +02:00
Harald Welte
16c0ab92c1 add commands to configure RTP jitter buffer
there's one global setting for the BTS default value, plus an
interactive command to change the buffer of an active lchan on the fly
2011-09-08 15:21:39 +02:00
261 changed files with 55789 additions and 3548 deletions

58
.gitignore vendored
View File

@@ -4,17 +4,71 @@ Makefile.in
Makefile
.deps
btsconfig.h
btsconfig.h.in
aclocal.m4
autom4te.cache
config.log
config.status
config.guess
config.sub
configure
compile
depcomp
install-sh
missing
stamp-h1
core
core.*
contrib/sysmobts-calib/sysmobts-calib
src/osmo-bts-sysmo/l1fwd-proxy
src/osmo-bts-sysmo/sysmobts
src/osmo-bts-sysmo/sysmobts-remote
src/osmo-bts-sysmo/osmo-bts-sysmo
src/osmo-bts-sysmo/osmo-bts-sysmo-remote
src/osmo-bts-sysmo/sysmobts-mgr
src/osmo-bts-sysmo/sysmobts-util
src/osmo-bts-litecell15/lc15bts-mgr
src/osmo-bts-litecell15/lc15bts-util
src/osmo-bts-litecell15/misc/.dirstamp
src/osmo-bts-litecell15/osmo-bts-lc15
src/osmo-bts-trx/osmo-bts-trx
src/osmo-bts-octphy/osmo-bts-octphy
src/osmo-bts-virtual/osmo-bts-virtual
tests/atconfig
tests/package.m4
tests/agch/agch_test
tests/paging/paging_test
tests/cipher/cipher_test
tests/sysmobts/sysmobts_test
tests/misc/misc_test
tests/handover/handover_test
tests/tx_power/tx_power_test
tests/testsuite
tests/testsuite.log
# Possible generated file
doc/vty_reference.xml
# Backups, vi, merges
*~
*.sw?
*.orig
*.sav
# debian
.tarball-version
debian/autoreconf.after
debian/autoreconf.before
debian/files
debian/*.debhelper.log
debian/*.substvars
debian/osmo-bts-trx-dbg/
debian/osmo-bts-trx/
debian/tmp/

3
.gitreview Normal file
View File

@@ -0,0 +1,3 @@
[gerrit]
host=gerrit.osmocom.org
project=osmo-bts

12
.mailmap Normal file
View File

@@ -0,0 +1,12 @@
Harald Welte <laforge@gnumonks.org>
Harald Welte <laforge@gnumonks.org> <laflocal@hanuman.gnumonks.org>
Harald Welte <laforge@gnumonks.org> <laflocal@goeller.de.gnumonks.org>
Holger Hans Peter Freyther <holger@moiji-mobile.com> <zecke@selfish.org>
Holger Hans Peter Freyther <holger@moiji-mobile.com> <ich@tamarin.(none)>
Holger Hans Peter Freyther <holgre@moiji-mobile.com> <holger@freyther.de>
Andreas Eversberg <jolly@eversberg.eu>
Andreas Eversberg <jolly@eversberg.eu> <Andreas.Eversberg@versatel.de>
Andreas Eversberg <jolly@eversberg.eu> <root@nuedel.(none)>
Pablo Neira Ayuso <pablo@soleta.eu> <pablo@gnumonks.org>
Max Suraev <msuraev@sysmocom.de>
Tom Tsou <tom.tsou@ettus.com> <tom@tsou.cc>

View File

@@ -1,3 +1,28 @@
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
SUBDIRS = include src
SUBDIRS = include src tests
# package the contrib and doc
EXTRA_DIST = \
contrib/dump_docs.py contrib/screenrc-l1fwd contrib/osmo-bts-sysmo.service \
contrib/l1fwd.init contrib/screenrc-sysmobts contrib/respawn.sh \
contrib/sysmobts.init contrib/sysmobts-calib/Makefile \
contrib/sysmobts-calib/sysmobts-calib.c \
contrib/sysmobts-calib/sysmobts-layer1.c \
contrib/sysmobts-calib/sysmobts-layer1.h \
doc/examples/sysmo/osmo-bts.cfg \
doc/examples/sysmo/sysmobts-mgr.cfg \
doc/examples/virtual/openbsc-virtual.cfg \
doc/examples/virtual/osmobts-virtual.cfg \
git-version-gen .version \
README.md
@RELMAKE@
BUILT_SOURCES = $(top_srcdir)/.version
$(top_srcdir)/.version:
echo $(VERSION) > $@-t && mv $@-t $@
dist-hook:
echo $(VERSION) > $(distdir)/.tarball-version

10
README
View File

@@ -1,10 +0,0 @@
Repsoitory for new BTS-side A-bis code
This is the code that was originally developed inside osmocom-bb.git
for turning modified OsmocomBB-supported phones into a simplistic BTS.
However, the BTS-side A-bis is also going to be needed for other projects, thus
the split.
It doesn't really build yet, as a lot of dependencies have not yet been
resolved.

127
README.md Normal file
View File

@@ -0,0 +1,127 @@
osmo-bts - Osmocom BTS Implementation
====================================
This repository contains a C-language implementation of a GSM Base
Transceiver Station (BTS). It is part of the
[Osmocom](https://osmocom.org/) Open Source Mobile Communications
project.
This code implements Layer 2 and higher of a more or less conventional GSM BTS
(Base Transceiver Station) - however, using an Abis/IP interface, rather than
the old-fashioned E1/T1.
Specifically, this includes
* BTS-side implementation of TS 08.58 (RSL) and TS 12.21 (OML)
* BTS-side implementation of LAPDm (using libosmocore/libosmogsm)
* A somewhat separated interface between those higher layer parts and the
Layer1 interface.
Several kinds of BTS hardware are supported:
* sysmocom sysmoBTS
* Octasic octphy
* Nutaq litecell 1.5
* software-defined radio based osmo-bts-trx (e.g. USRP B210, UmTRX)
Homepage
--------
The official homepage of the project is
https://osmocom.org/projects/osmobts/wiki
GIT Repository
--------------
You can clone from the official osmo-bts.git repository using
git clone git://git.osmocom.org/osmo-bts.git
There is a cgit interface at http://git.osmocom.org/osmo-bts/
Documentation
-------------
We provide a
[User Manual](http://ftp.osmocom.org/docs/latest/osmobts-usermanual.pdf)
as well as a
[VTY Reference Manual](http://ftp.osmocom.org/docs/latest/osmobsc-vty-reference.pdf)
and a
[Abis refrence MAnual](http://ftp.osmocom.org/docs/latest/osmobts-abis.pdf)
describing the OsmoBTS specific A-bis dialect.
Mailing List
------------
Discussions related to osmo-bts are happening on the
openbsc@lists.osmocom.org mailing list, please see
https://lists.osmocom.org/mailman/listinfo/openbsc for subscription
options and the list archive.
Please observe the [Osmocom Mailing List
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
when posting.
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
contributions. Please see
https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit for
more details
The current patch queue for osmo-bts can be seen at
https://gerrit.osmocom.org/#/q/project:osmo-bts+status:open
Known Limitations
=================
As of March 17, 2017, the following known limitations exist in this
implementation:
Common Core
-----------
* No Extended BCCH support
* System Information limited to 1,2,2bis,2ter,2quater,3,4,5,6,9,13
* No RATSCCH in AMR
* Will reject TS 12.21 STARTING TIME in SET BTS ATTR / SET CHAN ATTR
* No support for frequency hopping
* No reporting of interference levels as part of TS 08.58 RF RES IND
* No error reporting in case PAGING COMMAND fails due to queue overflow
* No use of TS 08.58 BS Power and MS Power parameters
* No support of TS 08.58 MultiRate Control
* No support of TS 08.58 Supported Codec Types
* No support of Bter frame / ENHANCED MEASUREMENT REPORT
osmo-bts-sysmo
--------------
* No CSD / ECSD support (not planned)
* GSM-R frequency band supported, but no NCH/ASCI/SoLSA
* All timeslots on one TRX have to use same training sequence (TSC)
* No multi-TRX support yet, though hardware+L1 support stacking
* Makes no use of 12.21 Intave Parameters and Interference
Level Boundaries
* MphConfig.CNF can be returned to the wrong callback. E.g. with Tx Power
and ciphering. The dispatch should take a look at the hLayer3.
osmo-bts-octphy
---------------
* No support of EFR, HR voice codec (lack of PHY support?)
* No re-transmission of PHY primitives in case of time-out
* Link Quality / Measurement processing incomplete
* impossible to modify encryption parameters using RSL MODE MODIFY
* no clear indication of nominal transmit power, various power related
computations are likely off
* no OML attribute validation during bts_model_check_oml()
osmo-bts-trx
------------
* TCH/F_PDCH cannel not working as voice (https://osmocom.org/issues/1865)
* No BER value delivered to OsmoPCU (https://osmocom.org/issues/1855)
* No 11bit RACH support (https://osmocom.org/issues/1854)
* No CBCH support (https://osmocom.org/issues/1617)

View File

@@ -3,17 +3,32 @@ AC_INIT([osmo-bts],
m4_esyscmd([./git-version-gen .tarball-version]),
[openbsc-devel@lists.openbsc.org])
dnl *This* is the root dir, even if an install-sh exists in ../ or ../../
AC_CONFIG_AUX_DIR([.])
AM_INIT_AUTOMAKE([dist-bzip2])
AC_CONFIG_TESTDIR(tests)
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl include release helper
RELMAKE='-include osmo-release.mk'
AC_SUBST([RELMAKE])
dnl checks for programs
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_RANLIB
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
AC_MSG_WARN([You need to install pkg-config])
fi
PKG_PROG_PKG_CONFIG([0.20])
dnl checks for header files
AC_HEADER_STDC
@@ -22,22 +37,162 @@ dnl Checks for typedefs, structures and compiler characteristics
dnl checks for libraries
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.9)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty)
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 0.0.7)
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 0.3.2)
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.3.3)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl)
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis)
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec)
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding)
PKG_CHECK_MODULES(ORTP, ortp)
AC_MSG_CHECKING([whether to enable sysmocom-bts hardware support])
AC_MSG_CHECKING([whether to enable support for sysmoBTS L1/PHY support])
AC_ARG_ENABLE(sysmocom-bts,
AC_HELP_STRING([--enable-sysmocom-bts],
[enable code for sysmocom femto-bts [default=no]]),
[enable code for sysmoBTS L1/PHY [default=no]]),
[enable_sysmocom_bts="yes"],[enable_sysmocom_bts="no"])
AC_MSG_RESULT([$enable_sysmocom_bts])
AM_CONDITIONAL(ENABLE_SYSMOBTS, test "x$enable_sysmocom_bts" = "xyes")
if test "$enable_sysmocom_bts" = "yes"; then
PKG_CHECK_MODULES(LIBGPS, libgps)
fi
AC_MSG_CHECKING([whether to enable support for osmo-trx based L1/PHY support])
AC_ARG_ENABLE(trx,
AC_HELP_STRING([--enable-trx],
[enable code for osmo-trx L1/PHY [default=no]]),
[enable_trx="yes"],[enable_trx="no"])
AC_MSG_RESULT([$enable_trx])
AM_CONDITIONAL(ENABLE_TRX, test "x$enable_trx" = "xyes")
AC_MSG_CHECKING([whether to enable support for Octasic OCTPHY-2G])
AC_ARG_ENABLE(octphy,
AC_HELP_STRING([--enable-octphy],
[enable code for Octasic OCTPHY-2G [default=no]]),
[enable_octphy="yes"],[enable_octphy="no"])
AC_ARG_WITH([octsdr-2g], [AS_HELP_STRING([--with-octsdr-2g], [Location of the OCTSDR-2G API header files])],
[octsdr2g_incdir="$withval"],[octsdr2g_incdir="`cd $srcdir; pwd`/src/osmo-bts-octphy/"])
AC_SUBST([OCTSDR2G_INCDIR], $octsdr2g_incdir)
AC_MSG_RESULT([$enable_octphy])
AM_CONDITIONAL(ENABLE_OCTPHY, test "x$enable_octphy" = "xyes")
if test "$enable_octphy" = "yes" ; then
oldCPPFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$OCTSDR2G_INCDIR -I$srcdir/include $LIBOSMOCORE_CFLAGS"
AC_CHECK_HEADER([octphy/octvc1/gsm/octvc1_gsm_default.h],[],
[AC_MSG_ERROR([octphy/octvc1/gsm/octvc1_gsm_default.h can not be found in $octsdr2g_incdir])],
[#include <octphy/octvc1/gsm/octvc1_gsm_default.h>])
AC_CHECK_MEMBER([tOCTVC1_GSM_TRX_CONFIG.usCentreArfcn],
AC_DEFINE([OCTPHY_MULTI_TRX],
[1],
[Define to 1 if your octphy header files support multi-trx]),
[],
[#include <octphy/octvc1/gsm/octvc1_gsm_api.h>])
AC_CHECK_MEMBER([tOCTVC1_HW_RF_PORT_RX_STATS.Frequency],
AC_DEFINE([OCTPHY_USE_FREQUENCY],
[1],
[Define to 1 if your octphy header files support tOCTVC1_RADIO_FREQUENCY_VALUE type]),
[],
[#include <octphy/octvc1/hw/octvc1_hw_api.h>])
AC_CHECK_MEMBER([tOCTVC1_HW_MSG_CLOCK_SYNC_MGR_STATS_RSP.ulSyncLossCnt],
AC_DEFINE([OCTPHY_USE_SYNC_LOSS_CNT],
[1],
[Define to 1 if your octphy header files renamed ulSyncLosseCnt to ulSyncLossCnt]),
[],
[#include <octphy/octvc1/hw/octvc1_hw_api.h>])
AC_CHECK_MEMBER([tOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_TX_CONFIG_RSP.TxConfig],
AC_DEFINE([OCTPHY_USE_TX_CONFIG],
[1],
[Define to 1 if your octphy header files support tOCTVC1_HW_RF_PORT_ANTENNA_TX_CONFIG type]),
[],
[#include <octphy/octvc1/hw/octvc1_hw_api.h>])
AC_CHECK_MEMBER([tOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_RX_CONFIG_RSP.RxConfig],
AC_DEFINE([OCTPHY_USE_RX_CONFIG],
[1],
[Define to 1 if your octphy header files support tOCTVC1_HW_RF_PORT_ANTENNA_RX_CONFIG type]),
[],
[#include <octphy/octvc1/hw/octvc1_hw_api.h>])
AC_CHECK_MEMBER([tOCTVC1_GSM_RF_CONFIG.ulTxAntennaId],
AC_DEFINE([OCTPHY_USE_ANTENNA_ID],
[1],
[Define to 1 if your octphy header files support antenna ids in tOCTVC1_GSM_RF_CONFIG]),
[],
[#include <octphy/octvc1/gsm/octvc1_gsm_api.h>])
CPPFLAGS=$oldCPPFLAGS
fi
AC_MSG_CHECKING([whether to enable NuRAN Wireless Litecell 1.5 hardware support])
AC_ARG_ENABLE(litecell15,
AC_HELP_STRING([--enable-litecell15],
[enable code for NuRAN Wireless Litecell15 bts [default=no]]),
[enable_litecell15="yes"],[enable_litecell15="no"])
AC_ARG_WITH([litecell15], [AS_HELP_STRING([--with-litecell15=INCLUDE_DIR], [Location of the litecell 1.5 API header files])],
[litecell15_incdir="$withval"],[litecell15_incdir="$incdir"])
AC_SUBST([LITECELL15_INCDIR], $litecell15_incdir)
AC_MSG_RESULT([$enable_litecell15])
AM_CONDITIONAL(ENABLE_LC15BTS, test "x$enable_litecell15" = "xyes")
if test "$enable_litecell15" = "yes"; then
oldCPPFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$LITECELL15_INCDIR -I$srcdir/include $LIBOSMOCORE_CFLAGS"
AC_CHECK_HEADER([nrw/litecell15/litecell15.h],[],
[AC_MSG_ERROR([nrw/litecell15/litecell15.h can not be found in $litecell15_incdir])],
[#include <nrw/litecell15/litecell15.h>])
PKG_CHECK_MODULES(LIBSYSTEMD, libsystemd)
CPPFLAGS=$oldCPPFLAGS
fi
# We share gsm_data.h with OpenBSC and need to be pointed to the source
# directory of OpenBSC for now.
AC_ARG_WITH([openbsc],
[AS_HELP_STRING([--with-openbsc=INCLUDE_DIR],
[OpenBSC include directory for openbsc/gsm_data_shared.h])],
[openbsc_incdir="$withval"],
[openbsc_incdir="`cd $srcdir; pwd`/../openbsc/openbsc/include"])
AC_SUBST([OPENBSC_INCDIR], $openbsc_incdir)
oldCPPFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$OPENBSC_INCDIR -I$srcdir/include $LIBOSMOCORE_CFLAGS"
AC_CHECK_HEADER([openbsc/gsm_data_shared.h],[],
[AC_MSG_ERROR([openbsc/gsm_data_shared.h can not be found in $openbsc_incdir])],
[#include <osmo-bts/tx_power.h>])
CPPFLAGS=$oldCPPFLAGS
# Check for the sbts2050_header.h that was added after the 3.6 release
oldCPPFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$OPENBSC_INCDIR $LIBOSMOCORE_CFLAGS"
AC_CHECK_HEADER([sysmocom/femtobts/sbts2050_header.h],
[sysmo_uc_header="yes"],[])
CPPFLAGS=$oldCPPFLAGS
if test "$sysmo_uc_header" = "yes" ; then
AC_DEFINE(BUILD_SBTS2050, 1, [Define if we want to build SBTS2050])
fi
AM_CONDITIONAL(BUILD_SBTS2050, test "x$sysmo_uc_header" = "xyes")
AM_CONFIG_HEADER(btsconfig.h)
AC_OUTPUT(
src/Makefile
src/common/Makefile
src/osmo-bts-virtual/Makefile
src/osmo-bts-sysmo/Makefile
src/osmo-bts-bb/Makefile
src/osmo-bts-litecell15/Makefile
src/osmo-bts-trx/Makefile
src/osmo-bts-octphy/Makefile
include/Makefile
include/osmo-bts/Makefile
tests/Makefile
tests/paging/Makefile
tests/agch/Makefile
tests/cipher/Makefile
tests/sysmobts/Makefile
tests/misc/Makefile
tests/handover/Makefile
tests/tx_power/Makefile
tests/meas/Makefile
Makefile)

89
contrib/dtx_check.gawk Executable file
View File

@@ -0,0 +1,89 @@
#!/usr/bin/gawk -f
# Expected input format: FN TYPE
BEGIN {
DELTA = 0
ERR = 0
FORCE = 0
FN = 0
SILENCE = 0
TYPE = ""
CHK = ""
U_MAX = 8 * 20 + 120 / 26
U_MIN = 8 * 20 - 120 / 26
F_MAX = 3 * 20 + 120 / 26
F_MIN = 3 * 20 - 120 / 26
}
{
if (NR > 2) { # we have data from previous record to compare to
DELTA = ($1 - FN) * 120 / 26
CHK = "OK"
if ("FACCH" == $2 && "ONSET" == TYPE) { # ONSET due to FACCH is NOT a talkspurt
SILENCE = 1
}
if (("UPDATE" == TYPE || "FIRST" == TYPE) && ("FACCH" == $2 || "SPEECH" == $2)) { # check for missing ONSET:
CHK = "FAIL: missing ONSET (" $2 ") after " TYPE "."
ERR++
}
if ("SID_P1" == $2) {
CHK = "FAIL: regular AMR payload with FT SID and STI=0 (should be either pyaload Update or STI=1)."
ERR++
}
if ("FORCED_FIRST" == $2 || "FORCED_NODATA" == $2 || "FORCED_F_P2" == $2 || "FORCED_F_INH" == $2 || "FORCED_U_INH" == $2) {
CHK = "FAIL: event " $2 " inserted by DSP."
FORCE++
ERR++
}
if ("FIRST_P2" != $2 && "FIRST_P1" == TYPE) {
CHK = "FAIL: " TYPE " followed by " $2 " instead of P2."
ERR++
}
if ("FIRST" == $2 && "FIRST" == TYPE) {
CHK = "FAIL: multiple SID FIRST in a row."
ERR++
}
if ("OK" == CHK && "ONSET" != $2) { # check inter-SID distances:
if ("UPDATE" == TYPE) {
if (DELTA > U_MAX) {
CHK = "FAIL: delta (" $1 - FN "fn) from previous SID UPDATE (@" FN ") too big " DELTA "ms > " U_MAX "ms."
ERR++
}
if ("UPDATE" == $2 && DELTA < U_MIN) {
CHK = "FAIL: delta (" $1 - FN "fn) from previous SID UPDATE (@" FN ") too small " DELTA "ms < " U_MIN "ms."
ERR++
}
}
if ("FIRST" == TYPE) {
if (DELTA > F_MAX) {
CHK = "FAIL: delta (" $1 - FN "fn) from previous SID FIRST (@" FN ") too big " DELTA "ms > " F_MAX "ms."
ERR++
}
if ("UPDATE" == $2 && DELTA < F_MIN) {
CHK = "FAIL: delta (" $1 - FN "fn) from previous SID UPDATE (@" FN ") too small " DELTA "ms < " F_MIN "ms."
ERR++
}
}
}
if ("FACCH" == TYPE && "FIRST" != $2 && "FACCH" != $2 && 1 == SILENCE) { # check FACCH handling
CHK = "FAIL: incorrect silence resume with " $2 " after FACCH."
ERR++
}
}
if ("SPEECH" == $2 || "ONSET" == $2) { # talkspurt
SILENCE = 0
}
if ("UPDATE" == $2 || "FIRST" == $2) { # silence
SILENCE = 1
}
print $1, $2, CHK
if ($2 != "EMPTY") { # skip over EMPTY records
TYPE = $2
FN = $1
}
}
END {
print "Check completed: found " ERR " errors (" FORCE " events inserted by DSP) in " NR " records."
}

40
contrib/dump_docs.py Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env python
"""
Start the process and dump the documentation to the doc dir
"""
import socket, subprocess, time,os
env = os.environ
env['L1FWD_BTS_HOST'] = '127.0.0.1'
bts_proc = subprocess.Popen(["./src/osmo-bts-sysmo/sysmobts-remote",
"-c", "./doc/examples/sysmo/osmo-bts.cfg"], env = env,
stdin=None, stdout=None)
time.sleep(1)
try:
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sck.setblocking(1)
sck.connect(("localhost", 4241))
sck.recv(4096)
# Now send the command
sck.send("show online-help\r")
xml = ""
while True:
data = sck.recv(4096)
xml = "%s%s" % (xml, data)
if data.endswith('\r\nOsmoBTS> '):
break
# Now write everything until the end to the file
out = open('doc/vty_reference.xml', 'w')
out.write(xml[18:-11])
out.close()
finally:
# Clean-up
bts_proc.kill()
bts_proc.wait()

91
contrib/eeprom_reader.c Normal file
View File

@@ -0,0 +1,91 @@
/* GPLv3+ to read sysmobts-v2 revD or later EEPROM from userspace */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
/* Can read a 16bit at24 eeprom with 8192 byte in storage (24c64) */
static int dump_eeprom(int fd, int out)
{
#define STEP 8192
#define SIZE 8192
uint8_t buf[STEP + 2];
int rc = 0;
int i;
for (i = 0; i < SIZE; i += STEP) {
/* write the address */
buf[0] = i >> 8;
buf[1] = i;
rc = write(fd, buf, 2);
if (rc != 2) {
fprintf(stderr, "writing address failed: %d/%d/%s\n", rc, errno, strerror(errno));
return 1;
}
/* execute step amount of reads */
rc = read(fd, buf, STEP);
if (rc != STEP) {
fprintf(stderr, "Failed to read: %d/%d/%s\n", rc, errno, strerror(errno));
return 1;
}
write(out, buf, STEP);
}
return 0;
}
int main(int argc, char **argv)
{
int i2c_fd, out_fd;
char *filename = "/dev/i2c-1";
char *out_file = "eeprom.out";
int addr = 0x50;
int rc;
i2c_fd = open(filename, O_RDWR);
if (i2c_fd < 0) {
fprintf(stderr, "Failed to open i2c device %d/%d/%s\n",
i2c_fd, errno, strerror(errno));
return EXIT_FAILURE;
}
/* force using that address it is already bound with a driver */
rc = ioctl(i2c_fd, I2C_SLAVE_FORCE, addr);
if (rc < 0) {
fprintf(stderr, "Failed to claim i2c device %d/%d/%s\n",
rc, errno, strerror(errno));
return EXIT_FAILURE;
}
if (argc >= 2)
out_file = argv[1];
out_fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (out_fd < 0) {
fprintf(stderr, "Failed to open out device %s %d/%d/%s\n",
out_file, rc, errno, strerror(errno));
return EXIT_FAILURE;
}
if (dump_eeprom(i2c_fd, out_fd) != 0) {
unlink(out_file);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

45
contrib/jenkins_bts_model.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/sh
# this is a dispatcher script which will call the bts-model-specific
# script based on the bts model specified as command line argument
bts_model="$1"
if [ "x$bts_model" == "x" ]; then
echo "Error: You have to specify the BTS model as first argument, e.g. $0 sysmo"
exit 2
fi
if [ ! -d "./contrib" ]; then
echo "Run ./contrib/jenkins_bts_model.sh from the root of the osmo-bts tree"
exit 1
fi
set -x -e
case "$bts_model" in
sysmo)
./contrib/jenkins_sysmobts.sh
;;
oct)
./contrib/jenkins_oct.sh
;;
lc15)
./contrib/jenkins_lc15.sh
;;
trx)
./contrib/jenkins_bts_trx.sh
;;
oct+trx)
./contrib/jenkins_oct_and_bts_trx.sh
;;
*)
set +x
echo "Unknown BTS model '$bts_model'"
;;
esac

24
contrib/jenkins_bts_trx.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/sh
# jenkins build helper script for osmo-bts-trx
# shellcheck source=contrib/jenkins_common.sh
. $(dirname "$0")/jenkins_common.sh
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmocore
osmo-build-dep.sh libosmo-abis
cd "$deps"
# Get osmo-pcu for pcuif_proto.h
osmo-deps.sh osmo-pcu
configure_flags="\
--with-osmo-pcu=$deps/osmo-pcu/include \
--enable-trx \
"
build_bts "osmo-bts-trx" "$configure_flags"

54
contrib/jenkins_common.sh Normal file
View File

@@ -0,0 +1,54 @@
#!/bin/sh
# this is a common helper script that is shared among all BTS model
# specific helper scripts like jenkins_sysmobts.sh. You shouldn't call
# this directly, but rather indirectly via the bts-specific scripts
if ! [ -x "$(command -v osmo-deps.sh)" ]; then
echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !"
exit 2
fi
set -ex
base="$PWD"
deps="$base/deps"
inst="$deps/install"
export deps inst
mkdir -p "$deps"
rm -rf "$inst"
cd "$deps"
# Get libosmocore for verify_value_string_arrays_are_terminated.py
osmo-deps.sh libosmocore
cd "$base"
"$deps"/libosmocore/contrib/verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]")
# generic project build function, usage:
# build "PROJECT-NAME" "CONFIGURE OPTIONS"
build_bts() {
set +x
echo
echo
echo
echo " =============================== $1 ==============================="
echo
set -x
cd $deps
osmo-deps.sh openbsc
conf_flags="--with-openbsc=$deps/openbsc/openbsc/include"
cd $base
shift
conf_flags="$conf_flags $*"
autoreconf --install --force
./configure $conf_flags
$MAKE $PARALLEL_MAKE
$MAKE check || cat-testlogs.sh
DISTCHECK_CONFIGURE_FLAGS=$conf_flags $MAKE distcheck || cat-testlogs.sh
}

19
contrib/jenkins_lc15.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/sh
# jenkins build helper script for osmo-bts-lc15
# shellcheck source=contrib/jenkins_common.sh
. $(dirname "$0")/jenkins_common.sh
osmo-build-dep.sh libosmocore
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmo-abis
cd "$deps"
osmo-layer1-headers.sh lc15 "$FIRMWARE_VERSION"
configure_flags="--with-litecell15=$deps/layer1-headers/inc/ --enable-litecell15"
build_bts "osmo-bts-lc15" "$configure_flags"

19
contrib/jenkins_oct.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/sh
# jenkins build helper script for osmo-bts-octphy
# shellcheck source=contrib/jenkins_common.sh
. $(dirname "$0")/jenkins_common.sh
osmo-build-dep.sh libosmocore
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmo-abis
cd "$deps"
osmo-layer1-headers.sh oct "$FIRMWARE_VERSION"
configure_flags="--with-octsdr-2g=$deps/layer1-headers/ --enable-octphy"
build_bts "osmo-bts-octphy" "$configure_flags"

View File

@@ -0,0 +1,28 @@
#!/bin/sh
# jenkins build helper script for osmo-bts-octphy + osmo-bts-trx
# shellcheck source=contrib/jenkins_common.sh
. $(dirname "$0")/jenkins_common.sh
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmocore
osmo-build-dep.sh libosmo-abis
cd "$deps"
# Get osmo-pcu for pcuif_proto.h
osmo-deps.sh osmo-pcu
osmo-layer1-headers.sh oct "$FIRMWARE_VERSION"
configure_flags="\
--with-osmo-pcu=$deps/osmo-pcu/include \
--with-octsdr-2g=$deps/layer1-headers/ \
--enable-octphy \
--enable-trx \
"
build_bts "osmo-bts-octphy+trx" "$configure_flags"

26
contrib/jenkins_sysmobts.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/sh
# jenkins build helper script for osmo-bts-sysmo
# shellcheck source=contrib/jenkins_common.sh
. $(dirname "$0")/jenkins_common.sh
osmo-build-dep.sh libosmocore
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmo-abis
cd "$deps"
osmo-layer1-headers.sh sysmo "$FIRMWARE_VERSION"
mkdir -p "$inst/include/sysmocom/femtobts"
ln -s $deps/layer1-headers/include/* "$inst/include/sysmocom/femtobts/"
configure_flags="--enable-sysmocom-bts"
build_bts "osmo-bts-sysmo" "$configure_flags"
# This will not work for the femtobts
if [ $FIRMWARE_VERSION != "femtobts_v2.7" ]; then
$MAKE -C contrib/sysmobts-calib
fi

View File

@@ -0,0 +1,29 @@
[Unit]
Description=osmo-bts manager for LC15 / sysmoBTS 2100
After=lc15-sysdev-remap.service
Wants=lc15-sysdev-remap.service
[Service]
Type=simple
NotifyAccess=all
WatchdogSec=21780s
Restart=always
RestartSec=2
# Make sure directories and symbolic link exist
ExecStartPre=/bin/sh -c 'test -d /mnt/storage/var/run/lc15bts-mgr || mkdir -p /mnt/storage/var/run/lc15bts-mgr ; test -d /var/run/lc15bts-mgr || ln -sf /mnt/storage/var/run/lc15bts-mgr/ /var/run'
# Make sure BTS operation hour exist
ExecStartPre=/bin/sh -c 'test -f /mnt/storage/var/run/lc15bts-mgr/hours-running || echo 0 > /mnt/storage/var/run/lc15bts-mgr/hours-running'
# Shutdown all PA correctly
ExecStartPre=/bin/sh -c 'echo disabled > /var/lc15/pa-state/pa0/state; echo disabled > /var/lc15/pa-state/pa1/state'
ExecStartPre=/bin/sh -c 'echo 0 > /var/lc15/pa-supply/max_microvolts; echo 0 > /var/lc15/pa-supply/min_microvolts'
ExecStart=/usr/bin/lc15bts-mgr -s -c /etc/osmocom/lc15bts-mgr.cfg
# Shutdown all PA correctly
ExecStopPost=/bin/sh -c 'echo disabled > /var/lc15/pa-state/pa0/state; echo disabled > /var/lc15/pa-state/pa1/state'
ExecStopPost=/bin/sh -c 'echo 0 > /var/lc15/pa-supply/max_microvolts; echo 0 > /var/lc15/pa-supply/min_microvolts'
[Install]
WantedBy=multi-user.target
Alias=osmo-bts-mgr.service

View File

@@ -0,0 +1,21 @@
[Unit]
Description=osmo-bts for LC15 / sysmoBTS 2100
[Service]
Type=simple
ExecStartPre=/bin/sh -c 'echo 1 > /sys/class/leds/usr0/brightness'
ExecStartPre=/bin/sh -c 'echo 1 > /sys/class/leds/usr1/brightness'
ExecStart=/usr/bin/osmo-bts-lc15 -t 2 -s -c /etc/osmocom/osmo-bts.cfg -M
ExecStopPost=/bin/sh -c 'echo 1 > /sys/class/leds/usr0/brightness'
ExecStopPost=/bin/sh -c 'echo 0 > /sys/class/leds/usr1/brightness'
Restart=always
RestartSec=2
RestartPreventExitStatus=1
# The msg queues must be read fast enough
CPUSchedulingPolicy=rr
CPUSchedulingPriority=1
[Install]
WantedBy=multi-user.target
Alias=osmo-bts.service

View File

@@ -0,0 +1,21 @@
[Unit]
Description=osmo-bts for sysmocom sysmoBTS
[Service]
Type=simple
ExecStartPre=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness'
ExecStart=/usr/bin/osmo-bts-sysmo -s -c /etc/osmocom/osmo-bts.cfg -M
ExecStopPost=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness'
ExecStopPost=/bin/sh -c 'cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; sleep 3s; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0; sleep 1s'
Restart=always
RestartSec=2
RestartPreventExitStatus=1
# The msg queues must be read fast enough
CPUSchedulingPolicy=rr
CPUSchedulingPriority=1
[Install]
WantedBy=multi-user.target
Alias=sysmobts.service
Alias=osmo-bts.service

13
contrib/respawn-only.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/sh
PID=$$
echo "-1000" > /proc/$PID/oom_score_adj
trap "{ kill 0; kill -2 0; }" EXIT
while [ -f $1 ]; do
(echo "0" > /proc/self/oom_score_adj && exec nice -n -20 $*) &
LAST_PID=$!
wait $LAST_PID
sleep 10s
done

View File

@@ -1,4 +1,18 @@
#!/bin/sh
PID=$$
echo "-1000" > /proc/$PID/oom_score_adj
trap "kill 0" EXIT
while [ -e /etc/passwd ]; do
$*
cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0
sleep 2s
cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0
sleep 1s
echo "0" > /sys/class/leds/activity_led/brightness
(echo "0" > /proc/self/oom_score_adj && exec nice -n -20 $*) &
LAST_PID=$!
wait $LAST_PID
sleep 10s
done

View File

@@ -1,3 +1,5 @@
chdir /tmp
screen -t BTS 0 /etc/osmocom/respawn.sh /usr/bin/sysmobts -c /etc/osmocom/osmo-bts.cfg
screen -t BTS 0 /etc/osmocom/respawn.sh /usr/bin/osmo-bts-sysmo -c /etc/osmocom/osmo-bts.cfg -r 1 -M
screen -t PCU 1 /etc/osmocom/respawn-only.sh /usr/bin/osmo-pcu -c /etc/osmocom/osmo-pcu.cfg -e
screen -t MGR 2 /etc/osmocom/respawn-only.sh /usr/bin/sysmobts-mgr -n -c /etc/osmocom/sysmobts-mgr.cfg
detach

91
contrib/si_check.gawk Executable file
View File

@@ -0,0 +1,91 @@
#!/usr/bin/gawk -f
# Usage example:
# tshark -2 -t r -E 'header=n' -E 'separator=,' -E 'quote=n' -T fields -e gsmtap.frame_nr -e gsmtap.ts -e gsmtap.arfcn -e _ws.col.Info -Y 'gsmtap' -r test.pcapng.gz | grep Information | env ARFCN=878 ./si_check.gawk
# read summary on number of bis/ter messages and adjust BT_BOTH and BT_NONE environment variables accordingly
BEGIN {
FS = ","
FAILED = 0
IGNORE = 0
BIS = 0
TER = 0
QUA = 0
BT_BOTH = ENVIRON["BOTH"]
BT_NONE = ENVIRON["NONE"]
TC_INDEX = 0
TC4[4] = 0
}
{ # expected .csv input as follows: gsmtap.frame_nr,gsmtap.ts,gsmtap.arfcn,_ws.col.Info
if ("ARFCN" in ENVIRON) { # ARFCN filtering is enabled
if (ENVIRON["ARFCN"] != $3) { # ignore other ARFCNs
IGNORE++
next
}
}
type = get_si_type($4)
tc = get_tc($1)
result = "FAIL"
if (1 == check_si_tc(tc, type)) { result = "OK" }
else { FAILED++ }
if (4 == tc) {
TC4[TC_INDEX] = type
TC_INDEX = int((TC_INDEX + 1) % 4)
if (0 == check_tc4c(type) && "OK" == result) {
result = "FAIL"
FAILED++
}
}
if (type == "2bis") { BIS++ }
if (type == "2ter") { TER++ }
if (type == "2quater") { QUA++ }
# for (i in TC4) print TC4[i] # debugging
printf "ARFCN=%d FN=%d TS=%d TC=%d TYPE=%s %s\n", $3, $1, $2, tc, type, result
}
END {
printf "check completed: total %d, failed %d, ignored %d, ok %d\nSI2bis = %d, SI2ter = %d, SI2quater = %d\n", NR, FAILED, IGNORE, NR - FAILED - IGNORE, BIS, TER, QUA
if ((BIS > 0 || TER > 0) && BT_NONE) { printf "please re-run with correct environment: unset 'NONE' variable\n" }
if ((BIS > 0 && TER > 0) && !BT_BOTH) { printf "please re-run with correct environment: set 'BOTH' variable\n" }
}
func get_si_type(s, x) { # we rely on format of Info column in wireshark output - if it's changed we're screwed
return x[split(s, x, " ")]
}
func get_tc(f) { # N. B: all numbers in awk are float
return int(int(f / 51) % 8)
}
func check_tc4c(si, count) { # check for "once in 4 consecutive occurrences" rule
count = 0
if ("2quater" != si || "2ter" != si) { return 1 } # rules is not applicable to other types
if (BT_NONE && "2quater" == si) { return 0 } # should be on TC=5 instead
if (!BT_BOTH && "2ter" == si) { return 0 } # should be on TC=5 instead
if (0 in TC4 && 1 in TC4 && 2 in TC4 && 3 in TC4) { # only check if we have 4 consecutive occurrences already
if (si == TC4[0]) { count++ }
if (si == TC4[1]) { count++ }
if (si == TC4[2]) { count++ }
if (si == TC4[3]) { count++ }
if (0 == count) { return 0 }
}
return 1
}
func check_si_tc(tc, si) { # check that SI scheduling on BCCH Norm is matching rules from 3GPP TS 05.02 § 6.3.1.3
switch (si) {
case "1": return (0 == tc) ? 1 : 0
case "2": return (1 == tc) ? 1 : 0
case "2bis": return (5 == tc) ? 1 : 0
case "13": return (4 == tc) ? 1 : 0
case "9": return (4 == tc) ? 1 : 0
case "2ter": if (BT_BOTH) { return (4 == tc) ? 1 : 0 } else { return (5 == tc) ? 1 : 0 }
case "2quater": if (BT_NONE) { return (5 == tc) ? 1 : 0 } else { return (4 == tc) ? 1 : 0 }
case "3": return (2 == tc || 6 == tc) ? 1 : 0
case "4": return (3 == tc || 7 == tc) ? 1 : 0
}
return 0
}

110
contrib/superfemto.sh Executable file
View File

@@ -0,0 +1,110 @@
#!/bin/sh
# Split common DSP call log file (produced by superfemto-compatible firmware) into 4 separate call leg files (MO/MT & DL/UL) with events in format "FN EVENT_TYPE":
# MO Mobile Originated
# MT Mobile Terminated
# DL DownLink (BTS -> L1)
# UL UpLink (L1 -> BTS)
if [ -z $1 ]; then
echo "expecting DSP log file name as parameter"
exit 1
fi
# MO handle appear 1st in the logs
MO=$(grep 'h=' $1 | head -n 1 | cut -f2 -d',' | cut -f2 -d= | cut -f1 -d']')
# direction markers:
DLST="_CodeBurst"
ULST="_DecodeAndIdentify"
# DL sed filters:
D_EMP='s/ Empty frame request!/EMPTY/i'
D_FAC='s/ Coding a FACCH\/. frame !!/FACCH/i'
D_FST='s/ Coding a RTP SID First frame !!/FIRST/i'
D_FS1='s/ Coding a SID First P1 frame !!/FIRST_P1/i'
D_FS2='s/ Coding a SID First P2 frame !!/FIRST_P2/i'
D_RP1='s/ Coding a RTP SID P1 frame !!/SID_P1/i'
D_UPD='s/ Coding a RTP SID Update frame !!/UPDATE/i'
D_SPE='s/ Coding a RTP Speech frame !!/SPEECH/i'
D_ONS='s/ Coding a Onset frame !!/ONSET/i'
D_FO1='s/ A speech frame is following a NoData or SID First without an Onset./FORCED_FIRST/i'
D_FO2='s/ A speech frame is following a NoData without an Onset./FORCED_NODATA/i'
D_FP2='s/ A speech frame is following a NoData or SID_FIRST_P2 without an Onset./FORCED_F_P2/i'
D_FIN='s/ A speech frame is following a SID_FIRST without inhibit. A SID_FIRST_INH will be inserted./FORCED_F_INH/i'
D_UIN='s/ A speech frame is following a SID_UPDATE without inhibit. A SID_UPDATE_INH will be inserted./FORCED_U_INH/i'
# UL sed filters:
U_NOD='s/ It is a No Data frame !!/NODATA/i'
U_ONS='s/ It is an ONSET frame !!/ONSET/i'
U_UPD='s/ It is a SID UPDATE frame !!/UPDATE/i'
U_FST='s/ It is a SID FIRST frame !!/FIRST/i'
U_FP1='s/ It is a SID-First P1 frame !!/FIRST_P1/i'
U_FP2='s/ It is a SID-First P2 frame !!/FIRST_P2/i'
U_SPE='s/ It is a SPEECH frame *!!/SPEECH/i'
U_UIN='s/ It is a SID update InH frame !!/UPD_INH/i'
U_FIN='s/ It is a SID-First InH frame !!/FST_INH/i'
U_RAT='s/ It is a RATSCCH data frame !!/RATSCCH/i'
DL () { # filter downlink-related entries
grep $DLST $1 > $1.DL.tmp
}
UL () { # uplink does not require special fix
grep $ULST $1 > $1.UL.tmp.fix
}
DL $1
UL $1
FIX() { # add MO/MT marker from preceding line to inserted ONSETs so filtering works as expected
cat $1.DL.tmp | awk 'BEGIN{ FS=" h="; H="" } { if (NF > 1) { H = $2; print $1 "h=" $2 } else { print $1 ", h=" H } }' > $1.DL.tmp.fix
}
FIX $1
MO() { # filter MO call DL or UL logs
grep "h=$MO" $1.tmp.fix > $1.MO.raw
}
MT() { # filter MT call DL or UL logs
grep -v "h=$MO" $1.tmp.fix > $1.MT.raw
}
MO $1.DL
MT $1.DL
MO $1.UL
MT $1.UL
PREP() { # prepare logs for reformatting
cat $1.raw | cut -f2 -d')' | cut -f1 -d',' | cut -f2 -d'>' | sed 's/\[u32Fn/fn/' | sed 's/\[ u32Fn/fn/' | sed 's/fn = /fn=/' | sed 's/fn=//' | sed 's/\[Fn=//' | sed 's/ An Onset will be inserted.//' > $1.tmp1
}
PREP "$1.DL.MT"
PREP "$1.DL.MO"
PREP "$1.UL.MT"
PREP "$1.UL.MO"
RD() { # reformat DL logs for consistency checks
cat $1.tmp1 | sed "$D_FST" | sed "$D_SPE" | sed "$D_FS1" | sed "$D_FS2" | sed "$D_UIN" | sed "$D_FIN" | sed "$D_UPD" | sed "$D_INH" | sed "$D_RP1" | sed "$D_ONS" | sed "$D_EMP" | sed "$D_FAC" | sed "$D_FO1" | sed "$D_FO2" | sed "$D_FP2" > $1.tmp2
}
RU() { # reformat UL logs for consistency checks
cat $1.tmp1 | sed "$U_FST" | sed "$U_SPE" | sed "$U_FP1" | sed "$U_FP2" | sed "$U_UPD" | sed "$U_ONS" | sed "$U_NOD" | sed "$U_UIN" | sed "$U_FIN" | sed "$U_RAT" > $1.tmp2
}
RD "$1.DL.MT"
RD "$1.DL.MO"
RU "$1.UL.MT"
RU "$1.UL.MO"
SW() { # swap fields
cat $1.tmp2 | awk '{ print $2, $1 }' > $1
}
SW "$1.DL.MT"
SW "$1.DL.MO"
SW "$1.UL.MT"
SW "$1.UL.MO"
rm $1.*.tmp*

View File

@@ -0,0 +1,10 @@
CFLAGS=`pkg-config --cflags libosmocore` -Wall -Werror
LIBS=`pkg-config --libs libosmocore libosmogsm`
all: sysmobts-calib
sysmobts-calib: sysmobts-calib.o sysmobts-layer1.o
$(CC) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ -lrt $(LIBS)
clean:
@rm -f sysmobts-calib *.o

View File

@@ -0,0 +1,537 @@
/* OCXO/TCXO based calibration utility */
/*
* (C) 2012-2013 Holger Hans Peter Freyther
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
#include <math.h>
#define _GNU_SOURCE
#include <getopt.h>
#include <sysmocom/femtobts/superfemto.h>
#include <sysmocom/femtobts/gsml1types.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/core/utils.h>
#include "sysmobts-layer1.h"
enum actions {
ACTION_SCAN,
ACTION_CALIB,
ACTION_BCCH,
ACTION_BCCH_CCCH,
};
static const char *modes[] = {
[ACTION_SCAN] = "scan",
[ACTION_CALIB] = "calibrate",
[ACTION_BCCH] = "bcch",
[ACTION_BCCH_CCCH] = "bcch_ccch",
};
static const char *bands[] = {
[GsmL1_FreqBand_850] = "850",
[GsmL1_FreqBand_900] = "900",
[GsmL1_FreqBand_1800] = "1800",
[GsmL1_FreqBand_1900] = "1900",
};
struct channel_pair {
int min;
int max;
};
static const struct channel_pair arfcns[] = {
[GsmL1_FreqBand_850] = { .min = 128, .max = 251 },
[GsmL1_FreqBand_900] = { .min = 1, .max = 124 },
[GsmL1_FreqBand_1800] = { .min = 512, .max = 885 },
[GsmL1_FreqBand_1900] = { .min = 512, .max = 810 },
};
static const char *clk_source[] = {
[SuperFemto_ClkSrcId_Ocxo] = "ocxo",
[SuperFemto_ClkSrcId_Tcxo] = "tcxo",
[SuperFemto_ClkSrcId_External] = "external",
[SuperFemto_ClkSrcId_GpsPps] = "gps",
[SuperFemto_ClkSrcId_Trx] = "trx",
[SuperFemto_ClkSrcId_Rx] = "rx",
[SuperFemto_ClkSrcId_Edge] = "edge",
[SuperFemto_ClkSrcId_NetList] = "netlisten",
};
static const struct value_string sapi_names[GsmL1_Sapi_NUM+1] = {
{ GsmL1_Sapi_Fcch, "FCCH" },
{ GsmL1_Sapi_Sch, "SCH" },
{ GsmL1_Sapi_Sacch, "SACCH" },
{ GsmL1_Sapi_Sdcch, "SDCCH" },
{ GsmL1_Sapi_Bcch, "BCCH" },
{ GsmL1_Sapi_Pch, "PCH" },
{ GsmL1_Sapi_Agch, "AGCH" },
{ GsmL1_Sapi_Cbch, "CBCH" },
{ GsmL1_Sapi_Rach, "RACH" },
{ GsmL1_Sapi_TchF, "TCH/F" },
{ GsmL1_Sapi_FacchF, "FACCH/F" },
{ GsmL1_Sapi_TchH, "TCH/H" },
{ GsmL1_Sapi_FacchH, "FACCH/H" },
{ GsmL1_Sapi_Nch, "NCH" },
{ GsmL1_Sapi_Pdtch, "PDTCH" },
{ GsmL1_Sapi_Pacch, "PACCH" },
{ GsmL1_Sapi_Pbcch, "PBCCH" },
{ GsmL1_Sapi_Pagch, "PAGCH" },
{ GsmL1_Sapi_Ppch, "PPCH" },
{ GsmL1_Sapi_Pnch, "PNCH" },
{ GsmL1_Sapi_Ptcch, "PTCCH" },
{ GsmL1_Sapi_Prach, "PRACH" },
{ 0, NULL }
};
static int action = ACTION_SCAN;
static int band = GsmL1_FreqBand_900;
static int calib = SuperFemto_ClkSrcId_Ocxo;
static int source = SuperFemto_ClkSrcId_NetList;
static int dsp_flags = 0x0;
static int cal_arfcn = 0;
static int initial_cor = 0;
static int steps = -1;
static void print_usage(void)
{
printf("Usage: sysmobts-calib ARGS\n");
}
static void print_help(void)
{
printf(" -h --help this text\n");
printf(" -c --clock "
"ocxo|tcxo|external|gps|trx|rx|edge\n");
printf(" -s --calibration-source "
"ocxo|tcxo|external|gps|trx|rx|edge|netlisten\n");
printf(" -b --band 850|900|1800|1900\n");
printf(" -m --mode scan|calibrate|bcch|bcch_ccch\n");
printf(" -a --arfcn NR arfcn for calibration\n");
printf(" -d --dsp-flags NR dsp mask for debug log\n");
printf(" -t --threshold level\n");
printf(" -i --initial-clock-correction COR.\n");
printf(" -t --steps STEPS\n");
}
static int find_value(const char **array, int size, char *value)
{
int i = 0;
for (i = 0; i < size; ++i) {
if (array[i] == NULL)
continue;
if (strcmp(value, array[i]) == 0)
return i;
}
printf("Failed to find: '%s'\n", value);
exit(-2);
}
static void handle_options(int argc, char **argv)
{
while (1) {
int option_index = 0, c;
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"calibration-source", 1, 0, 's'},
{"clock", 1, 0, 'c'},
{"mode", 1, 0, 'm'},
{"band", 1, 0, 'b'},
{"dsp-flags", 1, 0, 'd'},
{"arfcn", 1, 0, 'a'},
{"initial-clock-correction", 1, 0, 'i'},
{"steps", 1, 0, 't'},
{0, 0, 0, 0},
};
c = getopt_long(argc, argv, "hs:c:m:b:d:a:i:t:",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'h':
print_usage();
print_help();
exit(0);
case 's':
source = find_value(clk_source,
ARRAY_SIZE(clk_source), optarg);
break;
case 'c':
calib = find_value(clk_source,
ARRAY_SIZE(clk_source), optarg);
break;
case 'm':
action = find_value(modes,
ARRAY_SIZE(modes), optarg);
break;
case 'b':
band = find_value(bands,
ARRAY_SIZE(bands), optarg);
break;
case 'd':
dsp_flags = strtol(optarg, NULL, 16);
break;
case 'a':
cal_arfcn = atoi(optarg);
break;
case 'i':
initial_cor = atoi(optarg);
break;
case 't':
steps = atoi(optarg);
break;
default:
printf("Unhandled option, terminating.\n");
exit(-1);
}
}
if (source == calib) {
printf("Clock source and reference clock may not be the same.\n");
exit(-3);
}
if (calib == SuperFemto_ClkSrcId_NetList) {
printf("Clock may not be network listen.\n");
exit(-4);
}
if (action == ACTION_CALIB && source == SuperFemto_ClkSrcId_NetList) {
if (cal_arfcn == 0) {
printf("Please specify the reference ARFCN.\n");
exit(-5);
}
if (cal_arfcn < arfcns[band].min || cal_arfcn > arfcns[band].max) {
printf("ARFCN(%d) is not in the given band.\n", cal_arfcn);
exit(-6);
}
}
}
#define CHECK_RC(rc) \
if (rc != 0) \
return EXIT_FAILURE;
#define CHECK_RC_MSG(rc, msg) \
if (rc != 0) { \
printf("%s: %d\n", msg, rc); \
return EXIT_FAILURE; \
}
#define CHECK_COND_MSG(cond, rc, msg) \
if (cond) { \
printf("%s: %d\n", msg, rc); \
return EXIT_FAILURE; \
}
struct scan_result
{
uint16_t arfcn;
float rssi;
};
static int scan_cmp(const void *arg1, const void *arg2)
{
struct scan_result *elem1 = (struct scan_result *) arg1;
struct scan_result *elem2 = (struct scan_result * )arg2;
float diff = elem1->rssi - elem2->rssi;
if (diff > 0.0)
return 1;
else if (diff < 0.0)
return -1;
else
return 0;
}
static int scan_band()
{
int arfcn, rc, i;
/* Scan results.. at most 400 items */
struct scan_result results[400];
memset(&results, 0, sizeof(results));
int num_scan_results = 0;
printf("Going to scan bands.\n");
for (arfcn = arfcns[band].min; arfcn <= arfcns[band].max; ++arfcn) {
float mean_rssi;
printf(".");
fflush(stdout);
rc = power_scan(band, arfcn, 10, &mean_rssi);
CHECK_RC_MSG(rc, "Power Measurement failed");
results[num_scan_results].arfcn = arfcn;
results[num_scan_results].rssi = mean_rssi;
num_scan_results++;
}
qsort(results, num_scan_results, sizeof(struct scan_result), scan_cmp);
printf("\nSorted scan results (weakest first):\n");
for (i = 0; i < num_scan_results; ++i)
printf("ARFCN %3d: %.4f\n", results[i].arfcn, results[i].rssi);
return 0;
}
static int calib_get_clock_error(void)
{
int rc, clkErr, clkErrRes;
printf("Going to determine the clock offset.\n");
rc = rf_clock_info(&clkErr, &clkErrRes);
CHECK_RC_MSG(rc, "Clock info failed.\n");
if (clkErr == 0 && clkErrRes == 0) {
printf("Failed to get the clock info. Are both clocks present?\n");
return -1;
}
/*
* Empiric gps error determination. With revE and firmware v3.3
* the clock error for TCXO to GPS appears to have a different
* sign. The device in question doesn't have a networklisten mode
* so it is impossible to verify that this only applies to GPS.
*/
if (source == SuperFemto_ClkSrcId_GpsPps)
clkErr *= -1;
/* this is an absolute clock error */
printf("The calibration value is: %d\n", clkErr);
return 0;
}
static int calib_clock_after_sync(void)
{
int rc, clkErr, clkErrRes, iteration, cor;
iteration = 0;
cor = initial_cor;
printf("Trying to calibrate now and reducing clock error.\n");
for (iteration = 0; iteration < steps || steps <= 0; ++iteration) {
if (steps > 0)
printf("Iteration %d/%d with correction: %d\n", iteration, steps, cor);
else
printf("Iteration %d with correction: %d\n", iteration, cor);
rc = rf_clock_info(&clkErr, &clkErrRes);
CHECK_RC_MSG(rc, "Clock info failed.\n");
/*
* TODO: use the clock error resolution here, implement it as a
* a PID controller..
*/
/* Picocell class requires 0.1ppm.. but that is 'too easy' */
if (fabs(clkErr / 1000.0f) <= 0.05f) {
printf("The calibration value is: %d\n", cor);
return 1;
}
cor -= clkErr / 2;
rc = set_clock_cor(cor, calib, source);
CHECK_RC_MSG(rc, "Clock correction failed.\n");
}
return -1;
}
static int find_initial_clock(HANDLE layer1, int *clock)
{
int i;
printf("Trying to find an initial clock value.\n");
for (i = 0; i < 1000; ++i) {
int rc;
int cor = i * 150;
rc = wait_for_sync(layer1, cor, calib, source);
if (rc == 1) {
printf("Found initial clock offset: %d\n", cor);
*clock = cor;
break;
} else {
CHECK_RC_MSG(rc, "Failed to set new clock value.\n");
}
cor = i * -150;
rc = wait_for_sync(layer1, cor, calib, source);
if (rc == 1) {
printf("Found initial clock offset: %d\n", cor);
*clock = cor;
break;
} else {
CHECK_RC_MSG(rc, "Failed to set new clock value.\n");
}
}
return 0;
}
static int calib_clock_netlisten(void)
{
int rc, cor = initial_cor;
float mean_rssi;
HANDLE layer1;
rc = power_scan(band, cal_arfcn, 10, &mean_rssi);
CHECK_RC_MSG(rc, "ARFCN measurement scan failed");
if (mean_rssi < -118.0f)
printf("ARFCN has weak signal for calibration: %f\n", mean_rssi);
/* initial lock */
rc = follow_sch(band, cal_arfcn, calib, source, &layer1);
if (rc == -23)
rc = find_initial_clock(layer1, &cor);
CHECK_RC_MSG(rc, "Following SCH failed");
/* now try to calibrate it */
rc = set_clock_cor(cor, calib, source);
CHECK_RC_MSG(rc, "Clock setup failed.");
calib_clock_after_sync();
rc = mph_close(layer1);
CHECK_RC_MSG(rc, "MPH-Close");
return EXIT_SUCCESS;
}
static int calib_clock(void)
{
int rc;
/* now try to calibrate it */
rc = set_clock_cor(initial_cor, calib, source);
CHECK_RC_MSG(rc, "Clock setup failed.");
calib_get_clock_error();
return EXIT_SUCCESS;
}
static int bcch_follow(void)
{
int rc, cor = initial_cor;
float mean_rssi;
HANDLE layer1;
rc = power_scan(band, cal_arfcn, 10, &mean_rssi);
CHECK_RC_MSG(rc, "ARFCN measurement scan failed");
if (mean_rssi < -118.0f)
printf("ARFCN has weak signal for calibration: %f\n", mean_rssi);
/* initial lock */
rc = follow_sch(band, cal_arfcn, calib, source, &layer1);
if (rc == -23)
rc = find_initial_clock(layer1, &cor);
CHECK_RC_MSG(rc, "Following SCH failed");
/* identify the BSIC and set it as TSC */
rc = find_bsic();
CHECK_COND_MSG(rc < 0, rc, "Identifying the BSIC failed");
rc = set_tsc_from_bsic(layer1, rc);
CHECK_RC_MSG(rc, "Setting the TSC failed");
/* follow the bcch */
rc = follow_bcch(layer1);
CHECK_RC_MSG(rc, "Follow BCCH");
/* follow the pch */
if (action == ACTION_BCCH_CCCH) {
rc = follow_pch(layer1);
CHECK_RC_MSG(rc, "Follow BCCH/CCCH");
}
/* now wait for the PhDataInd */
for (;;) {
uint32_t fn;
uint8_t block;
uint8_t data[23];
size_t size;
struct gsm_time gsmtime;
GsmL1_Sapi_t sapi;
rc = wait_for_data(data, &size, &fn, &block, &sapi);
if (rc == 1)
continue;
CHECK_RC_MSG(rc, "No Data Indication");
gsm_fn2gsmtime(&gsmtime, fn);
printf("%02u/%02u/%02u %6s %s\n",
gsmtime.t1, gsmtime.t2, gsmtime.t3,
get_value_string(sapi_names, sapi),
osmo_hexdump(data, size));
}
rc = mph_close(layer1);
CHECK_RC_MSG(rc, "MPH-Close");
return EXIT_SUCCESS;
}
int main(int argc, char **argv)
{
int rc;
handle_options(argc, argv);
printf("Initializing the Layer1\n");
rc = initialize_layer1(dsp_flags);
CHECK_RC(rc);
printf("Fetching system info.\n");
rc = print_system_info();
CHECK_RC(rc);
printf("Opening RF frontend with clock(%d) and correction(%d)\n",
calib, initial_cor);
rc = activate_rf_frontend(calib, initial_cor);
CHECK_RC(rc);
if (action == ACTION_SCAN)
return scan_band();
else if (action == ACTION_BCCH || action == ACTION_BCCH_CCCH)
return bcch_follow();
else {
if (source == SuperFemto_ClkSrcId_NetList)
return calib_clock_netlisten();
return calib_clock();
}
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,800 @@
/* Layer1 handling for the DSP/FPGA */
/*
* (C) 2012-2013 Holger Hans Peter Freyther
*
* 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 <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sysmocom/femtobts/superfemto.h>
#include <sysmocom/femtobts/gsml1prim.h>
#include "sysmobts-layer1.h"
#define ARRAY_SIZE(ar) (sizeof(ar)/sizeof((ar)[0]))
#define BTS_DSP2ARM "/dev/msgq/superfemto_dsp2arm"
#define BTS_ARM2DSP "/dev/msgq/superfemto_arm2dsp"
#define L1_SIG_ARM2DSP "/dev/msgq/gsml1_sig_arm2dsp"
#define L1_SIG_DSP2ARM "/dev/msgq/gsml1_sig_dsp2arm"
int set_clock_cor(int clock_cor, int calib, int source);
static int wait_read_ignore(int seconds);
static int sys_dsp2arm = -1,
sys_arm2dsp = -1,
sig_dsp2arm = -1,
sig_arm2dsp = -1;
static int sync_indicated = 0;
static int time_indicated = 0;
static int open_devices()
{
sys_dsp2arm = open(BTS_DSP2ARM, O_RDONLY);
if (sys_dsp2arm == -1) {
perror("Failed to open dsp2arm system queue");
return -1;
}
sys_arm2dsp = open(BTS_ARM2DSP, O_WRONLY);
if (sys_arm2dsp == -1) {
perror("Failed to open arm2dsp system queue");
return -2;
}
sig_dsp2arm = open(L1_SIG_DSP2ARM, O_RDONLY);
if (sig_dsp2arm == -1) {
perror("Failed to open dsp2arm sig queue");
return -3;
}
sig_arm2dsp = open(L1_SIG_ARM2DSP, O_WRONLY);
if (sig_arm2dsp == -1) {
perror("Failed to open arm2dsp sig queue");
return -4;
}
return 0;
}
/**
* Send a primitive to the system queue
*/
static int send_primitive(int primitive, SuperFemto_Prim_t *prim)
{
prim->id = primitive;
return write(sys_arm2dsp, prim, sizeof(*prim)) != sizeof(*prim);
}
/**
* Wait for a confirmation
*/
static int wait_primitive(int wait_for, SuperFemto_Prim_t *prim)
{
memset(prim, 0, sizeof(*prim));
int rc = read(sys_dsp2arm, prim, sizeof(*prim));
if (rc != sizeof(*prim)) {
printf("Short read in %s: %d\n", __func__, rc);
return -1;
}
if (prim->id != wait_for) {
printf("Got primitive %d but waited for %d\n",
prim->id, wait_for);
return -2;
}
return 0;
}
/* The Cnf for the Req, assume it is a +1 */
static int answer_for(int primitive)
{
return primitive + 1;
}
static int send_recv_primitive(int p, SuperFemto_Prim_t *prim)
{
int rc;
rc = send_primitive(p, prim);
if (rc != 0)
return -1;
rc = wait_primitive(answer_for(p), prim);
if (rc != 0)
return -2;
return 0;
}
static int answer_for_sig(int prim)
{
static const GsmL1_PrimId_t cnf[] = {
[GsmL1_PrimId_MphInitReq] = GsmL1_PrimId_MphInitCnf,
[GsmL1_PrimId_MphCloseReq] = GsmL1_PrimId_MphCloseCnf,
[GsmL1_PrimId_MphConnectReq] = GsmL1_PrimId_MphConnectCnf,
[GsmL1_PrimId_MphActivateReq] = GsmL1_PrimId_MphActivateCnf,
[GsmL1_PrimId_MphConfigReq] = GsmL1_PrimId_MphConfigCnf,
[GsmL1_PrimId_MphMeasureReq] = GsmL1_PrimId_MphMeasureCnf,
};
if (prim < 0 || prim >= ARRAY_SIZE(cnf)) {
printf("Unknown primitive: %d\n", prim);
exit(-3);
}
return cnf[prim];
}
static int is_indication(int prim)
{
return
prim == GsmL1_PrimId_MphTimeInd ||
prim == GsmL1_PrimId_MphSyncInd ||
prim == GsmL1_PrimId_PhConnectInd ||
prim == GsmL1_PrimId_PhReadyToSendInd ||
prim == GsmL1_PrimId_PhDataInd ||
prim == GsmL1_PrimId_PhRaInd;
}
static int send_recv_sig_prim(int p, GsmL1_Prim_t *prim)
{
int rc;
prim->id = p;
rc = write(sig_arm2dsp, prim, sizeof(*prim));
if (rc != sizeof(*prim)) {
printf("Failed to write: %d\n", rc);
return -1;
}
do {
rc = read(sig_dsp2arm, prim, sizeof(*prim));
if (rc != sizeof(*prim)) {
printf("Failed to read: %d\n", rc);
return -2;
}
} while (is_indication(prim->id));
if (prim->id != answer_for_sig(p)) {
printf("Wrong L1 result got %d wanted %d for prim: %d\n",
prim->id, answer_for_sig(p), p);
return -3;
}
return 0;
}
static int wait_for_indication(int p, GsmL1_Prim_t *prim)
{
int rc;
memset(prim, 0, sizeof(*prim));
struct timespec start_time, now_time;
clock_gettime(CLOCK_MONOTONIC, &start_time);
/*
* TODO: select.... with timeout. The below will work 99% as we will
* get time indications very soonish after the connect
*/
for (;;) {
clock_gettime(CLOCK_MONOTONIC, &now_time);
if (now_time.tv_sec - start_time.tv_sec > 10) {
printf("Timeout waiting for indication.\n");
return -4;
}
rc = read(sig_dsp2arm, prim, sizeof(*prim));
if (rc != sizeof(*prim)) {
printf("Failed to read.\n");
return -1;
}
if (!is_indication(prim->id)) {
printf("No indication: %d\n", prim->id);
return -2;
}
if (p != prim->id && prim->id == GsmL1_PrimId_MphSyncInd) {
printf("Got sync.\n");
sync_indicated = 1;
continue;
}
if (p != prim->id && prim->id == GsmL1_PrimId_MphTimeInd) {
time_indicated = 1;
continue;
}
if (p != prim->id) {
printf("Wrong indication got %d wanted %d\n",
prim->id, p);
return -3;
}
break;
}
return 0;
}
static int set_trace_flags(uint32_t dsp)
{
SuperFemto_Prim_t prim;
memset(&prim, 0, sizeof(prim));
prim.u.setTraceFlagsReq.u32Tf = dsp;
return send_primitive(SuperFemto_PrimId_SetTraceFlagsReq, &prim);
}
static int reset_and_wait()
{
int rc;
SuperFemto_Prim_t prim;
memset(&prim, 0, sizeof(prim));
rc = send_recv_primitive(SuperFemto_PrimId_Layer1ResetReq, &prim);
if (rc != 0)
return -1;
if (prim.u.layer1ResetCnf.status != GsmL1_Status_Success)
return -2;
return 0;
}
/**
* Open the message queues and (re-)initialize the DSP and FPGA
*/
int initialize_layer1(uint32_t dsp_flags)
{
if (open_devices() != 0) {
printf("Failed to open devices.\n");
return -1;
}
if (set_trace_flags(dsp_flags) != 0) {
printf("Failed to set dsp flags.\n");
return -2;
}
if (reset_and_wait() != 0) {
printf("Failed to reset the firmware.\n");
return -3;
}
return 0;
}
/**
* Print systems infos
*/
int print_system_info()
{
int rc;
SuperFemto_Prim_t prim;
memset(&prim, 0, sizeof(prim));
rc = send_recv_primitive(SuperFemto_PrimId_SystemInfoReq, &prim);
if (rc != 0) {
printf("Failed to send SystemInfoRequest.\n");
return -1;
}
if (prim.u.systemInfoCnf.status != GsmL1_Status_Success) {
printf("Failed to request SystemInfoRequest.\n");
return -2;
}
#define INFO_DSP(x) x.u.systemInfoCnf.dspVersion
#define INFO_FPGA(x) x.u.systemInfoCnf.fpgaVersion
#ifdef FEMTOBTS_NO_BOARD_VERSION
#define BOARD_REV(x) -1
#define BOARD_OPT(x) -1
#define COMPILED_MAJOR (FEMTOBTS_API_VERSION >> 16)
#define COMPILED_MINOR ((FEMTOBTS_API_VERSION >> 8) & 0xff)
#define COMPILED_BUILD (FEMTOBTS_API_VERSION & 0xff)
#else
#define BOARD_REV(x) x.u.systemInfoCnf.boardVersion.rev
#define BOARD_OPT(x) x.u.systemInfoCnf.boardVersion.option
#define COMPILED_MAJOR (SUPERFEMTO_API_VERSION >> 16)
#define COMPILED_MINOR ((SUPERFEMTO_API_VERSION >> 8) & 0xff)
#define COMPILED_BUILD (SUPERFEMTO_API_VERSION & 0xff)
#endif
printf("Compiled against: v%u.%u.%u\n",
COMPILED_MAJOR, COMPILED_MINOR, COMPILED_BUILD);
printf("Running DSP v%d.%d.%d FPGA v%d.%d.%d Rev: %d Option: %d\n",
INFO_DSP(prim).major, INFO_DSP(prim).minor, INFO_DSP(prim).build,
INFO_FPGA(prim).major, INFO_FPGA(prim).minor, INFO_FPGA(prim).build,
BOARD_REV(prim), BOARD_OPT(prim));
if (COMPILED_MAJOR != INFO_DSP(prim).major || COMPILED_MINOR != INFO_DSP(prim).minor) {
printf("WARNING! WARNING! WARNING! WARNING! WARNING\n");
printf("You might run this against an incompatible firmware.\n");
printf("Continuing anyway but the result might be broken\n");
}
#undef INFO_DSP
#undef INFO_FPGA
#undef BOARD_REV
#undef BOARD_OPT
#undef COMPILED_MAJOR
#undef COMPILED_MINOR
#undef COMPILED_BUILD
return 0;
}
int activate_rf_frontend(int clock_source, int initial_cor)
{
int rc;
SuperFemto_Prim_t prim;
memset(&prim, 0, sizeof(prim));
prim.u.activateRfReq.timing.u8TimSrc = 1;
prim.u.activateRfReq.msgq.u8UseTchMsgq = 0;
prim.u.activateRfReq.msgq.u8UsePdtchMsgq = 0;
prim.u.activateRfReq.rfTrx.iClkCor = initial_cor;
prim.u.activateRfReq.rfTrx.clkSrc = clock_source;
#if SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,4,0)
prim.u.activateRfReq.rfRx.iClkCor = initial_cor;
prim.u.activateRfReq.rfRx.clkSrc = clock_source;
#endif
rc = send_recv_primitive(SuperFemto_PrimId_ActivateRfReq, &prim);
return rc;
}
static int mph_init(int band, int arfcn, HANDLE *layer1)
{
int rc;
GsmL1_Prim_t prim;
memset(&prim, 0, sizeof(prim));
prim.u.mphInitReq.deviceParam.devType = GsmL1_DevType_Rxd;
prim.u.mphInitReq.deviceParam.freqBand = band;
prim.u.mphInitReq.deviceParam.u16Arfcn = arfcn;
prim.u.mphInitReq.deviceParam.u16BcchArfcn = arfcn;
prim.u.mphInitReq.deviceParam.fRxPowerLevel = -75.f;
prim.u.mphInitReq.deviceParam.u8AutoTA = 1;
rc = send_recv_sig_prim(GsmL1_PrimId_MphInitReq, &prim);
if (rc != 0) {
printf("Failed to initialize the physical channel.\n");
return -1;
}
if (prim.u.mphInitCnf.status != GsmL1_Status_Success) {
printf("MPH Init failed.\n");
return -2;
}
#if 0
if (prim.u.mphInitCnf.freqBand != band) {
printf("Layer1 ignored the band: %d\n",
prim.u.mphInitCnf.freqBand);
return -3;
}
#endif
*layer1 = prim.u.mphInitCnf.hLayer1;
return 0;
}
int mph_close(HANDLE layer1)
{
int rc;
GsmL1_Prim_t prim;
memset(&prim, 0, sizeof(prim));
prim.u.mphCloseReq.hLayer1 = layer1;
rc = send_recv_sig_prim(GsmL1_PrimId_MphCloseReq, &prim);
if (rc != 0) {
printf("Failed to close the MPH\n");
return -6;
}
if (prim.u.mphCloseCnf.status != GsmL1_Status_Success) {
printf("MPH Close failed.\n");
return -7;
}
return 0;
}
int follow_sch(int band, int arfcn, int clock, int ref, HANDLE *layer1)
{
int rc;
GsmL1_Prim_t prim;
time_indicated = 0;
sync_indicated = 0;
rc = mph_init(band, arfcn, layer1);
if (rc != 0)
return rc;
/* 1.) Connect */
memset(&prim, 0, sizeof(prim));
prim.u.mphConnectReq.hLayer1 = *layer1;
prim.u.mphConnectReq.u8Tn = 0;
prim.u.mphConnectReq.logChComb = GsmL1_LogChComb_IV;
rc = send_recv_sig_prim(GsmL1_PrimId_MphConnectReq, &prim);
if (rc != 0) {
printf("Failed to connect.\n");
return -1;
}
if (prim.u.mphConnectCnf.status != GsmL1_Status_Success) {
printf("Connect failed.\n");
return -2;
}
if (prim.u.mphConnectCnf.u8Tn != 0) {
printf("Wrong timeslot.\n");
return -3;
}
/* 2.) Activate */
memset(&prim, 0, sizeof(prim));
prim.u.mphActivateReq.hLayer1 = *layer1;
prim.u.mphActivateReq.u8Tn = 0;
prim.u.mphActivateReq.sapi = GsmL1_Sapi_Sch;
prim.u.mphActivateReq.dir = GsmL1_Dir_RxDownlink;
rc = send_recv_sig_prim(GsmL1_PrimId_MphActivateReq, &prim);
if (rc != 0) {
printf("Activation failed.\n");
return -4;
}
if (prim.u.mphActivateCnf.status != GsmL1_Status_Success) {
printf("Activation not successful.\n");
return -5;
}
/* 3.) Wait for indication... TODO: check... */
printf("Waiting for connect indication.\n");
rc = wait_for_indication(GsmL1_PrimId_PhConnectInd, &prim);
if (rc != 0) {
printf("Didn't get a connect indication.\n");
return rc;
}
/* 4.) Indication Syndication TODO: check... */
if (!sync_indicated) {
printf("Waiting for sync indication.\n");
rc = wait_for_indication(GsmL1_PrimId_MphSyncInd, &prim);
if (rc < 0) {
printf("Didn't get a sync indication.\n");
return -23;
} else if (rc == 0) {
if (!prim.u.mphSyncInd.u8Synced) {
printf("Failed to get sync.\n");
return -23;
} else {
printf("Synced.\n");
}
}
} else {
printf("Already synced.\n");
}
return 0;
}
static int follow_sapi(HANDLE layer1, const GsmL1_Sapi_t sapi)
{
int rc;
GsmL1_Prim_t prim;
/* 1.) Activate BCCH or such... */
memset(&prim, 0, sizeof(prim));
prim.u.mphActivateReq.hLayer1 = layer1;
prim.u.mphActivateReq.u8Tn = 0;
prim.u.mphActivateReq.sapi = sapi;
prim.u.mphActivateReq.dir = GsmL1_Dir_RxDownlink;
rc = send_recv_sig_prim(GsmL1_PrimId_MphActivateReq, &prim);
if (rc != 0) {
printf("Activation failed.\n");
return -4;
}
if (prim.u.mphActivateCnf.status != GsmL1_Status_Success) {
printf("Activation not successful.\n");
return -5;
}
/* 2.) Wait for indication... */
printf("Waiting for connect indication.\n");
rc = wait_for_indication(GsmL1_PrimId_PhConnectInd, &prim);
if (rc != 0) {
printf("Didn't get a connect indication.\n");
return rc;
}
if (prim.u.phConnectInd.sapi != sapi) {
printf("Got a connect indication for the wrong type: %d\n",
prim.u.phConnectInd.sapi);
return -6;
}
/* 3.) Wait for PhDataInd... */
printf("Waiting for data.\n");
rc = wait_for_indication(GsmL1_PrimId_PhDataInd, &prim);
if (rc != 0) {
printf("Didn't get data.\n");
return rc;
}
return 0;
}
int follow_bcch(HANDLE layer1)
{
return follow_sapi(layer1, GsmL1_Sapi_Bcch);
}
int follow_pch(HANDLE layer1)
{
return follow_sapi(layer1, GsmL1_Sapi_Pch);
}
int find_bsic(void)
{
int rc, i;
GsmL1_Prim_t prim;
printf("Waiting for SCH data.\n");
for (i = 0; i < 10; ++i) {
uint8_t bsic;
rc = wait_for_indication(GsmL1_PrimId_PhDataInd, &prim);
if (rc < 0) {
printf("Didn't get SCH data.\n");
return rc;
}
if (prim.u.phDataInd.sapi != GsmL1_Sapi_Sch)
continue;
bsic = (prim.u.phDataInd.msgUnitParam.u8Buffer[0] >> 2) & 0xFF;
return bsic;
}
printf("Giving up finding the SCH\n");
return -1;
}
int set_tsc_from_bsic(HANDLE layer1, int bsic)
{
int rc;
int tsc = bsic & 0x7;
GsmL1_Prim_t prim;
memset(&prim, 0, sizeof(prim));
prim.u.mphConfigReq.hLayer3 = 0x23;
prim.u.mphConfigReq.hLayer1 = layer1;
prim.u.mphConfigReq.cfgParamId = GsmL1_ConfigParamId_SetNbTsc;
prim.u.mphConfigReq.cfgParams.setNbTsc.u8NbTsc = tsc;
rc = send_recv_sig_prim(GsmL1_PrimId_MphConfigReq, &prim);
if (rc != 0) {
printf("Failed to send configure.\n");
}
if (prim.u.mphConfigCnf.status != GsmL1_Status_Success) {
printf("Failed to set the config cnf.\n");
return -1;
}
return 0;
}
int set_clock_cor(int clock_cor, int calib, int source)
{
int rc;
SuperFemto_Prim_t prim;
memset(&prim, 0, sizeof(prim));
prim.u.rfClockSetupReq.rfTrx.iClkCor = clock_cor;
prim.u.rfClockSetupReq.rfTrx.clkSrc = calib;
#if SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,4,0)
prim.u.rfClockSetupReq.rfRx.iClkCor = clock_cor;
prim.u.rfClockSetupReq.rfRx.clkSrc = calib;
#endif
prim.u.rfClockSetupReq.rfTrxClkCal.clkSrc = source;
rc = send_recv_primitive(SuperFemto_PrimId_RfClockSetupReq, &prim);
if (rc != 0) {
printf("Failed to set the clock setup.\n");
return -1;
}
if (prim.u.rfClockSetupCnf.status != GsmL1_Status_Success) {
printf("Clock setup was not successfull.\n");
return -2;
}
return 0;
}
int rf_clock_info(int *clkErr, int *clkErrRes)
{
SuperFemto_Prim_t prim;
memset(&prim, 0, sizeof(prim));
int rc;
/* reset the counter */
prim.u.rfClockInfoReq.u8RstClkCal = 1;
rc = send_recv_primitive(SuperFemto_PrimId_RfClockInfoReq, &prim);
if (rc != 0) {
printf("Failed to reset the clock info.\n");
return -1;
}
/* wait for a value */
wait_read_ignore(15);
/* ask for the current counter/error */
memset(&prim, 0, sizeof(prim));
prim.u.rfClockInfoReq.u8RstClkCal = 0;
rc = send_recv_primitive(SuperFemto_PrimId_RfClockInfoReq, &prim);
if (rc != 0) {
printf("Failed to get the clock info.\n");
return -2;
}
printf("Error: %d Res: %d\n",
prim.u.rfClockInfoCnf.rfTrxClkCal.iClkErr,
prim.u.rfClockInfoCnf.rfTrxClkCal.iClkErrRes);
*clkErr = prim.u.rfClockInfoCnf.rfTrxClkCal.iClkErr;
*clkErrRes = prim.u.rfClockInfoCnf.rfTrxClkCal.iClkErrRes;
return 0;
}
int power_scan(int band, int arfcn, int duration, float *mean_rssi)
{
int rc;
HANDLE layer1;
GsmL1_Prim_t prim;
/* init */
rc = mph_init(band, arfcn, &layer1);
if (rc != 0)
return rc;
/* mph measure request */
memset(&prim, 0, sizeof(prim));
prim.u.mphMeasureReq.hLayer1 = layer1;
prim.u.mphMeasureReq.u32Duration = duration;
rc = send_recv_sig_prim(GsmL1_PrimId_MphMeasureReq, &prim);
if (rc != 0) {
printf("Failed to send measurement request.\n");
return -4;
}
if (prim.u.mphMeasureCnf.status != GsmL1_Status_Success) {
printf("MphMeasureReq was not confirmed.\n");
return -5;
}
*mean_rssi = prim.u.mphMeasureCnf.fMeanRssi;
/* close */
rc = mph_close(layer1);
return rc;
}
/**
* Wait for indication...
*/
int wait_for_sync(HANDLE layer1, int cor, int calib, int source)
{
GsmL1_Prim_t prim;
int rc;
rc = set_clock_cor(cor, calib, source);
if (rc != 0) {
printf("Failed to set the clock correction.\n");
return -1;
}
sync_indicated = 0;
rc = wait_for_indication(GsmL1_PrimId_MphSyncInd, &prim);
if (rc < 0 && rc != -4) {
return rc;
} else if (rc == 0) {
if (!prim.u.mphSyncInd.u8Synced) {
printf("Failed to get sync.\n");
return 0;
}
printf("Synced.\n");
return 1;
}
return 0;
}
int wait_for_data(uint8_t *data, size_t *size, uint32_t *fn, uint8_t *block, GsmL1_Sapi_t *sap)
{
GsmL1_Prim_t prim;
int rc;
rc = wait_for_indication(GsmL1_PrimId_PhDataInd, &prim);
if (rc < 0)
return rc;
if (prim.u.phDataInd.sapi == GsmL1_Sapi_Sch)
return 1;
*size = prim.u.phDataInd.msgUnitParam.u8Size;
*fn = prim.u.phDataInd.u32Fn;
*block = prim.u.phDataInd.u8BlockNbr;
*sap = prim.u.phDataInd.sapi;
memcpy(data, prim.u.phDataInd.msgUnitParam.u8Buffer, *size);
return 0;
}
/**
* Make sure the pipe is not running full.
*
*/
static int wait_read_ignore(int seconds)
{
int max, rc;
fd_set fds;
struct timeval timeout;
max = sys_dsp2arm > sig_dsp2arm ? sys_dsp2arm : sig_dsp2arm;
timeout.tv_sec = seconds;
timeout.tv_usec = 0;
while (1) {
FD_ZERO(&fds);
FD_SET(sys_dsp2arm, &fds);
FD_SET(sig_dsp2arm, &fds);
rc = select(max + 1, &fds, NULL, NULL, &timeout);
if (rc == -1) {
printf("Failed to select.\n");
return -1;
} else if (rc) {
if (FD_ISSET(sys_dsp2arm, &fds)) {
SuperFemto_Prim_t prim;
rc = read(sys_dsp2arm, &prim, sizeof(prim));
if (rc != sizeof(prim)) {
perror("Failed to read system primitive");
return -2;
}
}
if (FD_ISSET(sig_dsp2arm, &fds)) {
GsmL1_Prim_t prim;
rc = read(sig_dsp2arm, &prim, sizeof(prim));
if (rc != sizeof(prim)) {
perror("Failed to read signal primitiven");
return -3;
}
}
} else if (timeout.tv_sec <= 0 && timeout.tv_usec <= 0) {
break;
}
#ifndef __linux__
#error "Non portable code"
#endif
}
return 0;
}

View File

@@ -0,0 +1,45 @@
#ifndef SYSMOBTS_LAYER_H
#define SYSMOBTS_LAYER_H
#include <sysmocom/femtobts/superfemto.h>
#ifdef FEMTOBTS_API_VERSION
#define SuperFemto_PrimId_t FemtoBts_PrimId_t
#define SuperFemto_Prim_t FemtoBts_Prim_t
#define SuperFemto_PrimId_SystemInfoReq FemtoBts_PrimId_SystemInfoReq
#define SuperFemto_PrimId_SystemInfoCnf FemtoBts_PrimId_SystemInfoCnf
#define SuperFemto_SystemInfoCnf_t FemtoBts_SystemInfoCnf_t
#define SuperFemto_PrimId_SystemFailureInd FemtoBts_PrimId_SystemFailureInd
#define SuperFemto_PrimId_ActivateRfReq FemtoBts_PrimId_ActivateRfReq
#define SuperFemto_PrimId_ActivateRfCnf FemtoBts_PrimId_ActivateRfCnf
#define SuperFemto_PrimId_DeactivateRfReq FemtoBts_PrimId_DeactivateRfReq
#define SuperFemto_PrimId_DeactivateRfCnf FemtoBts_PrimId_DeactivateRfCnf
#define SuperFemto_PrimId_SetTraceFlagsReq FemtoBts_PrimId_SetTraceFlagsReq
#define SuperFemto_PrimId_RfClockInfoReq FemtoBts_PrimId_RfClockInfoReq
#define SuperFemto_PrimId_RfClockInfoCnf FemtoBts_PrimId_RfClockInfoCnf
#define SuperFemto_PrimId_RfClockSetupReq FemtoBts_PrimId_RfClockSetupReq
#define SuperFemto_PrimId_RfClockSetupCnf FemtoBts_PrimId_RfClockSetupCnf
#define SuperFemto_PrimId_Layer1ResetReq FemtoBts_PrimId_Layer1ResetReq
#define SuperFemto_PrimId_Layer1ResetCnf FemtoBts_PrimId_Layer1ResetCnf
#define SuperFemto_PrimId_NUM FemtoBts_PrimId_NUM
#define HW_SYSMOBTS_V1 1
#define SUPERFEMTO_API(x,y,z) FEMTOBTS_API(x,y,z)
#endif
extern int initialize_layer1(uint32_t dsp_flags);
extern int print_system_info();
extern int activate_rf_frontend(int clock_source, int clock_cor);
extern int power_scan(int band, int arfcn, int duration, float *mean_rssi);
extern int follow_sch(int band, int arfcn, int calib, int reference, HANDLE *layer1);
extern int follow_bch(HANDLE layer1);
extern int find_bsic(void);
extern int set_tsc_from_bsic(HANDLE layer1, int bsic);
extern int set_clock_cor(int clock_corr, int calib, int source);
extern int rf_clock_info(int *clkErr, int *clkErrRes);
extern int mph_close(HANDLE layer1);
extern int wait_for_sync(HANDLE layer1, int cor, int calib, int source);
extern int follow_bcch(HANDLE layer1);
extern int follow_pch(HANDLE layer1);
extern int wait_for_data(uint8_t *data, size_t *size, uint32_t *fn, uint8_t *block, GsmL1_Sapi_t *sapi);
#endif

View File

@@ -0,0 +1,12 @@
[Unit]
Description=osmo-bts manager for sysmoBTS
[Service]
Type=simple
ExecStart=/usr/bin/sysmobts-mgr -ns -c /etc/osmocom/sysmobts-mgr.cfg
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
Alias=osmo-bts-mgr.service

View File

@@ -9,14 +9,12 @@
# Description:
### END INIT INFO
. /etc/default/rcS
case "$1" in
start)
/usr/bin/screen -d -m -c /etc/osmocom/screenrc-sysmobts
/usr/bin/screen -d -m -c /etc/osmocom/screenrc-sysmobts -S sysmobts
;;
stop)
echo "This script doesn't support stop"
/usr/bin/screen -d -r sysmobts -X quit
exit 1
;;
restart|reload|force-reload)

20
contrib/sysmobts.service Normal file
View File

@@ -0,0 +1,20 @@
[Unit]
Description=sysmocom sysmoBTS
[Service]
Type=simple
ExecStartPre=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness'
ExecStart=/usr/bin/osmo-bts-sysmo -s -c /etc/osmocom/osmo-bts.cfg -M
ExecStopPost=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness'
ExecStopPost=/bin/sh -c 'cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; sleep 3s; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0; sleep 1s'
Restart=always
RestartSec=2
RestartPreventExitStatus=1
# The msg queues must be read fast enough
CPUSchedulingPolicy=rr
CPUSchedulingPriority=1
[Install]
WantedBy=multi-user.target
Alias=osmo-bts-sysmo.service

486
debian/changelog vendored Normal file
View File

@@ -0,0 +1,486 @@
osmo-bts (0.6.0) unstable; urgency=medium
[ Holger Hans Peter Freyther ]
* Initial release.
* misc: Ignore files generated by a debian packaging build
* jenkins: Add the build script from jenkins here
* jenkins: Add the build script from jenkins here
* sysmobts: Add the barebox boot state reservation
* sysmobts: Fix eeprom padding before gpg key
* ci/spatch: Remove the "static" analysis handling
* oct: Attempt to enable the Octphy for the osmo-bts-oct build
* debian: Use the header files installed by openbsc-dev
* build: Do not require more headers from OpenBSC
* sysmobts: Make reservation for mode/netmask/ip and suc
* sysmobts: Store a simple network config in the EEPROM as well
[ Max ]
* Ensure TRX invariant
* Use libosmocore function for uplink measurements
* Fix debug output
* Fix RTP timestamps in case of DTX
* Add DTXd support for sysmoBTS and LC15
* Use libosmocodec for AMR RTP
* octphy: Use the app. info. defaults as base
* Fix debug output
* DTXd: store/repeat last SID
* DTXd: store/repeat last SID
* DTXu: mark beginning of speech burst in RTP
* Fix OML activation
* TRX: Add vty command to power on/off transceiver
* TRX: add configuration example
* Add .gitreview
* DTX: add support for AMR/HR
* Move copy-pasted code into common part
* Use libosmocodec functions for AMR
* Use error values instead of number for RSL error
* Clarify logging message
* Make get_lchan_by_chan_nr globally available
* DTXu: move copy-pasted code to common part
* Remove duplicated nibble shift code
* TRX: add Uplink DTX support for FR/HR
* Mark array as static const
* sysmobts: dump PRACH and PTCCH parameters
* Activate PTCCH UL
* Fix dsp tracing at phy config
* octphy: fix build
* Fill measurements data for L1SAP
* sysmo: ts_connect: log channel combination name instead of number
* DTX: fix last SID saving
* DTX: fix SID repeat scheduling
* DTX: fix SID logic
* lc15, sysmo: Use SID_FIRST_P1 to initiate DTX
* DTX: check Marker bit to send ONSET to L1
* DTX: remove misleading comment
* LC15: Clarify msgb ownership / fix memory leaks
* DTX: move scheduling check inside repeat_last_sid
* DTX: further AMR SID cache fixes (lc15, sysmo)
* DTX: move ONSET detection into separate function
* DTX: send AMR voice alongside with ONSET
* DTX: fix conversion from fn to ms
* Move copy-pasted array into shared header
* DTX DL: use FSM for AMR
* TRX: fix building with latest DTX changes
* DTX: fix array size calculation
* DTX AMR - fix buffer length check
* Replace magic number with define
* Fix lc15 build
* Extend RTP RX callback parameters
* DTX HR - fix array size calculation
* Fix DTX DL AMR SIDscheduling logic
* Add tools to check DTX operation
* DTX DL: split ONSET state handling
* Remove obsolete define
* DTX DL: add AMR HR support to scheduling check
* DTX fix ONSET handling
* dtx_check.gawk: Fix false-positives in DTX check
* Fix tests linking with libosmocodec
* DTX DL: tighten check for enabled operation
* DTX: wrap FSM signal dispatching
* Add libosmocodec for octphy build
* dtx_check.gawk: add check for repetitive SID FIRST
* Remove duplicated code
* Replace link_id constant with define
* DTX DL AMR: rewrite FSM recursion
* Remove duplicated code
* Fix AGCH/PCH proportional allocation
* TRX: prevent segfault upon phy init
* DTX: add explicit check if DTX enabled
* Save RTP metadata in Control Buffer
* osmo-bts-trx: fix lchan deactivation
* DTX: fix TS adjustment for ONSET
* Optionally use adaptive RTP jitter buffering
* Integrate Debian packaging changes
* DTX AMR HR: fix inhibition
* Add copyright for .deb packages
* Move code to libosmocore
* Log socket path on error
* Add Abis OML failure event reporting
* Alarm on various errors
* Remove obsolete define TLVP_PRES_LEN
* scheduler: log lchan on which prim error occured
* deb: use gsm_data_shared.* from openbsc-dev
* OML: internalize failure reporting
* Add ctrl command to send OML alert
* Fix typo in TCH/H interleaving table
* Use oml-alert CTRL command for temp report
* Remove code duplication
* Handle ctrl cmd allocation failures
* Check for suitable lchan type when detecting HO
* osmo-bts-trx: fix scheduling of broken frames
* Sync protocol with OsmoPCU
* vty: reduce code duplication
* Handle TXT indication from OsmoPCU
* Add MS TO to RSL measurements
* Signal to BSC when PCU disconnects
* Prepare for extended SI2quater support
* Set BTS variant while initializing BTS model
* Prepare for BTS attribute reporting via OML
* osmo-bts-trx: use libosmocoding
* Remove redundant test
* Implement basic Get Attribute responder
* Add version to phy_instance
* OML: fix Coverity-reported issues
* Re-add version to phy_instance
* Use systemd template specifiers
* Place *-mgr config examples according to BTS model
* lc15: add example systemd service file
* Extend Get Attribute responder
* Set and report BTS features
* Cleanup SI scheduling
* RSL: receive and send multiple SI2q messages
* RSL: check for abnormal SI2q values
* lc15bts-mgr: use extended config file example
* Move parameter file opening into separate function
* Move common steps into common jenkins helper
* lc15: add jenkins helper
* Use generic L1 headers helper
* Copy sysmobts.service to osmo-bts-sysmo
* OML: move BTS number check into separate function
* lc15: make jenkins helper executable
* lc15: fix jenkins build
* Add missing include for abis.h header file
* RSL: receive and send multiple SI2q messages
* Use release helper from libosmocore
* si2q: do not consider count update as error
* Cleanup example config files
* Fix .deb build
* Unify *.service files
* lc15: cleanup board parameters reading
* lc15-mgr: update parameter read/write
* lc15: fix BTS revision and hw options
* lc15: make default config usable
* lc15: port lc15bts-mgr changes
* lc15bts-mgr: separate service file
* lc15: port lc15bts-mgr dependency changes
* Simplify jenkins build scripts
* OML: use fom_hdr while handling attr. request
* osmo-bts-trx: fix 'osmotrx legacy-setbsic'
* osmo-bts-trx: remove global variables from loops
[ Daniel Laszlo Sitzer ]
* octphy: Update outdated config param name in error message.
[ Jason DSouza ]
* Close TRX session before opening new one
[ Minh-Quang Nguyen ]
* l1sap.h: fix wrong L1SAP_FN2PTCCHBLOCK calculation according to TS 45.002 Table 6
* common/abis.c: fix 100% CPU usage after disconnecting OML/RSL link (Bug #1703)
* LC15: Bring back DSP trace argument
* LC15: Hardware changes
* LC15: TRX nominal TX power can be used from EEPROM or from BTS configuration
* rsl: Fix dropping of LAPDm UA message.
* LC15: properly handle BS-AG-BLKS-RES as received from BSC
[ Neels Hofmeyr ]
* sysmo: add L3 handle to l1prim messages
* pcu_sock: add pcu_connected() to query PCU availability
* tests/stubs.c: remove unused stubs
* fix typo in error message ('at lEast')
* oml, Set Chan Attr: treat unknown PCHAN types as error
* dyn PDCH: rsl rx dchan: also log ip.access message names
* doc: add ladder diagram on dynamic PDCH, add msc-README
* add missing DSUM entry to bts_log_info_cat
* fix compiler warning: printf format for sizeof()
* fix compiler warning: add missing case (PHY_LINK_CONNECTING)
* fix two compiler warnings: add two opaque struct declarations
* dyn PDCH: add bts_model_ts_connect() and _disconnect() stubs
* dyn PDCH: conf_lchans_for_pchan(): handle TCH/F_PDCH
* dyn PDCH: pcu_tx_info_ind(): handle TCH/F_PDCH in PDCH mode
* dyn PDCH: chan_nr_by_sapi(): handle TCH/F_PDCH according to ts->flags
* dyn PDCH: implement main dyn PDCH logic in common/
* dyn PDCH: sysmo-bts/oml.c: add ts_connect_as(), absorbing ts_connect() guts
* dyn PDCH: sysmo: handle TCH/F_PDCH init like TCH/F
* dyn PDCH: complete for sysmo-bts: implement bts_model_ts_*()
* error log: two minor clarifications
* debug log: log lchan state transitions
* debug log: log TS pchan type on connect
* fix lc15 build: put src/common/libbts.a left of -losmogsm
* lc15: add L3 handle to l1prim messages
* dyn PDCH: lc15: chan_nr_by_sapi(): handle TCH/F_PDCH according to ts->flags
* dyn PDCH: lc15: add ts_connect_as(), absorbing ts_connect() guts
* dyn PDCH: lc15: handle TCH/F_PDCH init like TCH/F
* dyn PDCH: lc15: complete for litecell15-bts: implement bts_model_ts_*()
* dyn PDCH: safeguard: exit if nothing pending in dyn_pdch_ts_disconnected()
* vty: install orphaned trx nominal power command
* fix compiler warnings: include bts_model.h in phy_link.c
* fix compiler warning: remove useless 'static' storage class for struct decl
* fix compiler warning: remove unused variable 'i' in calib_verify()
* log: osmo-bts-trx: change access burst logs to DEBUG level
* log: osmo-bts-trx: change PDTCH block logs to DEBUG level
* osmo-bts-trx: init OML only once by sending AVSTATE_OK with OPSTATE_ENABLED
* doc: move dyn_pdch.msc to osmo-gsm-manuals.git
* error log: rsl.c: typo x2
* info log: l1sap.c: add '0x' to hex output
* fix compiler warning: msg_utils.c: fn_chk() constify arg
* fix compiler warning: msg_utils.c: fn_chk() constify arg
* info log: l1sap.c: add '0x' to hex output
* error log: rsl.c: typo x2
* dyn PDCH: code dup: use conf_lchans_as_pchan()
* prepare dyn TS: split/replace conf_lchans_for_pchan()
* code dup: join [rsl_]lchan_lookup() from libbsc and osmo-bts
* dyn TS: common TCH/F_TCH/H_PDCH implementation
* sysmo/oml.c: rename ts_connect() to ts_opstart()
* dyn TS: implement SysmoBTS specifics
* lc15/oml.c: rename ts_connect() to ts_opstart()
* dyn TS: implement litecell15 specifics
* comment typo: common/l1sap.c
* log typo: trx_sched_set_pchan()
* dyn TS: sysmo,lc15: chan_nr_by_sapi(): add missing assertion
* fix comment in common/l1sap.c, function name changed
* dyn TS, dyn PDCH: common/l1sap.c: properly notice PDCH
* dyn PDCH: trx l1_if.c: factor out trx_set_ts_as_pchan() from trx_set_ts()
* dyn PDCH: complete for trx: implement bts_model_ts_[dis]connect()
* dyn PDCH: trx l1_if.c: drop fixme, add comment
* dyn TS: complete for TRX
* dyn TS: measurement.c: replace fixme with comment
* sysmo,lc15: ts_connect_as(): log error also for pchan_as == TCH/F_PDCH
* sysmo: fix dyn TS: Revert "Activate PTCCH UL" [in sysmobts]
* log: l1sap: add 0x to hex output of chan_nr, 5 times
* dyn TS: measurement: use correct nr of subslots, rm code dup
* dyn TS: sysmo,lc15: ph_data_req: fix PDCH mode detection
* Fix ip.access style dyn PDCH, broken in 37af36e85eca546595081246aec010fa7f6fd0be
* common/rsl: move decision whether to chan act ack/nack to common function
* octphy: fix build: Revert "octphy: fix for multiple trx with more than 1 dsp"
* octphy: fix build: Revert "octphy: add support for multiple trx ids"
* octphy: fix build with OCTSDR-OPENBSC-02.07.00-B708: name changed
* dyn TS: if PCU is not connected, allow operation as TCH
* log: sysmo,lc15: tweak log about sapi_cmds queue
* log causing rx event for lchan_lookup errors
* heed VTY 'line vty'/'bind' command
* sysmobts_mgr, lc15bts_mgr: fix tall context for telnet vty
* build: be robust against install-sh files above the root dir
* configure: check for pkg-config presence
* jenkins.sh: use osmo-build-dep.sh, log test failures
* msgb ctx: use new msgb_talloc_ctx_init() in various main()s
* jenkins-oct.sh: fix build: typo in deps path
* fix 'osmo-bts-* --version' segfault
* osmo-bts-trx: remove obsolete include of netif/rtp.h
* add jenkins_bts_trx.sh
* add jenkins_oct_and_bts_trx.sh
* jenkins: add jenkins_bts_model.sh
* bursts test: test_pdtch: pre-init result mem
* fix: dyn ts: uplink measurement report
* fix missing ~ in bit logic for lchan->si.valid in rsl_rx_sacch_inf_mod()
* SACCH: fix sending of SI with an enum value > 7
* SACCH SI: assert that SI enum vals fit in bit mask
* all models: fix vty write: bts_model_config_write_phy
* jenkins: add value_string termination check
* Revert "Add version to phy_instance"
* Revert "RSL: check for abnormal SI2q values"
* Revert "RSL: receive and send multiple SI2q messages"
[ Harald Welte ]
* sysmobts: screnrc/systemd-service: Use osmo-bts-sysmo instead of sysmobts
* Add .mailmap for mapping mail addresses in shortlog
* vty: Ensure to not use negative (error) sapi value
* sysmobts: Add correct nominal transmit power for sysmoBTS 1020
* sysmobts_eeprom.h: Fix/extend model number definitions
* Revert "sysmobts: Add correct nominal transmit power for sysmoBTS 1020"
* tx_power: Change PA calibration tables to use delta vales
* Add new unit-test for transmit power computation code
* sysmobts: fully support trx_power_params
* README: Add general project information and convert to markdown
* README: update some of the limitations
* sysmobts: Don't start with 0dBm TRX output power before ramping
* Remove unusued left-over gsm0503_conv.c
* scheduler_trx.c: Avoid code duplication for BER10k computation
* scheduler_trx: Avoid copy+pasting determining CMR from FN
* rx_tchh_fn(): Avoid copy+pasting formula to determine odd-ness of fn
* Consistently check for minimum attribute/TLV length in RSL and OML
* l1sap.c: Add spec reference to link timeout implementation
* osmo-bts-trx: Remove duplicate parsing of NM_ATT_CONN_FAIL_CRIT
* vty: Remove command for manual channel activation/deactivation
* l1_if: Add inline functions to check dsp/fgpa version at runtime
* sysmobts: Re-order the bit-endianness of every HR codec parameter
* OML Add osmocom-specific way to deactivate radio link timeout
* measurement: Remove dead code
* l1sap.c: Factor out function to limit message queue
* osmo-bts-sysmo/l1_if.c: PH-DATA.ind belongs to L1P, not L1C
* l1sap: if lchan is in loopback, don't accept incoming RTP
* TRX: Use timerfd and CLOCK_MONOTONIC for GSM frame timer (Closes: #2325)
* Add loopback support for PDTCH
* TRX: trx_if: Improve code description / comments
* trx_if: Improve error handling
* TRX: Rename trx_if_data() -> trx_if_send_burst()
* TRX: merge/simplify l1_if and trx_if code
* TRX: don't free l1h in trx_phy_inst_close()
* l1sap: Don't enqueue PTCCH blocks for loopback
* TRX: permit transmission of all-zero loopback frames
* jenkins helpers: some minimal documentation/comments + print errors
* VIRT-PHY: Initial check-in of a new virtual BTS
* VIRT-PHY: Fix handling of default values for vty configuration
* VIRT-PHY: Use IPv4 multicast groups for private / local scope
* VIRT-PHY: cause BTS to terminate in case of recv()/send() on udp socket returns 0
* Ensure we don't send dummy UI frames on BCCH for TC=5
* virt: Don't print NOTICE log message if ARFCN doesn't match
* VIRT-PHY: Report virtual RACH bursts with plausible burst type
* scheduler: Fix wrong log subsystem: L1C is L1 *control* not user data
* VIRT-PHY: Print NOTICE log message from unimplemented stubs
* TRX / VIRT-PHY: Make check for BCCH/CCCH more specific
* L1SAP: Print chan_nr and link_id always as hex
* VIRT-BTS: Support for GPRS
* L1SAP: Use RSL_CHAN_OSMO_PDCH across L1SAP
* GSMTAP: Don't log fill frames via GSMTAP
* TRX: Remove bogus extern global variable declarations
* l1sap/osmo-bts-sysmo: Improve logging
* TRX: Remove global variables, move SETBSIC/SETTSC handling into phy_link
* Fix build after recent gsm_bts_alloc() change
* Treat SIGTERM just like SIGINT in our programs
[ Tom Tsou ]
* trx: Add EGPRS tables, sequences, and mappings
* trx: Add EGPRS coding and decoding procedures
* trx: Enable EGPRS handling through burst lengths
* trx: Fix coverity BER calculation NULL dereference
[ Vadim Yanitskiy ]
* pcu_sock: use osmo_sock_unix_init() from libosmocore
* osmo-bts-trx/l1_if.c: use channel combination III for TCH/H
* scheduler_trx.c: strip unused variable
[ Mike McTernan ]
* osmo-bts-trx: Fix PCS1900 operation
* osmo-bts-trx: log decoder bit errors as DEBUG, not NOTICE
[ bhargava ]
* Change interface in osmo-bts for 11 bit RACH
* Update parameters in osmo-bts-sysmo for 11bit RACH
* 11bit RACH support for osmo-bts-litecell15
* Initialize parameters in osmo-trx for 11bit RACH
[ Philipp ]
* octphy: Fixing missing payload type in ph. chan. activation
* octphy: Fixing band selection for ARFCN 0
* octphy: reintroducing multi-trx support
* octopy: fixing renamed constant
* octphy: prevent mismatch between dsp-firmware and octphy headers
* rsl: improving the log output
* octphy: multi-trx support: fix AC_CHECK order
* RSL: drop obsolete NULL check
* RSL: add assertions to check args of public API
* OML: fix possible segfault: add NULL check in oml_ipa_set_attr()
* CTRL: make the CTRL-Interface IP address configurable
* l1sap: Fix expired rach slot counting
* l1sap: fix missing 'else's causing wrong rach frame expiry counts
* octphy: set tx attenuation via VTY
* octphy: Improve OML ADM state handling
[ Yves Godin ]
* DTX: fix 1st RTP packet drop
[ Alexander Chemeris ]
* l1sap: Fix use-after-free in loopback mode.
* vty: Add commands to manually activate/deactivate a channel.
* trx: Add "maxdlynb" VTY command to control max TA for Normal Bursts.
* rsl: Output RTP stats before closing the socket.
* osmo-bts-trx: Fix MS power control loop.
* osmo-bts-trx: Remove an unused variable. Resolves a compiler warning.
* osmo-bts-trx: Increase a maximum allowed MS power reduction step from 2dB to 4dB.
* Fix static build of osmo-bts-trx and osmo-bts-virtual.
[ Jean-Francois Dionne ]
* DTX: don't always perform AMR HR specific check
* DTX: fix SID-FIRST detection
* lc15,sysmobts l1_if: fix memleak in handle_mph_time_ind()
* sysmo,lc15: fix memory leak at each call placed
* DTX: fix "unexpected burst" error
* Fix AMR HR DTX FSM logic.
* Fix SACCH channel release indication not sent to BSC after location update.
* Fix RTP duration adjustment not done when speech resumes in DTX mode.
[ Ruben Undheim ]
* Fix some spelling errors
[ Holger Freyther ]
* Revert "deb: use gsm_data_shared.* from openbsc-dev"
[ Philipp Maier ]
* octphy VTY: fix vty write output for octphy's phy section
* octphy: Fix VTY commands
* l1sap: fix rach reason (ra) parsing
* l1sap: fix PTCCH detection
* octphy: fix usage of wrong define constant
* octphy: add CBCH support
* l1sap: improve log output
* octphy: print log message for multi-trx support
* octphy: display hint in case of wrongly configured transceiver number
* octphy: add conditional compilation to support latest octasic header release
* octphy: set tx/rx antenne IDs via VTY
* bts: revert trx shutdown order
* octphy: activate CBCH after all physical channels are activated
* octphy: align frame number for new firmware versions
* octphy: ensure that 11 bit rach flag is not set
* measurement: fix measurement reporting period
* measurement: make lchan_meas_check_compute() available to l1sap.c
* measurement: Compute measurement results on measurement idication
* measurement: exclude idle channels from uplink measurement
* octphy: integrate channel measurement handling
* octphy: remove old event control code
* osmo-bts-sysmo: Include frame number in MEAS IND
* measurement: fix measurement computation
* octphy: fix segfault
* Revert "measurement: exclude idle channels from uplink measurement"
* sysmobts: normalize frame number in measurement indication
* measurement: Improve log output
* measurement: improve log output
* octphy: improve log output
* octphy: initalize l1msg and only when needed
* octphy: initalize nmsg only when needed
* octphy: remove log output
* Revert "sysmobts: normalize frame number in measurement indication"
* osmo-bts-trx: fix missing frame number in MEAS IND
* osmo-bts-litecell15: Fix missing frame number in MEAS IND
* Revert "osmo-bts-sysmo: Include frame number in MEAS IND"
* octphy: complete value strings (octphy_cid_vals)
* octphy: do not send empty frames to phy
* osmo-bts-sysmo: Include frame number in MEAS IND
* measurement: fix measurment report
* octphy: remap frame number in MEAS_IND
* octphy: implement support for dynamic timeslots
[ Ivan Klyuchnikov ]
* osmo-trx-bts: Fix incorrect setting of RXGAIN and POWER parameters on second channel (TRX1) of osmo-trx
* osmo-trx-bts: Fix osmo-bts-trx crash on startup during reading phy instance parameters from config file
* osmo-trx-bts: Fix incorrect bts shutdown procedure in case of abis connection closure
* osmo-trx-bts: Fix incorrect bts shutdown procedure in case of clock loss from osmo-trx
[ Ivan Kluchnikov ]
* oml: Fix incorrect usage of const variable abis_nm_att_tlvdef_ipa
[ Pau Espin Pedrol ]
* phy_link: Fix typo in state being printed
* trx: Allow BTS and TRX to be on different IPs
* trx: Save osmotrx base-port vty properties
* sysmo/tch.c: Clean up use of empty buffer
* litecell15/tch.c: Clean up use of empty buffer
* Use L1P instead of L1C for TCH logging and allocation
* Fix annoying trailing whitespace
* sysmo, litecell15: Make sure all TCH events are triggered
* sysmo: Remove non longer valid -p option from help
* Allow passing low link quality buffers to upper layers
* l1sap.c: Avoid sending RTP frame with empty payload
* l1sap.c: fn_ms_adj: Add err logging and always return GSM_RTP_DURATION
* Move dump_gsmtime to libosmocore as osmo_dump_gsmtime
* Use osmo_dump_gsmtime to log fn across different layers
* lc15bts-mgr.cfg: Set default vswr to a value inside valid range
* litecell15: Register in vty limits for paX_pwr
* lc15: Tweak led colors used in service file
* lc-15, sysmo: l1_if: print name on PH-DATA.ind unknwon sapi
* lc15bts-mgr.service: Prepare dirs and sysctls for the process
* osmo-bts-trx: Enable osmotrx tx-attenuation oml by default
* osmo-bts-trx: Relax validation to allow TRX data bursts without padding
[ Sebastian Stumpf ]
* VIRT-PHY: Added example configurations for openbsc and osmobts.
* VIRT-PHY: Fixed timeslot in gsmtap-msg on downlink which was always 0.
* VIRT-PHY: Added test option for fast hyperframe repeat.
-- Max <msuraev@sysmocom.de> Fri, 25 Aug 2017 15:16:56 +0200
osmo-bts (0.5.0) unstable; urgency=medium
* Initial release.
-- Holger Hans Peter Freyther <holger@moiji-mobile.com> Fri, 01 Apr 2016 16:13:40 +0200

1
debian/compat vendored Normal file
View File

@@ -0,0 +1 @@
9

36
debian/control vendored Normal file
View File

@@ -0,0 +1,36 @@
Source: osmo-bts
Maintainer: Holger Hans Peter Freyther <holger@moiji-mobile.com>
Section: net
Priority: optional
Build-Depends: debhelper (>= 9),
pkg-config,
dh-autoreconf,
dh-systemd (>= 1.5),
autotools-dev,
pkg-config,
libosmocore-dev,
openbsc-dev,
libosmo-abis-dev,
libosmo-netif-dev,
libgps-dev,
libortp-dev,
txt2man
Standards-Version: 3.9.8
Vcs-Browser: http://git.osmocom.org/osmo-bts/
Vcs-Git: git://git.osmocom.org/osmo-bts
Homepage: https://projects.osmocom.org/projects/osmobts
Package: osmo-bts-trx
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: osmo-bts-trx GSM BTS with osmo-trx
osmo-bts-trx to be used with the osmo-trx application
Package: osmo-bts-trx-dbg
Architecture: any
Section: debug
Priority: extra
Depends: osmo-bts-trx (= ${binary:Version}), ${misc:Depends}
Description: Debug symbols for the osmo-bts-trx
Make debugging possible

81
debian/copyright vendored Normal file
View File

@@ -0,0 +1,81 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: osmo-bts
Source: http://cgit.osmocom.org/osmo-bts/
Files: *
Copyright: 2008-2014 Harald Welte <laforge@gnumonks.org>
2009,2011,2013 Andreas Eversberg <jolly@eversberg.eu>
2010,2011 On-Waves
2012-2015 Holger Hans Peter Freyther
2014 sysmocom s.f.m.c. Gmbh
2015 Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
License: AGPL-3+
Files: src/osmo-bts-sysmo/eeprom.c
src/osmo-bts-sysmo/eeprom.h
Copyright: 2012 Nutaq
License: MIT
Comment: Yves Godin is the author
Files: src/common/pcu_sock.c
Copyright: 2008-2010 Harald Welte <laforge@gnumonks.org>
2009-2012 Andreas Eversberg <jolly@eversberg.eu>
2012 Holger Hans Peter Freyther
License: GPL-2+
Files: debian/*
Copyright: 2015-2016 Ruben Undheim <ruben.undheim@gmail.com>
License: AGPL-3+
License: AGPL-3+
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 General Public License for more details.
.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
License: GPL-2+
This package is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

2
debian/osmo-bts-trx.install vendored Normal file
View File

@@ -0,0 +1,2 @@
usr/bin/osmo-bts-trx
usr/bin/osmo-bts-virtual

15
debian/osmo-bts-trx.service vendored Normal file
View File

@@ -0,0 +1,15 @@
[Unit]
Description=Osmocom osmo-bts for osmo-trx
[Service]
Type=simple
ExecStart=/usr/bin/osmo-bts-trx -s -c /etc/osmocom/osmo-bts.cfg
Restart=always
RestartSec=2
# Let it process messages quickly enough
CPUSchedulingPolicy=rr
CPUSchedulingPriority=1
[Install]
WantedBy=multi-user.target

32
debian/rules vendored Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/make -f
DEBIAN := $(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2)
DEBVERS := $(shell echo '$(DEBIAN)' | cut -d- -f1)
VERSION := $(shell echo '$(DEBVERS)' | sed -e 's/[+-].*//' -e 's/~//g')
#export DH_VERBOSE=1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
%:
dh $@ --with=systemd --with autoreconf --fail-missing
override_dh_strip:
dh_strip --dbg-package=osmo-bts-trx-dbg
override_dh_autoreconf:
echo $(VERSION) > .tarball-version
dh_autoreconf
override_dh_auto_configure:
dh_auto_configure -- --enable-trx --with-openbsc=/usr/src/osmocom/openbsc/openbsc/include/
override_dh_clean:
dh_clean
$(RM) tests/package.m4
$(RM) tests/testsuite
# Print test results in case of a failure
override_dh_auto_test:
dh_auto_test || (find . -name testsuite.log -exec cat {} \; ; false)

1
debian/source/format vendored Normal file
View File

@@ -0,0 +1 @@
3.0 (native)

61
doc/control_interface.txt Normal file
View File

@@ -0,0 +1,61 @@
The osmo-bts control interface is currently supporting the following operations:
h2. generic
h3. trx.0.thermal-attenuation
The idea of this paramter is to attenuate the system output power as part of
thermal management. In some cases the PA might be passing a critical level,
so an external control process can use this attribute to reduce the system
output power.
Please note that all values in the context of transmit power calculation
are integers in milli-dB (1/10000 bel), so the below example is setting
the attenuation at 3 dB:
<pre>
bsc_control.py -d localhost -p 4238 -s trx.0.thermal-attenuation 3000
Got message: SET_REPLY 1 trx.0.thermal-attenuation 3000
</pre>
<pre>
bsc_control.py -d localhost -p 4238 -g trx.0.thermal-attenuation
Got message: GET_REPLY 1 trx.0.thermal-attenuation 3000
</pre>
h2. sysmobts specific
h3. trx.0.clock-info
obtain information on the current clock status:
<pre>
bsc_control.py -d localhost -p 4238 -g trx.0.clock-info
Got message: GET_REPLY 1 trx.0.clock-info -100,ocxo,0,0,gps
</pre>
which is to be interpreted as:
* current clock correction value is -100 ppb
* current clock source is OCXO
* deviation between clock source and calibration source is 0 ppb
* resolution of clock error measurement is 0 ppt (0 means no result yet)
* current calibration source is GPS
When this attribute is set, any value passed on is discarded, but the clock
calibration process is re-started.
h3. trx.0.clock-correction
This attribute can get and set the current clock correction value:
<pre>
bsc_control.py -d localhost -p 4238 -g trx.0.clock-correction
Got message: GET_REPLY 1 trx.0.clock-correction -100
</pre>
<pre>
bsc_control.py -d localhost -p 4238 -s trx.0.clock-correction -- -99
Got message: SET_REPLY 1 trx.0.clock-correction success
</pre>

View File

@@ -0,0 +1,43 @@
!
! lc15bts-mgr (0.3.0.284-a7c2-dirty) configuration saved from vty
!!
!
log stderr
logging filter all 1
logging color 1
logging print category 0
logging timestamp 0
logging level temp info
logging level fw info
logging level find info
logging level calib info
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
logging level lctrl notice
logging level lgtp notice
!
line vty
no login
!
lc15bts-mgr
limits supply_volt
threshold warning min 17500
threshold critical min 19000
limits tx0_vswr
threshold warning max 1000
limits tx1_vswr
threshold warning max 1000
limits supply_pwr
threshold warning max 110
threshold critical max 120
limits pa0_pwr
threshold warning max 50
threshold critical max 60
limits pa1_pwr
threshold warning max 50
threshold critical max 60

View File

@@ -0,0 +1,43 @@
!
! OsmoBTS (0.0.1.100-0455-dirty) configuration saved from vty
!!
!
log stderr
logging color 1
logging timestamp 0
logging level rsl info
logging level oml info
logging level rll notice
logging level rr notice
logging level meas notice
logging level pag info
logging level l1c info
logging level l1p info
logging level dsp debug
logging level abis notice
logging level rtp notice
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
!
line vty
no login
!
phy 0
instance 0
trx-calibration-path /mnt/rom/factory/calib
phy 1
instance 0
trx-calibration-path /mnt/rom/factory/calib
bts 0
band 900
ipa unit-id 1500 0
oml remote-ip 192.168.234.185
trx 0
phy 0 instance 0
trx 1
phy 1 instance 0

View File

@@ -0,0 +1,34 @@
!
! OsmoBTS () configuration saved from vty
!!
!
log stderr
logging color 1
logging timestamp 0
logging level rsl info
logging level oml info
logging level rll notice
logging level rr notice
logging level meas notice
logging level pag info
logging level l1c info
logging level l1p info
logging level dsp info
logging level abis notice
!
line vty
no login
!
phy 0
octphy hw-addr 00:0c:de:ad:fa:ce
octphy net-device eth2
instance 0
instance 1
bts 0
band 1800
ipa unit-id 1234 0
oml remote-ip 127.0.0.1
trx 0
phy 0 instance 0
trx 1
phy 0 instance 1

View File

@@ -5,7 +5,6 @@
log stderr
logging color 1
logging timestamp 0
logging level all everything
logging level rsl info
logging level oml info
logging level rll notice
@@ -13,21 +12,20 @@ log stderr
logging level meas notice
logging level pag info
logging level l1c info
logging level l1p debug
logging level dsp debug
logging level l1p info
logging level dsp info
logging level abis notice
logging level lglobal notice
logging level llapdm notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
!
line vty
no login
!
phy 0
octphy hw-addr 00:0C:90:2e:80:1e
octphy net-device eth0.2342
instance 0
bts 0
band 1800
ipa unit-id 1234 0
oml remote-ip 192.168.100.11
rtp bind-ip 192.168.100.239
oml remote-ip 127.0.0.1
trx 0
phy 0 instance 0

View File

@@ -0,0 +1,29 @@
!
! OsmoBTS () configuration saved from vty
!!
!
log stderr
logging color 1
logging timestamp 0
logging level rsl info
logging level oml info
logging level rll notice
logging level rr notice
logging level meas notice
logging level pag info
logging level l1c info
logging level l1p info
logging level dsp info
logging level abis notice
!
line vty
no login
!
phy 0
instance 0
bts 0
band 1800
ipa unit-id 666 0
oml remote-ip 10.1.2.3
trx 0
phy 0 instance 0

View File

@@ -0,0 +1,23 @@
!
! SysmoMgr (0.3.0.141-33e5) configuration saved from vty
!!
!
log stderr
logging filter all 1
logging color 1
logging timestamp 0
logging level temp info
logging level fw info
logging level find info
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
!
line vty
no login
!
sysmobts-mgr

View File

@@ -0,0 +1,35 @@
!
! OsmoBTS () configuration saved from vty
!!
!
log stderr
logging color 1
logging timestamp 0
logging level rsl notice
logging level oml notice
logging level rll notice
logging level rr notice
logging level meas error
logging level pag error
logging level l1c error
logging level l1p error
logging level dsp error
logging level abis error
!
line vty
no login
!
phy 0
instance 0
osmotrx rx-gain 1
osmotrx ip local 127.0.0.1
osmotrx ip remote 127.0.0.1
bts 0
band 1800
ipa unit-id 6969 0
oml remote-ip 192.168.122.1
settsc
gsmtap-sapi ccch
gsmtap-sapi pdtch
trx 0
phy 0 instance 0

View File

@@ -0,0 +1,151 @@
!
! OpenBSC (0.15.0.629-34f0-dirty) configuration saved from vty
!!
!
log stderr
logging filter all 1
logging color 0
logging print category 1
logging timestamp 1
logging level all info
logging level rll notice
logging level cc notice
logging level mm debug
logging level rr notice
logging level rsl notice
logging level nm info
logging level mncc notice
logging level pag notice
logging level meas notice
logging level sccp notice
logging level msc notice
logging level mgcp notice
logging level ho notice
logging level db notice
logging level ref notice
logging level gprs debug
logging level ns info
logging level bssgp debug
logging level llc debug
logging level sndcp debug
logging level nat notice
logging level ctrl notice
logging level smpp debug
logging level filter debug
logging level ranap debug
logging level sua debug
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
logging level lctrl notice
logging level lgtp notice
logging level lstats notice
logging level lgsup notice
logging level loap notice
!
stats interval 5
!
line vty
no login
!
e1_input
e1_line 0 driver ipa
e1_line 0 port 0
no e1_line 0 keepalive
network
network country code 262
mobile network code 42
short name OpenBSC
long name OpenBSC
auth policy accept-all
authorized-regexp .*
location updating reject cause 13
encryption a5 0
neci 1
paging any use tch 0
rrlp mode ms-based
mm info 1
handover 0
handover window rxlev averaging 10
handover window rxqual averaging 1
handover window rxlev neighbor averaging 10
handover power budget interval 6
handover power budget hysteresis 3
handover maximum distance 9999
timer t3101 10
timer t3103 0
timer t3105 0
timer t3107 0
timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0
timer t3117 0
timer t3119 0
timer t3122 10
timer t3141 0
subscriber-keep-in-ram 0
bts 0
type sysmobts
band DCS1800
cell_identity 6969
location_area_code 1
base_station_id_code 63
ms max power 0
cell reselection hysteresis 4
rxlev access min 0
periodic location update 30
radio-link-timeout 32
channel allocator descending
rach tx integer 9
rach max transmission 7
channel-descrption attach 1
channel-descrption bs-pa-mfrms 5
channel-descrption bs-ag-blks-res 1
ip.access unit_id 6969 0
oml ip.access stream_id 255 line 0
neighbor-list mode automatic
codec-support fr
gprs mode none
no force-combined-si
trx 0
rf_locked 0
arfcn 666
nominal power 0
max_power_red 0
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
timeslot 1
phys_chan_config SDCCH8
hopping enabled 0
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
mncc-int
default-codec tch-f fr
default-codec tch-h hr
nitb
subscriber-create-on-demand
subscriber-create-on-demand random 1 24
assign-tmsi

View File

@@ -0,0 +1,61 @@
!
! OsmoBTS (0.4.0.216-bc49-dirty) configuration saved from vty
!!
!
log stderr
logging filter all 0
logging color 0
logging print category 1
logging timestamp 0
logging level rsl info
logging level oml info
logging level rll notice
logging level rr notice
logging level meas notice
logging level pag info
logging level l1c info
logging level l1p info
logging level dsp error
logging level pcu notice
logging level ho debug
logging level trx notice
logging level loop notice
logging level abis debug
logging level rtp notice
logging level sum error
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
logging level lctrl notice
logging level lgtp notice
logging level lstats error
!
line vty
no login
!
e1_input
e1_line 0 driver ipa
e1_line 0 port 0
no e1_line 0 keepalive
phy 0
instance 0
bts 0
band DCS1800
ipa unit-id 6969 0
oml remote-ip 127.0.0.1
rtp jitter-buffer 100
paging queue-size 200
paging lifetime 0
uplink-power-target -75
min-qual-rach 50
min-qual-norm -5
trx 0
power-ramp max-initial 23000 mdBm
power-ramp step-size 2000 mdB
power-ramp step-interval 1
ms-power-control dsp
phy 0 instance 0

57
doc/phy_link.txt Normal file
View File

@@ -0,0 +1,57 @@
== OsmoBTS PHY interface abstraction
The OsmoBTS PHY interface serves as an abstraction layer between given
PHY hardware and the actual logical transceivers (TRXs) of a BTS inside
the OsmoBTS code base.
=== PHY link
A PHY link is a physical connection / link towards a given PHY. This
might be, for example,
* a set of file descriptors to device nodes in the /dev/ directory
(sysmobts, litecell15)
* a packet socket for sending raw Ethernet frames to an OCTPHY
* a set of UDP sockets for interacting with OsmoTRX
Each PHY interface has a set of attribute/parameters and a list of 1 to
n PHY instances.
PHY links are numbered 0..n globally inside OsmoBTS.
Each PHY link is configured via the VTY using its individual top-level
vty node. Given the different bts-model / phy specific properties, the
VTY configuration options (if any) of the PHY instance differ between
BTS models.
The PHY links and instances must be configured above the BTS/TRX nodes
in the configuration file. If the file is saved via the VTY, the code
automatically ensures this.
=== PHY instance
A PHY instance is an instance of a PHY, accessed via a PHY link.
In the case of osmo-bts-sysmo and osmo-bts-trx, there is only one
instance in every PHY link. This is due to the fact that the API inside
that PHY link does not permit for distinguishing multiple different
logical TRXs.
Other PHY implementations like the OCTPHY however do support addressing
multiple PHY instances via a single PHY link.
PHY instances are numbered 0..n inside each PHY link.
Each PHY instance is configured via the VTY as a separate node beneath each
PHY link. Given the different bts-model / phy specific properties, the
VTY configuration options (if any) of the PHY instance differ between
BTS models.
=== Mapping PHY instances to TRXs
Each TRX node in the VTY must use the 'phy N instance M' command in
order to specify which PHY instance is allocated to this specific TRX.

42
doc/startup.txt Normal file
View File

@@ -0,0 +1,42 @@
== start-up / sequencing during OsmoBTS start
The start-up procedure of OsmoBTS can be described as follows:
|===
| bts-specific | main() |
| common | bts_main() | initialization of talloc contexts
| common | bts_log_init() | initialization of logging
| common | handle_options() | common option parsing
| bts-specific | bts_model_handle_options() | model-specific option parsing
| common | gsm_bts_alloc() | allocation of BTS/TRX/TS data structures
| common | vty_init() | Initialziation of VTY core, libosmo-abis and osmo-bts VTY
| common | main() | Setting of scheduler RR priority (if configured)
| common | main() | Initialization of GSMTAP (if configured)
| common | bts_init() | configuration of defaults in bts/trx/s object
| bts-specific | bts_model_init | ?
| common | abis_init() | Initialization of libosmo-abis
| common | vty_read_config_file() | Reading of configuration file
| bts-specific | bts_model_phy_link_set_defaults() | Called for every PHY link created
| 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 | pcu_sock_init() | Initializaiton of PCU socket
| common | main() | Installation of signal handlers
| common | abis_open() | Start of the A-bis connection to BSC
| common | phy_links_open() | Iterate over list of configured PHY links
| bts-specific | bts_model_phy_link_open() | Open each of the configured PHY links
| common | write_pid_file() | Generate the pid file
| common | osmo_daemonize() | Fork as daemon in background (if configured)
| common | bts_main() | Run main loop until global variable quit >= 2
| bts-specific | bts_model_oml_estab() | Called by core once OML link is established
| bts-specific | bts_model_check_oml() | called each time OML sets some attributes on a MO, checks if attributes are valid
| bts-specific | bts_model_apply_oml() | called each time OML sets some attributes on a MO, stores attribute contents in data structures
| bts-specific | bts_model_opstart() | for NM_OC_BTS, NM_OC_SITE_MANAGER, NM_OC_GPRS_NSE, NM_OC_GPRS_CELL, NMO_OC_GPRS_NSVC
| bts-specific | bts_model_opstart() | for NM_OC_RADIO_CARRIER for each trx
| bts-specific | bts_model_opstart() | for NM_OC_BASEB_TRANSC for each trx
| bts-specific | bts_model_opstart() | for NM_OC_CHANNEL for each timeslot on each trx
| bts-specific | bts_model_change_power() | change transmit power for each trx (power ramp-up/ramp-down
| bts-specific | bts_model_abis_close() | called when either one of the RSL links or the OML link are down

View File

@@ -1 +1,3 @@
SUBDIRS = osmo-bts
noinst_HEADERS = openbsc/gsm_data.h

View File

@@ -1,2 +1,5 @@
noinst_HEADERS = abis.h bts.h bts_model.h gsm_data.h logging.h measurement.h \
oml.h paging.h rsl.h signal.h vty.h
oml.h paging.h rsl.h signal.h vty.h amr.h pcu_if.h pcuif_proto.h \
handover.h msg_utils.h tx_power.h control_if.h cbch.h l1sap.h \
power_control.h scheduler.h scheduler_backend.h phy_link.h \
dtx_dl_amr_fsm.h

View File

@@ -3,25 +3,12 @@
#include <osmocom/core/select.h>
#include <osmocom/core/timer.h>
#include <osmocom/gsm/protocol/ipaccess.h>
#include <osmo-bts/gsm_data.h>
#define OML_RETRY_TIMER 5
#define OML_PING_TIMER 20
struct ipabis_link {
int state;
struct gsm_bts *bts; /* set, if OML link */
struct gsm_bts_trx *trx; /* set, if RSL link */
struct osmo_fd bfd;
struct osmo_timer_list timer;
struct msgb *rx_msg;
struct llist_head tx_queue;
int ping, pong, id_resp;
uint32_t ip;
};
enum {
LINK_STATE_IDLE = 0,
LINK_STATE_RETRYING,
@@ -29,14 +16,14 @@ enum {
LINK_STATE_CONNECT,
};
int abis_tx(struct ipabis_link *link, struct msgb *msg);
struct msgb *abis_msgb_alloc(int headroom);
void abis_push_ipa(struct msgb *msg, uint8_t proto);
int abis_open(struct ipabis_link *link, uint32_t ip);
void abis_close(struct ipabis_link *link);
void abis_init(struct gsm_bts *bts);
struct e1inp_line *abis_open(struct gsm_bts *bts, char *dst_host,
char *model_name);
int abis_oml_sendmsg(struct msgb *msg);
int abis_rsl_sendmsg(struct msgb *msg);
int abis_bts_rsl_sendmsg(struct msgb *msg);
uint32_t get_signlink_remote_ip(struct e1inp_sign_link *link);
#endif /* _ABIS_H */

18
include/osmo-bts/amr.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _OSMO_BTS_AMR_H
#define _OSMO_BTS_AMR_H
#include <osmo-bts/gsm_data.h>
#define AMR_TOC_QBIT 0x04
#define AMR_CMR_NONE 0xF
void amr_log_mr_conf(int ss, int logl, const char *pfx,
struct amr_multirate_conf *amr_mrc);
int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
const uint8_t *mr_conf, unsigned int len);
void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc,
uint8_t cmi, uint8_t cmr);
unsigned int amr_get_initial_mode(struct gsm_lchan *lchan);
#endif /* _OSMO_BTS_AMR_H */

View File

@@ -3,6 +3,12 @@
#include <osmo-bts/gsm_data.h>
enum bts_global_status {
BTS_STATUS_RF_ACTIVE,
BTS_STATUS_RF_MUTE,
BTS_STATUS_LAST,
};
extern void *tall_bts_ctx;
int bts_init(struct gsm_bts *bts);
@@ -15,16 +21,29 @@ void destroy_bts(struct gsm_bts *bts);
int work_bts(struct gsm_bts *bts);
int bts_link_estab(struct gsm_bts *bts);
int trx_link_estab(struct gsm_bts_trx *trx);
int trx_set_available(struct gsm_bts_trx *trx, int avail);
void bts_new_si(void *arg);
void bts_setup_slot(struct gsm_bts_trx_ts *slot, uint8_t comb);
int lchan_init_lapdm(struct gsm_lchan *lchan);
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);
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, struct gsm_time *g_time);
uint8_t *lchan_sacch_get(struct gsm_lchan *lchan, struct gsm_time *g_time);
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time);
uint8_t *lchan_sacch_get(struct gsm_lchan *lchan);
int lchan_init_lapdm(struct gsm_lchan *lchan);
void load_timer_start(struct gsm_bts *bts);
uint8_t num_agch(struct gsm_bts_trx *trx, const char * arg);
void bts_update_status(enum bts_global_status which, int on);
int trx_ms_pwr_ctrl_is_osmo(struct gsm_bts_trx *trx);
struct gsm_time *get_time(struct gsm_bts *bts);
int bts_main(int argc, char **argv);
#endif /* _BTS_H */

View File

@@ -8,18 +8,19 @@
#include <osmo-bts/gsm_data.h>
struct phy_link;
struct phy_instance;
/* BTS model specific functions needed by the common code */
int bts_model_init(struct gsm_bts *bts);
struct gsm_time *bts_model_get_time(struct gsm_bts *bts);
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, void *obj);
struct tlv_parsed *new_attr, int obj_kind, void *obj);
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
void *obj);
@@ -27,13 +28,37 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo,
void *obj, uint8_t adm_state);
int bts_model_rsl_chan_act(struct gsm_lchan *lchan, struct tlv_parsed *tp);
int bts_model_rsl_chan_rel(struct gsm_lchan *lchan);
int bts_model_rsl_deact_sacch(struct gsm_lchan *lchan);
int bts_model_trx_deact_rf(struct gsm_bts_trx *trx);
int bts_model_trx_close(struct gsm_bts_trx *trx);
void bts_model_rtp_rx_cb(struct osmo_rtp_socket *rs, uint8_t *rtp_pl,
unsigned int rtp_pl_len);
int bts_model_vty_init(struct gsm_bts *bts);
void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts);
void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx);
void bts_model_config_write_phy(struct vty *vty, struct phy_link *plink);
void bts_model_config_write_phy_inst(struct vty *vty, struct phy_instance *pinst);
int bts_model_oml_estab(struct gsm_bts *bts);
int bts_model_change_power(struct gsm_bts_trx *trx, int p_trxout_mdBm);
int bts_model_adjst_ms_pwr(struct gsm_lchan *lchan);
int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap);
int bts_model_lchan_deactivate(struct gsm_lchan *lchan);
int bts_model_lchan_deactivate_sacch(struct gsm_lchan *lchan);
void bts_model_abis_close(struct gsm_bts *bts);
int bts_model_ctrl_cmds_install(struct gsm_bts *bts);
int bts_model_handle_options(int argc, char **argv);
void bts_model_print_help();
void bts_model_phy_link_set_defaults(struct phy_link *plink);
void bts_model_phy_instance_set_defaults(struct phy_instance *pinst);
int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts);
int bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan);
#endif

16
include/osmo-bts/cbch.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_08_58.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/bts.h>
/* incoming SMS broadcast command from RSL */
int bts_process_smscb_cmd(struct gsm_bts *bts,
struct rsl_ie_cb_cmd_type cmd_type,
uint8_t msg_len, const uint8_t *msg);
/* call-back from bts model specific code when it wants to obtain a CBCH
* block for a given gsm_time. outbuf must have 23 bytes of space. */
int bts_cbch_get(struct gsm_bts *bts, uint8_t *outbuf, struct gsm_time *g_time);

View File

@@ -0,0 +1,5 @@
#pragma once
int bts_ctrl_cmds_install(struct gsm_bts *bts);
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
const char *bind_addr, uint16_t port);

View File

@@ -0,0 +1,44 @@
#pragma once
#include <osmocom/core/fsm.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
/* DTX DL AMR FSM */
#define X(s) (1 << (s))
enum dtx_dl_amr_fsm_states {
ST_VOICE,
ST_SID_F1,
ST_SID_F2,
ST_F1_INH_V,
ST_F1_INH_F,
ST_U_INH_V,
ST_U_INH_F,
ST_U_NOINH,
ST_F1_INH_V_REC,
ST_F1_INH_F_REC,
ST_U_INH_V_REC,
ST_U_INH_F_REC,
ST_SID_U,
ST_ONSET_V,
ST_ONSET_F,
ST_ONSET_V_REC,
ST_ONSET_F_REC,
ST_FACCH,
};
enum dtx_dl_amr_fsm_events {
E_VOICE,
E_ONSET,
E_FACCH,
E_COMPL,
E_FIRST,
E_INHIB,
E_SID_F,
E_SID_U,
};
extern const struct value_string dtx_dl_amr_fsm_event_names[];
extern struct osmo_fsm dtx_dl_amr_fsm;

View File

@@ -6,10 +6,31 @@
#include <osmocom/gsm/lapdm.h>
#include <osmo-bts/paging.h>
#include <osmo-bts/tx_power.h>
#define GSM_FR_BITS 260
#define GSM_EFR_BITS 244
#define GSM_FR_BYTES 33 /* TS 101318 Chapter 5.1: 260 bits + 4bit sig */
#define GSM_HR_BYTES 14 /* TS 101318 Chapter 5.2: 112 bits, no sig */
#define GSM_EFR_BYTES 31 /* TS 101318 Chapter 5.3: 244 bits + 4bit sig */
#define GSM_SUPERFRAME (26*51) /* 1326 TDMA frames */
#define GSM_HYPERFRAME (2048*GSM_SUPERFRAME) /* GSM_HYPERFRAME frames */
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT 41
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE 999999
#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41
#define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91
struct pcu_sock_state;
struct smscb_msg;
struct gsm_network {
struct llist_head bts_list;
unsigned int num_bts;
uint16_t mcc, mnc;
struct pcu_sock_state *pcu_state;
};
/* data structure for BTS related data specific to the BTS role */
@@ -36,25 +57,93 @@ struct gsm_bts_role_bts {
/* Input parameters from OML */
int16_t busy_thresh; /* in dBm */
uint16_t averaging_slots;
/* Internal data */
unsigned int total; /* total nr */
unsigned int busy; /* above busy_thresh */
unsigned int access; /* access bursts */
} rach;
} load;
uint8_t ny1;
uint8_t max_ta;
/* AGCH queuing */
struct llist_head agch_queue;
int agch_queue_length;
int agch_max_queue_length;
int agch_queue_thresh_level; /* Cleanup threshold in percent of max len */
int agch_queue_low_level; /* Low water mark in percent of max len */
int agch_queue_high_level; /* High water mark in percent of max len */
/* TODO: Use a rate counter group instead */
uint64_t agch_queue_dropped_msgs;
uint64_t agch_queue_merged_msgs;
uint64_t agch_queue_rejected_msgs;
uint64_t agch_queue_agch_msgs;
uint64_t agch_queue_pch_msgs;
struct paging_state *paging_state;
char *bsc_oml_host;
char *rtp_bind_host;
struct llist_head oml_queue;
unsigned int rtp_jitter_buf_ms;
bool rtp_jitter_adaptive;
struct {
uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
} support;
struct {
uint8_t tc4_ctr;
} si;
struct gsm_time gsm_time;
/* Radio Link Timeout counter. -1 disables timeout for
* lab/measurement purpose */
int radio_link_timeout;
int ul_power_target; /* Uplink Rx power target */
/* used by the sysmoBTS to adjust band */
uint8_t auto_band;
struct {
struct llist_head queue; /* list of struct smscb_msg */
struct smscb_msg *cur_msg; /* current SMS-CB */
} smscb_state;
float min_qual_rach; /* minimum quality for RACH bursts */
float min_qual_norm; /* minimum quality for normal daata */
struct {
char *sock_path;
} pcu;
struct {
uint32_t last_fn;
struct timeval tv_clock;
struct osmo_timer_list fn_timer;
} vbts;
};
enum lchan_ciph_state {
LCHAN_CIPH_NONE,
LCHAN_CIPH_RX_REQ,
LCHAN_CIPH_RX_CONF,
LCHAN_CIPH_RXTX_REQ,
LCHAN_CIPH_RX_CONF_TX_REQ,
LCHAN_CIPH_RXTX_CONF,
};
#define bts_role_bts(x) ((struct gsm_bts_role_bts *)(x)->role)
#include "../../openbsc/openbsc/include/openbsc/gsm_data_shared.h"
#include "openbsc/gsm_data_shared.h"
struct femtol1_hdl;
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state);
int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts,
enum gsm_phys_chan_config pchan);
static inline struct femtol1_hdl *trx_femtol1_hdl(struct gsm_bts_trx *trx)
{
return trx->role_bts.l1h;
}
/* cipher code */
#define CIPHER_A5(x) (1 << (x-1))
int bts_supports_cipher(struct gsm_bts_role_bts *bts, int rsl_cipher);
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);
#endif /* _GSM_DATA_H */

View File

@@ -0,0 +1,12 @@
#pragma once
enum {
HANDOVER_NONE = 0,
HANDOVER_ENABLED,
HANDOVER_WAIT_FRAME,
};
void handover_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay);
void handover_frame(struct gsm_lchan *lchan);
void handover_reset(struct gsm_lchan *lchan);

96
include/osmo-bts/l1sap.h Normal file
View File

@@ -0,0 +1,96 @@
#ifndef L1SAP_H
#define L1SAP_H
#include <osmocom/gsm/protocol/gsm_04_08.h>
/* lchan link ID */
#define LID_SACCH 0x40
#define LID_DEDIC 0x00
/* timeslot and subslot from chan_nr */
#define L1SAP_CHAN2TS(chan_nr) (chan_nr & 7)
#define L1SAP_CHAN2SS_TCHH(chan_nr) ((chan_nr >> 3) & 1)
#define L1SAP_CHAN2SS_SDCCH4(chan_nr) ((chan_nr >> 3) & 3)
#define L1SAP_CHAN2SS_SDCCH8(chan_nr) ((chan_nr >> 3) & 7)
/* logical channel from chan_nr + link_id */
#define L1SAP_IS_LINK_SACCH(link_id) ((link_id & 0xC0) == LID_SACCH)
#define L1SAP_IS_CHAN_TCHF(chan_nr) ((chan_nr & 0xf8) == 0x08)
#define L1SAP_IS_CHAN_TCHH(chan_nr) ((chan_nr & 0xf0) == 0x10)
#define L1SAP_IS_CHAN_SDCCH4(chan_nr) ((chan_nr & 0xe0) == 0x20)
#define L1SAP_IS_CHAN_SDCCH8(chan_nr) ((chan_nr & 0xc0) == 0x40)
#define L1SAP_IS_CHAN_BCCH(chan_nr) ((chan_nr & 0xf8) == 0x80)
#define L1SAP_IS_CHAN_RACH(chan_nr) ((chan_nr & 0xf8) == 0x88)
#define L1SAP_IS_CHAN_AGCH_PCH(chan_nr) ((chan_nr & 0xf8) == 0x90)
#define L1SAP_IS_CHAN_PDCH(chan_nr) ((chan_nr & 0xf8) == 0xc0)
/* rach type from ra */
#define L1SAP_IS_PACKET_RACH(ra) ((ra & 0xf0) == 0x70 && (ra & 0x0f) != 0x0f)
/* CCCH block from frame number */
#define L1SAP_FN2CCCHBLOCK(fn) ((fn % 51) / 5 - 1)
/* PTCH layout from frame number */
#define L1SAP_FN2MACBLOCK(fn) ((fn % 52) / 4)
#define L1SAP_FN2PTCCHBLOCK(fn) ((fn / 104) & 3)
/* Calculate PTCCH occurrence, See also 3GPP TS 05.02, Clause 7, Table 6 of 9 */
#define L1SAP_IS_PTCCH(fn) (((fn % 52) == 12) || ((fn % 52) == 38))
static const uint8_t fill_frame[GSM_MACBLOCK_LEN] = {
0x03, 0x03, 0x01, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B,
0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B,
0x2B, 0x2B, 0x2B
};
/* subslot from any chan_nr */
static inline uint8_t l1sap_chan2ss(uint8_t chan_nr)
{
if (L1SAP_IS_CHAN_SDCCH8(chan_nr))
return L1SAP_CHAN2SS_SDCCH8(chan_nr);
if (L1SAP_IS_CHAN_SDCCH4(chan_nr))
return L1SAP_CHAN2SS_SDCCH4(chan_nr);
if (L1SAP_IS_CHAN_TCHH(chan_nr))
return L1SAP_CHAN2SS_TCHH(chan_nr);
return 0;
}
struct gsm_lchan *get_lchan_by_chan_nr(struct gsm_bts_trx *trx,
unsigned int chan_nr);
/* allocate a msgb containing a osmo_phsap_prim + optional l2 data */
struct msgb *l1sap_msgb_alloc(unsigned int l2_len);
/* any L1 prim received from bts model */
int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap);
/* pcu (socket interface) sends us a data request primitive */
int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn,
uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len);
/* call-back function for incoming RTP */
void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
unsigned int rtp_pl_len, uint16_t seq_number,
uint32_t timestamp, bool marker);
/* channel control */
int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp);
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);
extern const struct value_string gsmtap_sapi_names[];
extern struct gsmtap_inst *gsmtap;
extern uint32_t gsmtap_sapi_mask;
extern uint8_t gsmtap_sapi_acch;
int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg,
struct gsm_lchan *lchan, uint8_t chan_nr, uint32_t fn,
uint16_t ber10k, int16_t lqual_cb);
#define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h)
int bts_check_for_first_ciphrd(struct gsm_lchan *lchan,
uint8_t *data, int len);
#endif /* L1SAP_H */

View File

@@ -14,6 +14,10 @@ enum {
DL1C,
DL1P,
DDSP,
DPCU,
DHO,
DTRX,
DLOOP,
DABIS,
DRTP,
DSUM,

View File

@@ -1,13 +1,11 @@
#ifndef OSMO_BTS_MEAS_H
#define OSMO_BTS_MEAS_H
#define MEAS_MAX_TIMING_ADVANCE 63
#define MEAS_MIN_TIMING_ADVANCE 0
int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm);
int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn);
int ts_meas_check_compute(struct gsm_bts_trx_ts *ts, uint32_t fn);
int trx_meas_check_compute(struct gsm_bts_trx *trx, uint32_t fn);
/* build the 3 byte RSL uplinke measurement IE content */
int lchan_build_rsl_ul_meas(struct gsm_lchan *, uint8_t *buf);
#endif

View File

@@ -0,0 +1,48 @@
/*
* Routines to check the structurally integrity of messages
*/
#pragma once
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmocom/codec/codec.h>
#include <stdbool.h>
struct msgb;
/* Access 1st part of msgb control buffer */
#define rtpmsg_marker_bit(x) ((x)->cb[0])
/* Access 2nd part of msgb control buffer */
#define rtpmsg_seq(x) ((x)->cb[1])
/* Access 3rd part of msgb control buffer */
#define rtpmsg_ts(x) ((x)->cb[2])
/**
* Classification of OML message. ETSI for plain GSM 12.21
* messages and IPA/Osmo for manufacturer messages.
*/
enum {
OML_MSG_TYPE_ETSI,
OML_MSG_TYPE_IPA,
OML_MSG_TYPE_OSMO,
};
void lchan_set_marker(bool t, struct gsm_lchan *lchan);
bool dtx_dl_amr_enabled(const struct gsm_lchan *lchan);
void dtx_dispatch(struct gsm_lchan *lchan, enum dtx_dl_amr_fsm_events e);
bool dtx_recursion(const struct gsm_lchan *lchan);
void dtx_int_signal(struct gsm_lchan *lchan);
bool dtx_is_first_p1(const struct gsm_lchan *lchan);
void dtx_cache_payload(struct gsm_lchan *lchan, const uint8_t *l1_payload,
size_t length, uint32_t fn, int update);
int dtx_dl_amr_fsm_step(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload,
bool marker, uint8_t *len, uint8_t *ft_out);
uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn);
int msg_verify_ipa_structure(struct msgb *msg);
int msg_verify_oml_structure(struct msgb *msg);

View File

@@ -1,7 +1,15 @@
#ifndef _OML_H
#define _OML_H
int oml_init(void);
#include <osmocom/gsm/protocol/gsm_12_21.h>
struct gsm_bts;
struct gsm_abis_mo;
struct msgb;
struct gsm_lchan;
int oml_init(struct gsm_abis_mo *mo);
int down_oml(struct gsm_bts *bts, struct msgb *msg);
struct msgb *oml_msgb_alloc(void);
@@ -9,10 +17,19 @@ int oml_send_msg(struct msgb *msg, int is_mauf);
int oml_mo_send_msg(struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_type);
int oml_mo_opstart_ack(struct gsm_abis_mo *mo);
int oml_mo_opstart_nack(struct gsm_abis_mo *mo, uint8_t nack_cause);
int oml_mo_statechg_ack(struct gsm_abis_mo *mo);
int oml_mo_statechg_nack(struct gsm_abis_mo *mo, uint8_t nack_cause);
/* Change the state and send STATE CHG REP */
int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state);
/* First initialization of MO, does _not_ generate state changes */
void oml_mo_state_init(struct gsm_abis_mo *mo, int op_state, int avail_state);
/* Update admin state and send ACK/NACK */
int oml_mo_rf_lock_chg(struct gsm_abis_mo *mo, uint8_t mute_state[8],
int success);
/* Transmit STATE CHG REP even if there was no state change */
int oml_tx_state_changed(struct gsm_abis_mo *mo);
@@ -23,4 +40,11 @@ int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause);
int oml_mo_fom_ack_nack(struct gsm_abis_mo *mo, uint8_t orig_msg_type,
uint8_t cause);
/* Configure LAPDm T200 timers for this lchan according to OML */
int oml_set_lchan_t200(struct gsm_lchan *lchan);
extern const unsigned int oml_default_t200_ms[7];
/* Transmit failure event report */
void oml_fail_rep(uint16_t cause_value, const char *fmt, ...);
#endif // _OML_H */

View File

@@ -6,13 +6,28 @@
#include <osmocom/gsm/protocol/gsm_04_08.h>
struct paging_state;
struct gsm_bts_role_bts;
/* initialize paging code */
struct paging_state *paging_init(void *ctx, unsigned int num_paging_max,
struct paging_state *paging_init(struct gsm_bts_role_bts *btsb,
unsigned int num_paging_max,
unsigned int paging_lifetime);
/* (re) configure paging code */
void paging_config(struct paging_state *ps,
unsigned int num_paging_max,
unsigned int paging_lifetime);
void paging_reset(struct paging_state *ps);
/* The max number of paging entries */
unsigned int paging_get_queue_max(struct paging_state *ps);
void paging_set_queue_max(struct paging_state *ps, unsigned int queue_max);
/* The lifetime of a paging entry */
unsigned int paging_get_lifetime(struct paging_state *ps);
void paging_set_lifetime(struct paging_state *ps, unsigned int lifetime);
/* update with new SYSTEM INFORMATION parameters */
int paging_si_update(struct paging_state *ps, struct gsm48_control_channel_descr *chan_desc);
@@ -20,7 +35,18 @@ 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);
/* generate paging message for given gsm time */
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt);
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
int *is_empty);
/* inspection methods below */
int paging_group_queue_empty(struct paging_state *ps, uint8_t group);
int paging_queue_length(struct paging_state *ps);
int paging_buffer_space(struct paging_state *ps);
#endif

25
include/osmo-bts/pcu_if.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef _PCU_IF_H
#define _PCU_IF_H
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
extern int pcu_direct;
int pcu_tx_info_ind(void);
int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
uint16_t arfcn, uint8_t block_nr);
int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len,
int8_t rssi, uint16_t ber10k, int16_t bto, int16_t lqual);
int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn,
uint8_t is_11bit, enum ph_burst_type burst_type);
int pcu_tx_time_ind(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_sock_init(const char *path);
void pcu_sock_exit(void);
bool pcu_connected(void);
#endif /* _PCU_IF_H */

View File

@@ -0,0 +1,173 @@
#ifndef _PCUIF_PROTO_H
#define _PCUIF_PROTO_H
#include <osmocom/gsm/l1sap.h>
#define PCU_IF_VERSION 0x07
#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_RTS_REQ 0x10 /* ready to send request */
#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 */
#define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */
#define PCU_IF_MSG_PAG_REQ 0x60 /* paging request */
#define PCU_IF_MSG_TXT_IND 0x70 /* Text indication for BTS */
/* 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 */
/* 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_CS1 (1 << 16)
#define PCU_IF_FLAG_CS2 (1 << 17)
#define PCU_IF_FLAG_CS3 (1 << 18)
#define PCU_IF_FLAG_CS4 (1 << 19)
#define PCU_IF_FLAG_MCS1 (1 << 20)
#define PCU_IF_FLAG_MCS2 (1 << 21)
#define PCU_IF_FLAG_MCS3 (1 << 22)
#define PCU_IF_FLAG_MCS4 (1 << 23)
#define PCU_IF_FLAG_MCS5 (1 << 24)
#define PCU_IF_FLAG_MCS6 (1 << 25)
#define PCU_IF_FLAG_MCS7 (1 << 26)
#define PCU_IF_FLAG_MCS8 (1 << 27)
#define PCU_IF_FLAG_MCS9 (1 << 28)
enum gsm_pcu_if_text_type {
PCU_VERSION,
PCU_OML_ALERT,
};
struct gsm_pcu_if_txt_ind {
uint8_t type; /* gsm_pcu_if_text_type */
char text[TXT_MAX_LEN]; /* Text to be transmitted to BTS */
} __attribute__ ((packed));
struct gsm_pcu_if_data {
uint8_t sapi;
uint8_t len;
uint8_t data[162];
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 */
} __attribute__ ((packed));
struct gsm_pcu_if_rts_req {
uint8_t sapi;
uint8_t spare[3];
uint32_t fn;
uint16_t arfcn;
uint8_t trx_nr;
uint8_t ts_nr;
uint8_t block_nr;
} __attribute__ ((packed));
struct gsm_pcu_if_rach_ind {
uint8_t sapi;
uint16_t ra;
int16_t qta;
uint32_t fn;
uint16_t arfcn;
uint8_t is_11bit;
uint8_t burst_type;
} __attribute__ ((packed));
struct gsm_pcu_if_info_trx {
uint16_t arfcn;
uint8_t pdch_mask; /* PDCH channels per TS */
uint8_t spare;
uint8_t tsc[8]; /* TSC per channel */
uint32_t hlayer1;
} __attribute__ ((packed));
struct gsm_pcu_if_info_ind {
uint32_t version;
uint32_t flags;
struct gsm_pcu_if_info_trx trx[8]; /* TRX infos per BTS */
uint8_t bsic;
/* RAI */
uint16_t mcc, mnc, lac, rac;
/* NSE */
uint16_t nsei;
uint8_t nse_timer[7];
uint8_t cell_timer[11];
/* cell */
uint16_t cell_id;
uint16_t repeat_time;
uint8_t repeat_count;
uint16_t bvci;
uint8_t t3142;
uint8_t t3169;
uint8_t t3191;
uint8_t t3193_10ms;
uint8_t t3195;
uint8_t n3101;
uint8_t n3103;
uint8_t n3105;
uint8_t cv_countdown;
uint16_t dl_tbf_ext;
uint16_t ul_tbf_ext;
uint8_t initial_cs;
uint8_t initial_mcs;
/* NSVC */
uint16_t nsvci[2];
uint16_t local_port[2];
uint16_t remote_port[2];
uint32_t remote_ip[2];
} __attribute__ ((packed));
struct gsm_pcu_if_act_req {
uint8_t activate;
uint8_t trx_nr;
uint8_t ts_nr;
uint8_t spare;
} __attribute__ ((packed));
struct gsm_pcu_if_time_ind {
uint32_t fn;
} __attribute__ ((packed));
struct gsm_pcu_if_pag_req {
uint8_t sapi;
uint8_t chan_needed;
uint8_t identity_lv[9];
} __attribute__ ((packed));
struct gsm_pcu_if {
/* context based information */
uint8_t msg_type; /* message type */
uint8_t bts_nr; /* bts number */
uint8_t spare[2];
union {
struct gsm_pcu_if_data data_req;
struct gsm_pcu_if_data data_cnf;
struct gsm_pcu_if_data data_ind;
struct gsm_pcu_if_rts_req rts_req;
struct gsm_pcu_if_rach_ind rach_ind;
struct gsm_pcu_if_txt_ind txt_ind;
struct gsm_pcu_if_info_ind info_ind;
struct gsm_pcu_if_act_req act_req;
struct gsm_pcu_if_time_ind time_ind;
struct gsm_pcu_if_pag_req pag_req;
} u;
} __attribute__ ((packed));
#endif /* _PCUIF_PROTO_H */

160
include/osmo-bts/phy_link.h Normal file
View File

@@ -0,0 +1,160 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <osmocom/core/linuxlist.h>
#include <osmo-bts/scheduler.h>
#include <linux/if_packet.h>
#include "btsconfig.h"
struct gsm_bts_trx;
struct virt_um_inst;
enum phy_link_type {
PHY_LINK_T_NONE,
PHY_LINK_T_SYSMOBTS,
PHY_LINK_T_OSMOTRX,
PHY_LINK_T_VIRTUAL,
};
enum phy_link_state {
PHY_LINK_SHUTDOWN,
PHY_LINK_CONNECTING,
PHY_LINK_CONNECTED,
};
/* A PHY link represents the connection to a given PHYsical layer
* implementation. That PHY link contains 1...N PHY instances, one for
* each TRX */
struct phy_link {
struct llist_head list;
int num;
enum phy_link_type type;
enum phy_link_state state;
struct llist_head instances;
char *description;
union {
struct {
} sysmobts;
struct {
char *local_ip;
char *remote_ip;
uint16_t base_port_local;
uint16_t base_port_remote;
struct osmo_fd trx_ofd_clk;
bool trx_ta_loop;
bool trx_ms_power_loop;
int8_t trx_target_rssi;
uint32_t clock_advance;
uint32_t rts_advance;
bool use_legacy_setbsic;
} osmotrx;
struct {
char *mcast_dev; /* Network device for multicast */
char *bts_mcast_group; /* BTS are listening to this group */
uint16_t bts_mcast_port;
char *ms_mcast_group; /* MS are listening to this group */
uint16_t ms_mcast_port;
struct virt_um_inst *virt_um;
} virt;
struct {
/* MAC address of the PHY */
struct sockaddr_ll phy_addr;
/* Network device name */
char *netdev_name;
/* configuration */
uint32_t rf_port_index;
#if OCTPHY_USE_ANTENNA_ID == 1
uint32_t rx_ant_id;
uint32_t tx_ant_id;
#endif
uint32_t rx_gain_db;
bool tx_atten_flag;
uint32_t tx_atten_db;
#if OCTPHY_MULTI_TRX == 1
/* arfcn used by TRX with id 0 */
uint16_t center_arfcn;
#endif
struct octphy_hdl *hdl;
} octphy;
} u;
};
struct phy_instance {
/* liked inside phy_link.linstances */
struct llist_head list;
int num;
char *description;
char version[MAX_VERSION_LENGTH];
/* pointer to the PHY link to which we belong */
struct phy_link *phy_link;
/* back-pointer to the TRX to which we're associated */
struct gsm_bts_trx *trx;
union {
struct {
/* configuration */
uint8_t clk_use_eeprom;
uint32_t dsp_trace_f;
int clk_cal;
uint8_t clk_src;
char *calib_path;
struct femtol1_hdl *hdl;
} sysmobts;
struct {
struct trx_l1h *hdl;
bool sw_act_reported;
} osmotrx;
struct {
struct l1sched_trx sched;
} virt;
struct {
/* logical transceiver number within one PHY */
uint32_t trx_id;
/* trx lock state variable */
int trx_locked;
} octphy;
struct {
/* configuration */
uint32_t dsp_trace_f;
char *calib_path;
int minTxPower;
int maxTxPower;
struct lc15l1_hdl *hdl;
uint8_t max_cell_size; /* 0:166 qbits*/
uint8_t diversity_mode; /* 0: SISO A, 1: SISO B, 2: MRC */
uint8_t pedestal_mode; /* 0: unused TS is OFF, 1: unused TS is in minimum Tx power */
uint8_t dsp_alive_period; /* DSP alive timer period */
uint8_t tx_pwr_adj_mode; /* 0: no auto adjust power, 1: auto adjust power using RMS detector */
uint8_t tx_pwr_red_8psk; /* 8-PSK maximum Tx power reduction level in dB */
} lc15;
} u;
};
struct phy_link *phy_link_by_num(int num);
struct phy_link *phy_link_create(void *ctx, int num);
void phy_link_destroy(struct phy_link *plink);
void phy_link_state_set(struct phy_link *plink, enum phy_link_state state);
int phy_links_open(void);
struct phy_instance *phy_instance_by_num(struct phy_link *plink, int num);
struct phy_instance *phy_instance_create(struct phy_link *plink, int num);
void phy_instance_link_to_trx(struct phy_instance *pinst, struct gsm_bts_trx *trx);
void phy_instance_destroy(struct phy_instance *pinst);
const char *phy_instance_name(struct phy_instance *pinst);
void phy_user_statechg_notif(struct phy_instance *pinst, enum phy_link_state link_state);
static inline struct phy_instance *trx_phy_instance(struct gsm_bts_trx *trx)
{
OSMO_ASSERT(trx);
return trx->role_bts.l1h;
}
int bts_model_phy_link_open(struct phy_link *plink);

View File

@@ -0,0 +1,7 @@
#pragma once
#include <stdint.h>
#include <osmo-bts/gsm_data.h>
int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan,
const uint8_t ms_power, const int rxLevel);

View File

@@ -1,21 +1,46 @@
#ifndef _RSL_H
#define _RSL_H
/**
* What kind of release/activation is done? A silent one for
* the PDCH or one triggered through RSL?
*/
enum {
LCHAN_REL_ACT_RSL,
LCHAN_REL_ACT_PCU,
LCHAN_REL_ACT_OML,
LCHAN_REL_ACT_REACT,
};
#define LCHAN_FN_DUMMY 0xFFFFFFFF
#define LCHAN_FN_WAIT 0xFFFFFFFE
int msgb_queue_flush(struct llist_head *list);
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,
uint8_t ra, uint8_t acc_delay);
int rsl_tx_est_ind(struct gsm_lchan *lchan, uint8_t link_id, uint8_t *data, int len);
int rsl_tx_chan_act_ack(struct gsm_lchan *lchan, struct gsm_time *gtime);
int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause);
int rsl_tx_conn_fail(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 lchan_deactivate(struct gsm_lchan *lchan);
/* 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);
int rsl_tx_ipac_dlcx_ind(struct gsm_lchan *lchan, uint8_t cause);
int rsl_tx_ccch_load_ind_pch(struct gsm_bts *bts, uint16_t paging_avail);
int rsl_tx_ccch_load_ind_rach(struct gsm_bts *bts, uint16_t total,
uint16_t busy, uint16_t access);
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr);
void cb_ts_disconnected(struct gsm_bts_trx_ts *ts);
void cb_ts_connected(struct gsm_bts_trx_ts *ts);
void ipacc_dyn_pdch_complete(struct gsm_bts_trx_ts *ts, int rc);
#endif // _RSL_H */

View File

@@ -0,0 +1,191 @@
#ifndef TRX_SCHEDULER_H
#define TRX_SCHEDULER_H
#include <osmocom/core/utils.h>
#include <osmo-bts/gsm_data.h>
/* These types define the different channels on a multiframe.
* Each channel has queues and can be activated individually.
*/
enum trx_chan_type {
TRXC_IDLE = 0,
TRXC_FCCH,
TRXC_SCH,
TRXC_BCCH,
TRXC_RACH,
TRXC_CCCH,
TRXC_TCHF,
TRXC_TCHH_0,
TRXC_TCHH_1,
TRXC_SDCCH4_0,
TRXC_SDCCH4_1,
TRXC_SDCCH4_2,
TRXC_SDCCH4_3,
TRXC_SDCCH8_0,
TRXC_SDCCH8_1,
TRXC_SDCCH8_2,
TRXC_SDCCH8_3,
TRXC_SDCCH8_4,
TRXC_SDCCH8_5,
TRXC_SDCCH8_6,
TRXC_SDCCH8_7,
TRXC_SACCHTF,
TRXC_SACCHTH_0,
TRXC_SACCHTH_1,
TRXC_SACCH4_0,
TRXC_SACCH4_1,
TRXC_SACCH4_2,
TRXC_SACCH4_3,
TRXC_SACCH8_0,
TRXC_SACCH8_1,
TRXC_SACCH8_2,
TRXC_SACCH8_3,
TRXC_SACCH8_4,
TRXC_SACCH8_5,
TRXC_SACCH8_6,
TRXC_SACCH8_7,
TRXC_PDTCH,
TRXC_PTCCH,
_TRX_CHAN_MAX
};
extern const struct value_string trx_chan_type_names[];
#define GSM_BURST_LEN 148
#define GPRS_BURST_LEN GSM_BURST_LEN
#define EGPRS_BURST_LEN 444
enum trx_burst_type {
TRX_BURST_GMSK,
TRX_BURST_8PSK,
};
/* States each channel on a multiframe */
struct l1sched_chan_state {
/* scheduler */
uint8_t active; /* Channel is active */
ubit_t *dl_bursts; /* burst buffer for TX */
enum trx_burst_type dl_burst_type; /* GMSK or 8PSK burst type */
sbit_t *ul_bursts; /* burst buffer for RX */
uint32_t ul_first_fn; /* fn of first burst */
uint8_t ul_mask; /* mask of received bursts */
/* RSSI / TOA */
uint8_t rssi_num; /* number of RSSI values */
float rssi_sum; /* sum of RSSI values */
uint8_t toa_num; /* number of TOA values */
float toa_sum; /* sum of TOA values */
/* loss detection */
uint8_t lost; /* (SACCH) loss detection */
/* mode */
uint8_t rsl_cmode, tch_mode; /* mode for TCH channels */
/* AMR */
uint8_t codec[4]; /* 4 possible codecs for amr */
int codecs; /* number of possible codecs */
float ber_sum; /* sum of bit error rates */
int ber_num; /* number of bit error rates */
uint8_t ul_ft; /* current uplink FT index */
uint8_t dl_ft; /* current downlink FT index */
uint8_t ul_cmr; /* current uplink CMR index */
uint8_t dl_cmr; /* current downlink CMR index */
uint8_t amr_loop; /* if AMR loop is enabled */
/* TCH/H */
uint8_t dl_ongoing_facch; /* FACCH/H on downlink */
uint8_t ul_ongoing_facch; /* FACCH/H on uplink */
/* encryption */
int ul_encr_algo; /* A5/x encry algo downlink */
int dl_encr_algo; /* A5/x encry algo uplink */
int ul_encr_key_len;
int dl_encr_key_len;
uint8_t ul_encr_key[MAX_A5_KEY_LEN];
uint8_t dl_encr_key[MAX_A5_KEY_LEN];
/* measurements */
struct {
uint8_t clock; /* cyclic clock counter */
int8_t rssi[32]; /* last RSSI values */
int rssi_count; /* received RSSI values */
int rssi_valid_count; /* number of stored value */
int rssi_got_burst; /* any burst received so far */
float toa_sum; /* sum of TOA values */
int toa_num; /* number of TOA value */
} meas;
/* handover */
uint8_t ho_rach_detect; /* if rach detection is on */
};
struct l1sched_ts {
uint8_t mf_index; /* selected multiframe index */
uint32_t mf_last_fn; /* last received frame number */
uint8_t mf_period; /* period of multiframe */
const struct trx_sched_frame *mf_frames; /* pointer to frame layout */
struct llist_head dl_prims; /* Queue primitives for TX */
/* Channel states for all logical channels */
struct l1sched_chan_state chan_state[_TRX_CHAN_MAX];
};
struct l1sched_trx {
struct gsm_bts_trx *trx;
struct l1sched_ts ts[TRX_NR_TS];
};
struct l1sched_ts *l1sched_trx_get_ts(struct l1sched_trx *l1t, uint8_t tn);
/*! \brief how many frame numbers in advance we should send bursts to PHY */
extern uint32_t trx_clock_advance;
/*! \brief advance RTS.ind to L2 by that many clocks */
extern uint32_t trx_rts_advance;
/*! \brief last frame number as received from PHY */
extern uint32_t transceiver_last_fn;
/*! \brief Initialize the scheduler data structures */
int trx_sched_init(struct l1sched_trx *l1t, struct gsm_bts_trx *trx);
/*! \brief De-initialize the scheduler data structures */
void trx_sched_exit(struct l1sched_trx *l1t);
/*! \brief Handle a PH-DATA.req from L2 down to L1 */
int trx_sched_ph_data_req(struct l1sched_trx *l1t, struct osmo_phsap_prim *l1sap);
/*! \brief Handle a PH-TCH.req from L2 down to L1 */
int trx_sched_tch_req(struct l1sched_trx *l1t, struct osmo_phsap_prim *l1sap);
/*! \brief PHY informs us of new (current) GSM frame number */
int trx_sched_clock(struct gsm_bts *bts, uint32_t fn);
/*! \brief handle an UL burst received by PHY */
int trx_sched_ul_burst(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
sbit_t *bits, uint16_t nbits, int8_t rssi, float toa);
/*! \brief set multiframe scheduler to given physical channel config */
int trx_sched_set_pchan(struct l1sched_trx *l1t, uint8_t tn,
enum gsm_phys_chan_config pchan);
/*! \brief set all matching logical channels active/inactive */
int trx_sched_set_lchan(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t link_id,
int active);
/*! \brief set mode of all matching logical channels to given mode(s) */
int trx_sched_set_mode(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t rsl_cmode,
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
uint8_t codec2, uint8_t codec3, uint8_t initial_codec,
uint8_t handover);
/*! \brief set ciphering on given logical channels */
int trx_sched_set_cipher(struct l1sched_trx *l1t, uint8_t chan_nr, int downlink,
int algo, uint8_t *key, int key_len);
/* \brief close all logical channels and reset timeslots */
void trx_sched_reset(struct l1sched_trx *l1t);
#endif /* TRX_SCHEDULER_H */

View File

@@ -0,0 +1,88 @@
#pragma once
typedef int trx_sched_rts_func(struct l1sched_trx *l1t, uint8_t tn,
uint32_t fn, enum trx_chan_type chan);
typedef ubit_t *trx_sched_dl_func(struct l1sched_trx *l1t, uint8_t tn,
uint32_t fn, enum trx_chan_type chan,
uint8_t bid, uint16_t *nbits);
typedef int trx_sched_ul_func(struct l1sched_trx *l1t, uint8_t tn,
uint32_t fn, enum trx_chan_type chan,
uint8_t bid, sbit_t *bits, uint16_t nbits,
int8_t rssi, float toa);
struct trx_chan_desc {
/*! \brief Is this on a PDCH (PS) ? */
int pdch;
/*! \brief TRX Channel Type */
enum trx_chan_type chan;
/*! \brief Channel Number (like in RSL) */
uint8_t chan_nr;
/*! \brief Link ID (like in RSL) */
uint8_t link_id;
/*! \brief Human-readable name */
const char *name;
/*! \brief function to call when we want to generate RTS.req to L2 */
trx_sched_rts_func *rts_fn;
/*! \brief function to call when DATA.req received from L2 */
trx_sched_dl_func *dl_fn;
/*! \brief function to call when burst received from PHY */
trx_sched_ul_func *ul_fn;
/*! \brief is this channel automatically active at start? */
int auto_active;
};
extern const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX];
extern const ubit_t _sched_tsc[8][26];
extern const ubit_t _sched_egprs_tsc[8][78];
const ubit_t _sched_fcch_burst[148];
const ubit_t _sched_sch_train[64];
struct msgb *_sched_dequeue_prim(struct l1sched_trx *l1t, int8_t tn, uint32_t fn,
enum trx_chan_type chan);
int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t *l2,
uint8_t l2_len, float rssi,
int16_t ta_offs_qbits, int16_t link_qual_cb,
uint16_t ber10k,
enum osmo_ph_pres_info_type presence_info);
int _sched_compose_tch_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len);
ubit_t *tx_idle_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
ubit_t *tx_fcch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
ubit_t *tx_sch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
ubit_t *tx_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
ubit_t *tx_pdtch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
ubit_t *tx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
ubit_t *tx_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
int rx_rach_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits,
int8_t rssi, float toa);
int rx_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits,
int8_t rssi, float toa);
int rx_pdtch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits,
int8_t rssi, float toa);
int rx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits,
int8_t rssi, float toa);
int rx_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits,
int8_t rssi, float toa);
const ubit_t *_sched_dl_burst(struct l1sched_trx *l1t, uint8_t tn,
uint32_t fn, uint16_t *nbits);
int _sched_rts(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn);
void _sched_act_rach_det(struct l1sched_trx *l1t, uint8_t tn, uint8_t ss, int activate);

View File

@@ -5,10 +5,15 @@
enum sig_subsys {
SS_GLOBAL,
SS_FAIL,
};
enum signals_global {
S_NEW_SYSINFO,
S_NEW_OP_STATE,
S_NEW_NSE_ATTR,
S_NEW_CELL_ATTR,
S_NEW_NSVC_ATTR,
};
#endif

View File

@@ -0,0 +1,78 @@
#pragma once
#include <stdint.h>
#include <osmocom/core/timer.h>
/* our unit is 'milli dB" or "milli dBm", i.e. 1/1000 of a dB(m) */
#define to_mdB(x) (x * 1000)
/* PA calibration table */
struct pa_calibration {
int delta_mdB[1024]; /* gain delta at given ARFCN */
/* FIXME: thermal calibration */
};
/* representation of a RF power amplifier */
struct power_amp {
/* nominal gain of the PA */
int nominal_gain_mdB;
/* table with calibrated actual gain for each ARFCN */
struct pa_calibration calib;
};
/* Transmit power related parameters of a transceiver */
struct trx_power_params {
/* specified maximum output of TRX at full power, has to be
* initialized by BTS model at startup*/
int trx_p_max_out_mdBm;
/* intended current total system output power */
int p_total_tgt_mdBm;
/* actual current total system output power, filled in by tx_power code */
int p_total_cur_mdBm;
/* current temporary attenuation due to thermal management,
* set by thermal management code via control interface */
int thermal_attenuation_mdB;
/* external gain (+) or attenuation (-) added by the user, configured
* by the user via VTY */
int user_gain_mdB;
/* calibration table of internal PA */
struct power_amp pa;
/* calibration table of user PA */
struct power_amp user_pa;
/* power ramping related data */
struct {
/* maximum initial Pout including all PAs */
int max_initial_pout_mdBm;
/* temporary attenuation due to power ramping */
int attenuation_mdB;
unsigned int step_size_mdB;
unsigned int step_interval_sec;
struct osmo_timer_list step_timer;
} ramp;
};
int get_p_max_out_mdBm(struct gsm_bts_trx *trx);
int get_p_nominal_mdBm(struct gsm_bts_trx *trx);
int get_p_target_mdBm(struct gsm_bts_trx *trx, uint8_t bs_power_ie);
int get_p_target_mdBm_lchan(struct gsm_lchan *lchan);
int get_p_trxout_target_mdBm(struct gsm_bts_trx *trx, uint8_t bs_power_ie);
int get_p_trxout_target_mdBm_lchan(struct gsm_lchan *lchan);
int get_p_trxout_actual_mdBm(struct gsm_bts_trx *trx, uint8_t bs_power_ie);
int get_p_trxout_actual_mdBm_lchan(struct gsm_lchan *lchan);
int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass);
void power_trx_change_compl(struct gsm_bts_trx *trx, int p_trxout_cur_mdBm);
int power_ramp_initial_power_mdBm(struct gsm_bts_trx *trx);

View File

@@ -5,19 +5,27 @@
#include <osmocom/vty/command.h>
enum bts_vty_node {
BTS_NODE = _LAST_OSMOVTY_NODE + 1,
/* PHY_NODE must come before BTS node to ensure the phy
* instances are created at the time the TRX nodes want to refer
* to them */
PHY_NODE = _LAST_OSMOVTY_NODE + 1,
PHY_INST_NODE,
BTS_NODE,
TRX_NODE,
TS_NODE,
LCHAN_NODE,
};
extern struct cmd_element ournode_exit_cmd;
extern struct cmd_element ournode_end_cmd;
enum node_type bts_vty_go_parent(struct vty *vty);
extern struct cmd_element cfg_bts_auto_band_cmd;
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(const struct log_info *cat);
int bts_vty_init(struct gsm_bts *bts, const struct log_info *cat);
extern struct vty_app_info bts_vty_info;

View File

@@ -1,5 +1,17 @@
SUBDIRS = common #osmo-bts-bb
SUBDIRS = common osmo-bts-virtual
if ENABLE_SYSMOBTS
SUBDIRS += osmo-bts-sysmo
endif
if ENABLE_TRX
SUBDIRS += osmo-bts-trx
endif
if ENABLE_OCTPHY
SUBDIRS += osmo-bts-octphy
endif
if ENABLE_LC15BTS
SUBDIRS += osmo-bts-litecell15
endif

View File

@@ -1,7 +1,17 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS)
LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS)
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR)
AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS)
LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOCODEC_LIBS)
noinst_LIBRARIES = libbts.a
if ENABLE_LC15BTS
AM_CFLAGS += -DENABLE_LC15BTS
endif
noinst_LIBRARIES = libbts.a libl1sched.a
libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \
rsl.c vty.c paging.c measurement.c
rsl.c vty.c paging.c measurement.c amr.c lchan.c \
load_indication.c pcu_sock.c handover.c msg_utils.c \
tx_power.c bts_ctrl_commands.c bts_ctrl_lookup.c \
l1sap.c cbch.c power_control.c main.c phy_link.c \
dtx_dl_amr_fsm.c
libl1sched_a_SOURCES = scheduler.c

View File

@@ -1,8 +1,7 @@
/* Minimalistic Abis/IP interface routines, soon to be replaced by
* libosmo-abis (Pablo) */
/* Abis/IP interface routines utilizing libosmo-abis (Pablo) */
/* (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
* (C) 2011 by Harald Welte <laforge@gnumonks.org>
* (C) 2011-2013 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
@@ -21,6 +20,8 @@
*
*/
#include "btsconfig.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -34,496 +35,237 @@
#include <osmocom/core/select.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/protocol/ipaccess.h>
#include <osmocom/core/signal.h>
#include <osmocom/core/macaddr.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/logging.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/abis.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/rsl.h>
#include <osmo-bts/oml.h>
#include <osmo-bts/bts_model.h>
extern char *software_version;
extern uint8_t abis_mac[6];
/*
* support
*/
#define ABIS_ALLOC_SIZE 900
/* send message to BSC */
int abis_tx(struct ipabis_link *link, struct msgb *msg)
{
if (link->state != LINK_STATE_CONNECT) {
LOGP(DABIS, LOGL_NOTICE, "Link down, dropping message.\n");
msgb_free(msg);
return -EIO;
}
msgb_enqueue(&link->tx_queue, msg);
link->bfd.when |= BSC_FD_WRITE;
return 0;
}
static struct gsm_bts *g_bts;
int abis_oml_sendmsg(struct msgb *msg)
{
struct gsm_bts *bts = msg->trx->bts;
abis_push_ipa(msg, 0xff);
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
if (!bts->oml_link) {
msgb_free(msg);
llist_add_tail(&msg->list, &btsb->oml_queue);
return 0;
} else {
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
* the signalling link at msg->dst */
msg->dst = bts->oml_link;
return abis_sendmsg(msg);
}
return abis_tx((struct ipabis_link *) bts->oml_link, msg);
}
int abis_rsl_sendmsg(struct msgb *msg)
static void drain_oml_queue(struct gsm_bts *bts)
{
struct gsm_bts_trx *trx = msg->trx;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct msgb *msg, *msg2;
abis_push_ipa(msg, 0);
return abis_tx((struct ipabis_link *) trx->rsl_link, msg);
}
struct msgb *abis_msgb_alloc(int headroom)
{
struct msgb *nmsg;
headroom += sizeof(struct ipaccess_head);
nmsg = msgb_alloc_headroom(ABIS_ALLOC_SIZE + headroom,
headroom, "Abis/IP");
if (!nmsg)
return NULL;
return nmsg;
}
void abis_push_ipa(struct msgb *msg, uint8_t proto)
{
struct ipaccess_head *nhh;
msg->l2h = msg->data;
nhh = (struct ipaccess_head *) msgb_push(msg, sizeof(*nhh));
nhh->proto = proto;
nhh->len = htons(msgb_l2len(msg));
}
/*
* IPA related messages
*/
/* send ping/pong */
static int abis_tx_ipa_pingpong(struct ipabis_link *link, uint8_t pingpong)
{
struct msgb *nmsg;
nmsg = abis_msgb_alloc(0);
if (!nmsg)
return -ENOMEM;
*msgb_put(nmsg, 1) = pingpong;
abis_push_ipa(nmsg, IPAC_PROTO_IPACCESS);
return abis_tx(link, nmsg);
}
/* send ACK and ID RESP */
static int abis_rx_ipa_id_get(struct ipabis_link *link, uint8_t *data, int len)
{
struct gsm_bts *bts = link->bts;
struct msgb *nmsg, *nmsg2;
char str[64];
uint8_t *tag;
if (!link->bts)
bts = link->trx->bts;
LOGP(DABIS, LOGL_INFO, "Reply to ID_GET\n");
nmsg = abis_msgb_alloc(0);
if (!nmsg)
return -ENOMEM;
*msgb_put(nmsg, 1) = IPAC_MSGT_ID_RESP;
while (len) {
if (len < 2) {
LOGP(DABIS, LOGL_NOTICE,
"Short read of ipaccess tag\n");
msgb_free(nmsg);
return -EIO;
}
switch (data[1]) {
case IPAC_IDTAG_UNIT:
sprintf(str, "%u/%u/%u",
bts->ip_access.site_id,
bts->ip_access.bts_id,
(link->trx) ? link->trx->nr : 0);
break;
case IPAC_IDTAG_MACADDR:
sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
abis_mac[0], abis_mac[1], abis_mac[2],
abis_mac[3], abis_mac[4], abis_mac[5]);
break;
case IPAC_IDTAG_LOCATION1:
strcpy(str, "osmoBTS");
break;
case IPAC_IDTAG_LOCATION2:
strcpy(str, "osmoBTS");
break;
case IPAC_IDTAG_EQUIPVERS:
case IPAC_IDTAG_SWVERSION:
strcpy(str, software_version);
break;
case IPAC_IDTAG_UNITNAME:
sprintf(str, "osmoBTS-%02x-%02x-%02x-%02x-%02x-%02x",
abis_mac[0], abis_mac[1], abis_mac[2],
abis_mac[3], abis_mac[4], abis_mac[5]);
break;
case IPAC_IDTAG_SERNR:
strcpy(str, "");
break;
default:
LOGP(DABIS, LOGL_NOTICE,
"Unknown ipaccess tag 0x%02x\n", *data);
msgb_free(nmsg);
return -EINVAL;
}
LOGP(DABIS, LOGL_INFO, " tag %d: %s\n", data[1], str);
tag = msgb_put(nmsg, 3 + strlen(str) + 1);
tag[0] = 0x00;
tag[1] = 1 + strlen(str) + 1;
tag[2] = data[1];
memcpy(tag + 3, str, strlen(str) + 1);
data += 2;
len -= 2;
llist_for_each_entry_safe(msg, msg2, &btsb->oml_queue, list) {
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
* the signalling link at msg->dst */
llist_del(&msg->list);
msg->dst = bts->oml_link;
abis_sendmsg(msg);
}
abis_push_ipa(nmsg, IPAC_PROTO_IPACCESS);
nmsg2 = abis_msgb_alloc(0);
if (!nmsg2) {
msgb_free(nmsg);
return -ENOMEM;
}
*msgb_put(nmsg2, 1) = IPAC_MSGT_ID_ACK;
abis_push_ipa(nmsg2, IPAC_PROTO_IPACCESS);
link->id_resp = 1;
abis_tx(link, nmsg2);
return abis_tx(link, nmsg);
}
static int abis_rx_ipaccess(struct ipabis_link *link, struct msgb *msg)
int abis_bts_rsl_sendmsg(struct msgb *msg)
{
uint8_t *data = msgb_l2(msg);
int len = msgb_l2len(msg);
int ret = 0;
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
* the signalling link at msg->dst */
msg->dst = msg->trx->rsl_link;
return abis_sendmsg(msg);
}
if (len < 1) {
LOGP(DABIS, LOGL_NOTICE, "Short read of ipaccess message\n");
msgb_free(msg);
return EIO;
}
switch (*data) {
case IPAC_MSGT_PONG:
#if 0
#warning HACK
rsl_tx_chan_rqd(link->bts->trx[0]);
#endif
LOGP(DABIS, LOGL_DEBUG, "PONG\n");
link->pong = 1;
break;
case IPAC_MSGT_PING:
LOGP(DABIS, LOGL_DEBUG, "reply to ping request\n");
ret = abis_tx_ipa_pingpong(link, IPAC_MSGT_PONG);
break;
case IPAC_MSGT_ID_GET:
ret = abis_rx_ipa_id_get(link, data + 1, len - 1);
break;
case IPAC_MSGT_ID_ACK:
LOGP(DABIS, LOGL_DEBUG, "ID ACK\n");
if (link->id_resp && link->bts)
ret = bts_link_estab(link->bts);
if (link->id_resp && link->trx)
ret = trx_link_estab(link->trx);
link->id_resp = 0;
static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
enum e1inp_sign_type type)
{
struct e1inp_sign_link *sign_link = NULL;
struct gsm_bts_trx *trx;
int trx_nr;
switch (type) {
case E1INP_SIGN_OML:
LOGP(DABIS, LOGL_INFO, "OML Signalling link up\n");
e1inp_ts_config_sign(&line->ts[E1INP_SIGN_OML-1], line);
sign_link = g_bts->oml_link =
e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML-1],
E1INP_SIGN_OML, NULL, 255, 0);
drain_oml_queue(g_bts);
sign_link->trx = g_bts->c0;
bts_link_estab(g_bts);
break;
default:
LOGP(DABIS, LOGL_NOTICE,
"Unknown ipaccess message type 0x%02x\n", *data);
ret = -EINVAL;
trx_nr = type - E1INP_SIGN_RSL;
LOGP(DABIS, LOGL_INFO, "RSL Signalling link for TRX%d up\n",
trx_nr);
trx = gsm_bts_trx_num(g_bts, trx_nr);
if (!trx) {
LOGP(DABIS, LOGL_ERROR, "TRX%d does not exixt!\n",
trx_nr);
break;
}
e1inp_ts_config_sign(&line->ts[type-1], line);
sign_link = trx->rsl_link =
e1inp_sign_link_create(&line->ts[type-1],
E1INP_SIGN_RSL, NULL, 0, 0);
sign_link->trx = trx;
trx_link_estab(trx);
break;
}
msgb_free(msg);
return ret;
return sign_link;
}
/*
* A-Bis over IP implementation
*/
/* receive message from BSC */
static int abis_rx(struct ipabis_link *link, struct msgb *msg)
static void sign_link_down(struct e1inp_line *line)
{
struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
int ret = 0;
struct gsm_bts_trx *trx;
LOGP(DABIS, LOGL_ERROR, "Signalling link down\n");
switch (hh->proto) {
case IPAC_PROTO_RSL:
if (!link->trx) {
LOGP(DABIS, LOGL_NOTICE,
"Received RSL message not on RSL link\n");
msgb_free(msg);
ret = EIO;
break;
/* First remove the OML signalling link */
if (g_bts->oml_link)
e1inp_sign_link_destroy(g_bts->oml_link);
g_bts->oml_link = NULL;
/* Then iterate over the RSL signalling links */
llist_for_each_entry(trx, &g_bts->trx_list, list) {
if (trx->rsl_link) {
e1inp_sign_link_destroy(trx->rsl_link);
trx->rsl_link = NULL;
}
msg->trx = link->trx;
ret = down_rsl(link->trx, msg);
}
bts_model_abis_close(g_bts);
}
/* callback for incoming mesages from A-bis/IP */
static int sign_link_cb(struct msgb *msg)
{
struct e1inp_sign_link *link = msg->dst;
/* osmo-bts code assumes msg->trx is set, but libosmo-abis works
* with the sign_link stored in msg->dst, so we have to convert
* here */
msg->trx = link->trx;
switch (link->type) {
case E1INP_SIGN_OML:
down_oml(link->trx->bts, msg);
break;
case IPAC_PROTO_IPACCESS:
ret = abis_rx_ipaccess(link, msg);
break;
case IPAC_PROTO_SCCP:
LOGP(DABIS, LOGL_INFO, "Received SCCP message\n");
msgb_free(msg);
break;
case IPAC_PROTO_OML:
if (!link->bts) {
LOGP(DABIS, LOGL_NOTICE,
"Received OML message not on OML link\n");
msgb_free(msg);
ret = EIO;
break;
}
msg->trx = link->bts->c0;
ret = down_oml(link->bts, msg);
case E1INP_SIGN_RSL:
down_rsl(link->trx, msg);
break;
default:
LOGP(DABIS, LOGL_NOTICE, "Unknown Protocol %d\n", hh->proto);
msgb_free(msg);
ret = EINVAL;
}
return ret;
}
static void abis_timeout(void *arg)
{
struct ipabis_link *link = arg;
int ret;
switch (link->state) {
case LINK_STATE_RETRYING:
ret = abis_open(link, link->ip);
if (ret <= 0)
osmo_timer_schedule(&link->timer, OML_RETRY_TIMER, 0);
break;
case LINK_STATE_CONNECT:
if (link->ping && !link->pong) {
LOGP(DABIS, LOGL_NOTICE,
"No reply to PING. Link is lost\n");
abis_close(link);
ret = abis_open(link, link->ip);
if (ret <= 0) {
osmo_timer_schedule(&link->timer,
OML_RETRY_TIMER, 0);
link->state = LINK_STATE_RETRYING;
}
break;
}
link->ping = 1;
link->pong = 0;
LOGP(DABIS, LOGL_DEBUG, "PING\n");
abis_tx_ipa_pingpong(link, IPAC_MSGT_PING);
osmo_timer_schedule(&link->timer, OML_PING_TIMER, 0);
break;
}
}
static int abis_sock_cb(struct osmo_fd *bfd, unsigned int what)
{
struct ipabis_link *link = bfd->data;
struct ipaccess_head *hh;
struct msgb *msg;
int ret = 0;
if ((what & BSC_FD_WRITE) && link->state == LINK_STATE_CONNECTING) {
if (link->bts) {
if (osmo_timer_pending(&link->timer))
osmo_timer_del(&link->timer);
// osmo_timer_schedule(&link->timer, OML_PING_TIMER, 0);
#warning HACK
osmo_timer_schedule(&link->timer, 3, 0);
link->ping = link->pong = 0;
}
LOGP(DABIS, LOGL_INFO, "Abis socket now connected.\n");
link->state = LINK_STATE_CONNECT;
}
//printf("what %d\n", what);
if ((what & BSC_FD_READ)) {
if (!link->rx_msg) {
link->rx_msg = msgb_alloc(ABIS_ALLOC_SIZE, "Abis/IP");
if (!link->rx_msg)
return -ENOMEM;
}
msg = link->rx_msg;
hh = (struct ipaccess_head *) msg->data;
if (msg->len < sizeof(*hh)) {
ret = recv(link->bfd.fd, msg->data, sizeof(*hh), 0);
if (ret <= 0) {
goto close;
}
msgb_put(msg, ret);
if (msg->len < sizeof(*hh))
return 0;
msg->l2h = msg->data + sizeof(*hh);
if (ntohs(hh->len) > msgb_tailroom(msg)) {
LOGP(DABIS, LOGL_DEBUG, "Received packet from "
"Abis socket too large.\n");
goto close;
}
}
ret = recv(link->bfd.fd, msg->tail,
ntohs(hh->len) + sizeof(*hh) - msg->len, 0);
if (ret == 0)
goto close;
if (ret < 0 && errno != EAGAIN)
goto close;
msgb_put(msg, ret);
if (ntohs(hh->len) + sizeof(*hh) > msg->len)
return 0;
link->rx_msg = NULL;
LOGP(DABIS, LOGL_DEBUG, "Received messages from Abis socket.\n");
ret = abis_rx(link, msg);
}
if ((what & BSC_FD_WRITE)) {
msg = msgb_dequeue(&link->tx_queue);
if (msg) {
LOGP(DABIS, LOGL_DEBUG, "Sending messages to Abis socket.\n");
ret = send(link->bfd.fd, msg->data, msg->len, 0);
msgb_free(msg);
if (ret < 0)
goto close;
} else
link->bfd.when &= ~BSC_FD_WRITE;
}
if ((what & BSC_FD_EXCEPT)) {
LOGP(DABIS, LOGL_NOTICE, "Abis socket received exception\n");
goto close;
}
return ret;
close:
abis_close(link);
/* RSL link will just close and BSC is notified */
if (link->trx) {
LOGP(DABIS, LOGL_NOTICE, "Connection to BSC failed\n");
return trx_link_estab(link->trx);
}
LOGP(DABIS, LOGL_NOTICE, "Connection to BSC failed, retrying in %d "
"seconds.\n", OML_RETRY_TIMER);
osmo_timer_schedule(&link->timer, OML_RETRY_TIMER, 0);
link->state = LINK_STATE_RETRYING;
return 0;
}
int abis_open(struct ipabis_link *link, uint32_t ip)
uint32_t get_signlink_remote_ip(struct e1inp_sign_link *link)
{
unsigned int on = 1;
struct sockaddr_in addr;
int sock;
int ret;
int fd = link->ts->driver.ipaccess.fd.fd;
struct sockaddr_in sin;
socklen_t slen = sizeof(sin);
int rc;
oml_init();
if (link->bfd.fd > 0)
return -EBUSY;
INIT_LLIST_HEAD(&link->tx_queue);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
return sock;
ret = ioctl(sock, FIONBIO, (unsigned char *)&on);
if (ret < 0) {
close(sock);
return ret;
rc = getpeername(fd, (struct sockaddr *)&sin, &slen);
if (rc < 0) {
LOGP(DOML, LOGL_ERROR, "Cannot determine remote IP Addr: %s\n",
strerror(errno));
return 0;
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
if (link->bts)
addr.sin_port = htons(IPA_TCP_PORT_OML);
else
addr.sin_port = htons(IPA_TCP_PORT_RSL);
addr.sin_addr.s_addr = htonl(ip);
/* we assume that the soket is AF_INET. As Abis/IP contains
* lots of hard-coded IPv4 addresses, this safe */
OSMO_ASSERT(sin.sin_family == AF_INET);
ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0 && errno != EINPROGRESS) {
close(sock);
return ret;
}
link->bfd.data = link;
link->bfd.when = BSC_FD_READ | BSC_FD_WRITE | BSC_FD_EXCEPT;
link->bfd.cb = abis_sock_cb;
link->bfd.fd = sock;
link->state = LINK_STATE_CONNECTING;
link->ip = ip;
link->timer.cb = abis_timeout;
link->timer.data = link;
osmo_fd_register(&link->bfd);
LOGP(DABIS, LOGL_INFO, "Abis socket trying to reach BSC.\n");
return sock;
return ntohl(sin.sin_addr.s_addr);
}
void abis_close(struct ipabis_link *link)
static int inp_s_cbfn(unsigned int subsys, unsigned int signal,
void *hdlr_data, void *signal_data)
{
struct msgb *msg;
if (subsys != SS_L_INPUT)
return 0;
if (link->bfd.fd <= 0)
return;
LOGP(DABIS, LOGL_NOTICE, "Abis socket closed.\n");
DEBUGP(DABIS, "Input Signal %u received\n", signal);
if (link->rx_msg) {
msgb_free(link->rx_msg);
link->rx_msg = NULL;
}
while ((msg = msgb_dequeue(&link->tx_queue)))
msgb_free(msg);
osmo_fd_unregister(&link->bfd);
close(link->bfd.fd);
link->bfd.fd = -1; /* -1 or 0 indicates: 'close' */
link->state = LINK_STATE_IDLE;
if (osmo_timer_pending(&link->timer))
osmo_timer_del(&link->timer);
/* for now, we simply terminate the program and re-spawn */
if (link->bts)
bts_shutdown(link->bts, "Abis close / OML");
else if (link->trx)
bts_shutdown(link->trx->bts, "Abis close / RSL");
else {
LOGP(DABIS, LOGL_FATAL, "Unable to connect to BSC\n");
exit(43);
}
return 0;
}
static struct ipaccess_unit bts_dev_info = {
.unit_name = "sysmoBTS",
.equipvers = "", /* FIXME: read this from hw */
.swversion = PACKAGE_VERSION,
.location1 = "",
.location2 = "",
.serno = "",
};
static struct e1inp_line_ops line_ops = {
.cfg = {
.ipa = {
.role = E1INP_LINE_R_BTS,
.dev = &bts_dev_info,
},
},
.sign_link_up = sign_link_up,
.sign_link_down = sign_link_down,
.sign_link = sign_link_cb,
};
void abis_init(struct gsm_bts *bts)
{
g_bts = bts;
oml_init(&bts->mo);
libosmo_abis_init(NULL);
osmo_signal_register_handler(SS_L_INPUT, &inp_s_cbfn, bts);
}
struct e1inp_line *abis_open(struct gsm_bts *bts, char *dst_host,
char *model_name)
{
struct e1inp_line *line;
/* patch in various data from VTY and othe sources */
line_ops.cfg.ipa.addr = dst_host;
osmo_get_macaddr(bts_dev_info.mac_addr, "eth0");
bts_dev_info.site_id = bts->ip_access.site_id;
bts_dev_info.bts_id = bts->ip_access.bts_id;
bts_dev_info.unit_name = model_name;
if (bts->description)
bts_dev_info.unit_name = bts->description;
bts_dev_info.location2 = model_name;
line = e1inp_line_find(0);
if (!line)
line = e1inp_line_create(0, "ipa");
if (!line)
return NULL;
e1inp_line_bind_ops(line, &line_ops);
/* This will open the OML connection now */
if (e1inp_line_update(line) < 0)
return NULL;
return line;
}

170
src/common/amr.c Normal file
View File

@@ -0,0 +1,170 @@
#include <stdint.h>
#include <errno.h>
#include <osmocom/core/logging.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/amr.h>
void amr_log_mr_conf(int ss, int logl, const char *pfx,
struct amr_multirate_conf *amr_mrc)
{
int i;
LOGP(ss, logl, "%s AMR MR Conf: num_modes=%u",
pfx, amr_mrc->num_modes);
for (i = 0; i < amr_mrc->num_modes; i++)
LOGPC(ss, logl, ", mode[%u] = %u/%u/%u",
i, amr_mrc->bts_mode[i].mode,
amr_mrc->bts_mode[i].threshold,
amr_mrc->bts_mode[i].hysteresis);
LOGPC(ss, logl, "\n");
}
static inline int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc,
uint8_t cmi)
{
unsigned int i;
for (i = 0; i < amr_mrc->num_modes; i++) {
if (amr_mrc->bts_mode[i].mode == cmi)
return i;
}
return -EINVAL;
}
static inline uint8_t set_cmr_mode_idx(const struct amr_multirate_conf *amr_mrc,
uint8_t cmr)
{
int rc;
/* Codec Mode Request is in upper 4 bits of RTP payload header,
* and we simply copy the CMR into the CMC */
if (cmr == 0xF) {
/* FIXME: we need some state about the last codec mode */
return 0;
}
rc = get_amr_mode_idx(amr_mrc, cmr);
if (rc < 0) {
/* FIXME: we need some state about the last codec mode */
LOGP(DRTP, LOGL_INFO, "RTP->L1: overriding CMR %u\n", cmr);
return 0;
}
return rc;
}
static inline uint8_t set_cmi_mode_idx(const struct amr_multirate_conf *amr_mrc,
uint8_t cmi)
{
int rc = get_amr_mode_idx(amr_mrc, cmi);
if (rc < 0) {
LOGP(DRTP, LOGL_ERROR, "AMR CMI %u not part of AMR MR set\n",
cmi);
return 0;
}
return rc;
}
void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc,
uint8_t cmi, uint8_t cmr)
{
data[0] = set_cmi_mode_idx(amr_mrc, cmi);
data[1] = set_cmr_mode_idx(amr_mrc, cmr);
}
/* parse a GSM 04.08 MultiRate Config IE (10.5.2.21aa) in a more
* comfortable internal data structure */
int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
const uint8_t *mr_conf, unsigned int len)
{
uint8_t mr_version = mr_conf[0] >> 5;
uint8_t num_codecs = 0;
int i, j = 0;
if (mr_version != 1) {
LOGP(DRSL, LOGL_ERROR, "AMR Multirate Version %u unknown\n",
mr_version);
goto ret_einval;
}
/* check number of active codecs */
for (i = 0; i < 8; i++) {
if (mr_conf[1] & (1 << i))
num_codecs++;
}
/* check for minimum length */
if (num_codecs == 0 ||
(num_codecs == 1 && len < 2) ||
(num_codecs == 2 && len < 4) ||
(num_codecs == 3 && len < 5) ||
(num_codecs == 4 && len < 6) ||
(num_codecs > 4)) {
LOGP(DRSL, LOGL_ERROR, "AMR Multirate with %u modes len=%u "
"not possible\n", num_codecs, len);
goto ret_einval;
}
/* copy the first two octets of the IE */
amr_mrc->gsm48_ie[0] = mr_conf[0];
amr_mrc->gsm48_ie[1] = mr_conf[1];
amr_mrc->num_modes = num_codecs;
for (i = 0; i < 8; i++) {
if (mr_conf[1] & (1 << i)) {
amr_mrc->bts_mode[j++].mode = i;
}
}
if (num_codecs >= 2) {
amr_mrc->bts_mode[0].threshold = mr_conf[1] & 0x3F;
amr_mrc->bts_mode[0].hysteresis = mr_conf[2] >> 4;
}
if (num_codecs >= 3) {
amr_mrc->bts_mode[1].threshold =
((mr_conf[2] & 0xF) << 2) | (mr_conf[3] >> 6);
amr_mrc->bts_mode[1].hysteresis = (mr_conf[3] >> 2) & 0xF;
}
if (num_codecs >= 4) {
amr_mrc->bts_mode[2].threshold =
((mr_conf[3] & 0x3) << 4) | (mr_conf[4] >> 4);
amr_mrc->bts_mode[2].hysteresis = mr_conf[4] & 0xF;
}
return num_codecs;
ret_einval:
return -EINVAL;
}
/*! \brief determine AMR initial codec mode for given logical channel
* \returns integer between 0..3 for AMR codce mode 1..4 */
unsigned int amr_get_initial_mode(struct gsm_lchan *lchan)
{
struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr;
struct gsm48_multi_rate_conf *mr_conf =
(struct gsm48_multi_rate_conf *) amr_mrc->gsm48_ie;
if (mr_conf->icmi) {
/* initial mode given, coding in TS 05.09 3.4.1 */
return mr_conf->smod;
} else {
/* implicit rule according to TS 05.09 Chapter 3.4.3 */
switch (amr_mrc->num_modes) {
case 2:
case 3:
/* return the most robust */
return 0;
case 4:
/* return the second-most robust */
return 1;
case 1:
default:
/* return the only mode we have */
return 0;
}
}
}

View File

@@ -40,9 +40,17 @@
#include <osmo-bts/abis.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/pcu_if.h>
#include <osmo-bts/rsl.h>
#include <osmo-bts/oml.h>
#include <osmo-bts/signal.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
#define MIN_QUAL_RACH 5.0f /* at least 5 dB C/I */
#define MIN_QUAL_NORM -0.5f /* at least -1 dB C/I */
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 },
@@ -51,27 +59,90 @@ struct gsm_network bts_gsmnet = {
void *tall_bts_ctx;
/* Table 3.1 TS 04.08: Values of parameter S */
static const uint8_t tx_integer[] = {
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 25, 32, 50,
};
static const uint8_t s_values[][2] = {
{ 55, 41 }, { 76, 52 }, { 109, 58 }, { 163, 86 }, { 217, 115 },
};
static int bts_signal_cbfn(unsigned int subsys, unsigned int signal,
void *hdlr_data, void *signal_data)
{
if (subsys == SS_GLOBAL && signal == S_NEW_SYSINFO) {
struct gsm_bts *bts = signal_data;
bts_update_agch_max_queue_length(bts);
}
return 0;
}
/* Initialize the BTS (and TRX) data structures, called before config
* file reading */
int bts_init(struct gsm_bts *bts)
{
struct gsm_bts_role_bts *btsb;
struct gsm_bts_trx *trx;
int rc;
int rc, i;
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;
bts->role = btsb = talloc_zero(bts, struct gsm_bts_role_bts);
INIT_LLIST_HEAD(&btsb->agch_queue);
btsb->agch_queue_length = 0;
/* FIXME: make those parameters configurable */
/* enable management with default levels,
* raise threshold to GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE to
* disable this feature.
*/
btsb->agch_queue_low_level = GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT;
btsb->agch_queue_high_level = GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT;
btsb->agch_queue_thresh_level = GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT;
/* configurable via VTY */
btsb->paging_state = paging_init(btsb, 200, 0);
btsb->ul_power_target = -75; /* dBm default */
btsb->rtp_jitter_adaptive = false;
/* configurable via OML */
btsb->load.ccch.load_ind_period = 112;
load_timer_start(bts);
btsb->rtp_jitter_buf_ms = 100;
btsb->max_ta = 63;
btsb->ny1 = 4;
btsb->t3105_ms = 300;
btsb->min_qual_rach = MIN_QUAL_RACH;
btsb->min_qual_norm = MIN_QUAL_NORM;
btsb->pcu.sock_path = talloc_strdup(btsb, PCU_SOCK_DEFAULT);
for (i = 0; i < ARRAY_SIZE(btsb->t200_ms); i++)
btsb->t200_ms[i] = oml_default_t200_ms[i];
/* default RADIO_LINK_TIMEOUT */
btsb->radio_link_timeout = 32;
/* Start with the site manager */
oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
/* set BTS to dependency */
oml_mo_state_chg(&bts->mo, -1, NM_AVSTATE_DEPENDENCY);
oml_mo_state_init(&bts->mo, -1, NM_AVSTATE_DEPENDENCY);
oml_mo_state_init(&bts->gprs.nse.mo, -1, NM_AVSTATE_DEPENDENCY);
oml_mo_state_init(&bts->gprs.cell.mo, -1, NM_AVSTATE_DEPENDENCY);
oml_mo_state_init(&bts->gprs.nsvc[0].mo, -1, NM_AVSTATE_DEPENDENCY);
oml_mo_state_init(&bts->gprs.nsvc[1].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
/* initialize bts data structure */
llist_for_each_entry(trx, &bts->trx_list, list) {
struct trx_power_params *tpp = &trx->power_params;
int i;
for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
struct gsm_bts_trx_ts *ts = &trx->ts[i];
int k;
@@ -81,18 +152,35 @@ int bts_init(struct gsm_bts *bts)
INIT_LLIST_HEAD(&lchan->dl_tch_queue);
}
}
/* Default values for the power adjustments */
tpp->ramp.max_initial_pout_mdBm = to_mdB(0);
tpp->ramp.step_size_mdB = to_mdB(2);
tpp->ramp.step_interval_sec = 1;
}
osmo_rtp_init(tall_bts_ctx);
/* allocate a talloc pool for ORTP to ensure it doesn't have to go back
* to the libc malloc all the time */
tall_rtp_ctx = talloc_pool(tall_bts_ctx, 262144);
osmo_rtp_init(tall_rtp_ctx);
rc = bts_model_init(bts);
if (rc < 0)
if (rc < 0) {
llist_del(&bts->list);
return rc;
}
/* add to list of BTSs */
llist_add_tail(&bts->list, &bts_gsmnet.bts_list);
bts_gsmnet.num_bts++;
if (!initialized) {
osmo_signal_register_handler(SS_GLOBAL, bts_signal_cbfn, NULL);
initialized = 1;
}
INIT_LLIST_HEAD(&btsb->smscb_state.queue);
INIT_LLIST_HEAD(&btsb->oml_queue);
/* register DTX DL FSM */
osmo_fsm_register(&dtx_dl_amr_fsm);
return rc;
}
@@ -110,238 +198,25 @@ void bts_shutdown(struct gsm_bts *bts, const char *reason)
{
struct gsm_bts_trx *trx;
if (osmo_timer_pending(&shutdown_timer)) {
LOGP(DOML, LOGL_NOTICE,
"BTS is already being shutdown.\n");
return;
}
LOGP(DOML, LOGL_NOTICE, "Shutting down BTS %u, Reason %s\n",
bts->nr, reason);
llist_for_each_entry(trx, &bts->trx_list, list)
llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
bts_model_trx_deact_rf(trx);
bts_model_trx_close(trx);
}
/* shedule a timer to make sure select loop logic can run again
* to dispatch any pending primitives */
osmo_timer_schedule(&shutdown_timer, 3, 0);
}
#if 0
struct osmobts_lchan *lchan_by_channelnr(struct osmobts_trx *trx,
uint8_t channelnr)
{
uint8_t ts = channelnr & ~RSL_CHAN_NR_MASK;
uint8_t type = channelnr & RSL_CHAN_NR_MASK;
uint8_t sub = 0;
struct osmobts_slot *slot = trx->slot[ts];
if ((type & 0xf0) == RSL_CHAN_Lm_ACCHs) {
sub = (channelnr >> 3) & 1;
type = RSL_CHAN_Lm_ACCHs;
} else
if ((type & 0xe0) == RSL_CHAN_SDCCH4_ACCH) {
sub = (channelnr >> 3) & 3;
type = RSL_CHAN_SDCCH4_ACCH;
} else
if ((type & 0xc0) == RSL_CHAN_SDCCH8_ACCH) {
sub = (channelnr >> 3) & 7;
type = RSL_CHAN_SDCCH8_ACCH;
} else
if (type == RSL_CHAN_BCCH
|| type == RSL_CHAN_RACH
|| type == RSL_CHAN_PCH_AGCH) {
if (!slot->has_bcch) {
LOGP(DSUM, LOGL_NOTICE, "Slot %d has no BCCH\n", ts);
return NULL;
}
return slot->lchan[0];
} else {
LOGP(DSUM, LOGL_NOTICE, "Unknown channel type 0x%02x\n", type);
return NULL;
}
if (slot->acch_type == type)
return slot->lchan[sub];
}
LOGP(DSUM, LOGL_NOTICE, "No slot found with channel type 0x%02x\n", type);
return NULL;
}
struct osmocom_bts *create_bts(uint8_t num_trx, char *id)
{
struct osmocom_bts *bts;
struct osmobts_trx *trx;
int i, j;
LOGP(DSUM, LOGL_INFO, "Creating BTS\n");
bts = talloc_zero(l23_ctx, struct osmocom_bts);
if (!bts)
return NULL;
bts->link.bts = bts;
bts->id = id;
for (i = 0; i < num_trx; i++) {
LOGP(DSUM, LOGL_INFO, "Creating TRX %d\n", i);
trx = talloc_zero(l23_ctx, struct osmobts_trx);
if (!trx)
return NULL;
trx->bts = bts;
trx->trx_nr = i;
INIT_LLIST_HEAD(&trx->ms_list);
for (j = 0; j < 8; j++) {
trx->slot[j].trx = trx;
trx->slot[j].slot_nr = j;
trx->slot[j].chan_comb = 0xff; /* not set */
}
trx->link.trx = trx;
bts->trx[i] = trx;
}
bts->num_trx = num_trx;
return bts;
}
int create_ms(struct osmobts_trx *trx, int maskc, uint8_t *maskv_tx,
uint8_t *maskv_rx)
{
struct osmobts_ms *tx_ms, *rx_ms;
int i, j;
int rc;
static char sock_path[] = "/tmp/osmocom_l2.1";
for (i = 0; i < maskc; i++) {
/* create MS */
tx_ms = talloc_zero(l23_ctx, struct osmobts_ms);
printf("%p\n", tx_ms);
if (!tx_ms)
return -ENOMEM;
tx_ms->trx = trx;
rc = layer2_open(&tx_ms->ms, sock_path);
strcpy(tx_ms->ms.name, strchr(sock_path, '.') + 1);
sock_path[strlen(sock_path) - 1]++;
if (rc < 0) {
talloc_free(tx_ms);
return rc;
}
llist_add_tail(&tx_ms->entry, &trx->ms_list);
rx_ms = talloc_zero(l23_ctx, struct osmobts_ms);
rx_ms->trx = trx;
if (!rx_ms)
return -ENOMEM;
rc = layer2_open(&rx_ms->ms, sock_path);
strcpy(rx_ms->ms.name, strchr(sock_path, '.') + 1);
sock_path[strlen(sock_path) - 1]++;
if (rc < 0) {
talloc_free(rx_ms);
return rc;
}
llist_add_tail(&rx_ms->entry, &trx->ms_list);
/* assign to SLOT */
for (j = 0; j < 8; j++) {
if ((maskv_tx[i] & (1 << j)))
trx->slot[j].tx_ms = tx_ms;
if ((maskv_rx[i] & (1 << j)))
trx->slot[j].rx_ms = rx_ms;
}
}
return i;
}
void destroy_lchan(struct osmobts_lchan *lchan)
{
LOGP(DSUM, LOGL_INFO, "Destroying logical channel. (trx=%d ts=%d ss=%d)\n", lchan->slot->trx->trx_nr, lchan->slot->slot_nr, lchan->lchan_nr);
lapdm_exit(&lchan->l2_entity.lapdm_acch);
lapdm_exit(&lchan->l2_entity.lapdm_acch);
if (lchan->rtp.socket_created)
rtp_close_socket(&lchan->rtp);
talloc_free(lchan);
}
/* create and destroy lchan */
void bts_setup_slot(struct osmobts_slot *slot, uint8_t comb)
{
int i, ii;
struct osmobts_lchan *lchan;
uint8_t cbits;
if (slot->chan_comb == comb)
return;
/* destroy old */
for (i = 0; i < 8; i++) {
if (slot->lchan[i])
destroy_lchan(slot->lchan[i]);
slot->lchan[i] = NULL;
}
switch(comb) {
case 0xff:
return;
case NM_CHANC_TCHFull:
cbits = 0x01;
ii = 1;
break;
case NM_CHANC_TCHHalf:
cbits = 0x02;
ii = 2;
break;
case NM_CHANC_BCCHComb:
cbits = 0x04;
ii = 4;
break;
case NM_CHANC_SDCCH:
cbits = 0x08;
ii = 8;
break;
default:
cbits = 0x10;
ii = 0;
}
if (!slot->tx_ms) {
LOGP(DSUM, LOGL_ERROR, "Slot is not available\n");
return;
}
for (i = 0; i < ii; i++) {
LOGP(DSUM, LOGL_INFO, "Creating logical channel. (trx=%d ts=%d ss=%d)\n", slot->trx->trx_nr, slot->slot_nr, i);
lchan = talloc_zero(l23_ctx, struct osmobts_lchan);
lchan->slot = slot;
lchan->lchan_nr = i;
lchan->chan_nr = ((cbits | i) << 3) | slot->slot_nr;
lapdm_init(&lchan->l2_entity.lapdm_dcch, &lchan->l2_entity, &slot->tx_ms->ms);
lapdm_init(&lchan->l2_entity.lapdm_acch, &lchan->l2_entity, &slot->tx_ms->ms);
lapdm_set_bts();
osmol2_register_handler(&lchan->l2_entity, &rsl_tx_rll);
slot->lchan[i] = lchan;
}
}
static void destroy_ms(struct osmobts_ms *ms)
{
layer2_close(&ms->ms);
llist_del(&ms->entry);
talloc_free(ms);
}
void destroy_bts(struct osmocom_bts *bts)
{
int i;
struct osmobts_ms *ms;
for (i = 0; i < bts->num_trx; i++) {
abis_close(&bts->trx[i]->link);
while(!llist_empty(&bts->trx[i]->ms_list)) {
ms = llist_entry(bts->trx[i]->ms_list.next,
struct osmobts_ms, entry);
destroy_ms(ms);
}
if (osmo_timer_pending(&bts->trx[i]->si.timer))
osmo_timer_del(&bts->trx[i]->si.timer);
talloc_free(bts->trx[i]);
bts->trx[i] = NULL;
}
abis_close(&bts->link);
talloc_free(bts);
}
#endif
/* main link is established, send status report */
int bts_link_estab(struct gsm_bts *bts)
{
@@ -349,10 +224,16 @@ int bts_link_estab(struct gsm_bts *bts)
LOGP(DSUM, LOGL_INFO, "Main link established, sending Status'.\n");
/* BTS and SITE MGR are EAABLED, BTS is DEPENDENCY */
/* BTS and SITE MGR are EANBLED, BTS is DEPENDENCY */
oml_tx_state_changed(&bts->site_mgr.mo);
oml_tx_state_changed(&bts->mo);
/* 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);
@@ -367,54 +248,55 @@ int bts_link_estab(struct gsm_bts *bts)
}
}
return 0;
return bts_model_oml_estab(bts);
}
/* RSL link is established, send status report */
int trx_link_estab(struct gsm_bts_trx *trx)
{
struct ipabis_link *link = (struct ipabis_link *) trx->rsl_link;
uint8_t radio_state = (link->state == LINK_STATE_CONNECT) ? NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED;
struct e1inp_sign_link *link = trx->rsl_link;
uint8_t radio_state = link ? NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED;
int rc;
LOGP(DSUM, LOGL_INFO, "RSL link (TRX %02x) state changed to %s, sending Status'.\n",
trx->nr, (link->state == LINK_STATE_CONNECT) ? "up" : "down");
trx->nr, link ? "up" : "down");
oml_mo_state_chg(&trx->mo, radio_state, NM_AVSTATE_OK);
if (link->state == LINK_STATE_CONNECT)
rsl_tx_rf_res(trx);
if (link)
rc = rsl_tx_rf_res(trx);
else
rc = bts_model_trx_deact_rf(trx);
if (rc < 0)
oml_fail_rep(OSMO_EVT_MAJ_RSL_FAIL,
link ? "Failed to establish RSL link (%d)" :
"Failed to deactivate RF (%d)", rc);
return 0;
}
void bts_new_si(void *arg)
/* set the availability of the TRX (used by PHY driver) */
int trx_set_available(struct gsm_bts_trx *trx, int avail)
{
struct osmobts_trx *trx = arg;
int tn;
LOGP(DSUM, LOGL_INFO, "TRX(%d): Setting available = %d\n",
trx->nr, avail);
if (avail) {
/* FIXME: This needs to be sorted out */
#if 0
if (osmo_timer_pending(&trx->si.timer))
return;
i = 0;
while(i < BTS_SI_NUM) {
if ((trx->si.flags[i] & BTS_SI_NEW))
break;
i++;
}
if (i == BTS_SI_NUM)
return;
if ((trx->si.flags[i] & BTS_SI_USE))
LOGP(DSUM, LOGL_INFO, "Setting SYSTEM INFORMATION %s.\n", bts_si_name[i]);
else
LOGP(DSUM, LOGL_INFO, "Removing SYSTEM INFORMATION %s.\n", bts_si_name[i]);
trx->si.flags[i] &= ~BTS_SI_NEW;
/* distribute */
printf("TODO: send SI update to L1\n");
/* delay until next SI */
trx->si.timer.cb = bts_new_si;
trx->si.timer.data = trx;
osmo_timer_schedule(&trx->si.timer, 0, 200000);
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OFF_LINE);
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++)
oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
#endif
} else {
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_NOT_INSTALLED);
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++)
oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
}
return 0;
}
int lchan_init_lapdm(struct gsm_lchan *lchan)
@@ -425,30 +307,369 @@ int lchan_init_lapdm(struct gsm_lchan *lchan)
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY);
lapdm_channel_set_l1(lc, NULL, lchan);
lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan);
oml_set_lchan_t200(lchan);
return 0;
}
#define CCCH_RACH_RATIO_COMBINED256 (256*1/9)
#define CCCH_RACH_RATIO_SEPARATE256 (256*10/55)
int bts_agch_max_queue_length(int T, int bcch_conf)
{
int S, ccch_rach_ratio256, i;
int T_group = 0;
int is_ccch_comb = 0;
if (bcch_conf == RSL_BCCH_CCCH_CONF_1_C)
is_ccch_comb = 1;
/*
* The calculation is based on the ratio of the number RACH slots and
* CCCH blocks per time:
* Lmax = (T + 2*S) / R_RACH * R_CCCH
* where
* T3126_min = (T + 2*S) / R_RACH, as defined in GSM 04.08, 11.1.1
* R_RACH is the RACH slot rate (e.g. RACHs per multiframe)
* R_CCCH is the CCCH block rate (same time base like R_RACH)
* S and T are defined in GSM 04.08, 3.3.1.1.2
* The ratio is mainly influenced by the downlink only channels
* (BCCH, FCCH, SCH, CBCH) that can not be used for CCCH.
* An estimation with an error of < 10% is used:
* ~ 1/9 if CCCH is combined with SDCCH, and
* ~ 1/5.5 otherwise.
*/
ccch_rach_ratio256 = is_ccch_comb ?
CCCH_RACH_RATIO_COMBINED256 :
CCCH_RACH_RATIO_SEPARATE256;
for (i = 0; i < ARRAY_SIZE(tx_integer); i++) {
if (tx_integer[i] == T) {
T_group = i % 5;
break;
}
}
S = s_values[T_group][is_ccch_comb];
return (T + 2 * S) * ccch_rach_ratio256 / 256;
}
static void bts_update_agch_max_queue_length(struct gsm_bts *bts)
{
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct gsm48_system_information_type_3 *si3;
int old_max_length = btsb->agch_max_queue_length;
if (!(bts->si_valid & (1<<SYSINFO_TYPE_3)))
return;
si3 = GSM_BTS_SI(bts, SYSINFO_TYPE_3);
btsb->agch_max_queue_length =
bts_agch_max_queue_length(si3->rach_control.tx_integer,
si3->control_channel_desc.ccch_conf);
if (btsb->agch_max_queue_length != old_max_length)
LOGP(DRSL, LOGL_INFO, "Updated AGCH max queue length to %d\n",
btsb->agch_max_queue_length);
}
#define REQ_REFS_PER_IMM_ASS_REJ 4
static int store_imm_ass_rej_refs(struct gsm48_imm_ass_rej *rej,
struct gsm48_req_ref *req_refs,
uint8_t *wait_inds,
int count)
{
switch (count) {
case 0:
/* TODO: Warning ? */
return 0;
default:
count = 4;
rej->req_ref4 = req_refs[3];
rej->wait_ind4 = wait_inds[3];
/* fall through */
case 3:
rej->req_ref3 = req_refs[2];
rej->wait_ind3 = wait_inds[2];
/* fall through */
case 2:
rej->req_ref2 = req_refs[1];
rej->wait_ind2 = wait_inds[1];
/* fall through */
case 1:
rej->req_ref1 = req_refs[0];
rej->wait_ind1 = wait_inds[0];
break;
}
switch (count) {
case 1:
rej->req_ref2 = req_refs[0];
rej->wait_ind2 = wait_inds[0];
/* fall through */
case 2:
rej->req_ref3 = req_refs[0];
rej->wait_ind3 = wait_inds[0];
/* fall through */
case 3:
rej->req_ref4 = req_refs[0];
rej->wait_ind4 = wait_inds[0];
/* fall through */
default:
break;
}
return count;
}
static int extract_imm_ass_rej_refs(struct gsm48_imm_ass_rej *rej,
struct gsm48_req_ref *req_refs,
uint8_t *wait_inds)
{
int count = 0;
req_refs[count] = rej->req_ref1;
wait_inds[count] = rej->wait_ind1;
count++;
if (memcmp(&rej->req_ref1, &rej->req_ref2, sizeof(rej->req_ref2))) {
req_refs[count] = rej->req_ref2;
wait_inds[count] = rej->wait_ind2;
count++;
}
if (memcmp(&rej->req_ref1, &rej->req_ref3, sizeof(rej->req_ref3)) &&
memcmp(&rej->req_ref2, &rej->req_ref3, sizeof(rej->req_ref3))) {
req_refs[count] = rej->req_ref3;
wait_inds[count] = rej->wait_ind3;
count++;
}
if (memcmp(&rej->req_ref1, &rej->req_ref4, sizeof(rej->req_ref4)) &&
memcmp(&rej->req_ref2, &rej->req_ref4, sizeof(rej->req_ref4)) &&
memcmp(&rej->req_ref3, &rej->req_ref4, sizeof(rej->req_ref4))) {
req_refs[count] = rej->req_ref4;
wait_inds[count] = rej->wait_ind4;
count++;
}
return count;
}
static int try_merge_imm_ass_rej(struct gsm48_imm_ass_rej *old_rej,
struct gsm48_imm_ass_rej *new_rej)
{
struct gsm48_req_ref req_refs[2 * REQ_REFS_PER_IMM_ASS_REJ];
uint8_t wait_inds[2 * REQ_REFS_PER_IMM_ASS_REJ];
int count = 0;
int stored = 0;
if (new_rej->msg_type != GSM48_MT_RR_IMM_ASS_REJ)
return 0;
if (old_rej->msg_type != GSM48_MT_RR_IMM_ASS_REJ)
return 0;
/* GSM 08.58, 5.7
* -> The BTS may combine serveral IMM.ASS.REJ messages
* -> Identical request refs in one message may be squeezed
*
* GSM 04.08, 9.1.20.2
* -> Request ref and wait ind are duplicated to fill the message
*/
/* Extract all entries */
count = extract_imm_ass_rej_refs(old_rej,
&req_refs[count], &wait_inds[count]);
if (count == REQ_REFS_PER_IMM_ASS_REJ)
return 0;
count += extract_imm_ass_rej_refs(new_rej,
&req_refs[count], &wait_inds[count]);
/* Store entries into old message */
stored = store_imm_ass_rej_refs(old_rej,
&req_refs[stored], &wait_inds[stored],
count);
count -= stored;
if (count == 0)
return 1;
/* Store remaining entries into new message */
stored += store_imm_ass_rej_refs(new_rej,
&req_refs[stored], &wait_inds[stored],
count);
return 0;
}
int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg)
{
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
int hard_limit = 1000;
struct gsm48_imm_ass_rej *imm_ass_cmd = msgb_l3(msg);
/* FIXME: implement max queue length */
llist_add_tail(&msg->list, &btsb->agch_queue);
if (btsb->agch_queue_length > hard_limit) {
LOGP(DSUM, LOGL_ERROR,
"AGCH: too many messages in queue, "
"refusing message type 0x%02x, length = %d/%d\n",
((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type,
btsb->agch_queue_length, btsb->agch_max_queue_length);
btsb->agch_queue_rejected_msgs++;
return -ENOMEM;
}
if (btsb->agch_queue_length > 0) {
struct msgb *last_msg =
llist_entry(btsb->agch_queue.prev, struct msgb, list);
struct gsm48_imm_ass_rej *last_imm_ass_rej = msgb_l3(last_msg);
if (try_merge_imm_ass_rej(last_imm_ass_rej, imm_ass_cmd)) {
btsb->agch_queue_merged_msgs++;
msgb_free(msg);
return 0;
}
}
msgb_enqueue(&btsb->agch_queue, msg);
btsb->agch_queue_length++;
return 0;
}
struct msgb *bts_agch_dequeue(struct gsm_bts *bts)
{
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);;
struct msgb *msg;
if (llist_empty(&btsb->agch_queue))
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct msgb *msg = msgb_dequeue(&btsb->agch_queue);
if (!msg)
return NULL;
msg = llist_entry(btsb->agch_queue.next, struct msgb, list);
llist_del(&msg->list);
btsb->agch_queue_length--;
return msg;
}
/*
* Remove lower prio messages if the queue has grown too long.
*
* \return 0 iff the number of messages in the queue would fit into the AGCH
* reserved part of the CCCH.
*/
static void compact_agch_queue(struct gsm_bts *bts)
{
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct msgb *msg, *msg2;
int max_len, slope, offs;
int level_low = btsb->agch_queue_low_level;
int level_high = btsb->agch_queue_high_level;
int level_thres = btsb->agch_queue_thresh_level;
max_len = btsb->agch_max_queue_length;
if (max_len == 0)
max_len = 1;
if (btsb->agch_queue_length < max_len * level_thres / 100)
return;
/* p^
* 1+ /'''''
* | /
* | /
* 0+---/--+----+--> Q length
* low high max_len
*/
offs = max_len * level_low / 100;
if (level_high > level_low)
slope = 0x10000 * 100 / (level_high - level_low);
else
slope = 0x10000 * max_len; /* p_drop >= 1 if len > offs */
llist_for_each_entry_safe(msg, msg2, &btsb->agch_queue, list) {
struct gsm48_imm_ass *imm_ass_cmd = msgb_l3(msg);
int p_drop;
if (imm_ass_cmd->msg_type != GSM48_MT_RR_IMM_ASS_REJ)
return;
/* IMMEDIATE ASSIGN REJECT */
p_drop = (btsb->agch_queue_length - offs) * slope / max_len;
if ((random() & 0xffff) >= p_drop)
return;
llist_del(&msg->list);
btsb->agch_queue_length--;
msgb_free(msg);
btsb->agch_queue_dropped_msgs++;
}
return;
}
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
int is_ag_res)
{
struct msgb *msg = NULL;
struct gsm_bts_role_bts *btsb = bts->role;
int rc = 0;
int is_empty = 1;
/* Do queue house keeping.
* This needs to be done every time a CCCH message is requested, since
* the queue max length is calculated based on the CCCH block rate and
* PCH messages also reduce the drain of the AGCH queue.
*/
compact_agch_queue(bts);
/* Check for paging messages first if this is PCH */
if (!is_ag_res)
rc = paging_gen_msg(btsb->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;
/* Copy AGCH message */
memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg));
rc = msgb_l3len(msg);
msgb_free(msg);
if (is_ag_res)
btsb->agch_queue_agch_msgs++;
else
btsb->agch_queue_pch_msgs++;
return rc;
}
int bts_supports_cipher(struct gsm_bts_role_bts *bts, int rsl_cipher)
{
int sup;
if (rsl_cipher < 1 || rsl_cipher > 8)
return -ENOTSUP;
/* No encryption is always supported */
if (rsl_cipher == 1)
return 1;
sup = (1 << (rsl_cipher - 2)) & bts->support.ciphers;
return sup > 0;
}
int trx_ms_pwr_ctrl_is_osmo(struct gsm_bts_trx *trx)
{
return trx->ms_power_control == 1;
}
struct gsm_time *get_time(struct gsm_bts *bts)
{
struct gsm_bts_role_bts *btsb = bts->role;
return &btsb->gsm_time;
}

View File

@@ -0,0 +1,93 @@
/* Control Interface for osmo-bts */
/* (C) 2014 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/ctrl/control_cmd.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/tx_power.h>
#include <osmo-bts/signal.h>
#include <osmo-bts/oml.h>
#include <osmo-bts/bts.h>
CTRL_CMD_DEFINE(therm_att, "thermal-attenuation");
static int get_therm_att(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts_trx *trx = cmd->node;
struct trx_power_params *tpp = &trx->power_params;
cmd->reply = talloc_asprintf(cmd, "%d", tpp->thermal_attenuation_mdB);
return CTRL_CMD_REPLY;
}
static int set_therm_att(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts_trx *trx = cmd->node;
struct trx_power_params *tpp = &trx->power_params;
int val = atoi(cmd->value);
printf("set_therm_att(trx=%p, tpp=%p)\n", trx, tpp);
tpp->thermal_attenuation_mdB = val;
power_ramp_start(trx, tpp->p_total_cur_mdBm, 0);
return get_therm_att(cmd, data);
}
static int verify_therm_att(struct ctrl_cmd *cmd, const char *value, void *data)
{
int val = atoi(value);
/* permit between 0 to 40 dB attenuation */
if (val < 0 || val > to_mdB(40))
return 1;
return 0;
}
CTRL_CMD_DEFINE_WO_NOVRF(oml_alert, "oml-alert");
static int set_oml_alert(struct ctrl_cmd *cmd, void *data)
{
/* Note: we expect signal dispatch to be synchronous */
osmo_signal_dispatch(SS_FAIL, OSMO_EVT_EXT_ALARM, cmd->value);
cmd->reply = "OK";
return CTRL_CMD_REPLY;
}
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);
return rc;
}

View File

@@ -0,0 +1,115 @@
/* Control Interface for osmo-bts */
/* (C) 2014 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <errno.h>
#include <osmocom/vty/command.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/ports.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/control_if.h>
extern vector ctrl_node_vec;
/*! \brief control interface lookup function for bsc/bts gsm_data
* \param[in] data Private data passed to controlif_setup()
* \param[in] vline Vector of the line holding the command string
* \param[out] node_type type (CTRL_NODE_) that was determined
* \param[out] node_data private dta of node that was determined
* \param i Current index into vline, up to which it is parsed
*/
static int bts_ctrl_node_lookup(void *data, vector vline, int *node_type,
void **node_data, int *i)
{
struct gsm_bts *bts = data;
struct gsm_bts_trx *trx = NULL;
struct gsm_bts_trx_ts *ts = NULL;
char *token = vector_slot(vline, *i);
long num;
/* TODO: We need to make sure that the following chars are digits
* and/or use strtol to check if number conversion was successful
* Right now something like net.bts_stats will not work */
if (!strcmp(token, "trx")) {
if (*node_type != CTRL_NODE_ROOT || !*node_data)
goto err_missing;
bts = *node_data;
(*i)++;
if (!ctrl_parse_get_num(vline, *i, &num))
goto err_index;
trx = gsm_bts_trx_num(bts, num);
if (!trx)
goto err_missing;
*node_data = trx;
*node_type = CTRL_NODE_TRX;
} else if (!strcmp(token, "ts")) {
if (*node_type != CTRL_NODE_TRX || !*node_data)
goto err_missing;
trx = *node_data;
(*i)++;
if (!ctrl_parse_get_num(vline, *i, &num))
goto err_index;
if ((num >= 0) && (num < TRX_NR_TS))
ts = &trx->ts[num];
if (!ts)
goto err_missing;
*node_data = ts;
*node_type = CTRL_NODE_TS;
} else
return 0;
return 1;
err_missing:
return -ENODEV;
err_index:
return -ERANGE;
}
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
const char *bind_addr, uint16_t port)
{
struct ctrl_handle *hdl;
int rc = 0;
hdl = ctrl_interface_setup_dynip(bts, bind_addr, port,
bts_ctrl_node_lookup);
if (!hdl)
return NULL;
rc = bts_ctrl_cmds_install(bts);
if (rc) {
/* FIXME: close control interface */
return NULL;
}
rc = bts_model_ctrl_cmds_install(bts);
if (rc) {
/* FIXME: cleanup generic control commands */
/* FIXME: close control interface */
return NULL;
}
return hdl;
}

196
src/common/cbch.c Normal file
View File

@@ -0,0 +1,196 @@
/* Cell Broadcast routines */
/* (C) 2014 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/protocol/gsm_04_12.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/cbch.h>
#include <osmo-bts/logging.h>
struct smscb_msg {
struct llist_head list; /* list in smscb_state.queue */
uint8_t msg[GSM412_MSG_LEN]; /* message buffer */
uint8_t next_seg; /* next segment number */
uint8_t num_segs; /* total number of segments */
};
static int get_smscb_null_block(uint8_t *out)
{
struct gsm412_block_type *block_type = (struct gsm412_block_type *) out;
block_type->spare = 0;
block_type->lpd = 1;
block_type->seq_nr = GSM412_SEQ_NULL_MSG;
block_type->lb = 0;
memset(out+1, GSM_MACBLOCK_PADDING, GSM412_BLOCK_LEN);
return 0;
}
/* get the next block of the current CB message */
static int get_smscb_block(struct gsm_bts *bts, uint8_t *out)
{
int to_copy;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct gsm412_block_type *block_type;
struct smscb_msg *msg = btsb->smscb_state.cur_msg;
if (!msg) {
/* No message: Send NULL mesage */
return get_smscb_null_block(out);
}
block_type = (struct gsm412_block_type *) out++;
/* LPD is always 01 */
block_type->spare = 0;
block_type->lpd = 1;
/* determine how much data to copy */
to_copy = GSM412_MSG_LEN - (msg->next_seg * GSM412_BLOCK_LEN);
if (to_copy > GSM412_BLOCK_LEN)
to_copy = GSM412_BLOCK_LEN;
/* copy data and increment index */
memcpy(out, &msg->msg[msg->next_seg * GSM412_BLOCK_LEN], to_copy);
/* set + increment sequence number */
block_type->seq_nr = msg->next_seg++;
/* determine if this is the last block */
if (block_type->seq_nr + 1 == msg->num_segs)
block_type->lb = 1;
else
block_type->lb = 0;
if (block_type->lb == 1) {
/* remove/release the message memory */
talloc_free(btsb->smscb_state.cur_msg);
btsb->smscb_state.cur_msg = NULL;
}
return block_type->lb;
}
static const uint8_t last_block_rsl2um[4] = {
[RSL_CB_CMD_LASTBLOCK_4] = 4,
[RSL_CB_CMD_LASTBLOCK_1] = 1,
[RSL_CB_CMD_LASTBLOCK_2] = 2,
[RSL_CB_CMD_LASTBLOCK_3] = 3,
};
/* incoming SMS broadcast command from RSL */
int bts_process_smscb_cmd(struct gsm_bts *bts,
struct rsl_ie_cb_cmd_type cmd_type,
uint8_t msg_len, const uint8_t *msg)
{
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct smscb_msg *scm;
if (msg_len > sizeof(scm->msg)) {
LOGP(DLSMS, LOGL_ERROR,
"Cannot process SMSCB of %u bytes (max %zu)\n",
msg_len, sizeof(scm->msg));
return -EINVAL;
}
scm = talloc_zero_size(bts, sizeof(*scm));
/* initialize entire message with default padding */
memset(scm->msg, GSM_MACBLOCK_PADDING, sizeof(scm->msg));
/* next segment is first segment */
scm->next_seg = 0;
switch (cmd_type.command) {
case RSL_CB_CMD_TYPE_NORMAL:
case RSL_CB_CMD_TYPE_SCHEDULE:
case RSL_CB_CMD_TYPE_NULL:
scm->num_segs = last_block_rsl2um[cmd_type.last_block&3];
memcpy(scm->msg, msg, msg_len);
/* def_bcast is ignored */
break;
case RSL_CB_CMD_TYPE_DEFAULT:
/* use def_bcast, ignore command */
/* def_bcast == 0: normal mess */
break;
}
llist_add_tail(&scm->list, &btsb->smscb_state.queue);
return 0;
}
static struct smscb_msg *select_next_smscb(struct gsm_bts *bts)
{
struct smscb_msg *msg;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
if (llist_empty(&btsb->smscb_state.queue))
return NULL;
msg = llist_entry(btsb->smscb_state.queue.next,
struct smscb_msg, list);
llist_del(&msg->list);
return msg;
}
/* call-back from bts model specific code when it wants to obtain a CBCH
* block for a given gsm_time. outbuf must have 23 bytes of space. */
int bts_cbch_get(struct gsm_bts *bts, uint8_t *outbuf, struct gsm_time *g_time)
{
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
uint32_t fn = gsm_gsmtime2fn(g_time);
/* According to 05.02 Section 6.5.4 */
uint32_t tb = (fn / 51) % 8;
int rc = 0;
/* The multiframes used for the basic cell broadcast channel
* shall be those in * which TB = 0,1,2 and 3. The multiframes
* used for the extended cell broadcast channel shall be those
* in which TB = 4, 5, 6 and 7 */
/* The SMSCB header shall be sent in the multiframe in which TB
* = 0 for the basic, and TB = 4 for the extended cell
* broadcast channel. */
switch (tb) {
case 0:
/* select a new SMSCB message */
btsb->smscb_state.cur_msg = select_next_smscb(bts);
rc = get_smscb_block(bts, outbuf);
break;
case 1: case 2: case 3:
rc = get_smscb_block(bts, outbuf);
break;
case 4: case 5: case 6: case 7:
/* always send NULL frame in extended CBCH for now */
rc = get_smscb_null_block(outbuf);
break;
}
return rc;
}

477
src/common/dtx_dl_amr_fsm.c Normal file
View File

@@ -0,0 +1,477 @@
/* DTX DL AMR FSM */
/* (C) 2016 by sysmocom s.f.m.c. GmbH
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/logging.h>
void dtx_fsm_voice(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_VOICE:
case E_FACCH:
break;
case E_SID_F:
osmo_fsm_inst_state_chg(fi, ST_SID_F1, 0, 0);
break;
case E_SID_U:
osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
break;
case E_INHIB:
osmo_fsm_inst_state_chg(fi, ST_F1_INH_V, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Inexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_sid_f1(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_SID_F:
/* FIXME: what shall we do if we get SID-FIRST _again_ (twice in a row)?
Was observed during testing, let's just ignore it for now */
break;
case E_SID_U:
osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
break;
case E_FACCH:
osmo_fsm_inst_state_chg(fi, ST_F1_INH_F, 0, 0);
break;
case E_FIRST:
osmo_fsm_inst_state_chg(fi, ST_SID_F2, 0, 0);
break;
case E_ONSET:
osmo_fsm_inst_state_chg(fi, ST_ONSET_V, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_sid_f2(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
break;
case E_FACCH:
osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0);
break;
case E_ONSET:
osmo_fsm_inst_state_chg(fi, ST_ONSET_V, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_f1_inh_v(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_F1_INH_V_REC, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_f1_inh_f(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_F1_INH_F_REC, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_u_inh_v(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_U_INH_V_REC, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_u_inh_f(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_U_INH_F_REC, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_f1_inh_v_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_VOICE:
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_f1_inh_f_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_FACCH:
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_u_inh_v_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_VOICE:
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_u_inh_f_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_FACCH:
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_u_noinh(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_FACCH:
osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0);
break;
case E_VOICE:
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
break;
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_SID_U, 0, 0);
break;
case E_SID_U:
case E_SID_F:
/* FIXME: what shall we do if we get SID-FIRST _after_ sending SID-UPDATE?
Was observed during testing, let's just ignore it for now */
break;
case E_ONSET:
osmo_fsm_inst_state_chg(fi, ST_ONSET_V, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_sid_upd(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_FACCH:
osmo_fsm_inst_state_chg(fi, ST_U_INH_F, 0, 0);
break;
case E_VOICE:
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
break;
case E_INHIB:
osmo_fsm_inst_state_chg(fi, ST_U_INH_V, 0, 0);
break;
case E_SID_U:
case E_SID_F:
osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_onset_v(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_ONSET_V_REC, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_onset_f(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_ONSET_F_REC, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_onset_v_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_onset_f_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
void dtx_fsm_facch(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case E_SID_U:
case E_SID_F:
case E_FACCH:
break;
case E_VOICE:
osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
break;
case E_COMPL:
osmo_fsm_inst_state_chg(fi, ST_SID_F1, 0, 0);
break;
default:
LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
OSMO_ASSERT(0);
break;
}
}
static struct osmo_fsm_state dtx_dl_amr_fsm_states[] = {
/* default state for non-DTX and DTX when SPEECH is in progress */
[ST_VOICE] = {
.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_VOICE) | X(E_FACCH) | X(E_INHIB),
.out_state_mask = X(ST_SID_F1) | X(ST_U_NOINH) | X(ST_F1_INH_V),
.name = "Voice",
.action = dtx_fsm_voice,
},
/* SID-FIRST or SID-FIRST-P1 in case of AMR HR:
start of silence period (might be interrupted in case of AMR HR) */
[ST_SID_F1]= {
.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_FACCH) | X(E_FIRST) | X(E_ONSET),
.out_state_mask = X(ST_U_NOINH) | X(ST_ONSET_F) | X(ST_SID_F2) | X(ST_ONSET_V),
.name = "SID-FIRST (P1)",
.action = dtx_fsm_sid_f1,
},
/* SID-FIRST P2 (only for AMR HR):
actual start of silence period in case of AMR HR */
[ST_SID_F2]= {
.in_event_mask = X(E_COMPL) | X(E_FACCH) | X(E_ONSET),
.out_state_mask = X(ST_U_NOINH) | X(ST_ONSET_F) | X(ST_ONSET_V),
.name = "SID-FIRST (P2)",
.action = dtx_fsm_sid_f2,
},
/* SID-FIRST Inhibited: incoming SPEECH (only for AMR HR) */
[ST_F1_INH_V]= {
.in_event_mask = X(E_COMPL),
.out_state_mask = X(ST_F1_INH_V_REC),
.name = "SID-FIRST (Inh, SPEECH)",
.action = dtx_fsm_f1_inh_v,
},
/* SID-FIRST Inhibited: incoming FACCH frame (only for AMR HR) */
[ST_F1_INH_F]= {
.in_event_mask = X(E_COMPL),
.out_state_mask = X(ST_F1_INH_F_REC),
.name = "SID-FIRST (Inh, FACCH)",
.action = dtx_fsm_f1_inh_f,
},
/* SID-UPDATE Inhibited: incoming SPEECH (only for AMR HR) */
[ST_U_INH_V]= {
.in_event_mask = X(E_COMPL),
.out_state_mask = X(ST_U_INH_V_REC),
.name = "SID-UPDATE (Inh, SPEECH)",
.action = dtx_fsm_u_inh_v,
},
/* SID-UPDATE Inhibited: incoming FACCH frame (only for AMR HR) */
[ST_U_INH_F]= {
.in_event_mask = X(E_COMPL),
.out_state_mask = X(ST_U_INH_F_REC),
.name = "SID-UPDATE (Inh, FACCH)",
.action = dtx_fsm_u_inh_f,
},
/* SID-UPDATE: Inhibited not allowed (only for AMR HR) */
[ST_U_NOINH]= {
.in_event_mask = X(E_FACCH) | X(E_VOICE) | X(E_COMPL) | X(E_SID_U) | X(E_SID_F) | X(E_ONSET),
.out_state_mask = X(ST_ONSET_F) | X(ST_VOICE) | X(ST_SID_U) | X(ST_ONSET_V),
.name = "SID-UPDATE (NoInh)",
.action = dtx_fsm_u_noinh,
},
/* SID-FIRST Inhibition recursion in progress:
Inhibit itself was already sent, now have to send the voice that caused it */
[ST_F1_INH_V_REC]= {
.in_event_mask = X(E_COMPL) | X(E_VOICE),
.out_state_mask = X(ST_VOICE),
.name = "SID-FIRST (Inh, SPEECH, Rec)",
.action = dtx_fsm_f1_inh_v_rec,
},
/* SID-FIRST Inhibition recursion in progress:
Inhibit itself was already sent, now have to send the data that caused it */
[ST_F1_INH_F_REC]= {
.in_event_mask = X(E_COMPL) | X(E_FACCH),
.out_state_mask = X(ST_FACCH),
.name = "SID-FIRST (Inh, FACCH, Rec)",
.action = dtx_fsm_f1_inh_f_rec,
},
/* SID-UPDATE Inhibition recursion in progress:
Inhibit itself was already sent, now have to send the voice that caused it */
[ST_U_INH_V_REC]= {
.in_event_mask = X(E_COMPL) | X(E_VOICE),
.out_state_mask = X(ST_VOICE),
.name = "SID-UPDATE (Inh, SPEECH, Rec)",
.action = dtx_fsm_u_inh_v_rec,
},
/* SID-UPDATE Inhibition recursion in progress:
Inhibit itself was already sent, now have to send the data that caused it */
[ST_U_INH_F_REC]= {
.in_event_mask = X(E_COMPL) | X(E_FACCH),
.out_state_mask = X(ST_FACCH),
.name = "SID-UPDATE (Inh, FACCH, Rec)",
.action = dtx_fsm_u_inh_f_rec,
},
/* Silence period with periodic comfort noise data updates */
[ST_SID_U]= {
.in_event_mask = X(E_FACCH) | X(E_VOICE) | X(E_INHIB) | X(E_SID_U) | X(E_SID_F),
.out_state_mask = X(ST_ONSET_F) | X(ST_VOICE) | X(ST_U_INH_V) | X(ST_U_INH_F) | X(ST_U_NOINH),
.name = "SID-UPDATE (AMR/HR)",
.action = dtx_fsm_sid_upd,
},
/* ONSET - end of silent period due to incoming SPEECH frame */
[ST_ONSET_V]= {
.in_event_mask = X(E_COMPL),
.out_state_mask = X(ST_ONSET_V_REC),
.name = "ONSET (SPEECH)",
.action = dtx_fsm_onset_v,
},
/* ONSET - end of silent period due to incoming FACCH frame */
[ST_ONSET_F]= {
.in_event_mask = X(E_COMPL),
.out_state_mask = X(ST_ONSET_F_REC),
.name = "ONSET (FACCH)",
.action = dtx_fsm_onset_f,
},
/* ONSET recursion in progress:
ONSET itself was already sent, now have to send the voice that caused it */
[ST_ONSET_V_REC]= {
.in_event_mask = X(E_COMPL),
.out_state_mask = X(ST_VOICE),
.name = "ONSET (SPEECH, Rec)",
.action = dtx_fsm_onset_v_rec,
},
/* ONSET recursion in progress:
ONSET itself was already sent, now have to send the data that caused it */
[ST_ONSET_F_REC]= {
.in_event_mask = X(E_COMPL),
.out_state_mask = X(ST_FACCH),
.name = "ONSET (FACCH, Rec)",
.action = dtx_fsm_onset_f_rec,
},
/* FACCH sending state */
[ST_FACCH]= {
.in_event_mask = X(E_FACCH) | X(E_VOICE) | X(E_COMPL) | X(E_SID_U) | X(E_SID_F),
.out_state_mask = X(ST_VOICE) | X(ST_SID_F1),
.name = "FACCH",
.action = dtx_fsm_facch,
},
};
const struct value_string dtx_dl_amr_fsm_event_names[] = {
{ E_VOICE, "Voice" },
{ E_ONSET, "ONSET" },
{ E_FACCH, "FACCH" },
{ E_COMPL, "Complete" },
{ E_FIRST, "FIRST P1->P2" },
{ E_INHIB, "Inhibit" },
{ E_SID_F, "SID-FIRST" },
{ E_SID_U, "SID-UPDATE" },
{ 0, NULL }
};
struct osmo_fsm dtx_dl_amr_fsm = {
.name = "DTX DL AMR FSM",
.states = dtx_dl_amr_fsm_states,
.num_states = ARRAY_SIZE(dtx_dl_amr_fsm_states),
.event_names = dtx_dl_amr_fsm_event_names,
.log_subsys = DL1C,
};

166
src/common/handover.c Normal file
View File

@@ -0,0 +1,166 @@
/* Paging message encoding + queue management */
/* (C) 2012-2013 by Harald Welte <laforge@gnumonks.org>
* Andreas Eversberg <jolly@eversberg.eu>
* (C) 2014 by Holger Hans Peter Freyther
*
* 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 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/handover.h>
#include <osmo-bts/l1sap.h>
/* Transmit a handover related PHYS INFO on given lchan */
static int ho_tx_phys_info(struct gsm_lchan *lchan)
{
struct msgb *msg = msgb_alloc_headroom(1024, 128, "PHYS INFO");
struct gsm48_hdr *gh;
if (!msg)
return -ENOMEM;
LOGP(DHO, LOGL_INFO,
"%s Sending PHYSICAL INFORMATION to MS.\n",
gsm_lchan_name(lchan));
/* Build RSL UNITDATA REQUEST message with 04.08 PHYS INFO */
msg->l3h = msg->data;
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_RR;
gh->msg_type = GSM48_MT_RR_HANDO_INFO;
msgb_put_u8(msg, lchan->rqd_ta);
rsl_rll_push_l3(msg, RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan),
0x00, 0);
lapdm_rslms_recvmsg(msg, &lchan->lapdm_ch);
return 0;
}
/* timer call-back for T3105 (handover PHYS INFO re-transmit) */
static void ho_t3105_cb(void *data)
{
struct gsm_lchan *lchan = data;
struct gsm_bts *bts = lchan->ts->trx->bts;
struct gsm_bts_role_bts *btsb = bts->role;
LOGP(DHO, LOGL_INFO, "%s T3105 timeout (%d resends left)\n",
gsm_lchan_name(lchan), btsb->ny1 - lchan->ho.phys_info_count);
if (lchan->state != LCHAN_S_ACTIVE) {
LOGP(DHO, LOGL_NOTICE,
"%s is in not active. It is in state %s. Ignoring\n",
gsm_lchan_name(lchan), gsm_lchans_name(lchan->state));
return;
}
if (lchan->ho.phys_info_count >= btsb->ny1) {
/* HO Abort */
LOGP(DHO, LOGL_NOTICE, "%s NY1 reached, sending CONNection "
"FAILure to BSC.\n", gsm_lchan_name(lchan));
rsl_tx_conn_fail(lchan, RSL_ERR_HANDOVER_ACC_FAIL);
return;
}
ho_tx_phys_info(lchan);
lchan->ho.phys_info_count++;
osmo_timer_schedule(&lchan->ho.t3105, 0, btsb->t3105_ms * 1000);
}
/* received random access on dedicated channel */
void handover_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
struct gsm_bts_role_bts *btsb = bts->role;
/* Ignore invalid handover ref */
if (lchan->ho.ref != ra) {
LOGP(DHO, LOGL_INFO, "%s RACH on dedicated channel received, but "
"ra=0x%02x != expected ref=0x%02x. (This is no bug)\n",
gsm_lchan_name(lchan), ra, lchan->ho.ref);
return;
}
/* Ignore handover on channels other than DCCH and SACCH */
if (lchan->type != GSM_LCHAN_SDCCH && lchan->type != GSM_LCHAN_TCH_H &&
lchan->type != GSM_LCHAN_TCH_F) {
LOGP(DHO, LOGL_ERROR, "%s handover RACH received on %s?!\n",
gsm_lchan_name(lchan), gsm_lchant_name(lchan->type));
return;
}
LOGP(DHO, LOGL_NOTICE,
"%s RACH on dedicated channel type %s received with TA=%u, ref=%u\n",
gsm_lchan_name(lchan), gsm_lchant_name(lchan->type), acc_delay, ra);
/* Set timing advance */
lchan->rqd_ta = acc_delay;
/* Stop handover detection, wait for valid frame */
lchan->ho.active = HANDOVER_WAIT_FRAME;
if (l1sap_chan_modify(lchan->ts->trx, gsm_lchan2chan_nr(lchan)) != 0) {
LOGP(DHO, LOGL_ERROR,
"%s failed to modify channel after handover\n",
gsm_lchan_name(lchan));
rsl_tx_conn_fail(lchan, RSL_ERR_HANDOVER_ACC_FAIL);
return;
}
/* Send HANDover DETect to BSC */
rsl_tx_hando_det(lchan, &lchan->rqd_ta);
/* Send PHYS INFO */
lchan->ho.phys_info_count = 1;
ho_tx_phys_info(lchan);
/* Start T3105 */
LOGP(DHO, LOGL_DEBUG,
"%s Starting T3105 with %u ms\n",
gsm_lchan_name(lchan), btsb->t3105_ms);
lchan->ho.t3105.cb = ho_t3105_cb;
lchan->ho.t3105.data = lchan;
osmo_timer_schedule(&lchan->ho.t3105, 0, btsb->t3105_ms * 1000);
}
/* received frist valid data frame on dedicated channel */
void handover_frame(struct gsm_lchan *lchan)
{
LOGP(DHO, LOGL_INFO,
"%s First valid frame detected\n", gsm_lchan_name(lchan));
handover_reset(lchan);
}
/* release handover state */
void handover_reset(struct gsm_lchan *lchan)
{
/* Stop T3105 */
osmo_timer_del(&lchan->ho.t3105);
/* Handover process is done */
lchan->ho.active = HANDOVER_NONE;
}

1396
src/common/l1sap.c Normal file

File diff suppressed because it is too large Load Diff

49
src/common/lchan.c Normal file
View File

@@ -0,0 +1,49 @@
/* OsmoBTS lchan interface */
/* (C) 2012 by Holger Hans Peter Freyther
*
* 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 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/logging.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h>
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state)
{
DEBUGP(DL1C, "%s state %s -> %s\n",
gsm_lchan_name(lchan),
gsm_lchans_name(lchan->state),
gsm_lchans_name(state));
lchan->state = state;
}
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)
{
switch (ts->pchan) {
case GSM_PCHAN_PDCH:
return true;
case GSM_PCHAN_TCH_F_PDCH:
return (ts->flags & TS_F_PDCH_ACTIVE)
&& !(ts->flags & TS_F_PDCH_PENDING_MASK);
case GSM_PCHAN_TCH_F_TCH_H_PDCH:
return ts->dyn.pchan_is == GSM_PCHAN_PDCH
&& ts->dyn.pchan_want == ts->dyn.pchan_is;
default:
return false;
}
}

View File

@@ -19,12 +19,19 @@
*
*/
#include <rsl.h>
#include <stdint.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/msgb.h>
static void reset_load_counters(void)
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/rsl.h>
#include <osmo-bts/paging.h>
static void reset_load_counters(struct gsm_bts *bts)
{
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
/* re-set the counters */
btsb->load.ccch.pch_used = btsb->load.ccch.pch_total = 0;
}
@@ -32,38 +39,62 @@ static void reset_load_counters(void)
static void load_timer_cb(void *data)
{
struct gsm_bts *bts = data;
struct gsm_bts_role_bts *btsb = FIXME;
unsigned int pch_percent;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
unsigned int pch_percent, rach_percent;
/* compute percentages */
pch_percent = (btsb->load.ccch.pch_used * 100) / btsb->load.ccch.pch_total;
if (btsb->load.ccch.pch_total == 0)
pch_percent = 0;
else
pch_percent = (btsb->load.ccch.pch_used * 100) /
btsb->load.ccch.pch_total;
if (pch_percent >= btsb->load.ccch.load_ind_thresh) {
/* send RSL load indication message to BSC */
uint16_t paging_buffer_space = FIXME;
rsl_tx_ccch_load_ind_pch(bts, paging_buffer_space);
uint16_t buffer_space = paging_buffer_space(btsb->paging_state);
rsl_tx_ccch_load_ind_pch(bts, buffer_space);
} else {
/* This is an extenstion of TS 08.58. We don't only
* send load indications if the load is above threshold,
* but we also explicitly indicate that we are below
* threshold by using the magic value 0xffff */
rsl_tx_ccch_load_ind_pch(bts, 0xffff);
}
reset_load_counters();
if (btsb->load.rach.total == 0)
rach_percent = 0;
else
rach_percent = (btsb->load.rach.busy * 100) /
btsb->load.rach.total;
if (rach_percent >= btsb->load.ccch.load_ind_thresh) {
/* send RSL load indication message to BSC */
rsl_tx_ccch_load_ind_rach(bts, btsb->load.rach.total,
btsb->load.rach.busy,
btsb->load.rach.access);
}
reset_load_counters(bts);
/* re-schedule the timer */
osmo_timer_schedule(&btsb->load.ccch.timer,
btsb->load.ccch.load_ind_period, 0);
}
static void load_timer_start(struct gsm_bts *bts)
void load_timer_start(struct gsm_bts *bts)
{
struct gsm_bts_role_bts *btsb = FIXME;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
btsb->load.ccch.timer.data = bts;
reset_load_counters();
btsb->load.ccch.timer.cb = load_timer_cb;
reset_load_counters(bts);
osmo_timer_schedule(&btsb->load.ccch.timer,
btsb->load.ccch.load_ind_period, 0);
return 0
}
static void load_timer_stop(struct gsm_bts *bts)
void load_timer_stop(struct gsm_bts *bts)
{
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
osmo_timer_del(&btsb->load.ccch.timer);
}

View File

@@ -95,6 +95,30 @@ static struct log_info_cat bts_log_info_cat[] = {
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
[DPCU] = {
.name = "DPCU",
.description = "PCU interface",
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
[DHO] = {
.name = "DHO",
.description = "Handover",
.color = "\033[0;37m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
[DTRX] = {
.name = "DTRX",
.description = "TRX interface",
.color = "\033[1;33m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
[DLOOP] = {
.name = "DLOOP",
.description = "Control loops",
.color = "\033[0;34m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
#if 0
[DNS] = {
.name = "DNS",
@@ -112,6 +136,12 @@ static struct log_info_cat bts_log_info_cat[] = {
.enabled = 1, .loglevel = LOGL_DEBUG,
},
#endif
[DSUM] = {
.name = "DSUM",
.description = "DSUM",
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
};
const struct log_info bts_log_info = {

365
src/common/main.c Normal file
View File

@@ -0,0 +1,365 @@
/* Main program for Osmocom BTS */
/* (C) 2011-2016 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sched.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/application.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/logging.h>
#include <osmocom/core/gsmtap_util.h>
#include <osmocom/core/gsmtap.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/phy_link.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/abis.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/vty.h>
#include <osmo-bts/l1sap.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/pcu_if.h>
#include <osmo-bts/control_if.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/ports.h>
#include <osmocom/ctrl/control_vty.h>
#include <osmo-bts/oml.h>
int quit = 0;
static const char *config_file = "osmo-bts.cfg";
static int daemonize = 0;
static int rt_prio = -1;
static int trx_num = 1;
static char *gsmtap_ip = 0;
extern int g_vty_port_num;
static void print_help()
{
printf( "Some useful options:\n"
" -h --help this text\n"
" -d --debug MASK Enable debugging (e.g. -d DRSL:DOML:DLAPDM)\n"
" -D --daemonize For the process into a background daemon\n"
" -c --config-file Specify the filename of the config file\n"
" -s --disable-color Don't use colors in stderr log output\n"
" -T --timestamp Prefix every log line with a timestamp\n"
" -V --version Print version information and exit\n"
" -e --log-level Set a global log-level\n"
" -r --realtime PRIO Use SCHED_RR with the specified priority\n"
" -i --gsmtap-ip The destination IP used for GSMTAP.\n"
" -t --trx-num Set number of TRX (default=%d)\n",
trx_num
);
bts_model_print_help();
}
/* FIXME: finally get some option parsing code into libosmocore */
static void handle_options(int argc, char **argv)
{
char *argv_out[argc];
int argc_out = 0;
argv_out[argc_out++] = argv[0];
/* disable generation of error messages on encountering unknown
* options */
opterr = 0;
while (1) {
int option_idx = 0, c;
static const struct option long_options[] = {
/* FIXME: all those are generic Osmocom app options */
{ "help", 0, 0, 'h' },
{ "debug", 1, 0, 'd' },
{ "daemonize", 0, 0, 'D' },
{ "config-file", 1, 0, 'c' },
{ "disable-color", 0, 0, 's' },
{ "timestamp", 0, 0, 'T' },
{ "version", 0, 0, 'V' },
{ "log-level", 1, 0, 'e' },
/* FIXME: generic BTS app options */
{ "gsmtap-ip", 1, 0, 'i' },
{ "trx-num", 1, 0, 't' },
{ "realtime", 1, 0, 'r' },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "-hc:d:Dc:sTVe:i:t:r:",
long_options, &option_idx);
if (c == -1)
break;
switch (c) {
case 'h':
print_help();
exit(0);
break;
case 's':
log_set_use_color(osmo_stderr_target, 0);
break;
case 'd':
log_parse_category_mask(osmo_stderr_target, optarg);
break;
case 'D':
daemonize = 1;
break;
case 'c':
config_file = optarg;
break;
case 'T':
log_set_print_timestamp(osmo_stderr_target, 1);
break;
case 'V':
print_version(1);
exit(0);
break;
case 'e':
log_set_log_level(osmo_stderr_target, atoi(optarg));
break;
case 'r':
rt_prio = atoi(optarg);
break;
case 'i':
gsmtap_ip = optarg;
break;
case 't':
trx_num = atoi(optarg);
if (trx_num < 1)
trx_num = 1;
break;
case '?':
case 1:
/* prepare argv[] for bts_model */
argv_out[argc_out++] = argv[optind-1];
break;
default:
break;
}
}
/* re-set opt-ind for new parsig round */
optind = 1;
/* enable error-checking for the following getopt call */
opterr = 1;
if (bts_model_handle_options(argc_out, argv_out)) {
print_help();
exit(1);
}
}
static struct gsm_bts *bts;
static void signal_handler(int signal)
{
fprintf(stderr, "signal %u received\n", signal);
switch (signal) {
case SIGINT:
case SIGTERM:
if (!quit) {
oml_fail_rep(OSMO_EVT_CRIT_PROC_STOP,
"BTS: SIGINT received -> shutdown");
bts_shutdown(bts, "SIGINT");
}
quit++;
break;
case SIGABRT:
case SIGUSR1:
case SIGUSR2:
oml_fail_rep(OSMO_EVT_CRIT_PROC_STOP,
"BTS: signal %d (%s) received", signal,
strsignal(signal));
talloc_report_full(tall_bts_ctx, stderr);
break;
default:
break;
}
}
static int write_pid_file(char *procname)
{
FILE *outf;
char tmp[PATH_MAX+1];
snprintf(tmp, sizeof(tmp)-1, "/var/run/%s.pid", procname);
tmp[PATH_MAX-1] = '\0';
outf = fopen(tmp, "w");
if (!outf)
return -1;
fprintf(outf, "%d\n", getpid());
fclose(outf);
return 0;
}
int bts_main(int argc, char **argv)
{
struct gsm_bts_role_bts *btsb;
struct gsm_bts_trx *trx;
struct e1inp_line *line;
int rc, i;
printf("((*))\n |\n / \\ OsmoBTS\n");
tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context");
msgb_talloc_ctx_init(tall_bts_ctx, 100*1024);
bts_log_init(NULL);
vty_init(&bts_vty_info);
ctrl_vty_init(tall_bts_ctx);
handle_options(argc, argv);
bts = gsm_bts_alloc(tall_bts_ctx, 0);
if (!bts) {
fprintf(stderr, "Failed to create BTS structure\n");
exit(1);
}
for (i = 1; i < trx_num; i++) {
trx = gsm_bts_trx_alloc(bts);
if (!trx) {
fprintf(stderr, "Failed to create TRX structure\n");
exit(1);
}
}
e1inp_vty_init();
bts_vty_init(bts, &bts_log_info);
/* enable realtime priority for us */
if (rt_prio != -1) {
struct sched_param param;
memset(&param, 0, sizeof(param));
param.sched_priority = rt_prio;
rc = sched_setscheduler(getpid(), SCHED_RR, &param);
if (rc != 0) {
fprintf(stderr, "Setting SCHED_RR priority(%d) failed: %s\n",
param.sched_priority, strerror(errno));
exit(1);
}
}
if (gsmtap_ip) {
gsmtap = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1);
if (!gsmtap) {
fprintf(stderr, "Failed during gsmtap_init()\n");
exit(1);
}
gsmtap_source_add_sink(gsmtap);
}
if (bts_init(bts) < 0) {
fprintf(stderr, "unable to open bts\n");
exit(1);
}
btsb = bts_role_bts(bts);
abis_init(bts);
rc = vty_read_config_file(config_file, NULL);
if (rc < 0) {
fprintf(stderr, "Failed to parse the config file: '%s'\n",
config_file);
exit(1);
}
if (!phy_link_by_num(0)) {
fprintf(stderr, "You need to configure at least phy0\n");
exit(1);
}
llist_for_each_entry(trx, &bts->trx_list, list) {
if (!trx->role_bts.l1h) {
fprintf(stderr, "TRX %u has no associated PHY instance\n",
trx->nr);
exit(1);
}
}
write_pid_file("osmo-bts");
bts_controlif_setup(bts, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BTS);
rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(),
g_vty_port_num);
if (rc < 0) {
fprintf(stderr, "Error initializing telnet\n");
exit(1);
}
if (pcu_sock_init(btsb->pcu.sock_path)) {
fprintf(stderr, "PCU L1 socket failed\n");
exit(1);
}
signal(SIGINT, &signal_handler);
signal(SIGTERM, &signal_handler);
//signal(SIGABRT, &signal_handler);
signal(SIGUSR1, &signal_handler);
signal(SIGUSR2, &signal_handler);
osmo_init_ignore_signals();
if (!btsb->bsc_oml_host) {
fprintf(stderr, "Cannot start BTS without knowing BSC OML IP\n");
exit(1);
}
line = abis_open(bts, btsb->bsc_oml_host, "sysmoBTS");
if (!line) {
fprintf(stderr, "unable to connect to BSC\n");
exit(2);
}
rc = phy_links_open();
if (rc < 0) {
fprintf(stderr, "unable ot open PHY link(s)\n");
exit(2);
}
if (daemonize) {
rc = osmo_daemonize();
if (rc < 0) {
perror("Error during daemonize");
exit(1);
}
}
while (quit < 2) {
log_reset_context();
osmo_select_main(0);
}
return EXIT_SUCCESS;
}

View File

@@ -8,19 +8,42 @@
#include <osmo-bts/logging.h>
#include <osmo-bts/measurement.h>
/* TS 05.08, Chapter 8.4.1 */
/* measurement period ends at fn % 104 == ? */
/* Measurment reporting period and mapping of SACCH message block for TCHF
* and TCHH chan As per in 3GPP TS 45.008, secton 8.4.1.
*
* Timeslot number (TN) TDMA frame number (FN) modulo 104
* Half rate, Half rate, Reporting SACCH
* Full Rate subch.0 subch.1 period Message block
* 0 0 and 1 0 to 103 12, 38, 64, 90
* 1 0 and 1 13 to 12 25, 51, 77, 103
* 2 2 and 3 26 to 25 38, 64, 90, 12
* 3 2 and 3 39 to 38 51, 77, 103, 25
* 4 4 and 5 52 to 51 64, 90, 12, 38
* 5 4 and 5 65 to 64 77, 103, 25, 51
* 6 6 and 7 78 to 77 90, 12, 38, 64
* 7 6 and 7 91 to 90 103, 25, 51, 77 */
static const uint8_t tchf_meas_rep_fn104[] = {
[0] = 103,
[1] = 12,
[2] = 25,
[3] = 38,
[4] = 51,
[5] = 64,
[6] = 77,
[7] = 90,
[0] = 90,
[1] = 103,
[2] = 12,
[3] = 25,
[4] = 38,
[5] = 51,
[6] = 64,
[7] = 77,
};
static const uint8_t tchh0_meas_rep_fn104[] = {
[0] = 90,
[1] = 90,
[2] = 12,
[3] = 12,
[4] = 38,
[5] = 38,
[6] = 64,
[7] = 64,
};
static const uint8_t tchh1_meas_rep_fn104[] = {
[0] = 103,
[1] = 103,
[2] = 25,
@@ -30,59 +53,130 @@ static const uint8_t tchh0_meas_rep_fn104[] = {
[6] = 77,
[7] = 77,
};
static const uint8_t tchh1_meas_rep_fn104[] = {
[0] = 12,
[1] = 12,
[2] = 38,
[3] = 38,
[4] = 64,
[5] = 64,
[6] = 90,
[7] = 90,
/* Measurment reporting period for SDCCH8 and SDCCH4 chan
* As per in 3GPP TS 45.008, section 8.4.2.
*
* Logical Chan TDMA frame number
* (FN) modulo 102
*
* SDCCH/8 12 to 11
* SDCCH/4 37 to 36
*/
/* Added interleve offset to Meas period end Fn which
* would reduce the Meas Res msg load at Abis */
static const uint8_t sdcch8_meas_rep_fn102[] = {
[0] = 11 + 7,
[1] = 11 + 11,
[2] = 11 + 15,
[3] = 11 + 19,
[4] = 11 + 23,
[5] = 11 + 27,
[6] = 11 + 31,
[7] = 11 + 35
};
/* determine if a measurement period ends at the given frame number */
static int is_meas_complete(enum gsm_phys_chan_config pchan, unsigned int ts,
unsigned int subch, uint32_t fn)
static const uint8_t sdcch4_meas_rep_fn102[] = {
[0] = 36 + 4,
[1] = 36 + 8,
[2] = 36 + 14,
[3] = 36 + 18
};
/* Note: The reporting of the measurement results is done via the SACCH channel.
* The measurement interval is not alligned with the interval in which the
* SACCH is tranmitted. When we receive the measurement indication with the
* SACCH block, the coresponding measurement interval will already have ended
* and we will get the results late, but on spot with the beginning of the
* next measurement interval.
*
* For example: We get a measurement indication on FN%104=38 in TS=2. Then we
* will have to look at 3GPP TS 45.008, secton 8.4.1 (or 3GPP TS 05.02 Clause 7
* Table 1 of 9) what value we need to feed into the lookup tables in order to
* detect the measurement period ending. In this example the "real" ending
* was on FN%104=12. This is the value we have to look for in
* tchf_meas_rep_fn104 to know that a measurement period has just ended. */
/* See also 3GPP TS 05.02 Clause 7 Table 1 of 9:
* Mapping of logical channels onto physical channels (see subclauses 6.3, 6.4, 6.5) */
static uint8_t translate_tch_meas_rep_fn104(uint8_t fn_mod)
{
unsigned int fn_mod;
switch (fn_mod) {
case 25:
return 103;
case 38:
return 12;
case 51:
return 25;
case 64:
return 38;
case 77:
return 51;
case 90:
return 64;
case 103:
return 77;
case 12:
return 90;
}
/* Invalid / not of interest */
return 0;
}
/* determine if a measurement period ends at the given frame number */
static int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn)
{
unsigned int fn_mod = -1;
const uint8_t *tbl;
int rc = 0;
enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
if (ts >= 8)
if (lchan->ts->nr >= 8)
return -EINVAL;
if (pchan >= _GSM_PCHAN_MAX)
return -EINVAL;
switch (pchan) {
case GSM_PCHAN_TCH_F:
fn_mod = fn % 104;
if (tchf_meas_rep_fn104[ts] == fn_mod)
fn_mod = translate_tch_meas_rep_fn104(fn % 104);
if (tchf_meas_rep_fn104[lchan->ts->nr] == fn_mod)
rc = 1;
break;
case GSM_PCHAN_TCH_H:
fn_mod = fn % 104;
if (subch == 0)
fn_mod = translate_tch_meas_rep_fn104(fn % 104);
if (lchan->nr == 0)
tbl = tchh0_meas_rep_fn104;
else
tbl = tchh1_meas_rep_fn104;
if (tbl[ts] == fn_mod)
if (tbl[lchan->ts->nr] == fn_mod)
rc = 1;
break;
case GSM_PCHAN_SDCCH8_SACCH8C:
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
fn_mod = fn % 102;
if (fn_mod == 11)
if (sdcch8_meas_rep_fn102[lchan->nr] == fn_mod)
rc = 1;
break;
case GSM_PCHAN_CCCH_SDCCH4:
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
fn_mod = fn % 102;
if (fn_mod == 36)
if (sdcch4_meas_rep_fn102[lchan->nr] == fn_mod)
rc = 1;
break;
default:
rc = 0;
break;
}
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));
}
return rc;
}
@@ -92,9 +186,17 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm)
DEBUGP(DMEAS, "%s adding measurement, num_ul_meas=%d\n",
gsm_lchan_name(lchan), lchan->meas.num_ul_meas);
if (lchan->state != LCHAN_S_ACTIVE) {
LOGP(DMEAS, LOGL_NOTICE,
"%s measurement during state: %s, num_ul_meas=%d\n",
gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
lchan->meas.num_ul_meas);
}
if (lchan->meas.num_ul_meas >= ARRAY_SIZE(lchan->meas.uplink)) {
LOGP(DMEAS, LOGL_NOTICE, "%s no space for uplink measurement\n",
gsm_lchan_name(lchan));
LOGP(DMEAS, LOGL_NOTICE,
"%s no space for uplink measurement, num_ul_meas=%d\n",
gsm_lchan_name(lchan), lchan->meas.num_ul_meas);
return -ENOSPC;
}
@@ -107,7 +209,20 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm)
/* input: BER in steps of .01%, i.e. percent/100 */
static uint8_t ber10k_to_rxqual(uint32_t ber10k)
{
/* 05.08 / 8.2.4 */
/* Eight levels of Rx quality are defined and are mapped to the
* equivalent BER before channel decoding, as per in 3GPP TS 45.008,
* secton 8.2.4.
*
* RxQual: BER Range:
* RXQUAL_0 BER < 0,2 % Assumed value = 0,14 %
* RXQUAL_1 0,2 % < BER < 0,4 % Assumed value = 0,28 %
* RXQUAL_2 0,4 % < BER < 0,8 % Assumed value = 0,57 %
* RXQUAL_3 0,8 % < BER < 1,6 % Assumed value = 1,13 %
* RXQUAL_4 1,6 % < BER < 3,2 % Assumed value = 2,26 %
* RXQUAL_5 3,2 % < BER < 6,4 % Assumed value = 4,53 %
* RXQUAL_6 6,4 % < BER < 12,8 % Assumed value = 9,05 %
* RXQUAL_7 12,8 % < BER Assumed value = 18,10 % */
if (ber10k < 20)
return 0;
if (ber10k < 40)
@@ -125,8 +240,53 @@ static uint8_t ber10k_to_rxqual(uint32_t ber10k)
return 7;
}
/* Update order TA at end of meas period */
static void lchan_meas_update_ordered_TA(struct gsm_lchan *lchan,
int32_t taqb_sum)
{
int32_t ms_timing_offset = 0;
uint8_t l1_info_valid;
l1_info_valid = lchan->meas.flags & LC_UL_M_F_L1_VALID;
if (l1_info_valid) {
DEBUGP(DMEAS,
"%s Update TA TimingOffset_Mean:%d, UL RX TA:%d, DL ordered TA:%d, flags:%d \n",
gsm_lchan_name(lchan), taqb_sum, lchan->meas.l1_info[1],
lchan->rqd_ta, lchan->meas.flags);
ms_timing_offset =
taqb_sum + (lchan->meas.l1_info[1] - lchan->rqd_ta);
if (ms_timing_offset > 0) {
if (lchan->rqd_ta < MEAS_MAX_TIMING_ADVANCE) {
/* MS is moving away from BTS.
* So increment Ordered TA by 1 */
lchan->rqd_ta++;
}
} else if (ms_timing_offset < 0) {
if (lchan->rqd_ta > MEAS_MIN_TIMING_ADVANCE) {
/* MS is moving toward BTS. So decrement
* Ordered TA by 1 */
lchan->rqd_ta--;
}
}
DEBUGP(DMEAS,
"%s New Update TA--> TimingOff_diff:%d, UL RX TA:%d, DL ordered TA:%d \n",
gsm_lchan_name(lchan), ms_timing_offset,
lchan->meas.l1_info[1], lchan->rqd_ta);
}
/* Clear L1 INFO valid flag at Meas period end */
lchan->meas.flags &= ~LC_UL_M_F_L1_VALID;
return;
}
int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
{
struct gsm_meas_rep_unidir *mru;
uint32_t ber_full_sum = 0;
uint32_t irssi_full_sum = 0;
uint32_t ber_sub_sum = 0;
@@ -136,8 +296,7 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
int i;
/* if measurement period is not complete, abort */
if (!is_meas_complete(lchan->ts->pchan, lchan->ts->nr,
lchan->nr, fn))
if (!is_meas_complete(lchan, fn))
return 0;
/* if there are no measurements, skip computation */
@@ -169,6 +328,9 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
if (num_meas_sub) {
ber_sub_sum = ber_sub_sum / num_meas_sub;
irssi_sub_sum = irssi_sub_sum / num_meas_sub;
} else {
ber_sub_sum = ber_full_sum;
irssi_sub_sum = irssi_full_sum;
}
DEBUGP(DMEAS, "%s Computed TA(% 4dqb) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), "
@@ -177,11 +339,23 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
ber_full_sum%100, irssi_full_sum, ber_sub_sum/100, ber_sub_sum%100,
irssi_sub_sum);
/* Update ordered TA for DL SACCH L1 Header */
lchan_meas_update_ordered_TA(lchan, taqb_sum);
/* store results */
lchan->meas.res.rxlev_full = dbm2rxlev((int)irssi_full_sum * -1);
lchan->meas.res.rxlev_sub = dbm2rxlev((int)irssi_sub_sum * -1);
lchan->meas.res.rxqual_full = ber10k_to_rxqual(ber_full_sum);
lchan->meas.res.rxqual_sub = ber10k_to_rxqual(ber_sub_sum);
mru = &lchan->meas.ul_res;
mru->full.rx_lev = dbm2rxlev((int)irssi_full_sum * -1);
mru->sub.rx_lev = dbm2rxlev((int)irssi_sub_sum * -1);
mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum);
mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_sum);
DEBUGP(DMEAS, "%s UL MEAS RXLEV_FULL(%u), RXLEV_SUB(%u),"
"RXQUAL_FULL(%u), RXQUAL_SUB(%u), num_meas_sub(%u), num_ul_meas(%u) \n",
gsm_lchan_name(lchan),
mru->full.rx_lev,
mru->sub.rx_lev,
mru->full.rx_qual,
mru->sub.rx_qual, num_meas_sub, lchan->meas.num_ul_meas);
lchan->meas.flags |= LC_UL_M_F_RES_VALID;
lchan->meas.num_ul_meas = 0;
@@ -190,49 +364,3 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
return 1;
}
/* build the 3 byte RSL uplinke measurement IE content */
int lchan_build_rsl_ul_meas(struct gsm_lchan *lchan, uint8_t *buf)
{
buf[0] = (lchan->meas.res.rxlev_full & 0x3f); /* FIXME: DTXu support */
buf[1] = (lchan->meas.res.rxlev_sub & 0x3f);
buf[2] = ((lchan->meas.res.rxqual_full & 7) << 3) |
(lchan->meas.res.rxqual_sub & 7);
return 3;
}
int ts_meas_check_compute(struct gsm_bts_trx_ts *ts, uint32_t fn)
{
int i;
for (i = 0; i < ARRAY_SIZE(ts->lchan); i++) {
struct gsm_lchan *lchan = &ts->lchan[i];
if (lchan->state != LCHAN_S_ACTIVE)
continue;
switch (lchan->type) {
case GSM_LCHAN_SDCCH:
case GSM_LCHAN_TCH_F:
case GSM_LCHAN_TCH_H:
lchan_meas_check_compute(lchan, fn);
break;
default:
break;
}
}
return 0;
}
/* needs to be called once every TDMA frame ! */
int trx_meas_check_compute(struct gsm_bts_trx *trx, uint32_t fn)
{
int i;
for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
struct gsm_bts_trx_ts *ts = &trx->ts[i];
ts_meas_check_compute(ts, fn);
}
return 0;
}

603
src/common/msg_utils.c Normal file
View File

@@ -0,0 +1,603 @@
/* (C) 2014 by sysmocom s.f.m.c. GmbH
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/msg_utils.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/oml.h>
#include <osmo-bts/amr.h>
#include <osmo-bts/rsl.h>
#include <osmocom/gsm/protocol/ipaccess.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/gsm/abis_nm.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/fsm.h>
#include <osmocom/trau/osmo_ortp.h>
#include <arpa/inet.h>
#include <errno.h>
#define STI_BIT_MASK 16
static int check_fom(struct abis_om_hdr *omh, size_t len)
{
if (omh->length != len) {
LOGP(DL1C, LOGL_ERROR, "Incorrect OM hdr length value %d %zu\n",
omh->length, len);
return -1;
}
if (len < sizeof(struct abis_om_fom_hdr)) {
LOGP(DL1C, LOGL_ERROR, "FOM header insufficient space %zu %zu\n",
len, sizeof(struct abis_om_fom_hdr));
return -1;
}
return 0;
}
static int check_manuf(struct msgb *msg, struct abis_om_hdr *omh, size_t msg_size)
{
int type;
size_t size;
if (msg_size < 1) {
LOGP(DL1C, LOGL_ERROR, "No ManId Length Indicator %zu\n",
msg_size);
return -1;
}
if (omh->data[0] >= msg_size - 1) {
LOGP(DL1C, LOGL_ERROR,
"Insufficient message space for this ManId Length %d %zu\n",
omh->data[0], msg_size - 1);
return -1;
}
if (omh->data[0] == sizeof(abis_nm_ipa_magic) &&
strncmp(abis_nm_ipa_magic, (const char *)omh->data + 1,
sizeof(abis_nm_ipa_magic)) == 0) {
type = OML_MSG_TYPE_IPA;
size = sizeof(abis_nm_ipa_magic) + 1;
} else if (omh->data[0] == sizeof(abis_nm_osmo_magic) &&
strncmp(abis_nm_osmo_magic, (const char *) omh->data + 1,
sizeof(abis_nm_osmo_magic)) == 0) {
type = OML_MSG_TYPE_OSMO;
size = sizeof(abis_nm_osmo_magic) + 1;
} else {
LOGP(DL1C, LOGL_ERROR, "Manuf Label Unknown\n");
return -1;
}
/* we have verified that the vendor string fits */
msg->l3h = omh->data + size;
if (check_fom(omh, msgb_l3len(msg)) != 0)
return -1;
return type;
}
/* check that DTX is in the middle of silence */
static inline bool dtx_is_update(const struct gsm_lchan *lchan)
{
if (!dtx_dl_amr_enabled(lchan))
return false;
if (lchan->tch.dtx.dl_amr_fsm->state == ST_SID_U ||
lchan->tch.dtx.dl_amr_fsm->state == ST_U_NOINH)
return true;
return false;
}
/* check that DTX is in the beginning of silence for AMR HR */
bool dtx_is_first_p1(const struct gsm_lchan *lchan)
{
if (!dtx_dl_amr_enabled(lchan))
return false;
if ((lchan->type == GSM_LCHAN_TCH_H &&
lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F1))
return true;
return false;
}
/* update lchan SID status */
void lchan_set_marker(bool t, struct gsm_lchan *lchan)
{
if (t)
lchan->tch.dtx.ul_sid = true;
else if (lchan->tch.dtx.ul_sid) {
lchan->tch.dtx.ul_sid = false;
lchan->rtp_tx_marker = true;
}
}
/*! \brief Store the last SID frame in lchan context
* \param[in] lchan Logical channel on which we check scheduling
* \param[in] l1_payload buffer with SID data
* \param[in] length length of l1_payload
* \param[in] fn Frame Number for which we check scheduling
* \param[in] update 0 if SID_FIRST, 1 if SID_UPDATE, -1 if not AMR SID
*/
void dtx_cache_payload(struct gsm_lchan *lchan, const uint8_t *l1_payload,
size_t length, uint32_t fn, int update)
{
size_t amr = (update < 0) ? 0 : 2,
copy_len = OSMO_MIN(length,
ARRAY_SIZE(lchan->tch.dtx.cache) - amr);
lchan->tch.dtx.len = copy_len + amr;
/* SID FIRST is special because it's both sent and cached: */
if (update == 0) {
lchan->tch.dtx.is_update = false; /* Mark SID FIRST explicitly */
/* for non-AMR case - always update FN for incoming SID FIRST */
if (!amr || !dtx_is_update(lchan))
lchan->tch.dtx.fn = fn;
/* for AMR case - do not update FN if SID FIRST arrives in a
middle of silence: this should not be happening according to
the spec */
}
memcpy(lchan->tch.dtx.cache + amr, l1_payload, copy_len);
}
/*! \brief Check current state of DTX DL AMR FSM and dispatch necessary events
* \param[in] lchan Logical channel on which we check scheduling
* \param[in] rtp_pl buffer with RTP data
* \param[in] rtp_pl_len length of rtp_pl
* \param[in] fn Frame Number for which we check scheduling
* \param[in] l1_payload buffer where CMR and CMI prefix should be added
* \param[in] marker RTP Marker bit
* \param[out] len Length of expected L1 payload
* \param[out] ft_out Frame Type to be populated after decoding
* \returns 0 in case of success; negative on error
*/
int dtx_dl_amr_fsm_step(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload,
bool marker, uint8_t *len, uint8_t *ft_out)
{
uint8_t cmr;
enum osmo_amr_type ft;
enum osmo_amr_quality bfi;
int8_t sti, cmi;
int rc;
if (dtx_dl_amr_enabled(lchan)) {
if (lchan->type == GSM_LCHAN_TCH_H && !rtp_pl) {
/* we're called by gen_empty_tch_msg() to handle states
specific to AMR HR DTX */
switch (lchan->tch.dtx.dl_amr_fsm->state) {
case ST_SID_F2:
*len = 3; /* SID-FIRST P1 -> P2 completion */
memcpy(l1_payload, lchan->tch.dtx.cache, 2);
rc = 0;
dtx_dispatch(lchan, E_COMPL);
break;
case ST_SID_U:
rc = -EBADMSG;
dtx_dispatch(lchan, E_SID_U);
break;
default:
rc = -EBADMSG;
}
return rc;
}
}
if (!rtp_pl_len)
return -EBADMSG;
rc = osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti);
if (rc < 0) {
LOGP(DRTP, LOGL_ERROR, "failed to decode AMR RTP (length %zu, "
"%p)\n", rtp_pl_len, rtp_pl);
return rc;
}
/* only needed for old sysmo firmware: */
*ft_out = ft;
/* CMI in downlink tells the L1 encoder which encoding function
* it will use, so we have to use the frame type */
if (osmo_amr_is_speech(ft))
cmi = ft;
/* populate L1 payload with CMR/CMI - might be ignored by caller: */
amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr);
/* populate DTX cache with CMR/CMI - overwrite cache which will be
either updated or invalidated by caller anyway: */
amr_set_mode_pref(lchan->tch.dtx.cache, &lchan->tch.amr_mr, cmi, cmr);
*len = 3 + rtp_pl_len;
/* DTX DL is not enabled, move along */
if (!lchan->ts->trx->bts->dtxd)
return 0;
if (osmo_amr_is_speech(ft)) {
/* AMR HR - SID-FIRST_P1 Inhibition */
if (marker && lchan->tch.dtx.dl_amr_fsm->state == ST_VOICE)
return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
E_INHIB, (void *)lchan);
/* AMR HR - SID-UPDATE Inhibition */
if (marker && lchan->type == GSM_LCHAN_TCH_H &&
lchan->tch.dtx.dl_amr_fsm->state == ST_SID_U)
return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
E_INHIB, (void *)lchan);
/* AMR FR & HR - generic */
if (marker && (lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F1 ||
lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F2 ||
lchan->tch.dtx.dl_amr_fsm->state == ST_U_NOINH))
return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
E_ONSET, (void *)lchan);
if (lchan->tch.dtx.dl_amr_fsm->state != ST_VOICE)
return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
E_VOICE, (void *)lchan);
return 0;
}
if (ft == AMR_SID) {
if (lchan->tch.dtx.dl_amr_fsm->state == ST_VOICE) {
/* SID FIRST/UPDATE scheduling logic relies on SID FIRST
being sent first hence we have to force caching of SID
as FIRST regardless of actually decoded type */
dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, false);
return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
sti ? E_SID_U : E_SID_F,
(void *)lchan);
} else if (lchan->tch.dtx.dl_amr_fsm->state != ST_FACCH)
dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, sti);
if (lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F2)
return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
E_COMPL, (void *)lchan);
return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
sti ? E_SID_U : E_SID_F,
(void *)lchan);
}
if (ft != AMR_NO_DATA) {
LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft);
return -ENOTSUP;
}
if (marker)
osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm, E_VOICE,
(void *)lchan);
*len = 0;
return 0;
}
/* STI is located in payload byte 6, cache contains 2 byte prefix (CMR/CMI)
* STI set = SID UPDATE, STI unset = SID FIRST
*/
static inline void dtx_sti_set(struct gsm_lchan *lchan)
{
lchan->tch.dtx.cache[6 + 2] |= STI_BIT_MASK;
}
static inline void dtx_sti_unset(struct gsm_lchan *lchan)
{
lchan->tch.dtx.cache[6 + 2] &= ~STI_BIT_MASK;
}
/*! \brief Check if enough time has passed since last SID (if any) to repeat it
* \param[in] lchan Logical channel on which we check scheduling
* \param[in] fn Frame Number for which we check scheduling
* \returns true if transmission can be omitted, false otherwise
*/
static inline bool dtx_amr_sid_optional(struct gsm_lchan *lchan, uint32_t fn)
{
if (!dtx_dl_amr_enabled(lchan))
return true;
/* Compute approx. time delta x26 based on Fn duration */
uint32_t dx26 = 120 * (fn - lchan->tch.dtx.fn);
/* We're resuming after FACCH interruption */
if (lchan->tch.dtx.dl_amr_fsm->state == ST_FACCH) {
/* force STI bit to 0 so cache is treated as SID FIRST */
dtx_sti_unset(lchan);
lchan->tch.dtx.is_update = false;
/* check that this FN has not been used for FACCH message
already: we rely here on the order of RTS arrival from L1 - we
expect that PH-DATA.req ALWAYS comes before PH-TCH.req for the
same FN */
if(lchan->type == GSM_LCHAN_TCH_H) {
if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY &&
lchan->tch.dtx.fn != LCHAN_FN_WAIT) {
/* FACCH interruption is over */
dtx_dispatch(lchan, E_COMPL);
return false;
} else if(lchan->tch.dtx.fn == LCHAN_FN_DUMMY) {
lchan->tch.dtx.fn = LCHAN_FN_WAIT;
} else
lchan->tch.dtx.fn = fn;
} else if(lchan->type == GSM_LCHAN_TCH_F) {
if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY) {
/* FACCH interruption is over */
dtx_dispatch(lchan, E_COMPL);
return false;
} else
lchan->tch.dtx.fn = fn;
}
/* this FN was already used for FACCH or ONSET message so we just
prepare things for next one */
return true;
}
if (lchan->tch.dtx.dl_amr_fsm->state == ST_VOICE)
return true;
/* according to 3GPP TS 26.093 A.5.1.1:
(*26) to avoid float math, add 1 FN tolerance (-120) */
if (lchan->tch.dtx.is_update) { /* SID UPDATE: every 8th RTP frame */
if (dx26 < GSM_RTP_FRAME_DURATION_MS * 8 * 26 - 120)
return true;
return false;
}
/* 3rd frame after SID FIRST should be SID UPDATE */
if (dx26 < GSM_RTP_FRAME_DURATION_MS * 3 * 26 - 120)
return true;
return false;
}
static inline bool fn_chk(const uint8_t *t, uint32_t fn, uint8_t len)
{
uint8_t i;
for (i = 0; i < len; i++)
if (fn % 104 == t[i])
return false;
return true;
}
/*! \brief Check if TX scheduling is optional for a given FN in case of DTX
* \param[in] lchan Logical channel on which we check scheduling
* \param[in] fn Frame Number for which we check scheduling
* \returns true if transmission can be omitted, false otherwise
*/
static inline bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn)
{
/* According to 3GPP TS 45.008 § 8.3: */
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) {
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));
}
return false;
}
/*! \brief Check if DTX DL AMR is enabled for a given lchan (it have proper type,
* FSM is allocated etc.)
* \param[in] lchan Logical channel on which we check scheduling
* \returns true if DTX DL AMR is enabled, false otherwise
*/
bool dtx_dl_amr_enabled(const struct gsm_lchan *lchan)
{
if (lchan->ts->trx->bts->dtxd &&
lchan->tch.dtx.dl_amr_fsm &&
lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
return true;
return false;
}
/*! \brief Check if DTX DL AMR FSM state is recursive: requires secondary
* response to a single RTS request from L1.
* \param[in] lchan Logical channel on which we check scheduling
* \returns true if DTX DL AMR FSM state is recursive, false otherwise
*/
bool dtx_recursion(const struct gsm_lchan *lchan)
{
if (!dtx_dl_amr_enabled(lchan))
return false;
if (lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_V ||
lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F ||
lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_V_REC ||
lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F_REC ||
lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_V ||
lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F ||
lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_V_REC ||
lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F_REC ||
lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F ||
lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_V ||
lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F_REC ||
lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_V_REC)
return true;
return false;
}
/*! \brief Send signal to FSM: with proper check if DIX is enabled for this lchan
* \param[in] lchan Logical channel on which we check scheduling
* \param[in] e DTX DL AMR FSM Event
*/
void dtx_dispatch(struct gsm_lchan *lchan, enum dtx_dl_amr_fsm_events e)
{
if (dtx_dl_amr_enabled(lchan))
osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm, e,
(void *)lchan);
}
/*! \brief Send internal signal to FSM: check that DTX is enabled for this chan,
* check that current FSM and lchan states are permitting such signal.
* Note: this should be the only way to dispatch E_COMPL to FSM from
* BTS code.
* \param[in] lchan Logical channel on which we check scheduling
*/
void dtx_int_signal(struct gsm_lchan *lchan)
{
if (!dtx_dl_amr_enabled(lchan))
return;
if (dtx_is_first_p1(lchan) || dtx_recursion(lchan))
dtx_dispatch(lchan, E_COMPL);
}
/*! \brief Repeat last SID if possible in case of DTX
* \param[in] lchan Logical channel on which we check scheduling
* \param[in] dst Buffer to copy last SID into
* \returns Number of bytes copied + 1 (to accommodate for extra byte with
* payload type), 0 if there's nothing to copy
*/
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;
} else
if (dtx_amr_sid_optional(lchan, fn))
return 0;
if (lchan->tch.dtx.len) {
if (dtx_dl_amr_enabled(lchan)) {
if ((lchan->type == GSM_LCHAN_TCH_H &&
lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F2) ||
(lchan->type == GSM_LCHAN_TCH_F &&
lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F1)) {
/* advance FSM in case we've just sent SID FIRST
to restore silence after FACCH interruption */
osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
E_SID_U, (void *)lchan);
dtx_sti_unset(lchan);
} else if (dtx_is_update(lchan)) {
/* enforce SID UPDATE for next repetition: it
might have been altered by FACCH handling */
dtx_sti_set(lchan);
if (lchan->type == GSM_LCHAN_TCH_H &&
lchan->tch.dtx.dl_amr_fsm->state ==
ST_U_NOINH)
osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
E_COMPL,
(void *)lchan);
lchan->tch.dtx.is_update = true;
}
}
memcpy(dst, lchan->tch.dtx.cache, lchan->tch.dtx.len);
lchan->tch.dtx.fn = fn;
return lchan->tch.dtx.len + 1;
}
LOGP(DL1C, LOGL_DEBUG, "Have to send %s frame on TCH but SID buffer "
"is empty - sent nothing\n",
get_value_string(gsm48_chan_mode_names, lchan->tch_mode));
return 0;
}
/**
* Return 0 in case the IPA structure is okay and in this
* case the l2h will be set to the beginning of the data.
*/
int msg_verify_ipa_structure(struct msgb *msg)
{
struct ipaccess_head *hh;
if (msgb_l1len(msg) < sizeof(struct ipaccess_head)) {
LOGP(DL1C, LOGL_ERROR,
"Ipa header insufficient space %d %zu\n",
msgb_l1len(msg), sizeof(struct ipaccess_head));
return -1;
}
hh = (struct ipaccess_head *) msg->l1h;
if (ntohs(hh->len) != msgb_l1len(msg) - sizeof(struct ipaccess_head)) {
LOGP(DL1C, LOGL_ERROR,
"Incorrect ipa header msg size %d %zu\n",
ntohs(hh->len), msgb_l1len(msg) - sizeof(struct ipaccess_head));
return -1;
}
if (hh->proto == IPAC_PROTO_OSMO) {
struct ipaccess_head_ext *hh_ext = (struct ipaccess_head_ext *) hh->data;
if (ntohs(hh->len) < sizeof(*hh_ext)) {
LOGP(DL1C, LOGL_ERROR, "IPA length shorter than OSMO header\n");
return -1;
}
msg->l2h = hh_ext->data;
} else
msg->l2h = hh->data;
return 0;
}
/**
* \brief Verify the structure of the OML message and set l3h
*
* This function verifies that the data in \param in msg is a proper
* OML message. This code assumes that msg->l2h points to the
* beginning of the OML message. In the successful case the msg->l3h
* will be set and will point to the FOM header. The value is undefined
* in all other cases.
*
* \param msg The message to analyze starting from msg->l2h.
* \return In case the structure is correct a positive number will be
* returned and msg->l3h will point to the FOM. The number is a
* classification of the vendor type of the message.
*/
int msg_verify_oml_structure(struct msgb *msg)
{
struct abis_om_hdr *omh;
if (msgb_l2len(msg) < sizeof(*omh)) {
LOGP(DL1C, LOGL_ERROR, "Om header insufficient space %d %zu\n",
msgb_l2len(msg), sizeof(*omh));
return -1;
}
omh = (struct abis_om_hdr *) msg->l2h;
if (omh->mdisc != ABIS_OM_MDISC_FOM &&
omh->mdisc != ABIS_OM_MDISC_MANUF) {
LOGP(DL1C, LOGL_ERROR, "Incorrect om mdisc value %x\n",
omh->mdisc);
return -1;
}
if (omh->placement != ABIS_OM_PLACEMENT_ONLY) {
LOGP(DL1C, LOGL_ERROR, "Incorrect om placement value %x %x\n",
omh->placement, ABIS_OM_PLACEMENT_ONLY);
return -1;
}
if (omh->sequence != 0) {
LOGP(DL1C, LOGL_ERROR, "Incorrect om sequence value %d\n",
omh->sequence);
return -1;
}
if (omh->mdisc == ABIS_OM_MDISC_MANUF)
return check_manuf(msg, omh, msgb_l2len(msg) - sizeof(*omh));
msg->l3h = omh->data;
if (check_fom(omh, msgb_l3len(msg)) != 0)
return -1;
return OML_MSG_TYPE_ETSI;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* Paging message encoding + queue management */
/* (C) 2011 by Harald Welte <laforge@gnumonks.org>
/* (C) 2011-2012 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
@@ -41,18 +41,34 @@
#include <osmo-bts/logging.h>
#include <osmo-bts/paging.h>
#include <osmo-bts/signal.h>
#include <osmo-bts/pcu_if.h>
#define MAX_PAGING_BLOCKS_CCCH 9
#define MAX_BS_PA_MFRMS 9
enum paging_record_type {
PAGING_RECORD_PAGING,
PAGING_RECORD_IMM_ASS
};
struct paging_record {
struct llist_head list;
time_t expiration_time;
uint8_t chan_needed;
uint8_t identity_lv[9];
enum paging_record_type type;
union {
struct {
time_t expiration_time;
uint8_t chan_needed;
uint8_t identity_lv[9];
} paging;
struct {
uint8_t msg[GSM_MACBLOCK_LEN];
} imm_ass;
} u;
};
struct paging_state {
struct gsm_bts_role_bts *btsb;
/* parameters taken / interpreted from BCCH/CCCH configuration */
struct gsm48_control_channel_descr chan_desc;
@@ -65,6 +81,26 @@ struct paging_state {
struct llist_head paging_queue[MAX_PAGING_BLOCKS_CCCH*MAX_BS_PA_MFRMS];
};
unsigned int paging_get_lifetime(struct paging_state *ps)
{
return ps->paging_lifetime;
}
unsigned int paging_get_queue_max(struct paging_state *ps)
{
return ps->num_paging_max;
}
void paging_set_lifetime(struct paging_state *ps, unsigned int lifetime)
{
ps->paging_lifetime = lifetime;
}
void paging_set_queue_max(struct paging_state *ps, unsigned int queue_max)
{
ps->num_paging_max = queue_max;
}
static int tmsi_mi_to_uint(uint32_t *out, const uint8_t *tmsi_lv)
{
if (tmsi_lv[0] < 5)
@@ -128,6 +164,13 @@ static int get_pag_subch_nr(struct paging_state *ps, struct gsm_time *gt)
return pag_idx + mfrm_part;
}
int paging_buffer_space(struct paging_state *ps)
{
if (ps->num_paging >= ps->num_paging_max)
return 0;
else
return ps->num_paging_max - ps->num_paging;
}
/* Add an identity to the paging queue */
int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
@@ -144,10 +187,14 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
/* Check if we already have this identity */
llist_for_each_entry(pr, group_q, list) {
if (identity_lv[0] == pr->identity_lv[0] &&
!memcmp(identity_lv+1, pr->identity_lv+1, identity_lv[0])) {
if (pr->type != PAGING_RECORD_PAGING)
continue;
if (identity_lv[0] == pr->u.paging.identity_lv[0] &&
!memcmp(identity_lv+1, pr->u.paging.identity_lv+1,
identity_lv[0])) {
LOGP(DPAG, LOGL_INFO, "Ignoring duplicate paging\n");
pr->expiration_time = time(NULL) + ps->paging_lifetime;
pr->u.paging.expiration_time =
time(NULL) + ps->paging_lifetime;
return -EEXIST;
}
}
@@ -155,8 +202,9 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
pr = talloc_zero(ps, struct paging_record);
if (!pr)
return -ENOMEM;
pr->type = PAGING_RECORD_PAGING;
if (*identity_lv + 1 > sizeof(pr->identity_lv)) {
if (*identity_lv + 1 > sizeof(pr->u.paging.identity_lv)) {
talloc_free(pr);
return -E2BIG;
}
@@ -164,9 +212,9 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
LOGP(DPAG, LOGL_INFO, "Add paging to queue (group=%u, queue_len=%u)\n",
paging_group, ps->num_paging+1);
pr->expiration_time = time(NULL) + ps->paging_lifetime;
pr->chan_needed = chan_needed;
memcpy(&pr->identity_lv, identity_lv, identity_lv[0]+1);
pr->u.paging.expiration_time = time(NULL) + ps->paging_lifetime;
pr->u.paging.chan_needed = chan_needed;
memcpy(&pr->u.paging.identity_lv, identity_lv, identity_lv[0]+1);
/* enqueue the new identity to the HEAD of the queue,
* to ensure it will be paged quickly at least once. */
@@ -176,6 +224,42 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
return 0;
}
/* 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)
{
struct llist_head *group_q;
struct paging_record *pr;
uint16_t imsi, paging_group;
if (len != GSM_MACBLOCK_LEN + 3) {
LOGP(DPAG, LOGL_ERROR, "IMM.ASS invalid length %d\n", len);
return -EINVAL;
}
len -= 3;
imsi = 100 * ((*(data++)) - '0');
imsi += 10 * ((*(data++)) - '0');
imsi += (*(data++)) - '0';
paging_group = gsm0502_calc_paging_group(&ps->chan_desc, imsi);
group_q = &ps->paging_queue[paging_group];
pr = talloc_zero(ps, struct paging_record);
if (!pr)
return -ENOMEM;
pr->type = PAGING_RECORD_IMM_ASS;
LOGP(DPAG, LOGL_INFO, "Add IMM.ASS to queue (group=%u)\n",
paging_group);
memcpy(pr->u.imm_ass.msg, data, GSM_MACBLOCK_LEN);
/* enqueue the new message to the HEAD of the queue */
llist_add(&pr->list, group_q);
return 0;
}
#define L2_PLEN(len) (((len - 1) << 2) | 0x01)
static int fill_paging_type_1(uint8_t *out_buf, const uint8_t *identity1_lv,
@@ -266,7 +350,7 @@ static struct paging_record *dequeue_pr(struct llist_head *group_q)
static int pr_is_imsi(struct paging_record *pr)
{
if ((pr->identity_lv[1] & 7) == GSM_MI_TYPE_IMSI)
if ((pr->u.paging.identity_lv[1] & 7) == GSM_MI_TYPE_IMSI)
return 1;
else
return 0;
@@ -293,28 +377,52 @@ static void sort_pr_tmsi_imsi(struct paging_record *pr[], unsigned int n)
}
/* generate paging message for given gsm time */
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt)
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
int *is_empty)
{
unsigned int group = get_pag_subch_nr(ps, gt);
struct llist_head *group_q = &ps->paging_queue[group];
struct llist_head *group_q;
int group;
int len;
*is_empty = 0;
ps->btsb->load.ccch.pch_total += 1;
group = get_pag_subch_nr(ps, gt);
if (group < 0) {
LOGP(DPAG, LOGL_ERROR,
"Paging called for GSM wrong time: FN %d/%d/%d/%d.\n",
gt->fn, gt->t1, gt->t2, gt->t3);
return -1;
}
group_q = &ps->paging_queue[group];
/* There is nobody to be paged, send Type1 with two empty ID */
if (llist_empty(group_q)) {
//DEBUGP(DPAG, "Tx PAGING TYPE 1 (empty)\n");
len = fill_paging_type_1(out_buf, empty_id_lv, 0,
NULL, 0);
*is_empty = 1;
} else {
struct paging_record *pr[4];
unsigned int num_pr = 0;
unsigned int num_pr = 0, imm_ass = 0;
time_t now = time(NULL);
unsigned int i, num_imsi = 0;
ps->btsb->load.ccch.pch_used += 1;
/* get (if we have) up to four paging records */
for (i = 0; i < ARRAY_SIZE(pr); i++) {
if (llist_empty(group_q))
break;
pr[i] = dequeue_pr(group_q);
/* check for IMM.ASS */
if (pr[i]->type == PAGING_RECORD_IMM_ASS) {
imm_ass = 1;
break;
}
num_pr++;
/* count how many IMSIs are among them */
@@ -322,27 +430,43 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g
num_imsi++;
}
/* if we have an IMMEDIATE ASSIGNMENT */
if (imm_ass) {
/* re-add paging records */
for (i = 0; i < num_pr; i++)
llist_add(&pr[i]->list, group_q);
/* get message and free record */
memcpy(out_buf, pr[num_pr]->u.imm_ass.msg,
GSM_MACBLOCK_LEN);
pcu_tx_pch_data_cnf(gt->fn, pr[num_pr]->u.imm_ass.msg,
GSM_MACBLOCK_LEN);
talloc_free(pr[num_pr]);
return GSM_MACBLOCK_LEN;
}
/* make sure the TMSIs are ahead of the IMSIs in the array */
sort_pr_tmsi_imsi(pr, num_pr);
if (num_pr == 4 && num_imsi == 0) {
/* No IMSI: easy case, can use TYPE 3 */
DEBUGP(DPAG, "Tx PAGING TYPE 3 (4 TMSI)\n");
len = fill_paging_type_3(out_buf, pr[0]->identity_lv,
pr[0]->chan_needed,
pr[1]->identity_lv,
pr[1]->chan_needed,
pr[2]->identity_lv,
pr[3]->identity_lv);
len = fill_paging_type_3(out_buf,
pr[0]->u.paging.identity_lv,
pr[0]->u.paging.chan_needed,
pr[1]->u.paging.identity_lv,
pr[1]->u.paging.chan_needed,
pr[2]->u.paging.identity_lv,
pr[3]->u.paging.identity_lv);
} else if (num_pr >= 3 && num_imsi <= 1) {
/* 3 or 4, of which only up to 1 is IMSI */
DEBUGP(DPAG, "Tx PAGING TYPE 2 (2 TMSI,1 xMSI)\n");
len = fill_paging_type_2(out_buf,
pr[0]->identity_lv,
pr[0]->chan_needed,
pr[1]->identity_lv,
pr[1]->chan_needed,
pr[2]->identity_lv);
pr[0]->u.paging.identity_lv,
pr[0]->u.paging.chan_needed,
pr[1]->u.paging.identity_lv,
pr[1]->u.paging.chan_needed,
pr[2]->u.paging.identity_lv);
if (num_pr == 4) {
/* re-add #4 for next time */
llist_add(&pr[3]->list, group_q);
@@ -350,16 +474,19 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g
}
} else if (num_pr == 1) {
DEBUGP(DPAG, "Tx PAGING TYPE 1 (1 xMSI,1 empty)\n");
len = fill_paging_type_1(out_buf, pr[0]->identity_lv,
pr[0]->chan_needed, NULL, 0);
len = fill_paging_type_1(out_buf,
pr[0]->u.paging.identity_lv,
pr[0]->u.paging.chan_needed,
NULL, 0);
} else {
/* 2 (any type) or
* 3 or 4, of which only 2 will be sent */
DEBUGP(DPAG, "Tx PAGING TYPE 1 (2 xMSI)\n");
len = fill_paging_type_1(out_buf, pr[0]->identity_lv,
pr[0]->chan_needed,
pr[1]->identity_lv,
pr[1]->chan_needed);
len = fill_paging_type_1(out_buf,
pr[0]->u.paging.identity_lv,
pr[0]->u.paging.chan_needed,
pr[1]->u.paging.identity_lv,
pr[1]->u.paging.chan_needed);
if (num_pr >= 3) {
/* re-add #4 for next time */
llist_add(&pr[2]->list, group_q);
@@ -378,7 +505,7 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g
continue;
/* check if we can expire the paging record,
* or if we need to re-queue it */
if (pr[i]->expiration_time >= now) {
if (pr[i]->u.paging.expiration_time <= now) {
talloc_free(pr[i]);
ps->num_paging--;
LOGP(DPAG, LOGL_INFO, "Removed paging record, queue_len=%u\n",
@@ -395,7 +522,7 @@ int paging_si_update(struct paging_state *ps, struct gsm48_control_channel_descr
{
LOGP(DPAG, LOGL_INFO, "Paging SI update\n");
memcpy(&ps->chan_desc, chan_desc, sizeof(chan_desc));
ps->chan_desc = *chan_desc;
/* FIXME: do we need to re-sort the old paging_records? */
@@ -418,16 +545,18 @@ static int paging_signal_cbfn(unsigned int subsys, unsigned int signal, void *hd
static int initialized = 0;
struct paging_state *paging_init(void *ctx, unsigned int num_paging_max,
struct paging_state *paging_init(struct gsm_bts_role_bts *btsb,
unsigned int num_paging_max,
unsigned int paging_lifetime)
{
struct paging_state *ps;
unsigned int i;
ps = talloc_zero(ctx, struct paging_state);
ps = talloc_zero(btsb, struct paging_state);
if (!ps)
return NULL;
ps->btsb = btsb;
ps->paging_lifetime = paging_lifetime;
ps->num_paging_max = num_paging_max;
@@ -441,6 +570,14 @@ struct paging_state *paging_init(void *ctx, unsigned int num_paging_max,
return ps;
}
void paging_config(struct paging_state *ps,
unsigned int num_paging_max,
unsigned int paging_lifetime)
{
ps->num_paging_max = num_paging_max;
ps->paging_lifetime = paging_lifetime;
}
void paging_reset(struct paging_state *ps)
{
int i;
@@ -460,3 +597,18 @@ void paging_reset(struct paging_state *ps)
ps->num_paging = 0;
}
/**
* \brief Helper for the unit tests
*/
int paging_group_queue_empty(struct paging_state *ps, uint8_t grp)
{
if (grp >= ARRAY_SIZE(ps->paging_queue))
return 1;
return llist_empty(&ps->paging_queue[grp]);
}
int paging_queue_length(struct paging_state *ps)
{
return ps->num_paging;
}

939
src/common/pcu_sock.c Normal file
View File

@@ -0,0 +1,939 @@
/* pcu_sock.c: Connect from PCU via unix domain socket */
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
* (C) 2009-2012 by Andreas Eversberg <jolly@eversberg.eu>
* (C) 2012 by Holger Hans Peter Freyther
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <inttypes.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/socket.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/pcu_if.h>
#include <osmo-bts/pcuif_proto.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/rsl.h>
#include <osmo-bts/signal.h>
#include <osmo-bts/l1sap.h>
uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx);
extern struct gsm_network bts_gsmnet;
int pcu_direct = 0;
static int avail_lai = 0, avail_nse = 0, avail_cell = 0, avail_nsvc[2] = {0, 0};
static const char *sapi_string[] = {
[PCU_IF_SAPI_RACH] = "RACH",
[PCU_IF_SAPI_AGCH] = "AGCH",
[PCU_IF_SAPI_PCH] = "PCH",
[PCU_IF_SAPI_BCCH] = "BCCH",
[PCU_IF_SAPI_PDTCH] = "PDTCH",
[PCU_IF_SAPI_PRACH] = "PRACH",
[PCU_IF_SAPI_PTCCH] = "PTCCH",
};
static int pcu_sock_send(struct gsm_network *net, struct msgb *msg);
/*
* PCU messages
*/
struct msgb *pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr)
{
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
msg = msgb_alloc(sizeof(struct gsm_pcu_if), "pcu_sock_tx");
if (!msg)
return NULL;
msgb_put(msg, sizeof(struct gsm_pcu_if));
pcu_prim = (struct gsm_pcu_if *) msg->data;
pcu_prim->msg_type = msg_type;
pcu_prim->bts_nr = bts_nr;
return msg;
}
static bool ts_should_be_pdch(struct gsm_bts_trx_ts *ts) {
if (ts->pchan == GSM_PCHAN_PDCH)
return true;
if (ts->pchan == GSM_PCHAN_TCH_F_PDCH) {
/* When we're busy deactivating the PDCH, we first set
* DEACT_PENDING, tell the PCU about it and wait for a
* response. So DEACT_PENDING means "no PDCH" to the PCU.
* Similarly, when we're activating PDCH, we set the
* ACT_PENDING and wait for an activation response from the
* PCU, so ACT_PENDING means "is PDCH". */
if (ts->flags & TS_F_PDCH_ACTIVE)
return !(ts->flags & TS_F_PDCH_DEACT_PENDING);
else
return (ts->flags & TS_F_PDCH_ACT_PENDING);
}
if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
/*
* When we're busy de-/activating the PDCH, we first set
* ts->dyn.pchan_want, tell the PCU about it and wait for a
* response. So only care about dyn.pchan_want here.
*/
return ts->dyn.pchan_want == GSM_PCHAN_PDCH;
}
return false;
}
int pcu_tx_info_ind(void)
{
struct gsm_network *net = &bts_gsmnet;
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_info_ind *info_ind;
struct gsm_bts *bts;
struct gprs_rlc_cfg *rlcc;
struct gsm_bts_gprs_nsvc *nsvc;
struct gsm_bts_trx *trx;
struct gsm_bts_trx_ts *ts;
int i, j;
LOGP(DPCU, LOGL_INFO, "Sending info\n");
/* FIXME: allow multiple BTS */
bts = llist_entry(net->bts_list.next, struct gsm_bts, list);
rlcc = &bts->gprs.cell.rlc_cfg;
msg = pcu_msgb_alloc(PCU_IF_MSG_INFO_IND, bts->nr);
if (!msg)
return -ENOMEM;
pcu_prim = (struct gsm_pcu_if *) msg->data;
info_ind = &pcu_prim->u.info_ind;
info_ind->version = PCU_IF_VERSION;
if (avail_lai && avail_nse && avail_cell && avail_nsvc[0]) {
info_ind->flags |= PCU_IF_FLAG_ACTIVE;
LOGP(DPCU, LOGL_INFO, "BTS is up\n");
} else
LOGP(DPCU, LOGL_INFO, "BTS is down\n");
if (pcu_direct)
info_ind->flags |= PCU_IF_FLAG_SYSMO;
/* RAI */
info_ind->mcc = net->mcc;
info_ind->mnc = net->mnc;
info_ind->lac = bts->location_area_code;
info_ind->rac = bts->gprs.rac;
/* NSE */
info_ind->nsei = bts->gprs.nse.nsei;
memcpy(info_ind->nse_timer, bts->gprs.nse.timer, 7);
memcpy(info_ind->cell_timer, bts->gprs.cell.timer, 11);
/* cell attributes */
info_ind->cell_id = bts->cell_identity;
info_ind->repeat_time = rlcc->paging.repeat_time;
info_ind->repeat_count = rlcc->paging.repeat_count;
info_ind->bvci = bts->gprs.cell.bvci;
info_ind->t3142 = rlcc->parameter[RLC_T3142];
info_ind->t3169 = rlcc->parameter[RLC_T3169];
info_ind->t3191 = rlcc->parameter[RLC_T3191];
info_ind->t3193_10ms = rlcc->parameter[RLC_T3193];
info_ind->t3195 = rlcc->parameter[RLC_T3195];
info_ind->n3101 = rlcc->parameter[RLC_N3101];
info_ind->n3103 = rlcc->parameter[RLC_N3103];
info_ind->n3105 = rlcc->parameter[RLC_N3105];
info_ind->cv_countdown = rlcc->parameter[CV_COUNTDOWN];
if (rlcc->cs_mask & (1 << GPRS_CS1))
info_ind->flags |= PCU_IF_FLAG_CS1;
if (rlcc->cs_mask & (1 << GPRS_CS2))
info_ind->flags |= PCU_IF_FLAG_CS2;
if (rlcc->cs_mask & (1 << GPRS_CS3))
info_ind->flags |= PCU_IF_FLAG_CS3;
if (rlcc->cs_mask & (1 << GPRS_CS4))
info_ind->flags |= PCU_IF_FLAG_CS4;
if (rlcc->cs_mask & (1 << GPRS_MCS1))
info_ind->flags |= PCU_IF_FLAG_MCS1;
if (rlcc->cs_mask & (1 << GPRS_MCS2))
info_ind->flags |= PCU_IF_FLAG_MCS2;
if (rlcc->cs_mask & (1 << GPRS_MCS3))
info_ind->flags |= PCU_IF_FLAG_MCS3;
if (rlcc->cs_mask & (1 << GPRS_MCS4))
info_ind->flags |= PCU_IF_FLAG_MCS4;
if (rlcc->cs_mask & (1 << GPRS_MCS5))
info_ind->flags |= PCU_IF_FLAG_MCS5;
if (rlcc->cs_mask & (1 << GPRS_MCS6))
info_ind->flags |= PCU_IF_FLAG_MCS6;
if (rlcc->cs_mask & (1 << GPRS_MCS7))
info_ind->flags |= PCU_IF_FLAG_MCS7;
if (rlcc->cs_mask & (1 << GPRS_MCS8))
info_ind->flags |= PCU_IF_FLAG_MCS8;
if (rlcc->cs_mask & (1 << GPRS_MCS9))
info_ind->flags |= PCU_IF_FLAG_MCS9;
#warning "isn't dl_tbf_ext wrong?: * 10 and no ntohs"
info_ind->dl_tbf_ext = rlcc->parameter[T_DL_TBF_EXT];
#warning "isn't ul_tbf_ext wrong?: * 10 and no ntohs"
info_ind->ul_tbf_ext = rlcc->parameter[T_UL_TBF_EXT];
info_ind->initial_cs = rlcc->initial_cs;
info_ind->initial_mcs = rlcc->initial_mcs;
/* NSVC */
for (i = 0; i < 2; i++) {
nsvc = &bts->gprs.nsvc[i];
info_ind->nsvci[i] = nsvc->nsvci;
info_ind->local_port[i] = nsvc->local_port;
info_ind->remote_port[i] = nsvc->remote_port;
info_ind->remote_ip[i] = nsvc->remote_ip;
}
for (i = 0; i < 8; i++) {
trx = gsm_bts_trx_num(bts, i);
if (!trx)
break;
info_ind->trx[i].pdch_mask = 0;
info_ind->trx[i].arfcn = trx->arfcn;
info_ind->trx[i].hlayer1 = trx_get_hlayer1(trx);
for (j = 0; j < 8; j++) {
ts = &trx->ts[j];
if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED
&& ts_should_be_pdch(ts)) {
info_ind->trx[i].pdch_mask |= (1 << j);
info_ind->trx[i].tsc[j] =
(ts->tsc >= 0) ? ts->tsc : bts->bsic & 7;
LOGP(DPCU, LOGL_INFO, "trx=%d ts=%d: "
"available (tsc=%d arfcn=%d)\n",
trx->nr, ts->nr,
info_ind->trx[i].tsc[j],
info_ind->trx[i].arfcn);
}
}
}
return pcu_sock_send(net, msg);
}
static int pcu_if_signal_cb(unsigned int subsys, unsigned int signal,
void *hdlr_data, void *signal_data)
{
struct gsm_network *net = &bts_gsmnet;
struct gsm_bts_gprs_nsvc *nsvc;
struct gsm_bts *bts;
struct gsm48_system_information_type_3 *si3;
int id;
if (subsys != SS_GLOBAL)
return -EINVAL;
switch(signal) {
case S_NEW_SYSINFO:
bts = signal_data;
if (!(bts->si_valid & (1 << SYSINFO_TYPE_3)))
break;
si3 = (struct gsm48_system_information_type_3 *)
bts->si_buf[SYSINFO_TYPE_3];
net->mcc = ((si3->lai.digits[0] & 0x0f) << 8)
| (si3->lai.digits[0] & 0xf0)
| (si3->lai.digits[1] & 0x0f);
net->mnc = ((si3->lai.digits[2] & 0x0f) << 8)
| (si3->lai.digits[2] & 0xf0)
| ((si3->lai.digits[1] & 0xf0) >> 4);
if ((net->mnc & 0x00f) == 0x00f)
net->mnc >>= 4;
bts->location_area_code = ntohs(si3->lai.lac);
bts->cell_identity = si3->cell_identity;
avail_lai = 1;
break;
case S_NEW_NSE_ATTR:
bts = signal_data;
avail_nse = 1;
break;
case S_NEW_CELL_ATTR:
bts = signal_data;
avail_cell = 1;
break;
case S_NEW_NSVC_ATTR:
nsvc = signal_data;
id = nsvc->id;
if (id < 0 || id > 1)
return -EINVAL;
avail_nsvc[id] = 1;
break;
case S_NEW_OP_STATE:
break;
default:
return -EINVAL;
}
/* If all infos have been received, of if one info is updated after
* all infos have been received, transmit info update. */
if (avail_lai && avail_nse && avail_cell && avail_nsvc[0])
pcu_tx_info_ind();
return 0;
}
int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
uint16_t arfcn, uint8_t block_nr)
{
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_rts_req *rts_req;
struct gsm_bts *bts = ts->trx->bts;
LOGP(DPCU, LOGL_DEBUG, "Sending rts request: is_ptcch=%d arfcn=%d "
"block=%d\n", is_ptcch, arfcn, block_nr);
msg = pcu_msgb_alloc(PCU_IF_MSG_RTS_REQ, bts->nr);
if (!msg)
return -ENOMEM;
pcu_prim = (struct gsm_pcu_if *) msg->data;
rts_req = &pcu_prim->u.rts_req;
rts_req->sapi = (is_ptcch) ? PCU_IF_SAPI_PTCCH : PCU_IF_SAPI_PDTCH;
rts_req->fn = fn;
rts_req->arfcn = arfcn;
rts_req->trx_nr = ts->trx->nr;
rts_req->ts_nr = ts->nr;
rts_req->block_nr = block_nr;
return pcu_sock_send(&bts_gsmnet, msg);
}
int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len,
int8_t rssi, uint16_t ber10k, int16_t bto, int16_t lqual)
{
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_data *data_ind;
struct gsm_bts *bts = ts->trx->bts;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
LOGP(DPCU, LOGL_DEBUG, "Sending data indication: is_ptcch=%d arfcn=%d "
"block=%d data=%s\n", is_ptcch, arfcn, block_nr,
osmo_hexdump(data, len));
if (lqual / 10 < btsb->min_qual_norm) {
LOGP(DPCU, LOGL_DEBUG, "Link quality %"PRId16" is below threshold %f, dropping packet\n",
lqual, btsb->min_qual_norm);
return 0;
}
msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_IND, bts->nr);
if (!msg)
return -ENOMEM;
pcu_prim = (struct gsm_pcu_if *) msg->data;
data_ind = &pcu_prim->u.data_ind;
data_ind->sapi = (is_ptcch) ? PCU_IF_SAPI_PTCCH : PCU_IF_SAPI_PDTCH;
data_ind->rssi = rssi;
data_ind->fn = fn;
data_ind->arfcn = arfcn;
data_ind->trx_nr = ts->trx->nr;
data_ind->ts_nr = ts->nr;
data_ind->block_nr = block_nr;
data_ind->rssi = rssi;
data_ind->ber10k = ber10k;
data_ind->ta_offs_qbits = bto;
data_ind->lqual_cb = lqual;
memcpy(data_ind->data, data, len);
data_ind->len = len;
return pcu_sock_send(&bts_gsmnet, msg);
}
int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn,
uint8_t is_11bit, enum ph_burst_type burst_type)
{
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_rach_ind *rach_ind;
LOGP(DPCU, LOGL_INFO, "Sending RACH indication: qta=%d, ra=%d, "
"fn=%d\n", qta, ra, fn);
msg = pcu_msgb_alloc(PCU_IF_MSG_RACH_IND, bts->nr);
if (!msg)
return -ENOMEM;
pcu_prim = (struct gsm_pcu_if *) msg->data;
rach_ind = &pcu_prim->u.rach_ind;
rach_ind->sapi = PCU_IF_SAPI_RACH;
rach_ind->ra = ra;
rach_ind->qta = qta;
rach_ind->fn = fn;
rach_ind->is_11bit = is_11bit;
rach_ind->burst_type = burst_type;
return pcu_sock_send(&bts_gsmnet, msg);
}
int pcu_tx_time_ind(uint32_t fn)
{
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_time_ind *time_ind;
uint8_t fn13 = fn % 13;
/* omit frame numbers not starting at a MAC block */
if (fn13 != 0 && fn13 != 4 && fn13 != 8)
return 0;
msg = pcu_msgb_alloc(PCU_IF_MSG_TIME_IND, 0);
if (!msg)
return -ENOMEM;
pcu_prim = (struct gsm_pcu_if *) msg->data;
time_ind = &pcu_prim->u.time_ind;
time_ind->fn = fn;
return pcu_sock_send(&bts_gsmnet, msg);
}
int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed)
{
struct pcu_sock_state *state = bts_gsmnet.pcu_state;
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_pag_req *pag_req;
/* check if identity does not fit: length > sizeof(lv) - 1 */
if (identity_lv[0] >= sizeof(pag_req->identity_lv)) {
LOGP(DPCU, LOGL_ERROR, "Paging identity too large (%d)\n",
identity_lv[0]);
return -EINVAL;
}
/* socket not created */
if (!state) {
LOGP(DPCU, LOGL_DEBUG, "PCU socket not created, ignoring "
"paging message\n");
return 0;
}
msg = pcu_msgb_alloc(PCU_IF_MSG_PAG_REQ, 0);
if (!msg)
return -ENOMEM;
pcu_prim = (struct gsm_pcu_if *) msg->data;
pag_req = &pcu_prim->u.pag_req;
pag_req->chan_needed = chan_needed;
memcpy(pag_req->identity_lv, identity_lv, identity_lv[0] + 1);
return pcu_sock_send(&bts_gsmnet, msg);
}
int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len)
{
struct gsm_network *net = &bts_gsmnet;
struct gsm_bts *bts;
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_data *data_cnf;
/* FIXME: allow multiple BTS */
bts = llist_entry(net->bts_list.next, struct gsm_bts, list);
LOGP(DPCU, LOGL_INFO, "Sending PCH confirm\n");
msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_CNF, bts->nr);
if (!msg)
return -ENOMEM;
pcu_prim = (struct gsm_pcu_if *) msg->data;
data_cnf = &pcu_prim->u.data_cnf;
data_cnf->sapi = PCU_IF_SAPI_PCH;
data_cnf->fn = fn;
memcpy(data_cnf->data, data, len);
data_cnf->len = len;
return pcu_sock_send(&bts_gsmnet, msg);
}
static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
struct gsm_pcu_if_data *data_req)
{
uint8_t is_ptcch;
struct gsm_bts_trx *trx;
struct gsm_bts_trx_ts *ts;
struct msgb *msg;
int rc = 0;
LOGP(DPCU, LOGL_DEBUG, "Data request received: sapi=%s arfcn=%d "
"block=%d data=%s\n", sapi_string[data_req->sapi],
data_req->arfcn, data_req->block_nr,
osmo_hexdump(data_req->data, data_req->len));
switch (data_req->sapi) {
case PCU_IF_SAPI_BCCH:
if (data_req->len == 23) {
bts->si_valid |= (1 << SYSINFO_TYPE_13);
memcpy(bts->si_buf[SYSINFO_TYPE_13], data_req->data,
data_req->len);
} else {
bts->si_valid &= ~(1 << SYSINFO_TYPE_13);
}
osmo_signal_dispatch(SS_GLOBAL, S_NEW_SYSINFO, bts);
break;
case PCU_IF_SAPI_PCH:
if (msg_type == PCU_IF_MSG_PAG_REQ) {
/* FIXME: Add function to schedule paging request.
* This might not be required, if PCU_IF_MSG_DATA_REQ
* is used instead. */
} else {
struct gsm_bts_role_bts *btsb = bts->role;
paging_add_imm_ass(btsb->paging_state, data_req->data,
data_req->len);
}
break;
case PCU_IF_SAPI_AGCH:
msg = msgb_alloc(data_req->len, "pcu_agch");
if (!msg) {
rc = -ENOMEM;
break;
}
msg->l3h = msgb_put(msg, data_req->len);
memcpy(msg->l3h, data_req->data, data_req->len);
if (bts_agch_enqueue(bts, msg) < 0) {
msgb_free(msg);
rc = -EIO;
}
break;
case PCU_IF_SAPI_PDTCH:
case PCU_IF_SAPI_PTCCH:
trx = gsm_bts_trx_num(bts, data_req->trx_nr);
if (!trx) {
LOGP(DPCU, LOGL_ERROR, "Received PCU data request with "
"not existing TRX %d\n", data_req->trx_nr);
rc = -EINVAL;
break;
}
ts = &trx->ts[data_req->ts_nr];
is_ptcch = (data_req->sapi == PCU_IF_SAPI_PTCCH);
rc = l1sap_pdch_req(ts, is_ptcch, data_req->fn, data_req->arfcn,
data_req->block_nr, data_req->data, data_req->len);
break;
default:
LOGP(DPCU, LOGL_ERROR, "Received PCU data request with "
"unsupported sapi %d\n", data_req->sapi);
rc = -EINVAL;
}
return rc;
}
static int pcu_rx_txt_ind(struct gsm_bts *bts,
struct gsm_pcu_if_txt_ind *txt)
{
switch (txt->type) {
case PCU_VERSION:
LOGP(DPCU, LOGL_INFO, "OsmoPCU version %s connected\n",
txt->text);
osmo_signal_dispatch(SS_FAIL, OSMO_EVT_PCU_VERS, txt->text);
osmo_strlcpy(bts->pcu_version, txt->text, MAX_VERSION_LENGTH);
break;
case PCU_OML_ALERT:
osmo_signal_dispatch(SS_FAIL, OSMO_EVT_EXT_ALARM, txt->text);
break;
default:
LOGP(DPCU, LOGL_ERROR, "Unknown TXT_IND type %u received\n",
txt->type);
return -EINVAL;
}
return 0;
}
static int pcu_rx_act_req(struct gsm_bts *bts,
struct gsm_pcu_if_act_req *act_req)
{
struct gsm_bts_trx *trx;
struct gsm_lchan *lchan;
LOGP(DPCU, LOGL_INFO, "%s request received: TRX=%d TX=%d\n",
(act_req->activate) ? "Activate" : "Deactivate",
act_req->trx_nr, act_req->ts_nr);
trx = gsm_bts_trx_num(bts, act_req->trx_nr);
if (!trx || act_req->ts_nr >= 8)
return -EINVAL;
lchan = trx->ts[act_req->ts_nr].lchan;
lchan->rel_act_kind = LCHAN_REL_ACT_PCU;
if (lchan->type != GSM_LCHAN_PDTCH) {
LOGP(DPCU, LOGL_ERROR,
"%s request, but lchan is not of type PDTCH (is %s)\n",
(act_req->activate) ? "Activate" : "Deactivate",
gsm_lchant_name(lchan->type));
return -EINVAL;
}
if (act_req->activate)
l1sap_chan_act(trx, gsm_lchan2chan_nr(lchan), NULL);
else
l1sap_chan_rel(trx, gsm_lchan2chan_nr(lchan));
return 0;
}
static int pcu_rx(struct gsm_network *net, uint8_t msg_type,
struct gsm_pcu_if *pcu_prim)
{
int rc = 0;
struct gsm_bts *bts;
/* FIXME: allow multiple BTS */
bts = llist_entry(net->bts_list.next, struct gsm_bts, list);
switch (msg_type) {
case PCU_IF_MSG_DATA_REQ:
case PCU_IF_MSG_PAG_REQ:
rc = pcu_rx_data_req(bts, msg_type, &pcu_prim->u.data_req);
break;
case PCU_IF_MSG_ACT_REQ:
rc = pcu_rx_act_req(bts, &pcu_prim->u.act_req);
break;
case PCU_IF_MSG_TXT_IND:
rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind);
break;
default:
LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n",
msg_type);
rc = -EINVAL;
}
return rc;
}
/*
* PCU socket interface
*/
struct pcu_sock_state {
struct gsm_network *net;
struct osmo_fd listen_bfd; /* fd for listen socket */
struct osmo_fd conn_bfd; /* fd for connection to lcr */
struct llist_head upqueue; /* queue for sending messages */
};
static int pcu_sock_send(struct gsm_network *net, struct msgb *msg)
{
struct pcu_sock_state *state = net->pcu_state;
struct osmo_fd *conn_bfd;
struct gsm_pcu_if *pcu_prim = (struct gsm_pcu_if *) msg->data;
if (!state) {
if (pcu_prim->msg_type != PCU_IF_MSG_TIME_IND)
LOGP(DPCU, LOGL_INFO, "PCU socket not created, "
"dropping message\n");
msgb_free(msg);
return -EINVAL;
}
conn_bfd = &state->conn_bfd;
if (conn_bfd->fd <= 0) {
if (pcu_prim->msg_type != PCU_IF_MSG_TIME_IND)
LOGP(DPCU, LOGL_NOTICE, "PCU socket not connected, "
"dropping message\n");
msgb_free(msg);
return -EIO;
}
msgb_enqueue(&state->upqueue, msg);
conn_bfd->when |= BSC_FD_WRITE;
return 0;
}
static void pcu_sock_close(struct pcu_sock_state *state)
{
struct osmo_fd *bfd = &state->conn_bfd;
struct gsm_bts *bts;
struct gsm_bts_trx *trx;
struct gsm_bts_trx_ts *ts;
int i, j;
/* FIXME: allow multiple BTS */
bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list);
LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n");
osmo_signal_dispatch(SS_FAIL, OSMO_EVT_PCU_VERS, NULL);
bts->pcu_version[0] = '\0';
close(bfd->fd);
bfd->fd = -1;
osmo_fd_unregister(bfd);
/* re-enable the generation of ACCEPT for new connections */
state->listen_bfd.when |= BSC_FD_READ;
#if 0
/* remove si13, ... */
bts->si_valid &= ~(1 << SYSINFO_TYPE_13);
osmo_signal_dispatch(SS_GLOBAL, S_NEW_SYSINFO, bts);
#endif
/* release PDCH */
for (i = 0; i < 8; i++) {
trx = gsm_bts_trx_num(bts, i);
if (!trx)
break;
for (j = 0; j < 8; j++) {
ts = &trx->ts[j];
if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED
&& ts->pchan == GSM_PCHAN_PDCH) {
ts->lchan->rel_act_kind = LCHAN_REL_ACT_PCU;
l1sap_chan_rel(trx,
gsm_lchan2chan_nr(ts->lchan));
}
}
}
/* flush the queue */
while (!llist_empty(&state->upqueue)) {
struct msgb *msg = msgb_dequeue(&state->upqueue);
msgb_free(msg);
}
}
static int pcu_sock_read(struct osmo_fd *bfd)
{
struct pcu_sock_state *state = (struct pcu_sock_state *)bfd->data;
struct gsm_pcu_if *pcu_prim;
struct msgb *msg;
int rc;
msg = msgb_alloc(sizeof(*pcu_prim), "pcu_sock_rx");
if (!msg)
return -ENOMEM;
pcu_prim = (struct gsm_pcu_if *) msg->tail;
rc = recv(bfd->fd, msg->tail, msgb_tailroom(msg), 0);
if (rc == 0)
goto close;
if (rc < 0) {
if (errno == EAGAIN)
return 0;
goto close;
}
rc = pcu_rx(state->net, pcu_prim->msg_type, pcu_prim);
/* as we always synchronously process the message in pcu_rx() and
* its callbacks, we can free the message here. */
msgb_free(msg);
return rc;
close:
msgb_free(msg);
pcu_sock_close(state);
return -1;
}
static int pcu_sock_write(struct osmo_fd *bfd)
{
struct pcu_sock_state *state = bfd->data;
int rc;
while (!llist_empty(&state->upqueue)) {
struct msgb *msg, *msg2;
struct gsm_pcu_if *pcu_prim;
/* peek at the beginning of the queue */
msg = llist_entry(state->upqueue.next, struct msgb, list);
pcu_prim = (struct gsm_pcu_if *)msg->data;
bfd->when &= ~BSC_FD_WRITE;
/* bug hunter 8-): maybe someone forgot msgb_put(...) ? */
if (!msgb_length(msg)) {
LOGP(DPCU, LOGL_ERROR, "message type (%d) with ZERO "
"bytes!\n", pcu_prim->msg_type);
goto dontsend;
}
/* try to send it over the socket */
rc = write(bfd->fd, msgb_data(msg), msgb_length(msg));
if (rc == 0)
goto close;
if (rc < 0) {
if (errno == EAGAIN) {
bfd->when |= BSC_FD_WRITE;
break;
}
goto close;
}
dontsend:
/* _after_ we send it, we can deueue */
msg2 = msgb_dequeue(&state->upqueue);
assert(msg == msg2);
msgb_free(msg);
}
return 0;
close:
pcu_sock_close(state);
return -1;
}
static int pcu_sock_cb(struct osmo_fd *bfd, unsigned int flags)
{
int rc = 0;
if (flags & BSC_FD_READ)
rc = pcu_sock_read(bfd);
if (rc < 0)
return rc;
if (flags & BSC_FD_WRITE)
rc = pcu_sock_write(bfd);
return rc;
}
/* accept connection comming from PCU */
static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags)
{
struct pcu_sock_state *state = (struct pcu_sock_state *)bfd->data;
struct osmo_fd *conn_bfd = &state->conn_bfd;
struct sockaddr_un un_addr;
socklen_t len;
int rc;
len = sizeof(un_addr);
rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
if (rc < 0) {
LOGP(DPCU, LOGL_ERROR, "Failed to accept a new connection\n");
return -1;
}
if (conn_bfd->fd >= 0) {
LOGP(DPCU, LOGL_NOTICE, "PCU connects but we already have "
"another active connection ?!?\n");
/* We already have one PCU connected, this is all we support */
state->listen_bfd.when &= ~BSC_FD_READ;
close(rc);
return 0;
}
conn_bfd->fd = rc;
conn_bfd->when = BSC_FD_READ;
conn_bfd->cb = pcu_sock_cb;
conn_bfd->data = state;
if (osmo_fd_register(conn_bfd) != 0) {
LOGP(DPCU, LOGL_ERROR, "Failed to register new connection "
"fd\n");
close(conn_bfd->fd);
conn_bfd->fd = -1;
return -1;
}
LOGP(DPCU, LOGL_NOTICE, "PCU socket connected to external PCU\n");
/* send current info */
pcu_tx_info_ind();
return 0;
}
int pcu_sock_init(const char *path)
{
struct pcu_sock_state *state;
struct osmo_fd *bfd;
int rc;
state = talloc_zero(NULL, struct pcu_sock_state);
if (!state)
return -ENOMEM;
INIT_LLIST_HEAD(&state->upqueue);
state->net = &bts_gsmnet;
state->conn_bfd.fd = -1;
bfd = &state->listen_bfd;
bfd->fd = osmo_sock_unix_init(SOCK_SEQPACKET, 0, path,
OSMO_SOCK_F_BIND);
if (bfd->fd < 0) {
LOGP(DPCU, LOGL_ERROR, "Could not create %s unix socket: %s\n",
path, strerror(errno));
talloc_free(state);
return -1;
}
bfd->when = BSC_FD_READ;
bfd->cb = pcu_sock_accept;
bfd->data = state;
rc = osmo_fd_register(bfd);
if (rc < 0) {
LOGP(DPCU, LOGL_ERROR, "Could not register listen fd: %d\n",
rc);
close(bfd->fd);
talloc_free(state);
return rc;
}
osmo_signal_register_handler(SS_GLOBAL, pcu_if_signal_cb, NULL);
bts_gsmnet.pcu_state = state;
return 0;
}
void pcu_sock_exit(void)
{
struct pcu_sock_state *state = bts_gsmnet.pcu_state;
struct osmo_fd *bfd, *conn_bfd;
if (!state)
return;
osmo_signal_unregister_handler(SS_GLOBAL, pcu_if_signal_cb, NULL);
conn_bfd = &state->conn_bfd;
if (conn_bfd->fd > 0)
pcu_sock_close(state);
bfd = &state->listen_bfd;
close(bfd->fd);
osmo_fd_unregister(bfd);
talloc_free(state);
bts_gsmnet.pcu_state = NULL;
}
bool pcu_connected(void) {
struct gsm_network *net = &bts_gsmnet;
struct pcu_sock_state *state = net->pcu_state;
if (!state)
return false;
if (state->conn_bfd.fd <= 0)
return false;
return true;
}

163
src/common/phy_link.c Normal file
View File

@@ -0,0 +1,163 @@
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/talloc.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/phy_link.h>
#include <osmo-bts/oml.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/bts_model.h>
static LLIST_HEAD(g_phy_links);
struct phy_link *phy_link_by_num(int num)
{
struct phy_link *plink;
llist_for_each_entry(plink, &g_phy_links, list) {
if (plink->num == num)
return plink;
}
return NULL;
}
struct phy_link *phy_link_create(void *ctx, int num)
{
struct phy_link *plink;
if (phy_link_by_num(num))
return NULL;
plink = talloc_zero(ctx, struct phy_link);
plink->num = num;
plink->state = PHY_LINK_SHUTDOWN;
INIT_LLIST_HEAD(&plink->instances);
llist_add_tail(&plink->list, &g_phy_links);
bts_model_phy_link_set_defaults(plink);
return plink;
}
const struct value_string phy_link_state_vals[] = {
{ PHY_LINK_SHUTDOWN, "shutdown" },
{ PHY_LINK_CONNECTING, "connecting" },
{ PHY_LINK_CONNECTED, "connected" },
{ 0, NULL }
};
void phy_link_state_set(struct phy_link *plink, enum phy_link_state state)
{
struct phy_instance *pinst;
LOGP(DL1C, LOGL_INFO, "PHY link state change %s -> %s\n",
get_value_string(phy_link_state_vals, plink->state),
get_value_string(phy_link_state_vals, state));
/* notify all TRX associated with this phy */
llist_for_each_entry(pinst, &plink->instances, list) {
struct gsm_bts_trx *trx = pinst->trx;
if (!trx)
continue;
switch (state) {
case PHY_LINK_CONNECTED:
LOGP(DL1C, LOGL_INFO, "trx_set_avail(1)\n");
trx_set_available(trx, 1);
break;
case PHY_LINK_SHUTDOWN:
LOGP(DL1C, LOGL_INFO, "trx_set_avail(0)\n");
trx_set_available(trx, 0);
break;
case PHY_LINK_CONNECTING:
/* nothing to do */
break;
}
}
plink->state = state;
}
struct phy_instance *phy_instance_by_num(struct phy_link *plink, int num)
{
struct phy_instance *pinst;
llist_for_each_entry(pinst, &plink->instances, list) {
if (pinst->num == num)
return pinst;
}
return NULL;
}
struct phy_instance *phy_instance_create(struct phy_link *plink, int num)
{
struct phy_instance *pinst;
if (phy_instance_by_num(plink, num))
return NULL;
pinst = talloc_zero(plink, struct phy_instance);
pinst->num = num;
pinst->phy_link = plink;
llist_add_tail(&pinst->list, &plink->instances);
bts_model_phy_instance_set_defaults(pinst);
return pinst;
}
void phy_instance_link_to_trx(struct phy_instance *pinst, struct gsm_bts_trx *trx)
{
trx->role_bts.l1h = pinst;
pinst->trx = trx;
}
void phy_instance_destroy(struct phy_instance *pinst)
{
/* remove from list of instances in the link */
llist_del(&pinst->list);
/* remove reverse link from TRX */
OSMO_ASSERT(pinst->trx->role_bts.l1h == pinst);
pinst->trx->role_bts.l1h = NULL;
pinst->trx = NULL;
talloc_free(pinst);
}
void phy_link_destroy(struct phy_link *plink)
{
struct phy_instance *pinst, *pinst2;
llist_for_each_entry_safe(pinst, pinst2, &plink->instances, list)
phy_instance_destroy(pinst);
talloc_free(plink);
}
int phy_links_open(void)
{
struct phy_link *plink;
llist_for_each_entry(plink, &g_phy_links, list) {
int rc;
rc = bts_model_phy_link_open(plink);
if (rc < 0)
return rc;
}
return 0;
}
const char *phy_instance_name(struct phy_instance *pinst)
{
static char buf[32];
snprintf(buf, sizeof(buf), "phy%u.%u", pinst->phy_link->num,
pinst->num);
return buf;
}

Some files were not shown because too many files have changed in this diff Show More