Compare commits

...

743 Commits

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
227 changed files with 40957 additions and 2644 deletions

29
.gitignore vendored
View File

@@ -25,10 +25,21 @@ core.*
contrib/sysmobts-calib/sysmobts-calib contrib/sysmobts-calib/sysmobts-calib
src/osmo-bts-sysmo/l1fwd-proxy src/osmo-bts-sysmo/l1fwd-proxy
src/osmo-bts-sysmo/sysmobts src/osmo-bts-sysmo/osmo-bts-sysmo
src/osmo-bts-sysmo/sysmobts-remote src/osmo-bts-sysmo/osmo-bts-sysmo-remote
src/osmo-bts-sysmo/sysmobts-mgr 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/atconfig
tests/package.m4 tests/package.m4
@@ -37,6 +48,8 @@ tests/paging/paging_test
tests/cipher/cipher_test tests/cipher/cipher_test
tests/sysmobts/sysmobts_test tests/sysmobts/sysmobts_test
tests/misc/misc_test tests/misc/misc_test
tests/handover/handover_test
tests/tx_power/tx_power_test
tests/testsuite tests/testsuite
tests/testsuite.log tests/testsuite.log
@@ -44,6 +57,18 @@ tests/testsuite.log
doc/vty_reference.xml doc/vty_reference.xml
# Backups, vi, merges # Backups, vi, merges
*~
*.sw? *.sw?
*.orig *.orig
*.sav *.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

@@ -5,11 +5,24 @@ SUBDIRS = include src tests
# package the contrib and doc # package the contrib and doc
EXTRA_DIST = \ EXTRA_DIST = \
contrib/dump_docs.py contrib/screenrc-l1fwd contrib/sysmobts.service \ contrib/dump_docs.py contrib/screenrc-l1fwd contrib/osmo-bts-sysmo.service \
contrib/l1fwd.init contrib/screenrc-sysmobts contrib/respawn.sh \ contrib/l1fwd.init contrib/screenrc-sysmobts contrib/respawn.sh \
contrib/sysmobts.init contrib/sysmobts-calib/Makefile \ contrib/sysmobts.init contrib/sysmobts-calib/Makefile \
contrib/sysmobts-calib/sysmobts-calib.c \ contrib/sysmobts-calib/sysmobts-calib.c \
contrib/sysmobts-calib/sysmobts-layer1.c \ contrib/sysmobts-calib/sysmobts-layer1.c \
contrib/sysmobts-calib/sysmobts-layer1.h \ contrib/sysmobts-calib/sysmobts-layer1.h \
doc/examples/osmo-bts.cfg \ doc/examples/sysmo/osmo-bts.cfg \
doc/examples/sysmobts-mgr.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

59
README
View File

@@ -1,59 +0,0 @@
Repository for new the Osmocom BTS implementation.
This code implementes the 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.
Specificallt, 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.
Right now, only one hardware and Layer1 are supported: The sysmocom
sysmoBTS.
There is some experimental and way incomplete code to use a couple of
OsmocomBB phones and run them in the BTS. However, the required code
for the Calypso DSP code have not been written yet. This would still
require a lot of work.
Some additional work is being done in using some parts of the OpenBTS
L1FEC and glue it against omso-bts. However, this is also still in an
early, experimental stage.
== Known Limitations ==
As of June 3, 2012, 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
* No OML (TS 12.21) alarms yet (temperature, ...)
* Only single-TRX BTS at this point
* 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 hand-over support (planned)
* 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)
* No GPRS/EDGE support (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
* Makes no use of TS 12.21 T3105
* Doesn't yet include MAC address in Abis/IP Identity message
* 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.

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,18 +3,32 @@ AC_INIT([osmo-bts],
m4_esyscmd([./git-version-gen .tarball-version]), m4_esyscmd([./git-version-gen .tarball-version]),
[openbsc-devel@lists.openbsc.org]) [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]) AM_INIT_AUTOMAKE([dist-bzip2])
AC_CONFIG_TESTDIR(tests) AC_CONFIG_TESTDIR(tests)
dnl kernel style compile messages dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl include release helper
RELMAKE='-include osmo-release.mk'
AC_SUBST([RELMAKE])
dnl checks for programs dnl checks for programs
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
AC_PROG_CC AC_PROG_CC
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_RANLIB 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 dnl checks for header files
AC_HEADER_STDC AC_HEADER_STDC
@@ -23,18 +37,115 @@ dnl Checks for typedefs, structures and compiler characteristics
dnl checks for libraries dnl checks for libraries
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.9) PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.9)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty) 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(LIBOSMOGSM, libosmogsm >= 0.3.3)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl) PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl)
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis) 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_ARG_ENABLE(sysmocom-bts,
AC_HELP_STRING([--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"]) [enable_sysmocom_bts="yes"],[enable_sysmocom_bts="no"])
AC_MSG_RESULT([$enable_sysmocom_bts]) AC_MSG_RESULT([$enable_sysmocom_bts])
AM_CONDITIONAL(ENABLE_SYSMOBTS, test "x$enable_sysmocom_bts" = "xyes") 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 # We share gsm_data.h with OpenBSC and need to be pointed to the source
# directory of OpenBSC for now. # directory of OpenBSC for now.
@@ -68,7 +179,11 @@ AM_CONFIG_HEADER(btsconfig.h)
AC_OUTPUT( AC_OUTPUT(
src/Makefile src/Makefile
src/common/Makefile src/common/Makefile
src/osmo-bts-virtual/Makefile
src/osmo-bts-sysmo/Makefile src/osmo-bts-sysmo/Makefile
src/osmo-bts-litecell15/Makefile
src/osmo-bts-trx/Makefile
src/osmo-bts-octphy/Makefile
include/Makefile include/Makefile
include/osmo-bts/Makefile include/osmo-bts/Makefile
tests/Makefile tests/Makefile
@@ -77,4 +192,7 @@ AC_OUTPUT(
tests/cipher/Makefile tests/cipher/Makefile
tests/sysmobts/Makefile tests/sysmobts/Makefile
tests/misc/Makefile tests/misc/Makefile
tests/handover/Makefile
tests/tx_power/Makefile
tests/meas/Makefile
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."
}

View File

@@ -10,7 +10,7 @@ env = os.environ
env['L1FWD_BTS_HOST'] = '127.0.0.1' env['L1FWD_BTS_HOST'] = '127.0.0.1'
bts_proc = subprocess.Popen(["./src/osmo-bts-sysmo/sysmobts-remote", bts_proc = subprocess.Popen(["./src/osmo-bts-sysmo/sysmobts-remote",
"-c", "./doc/examples/osmo-bts.cfg"], env = env, "-c", "./doc/examples/sysmo/osmo-bts.cfg"], env = env,
stdin=None, stdout=None) stdin=None, stdout=None)
time.sleep(1) time.sleep(1)

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

View File

@@ -1,5 +1,5 @@
chdir /tmp chdir /tmp
screen -t BTS 0 /etc/osmocom/respawn.sh /usr/bin/sysmobts -c /etc/osmocom/osmo-bts.cfg -r 1 -M 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 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 screen -t MGR 2 /etc/osmocom/respawn-only.sh /usr/bin/sysmobts-mgr -n -c /etc/osmocom/sysmobts-mgr.cfg
detach 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

@@ -310,19 +310,36 @@ int print_system_info()
#ifdef FEMTOBTS_NO_BOARD_VERSION #ifdef FEMTOBTS_NO_BOARD_VERSION
#define BOARD_REV(x) -1 #define BOARD_REV(x) -1
#define BOARD_OPT(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 #else
#define BOARD_REV(x) x.u.systemInfoCnf.boardVersion.rev #define BOARD_REV(x) x.u.systemInfoCnf.boardVersion.rev
#define BOARD_OPT(x) x.u.systemInfoCnf.boardVersion.option #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 #endif
printf("DSP v%d.%d.%d FPGA v%d.%d.%d Rev: %d Option: %d\n", 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_DSP(prim).major, INFO_DSP(prim).minor, INFO_DSP(prim).build,
INFO_FPGA(prim).major, INFO_FPGA(prim).minor, INFO_FPGA(prim).build, INFO_FPGA(prim).major, INFO_FPGA(prim).minor, INFO_FPGA(prim).build,
BOARD_REV(prim), BOARD_OPT(prim)); 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_DSP
#undef INFO_FPGA #undef INFO_FPGA
#undef BOARD_REV #undef BOARD_REV
#undef BOARD_OPT #undef BOARD_OPT
#undef COMPILED_MAJOR
#undef COMPILED_MINOR
#undef COMPILED_BUILD
return 0; return 0;
} }

View File

@@ -1,5 +1,5 @@
[Unit] [Unit]
Description=sysmocom sysmoBTS manager Description=osmo-bts manager for sysmoBTS
[Service] [Service]
Type=simple Type=simple
@@ -9,4 +9,4 @@ RestartSec=2
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
Alias=osmo-bts-mgr.service

View File

@@ -4,7 +4,7 @@ Description=sysmocom sysmoBTS
[Service] [Service]
Type=simple Type=simple
ExecStartPre=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness' ExecStartPre=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness'
ExecStart=/usr/bin/sysmobts -s -c /etc/osmocom/osmo-bts.cfg -M 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 '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' 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 Restart=always
@@ -17,3 +17,4 @@ CPUSchedulingPriority=1
[Install] [Install]
WantedBy=multi-user.target 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)

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

@@ -0,0 +1,31 @@
!
! 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:90:2e:80:1e
octphy net-device eth0.2342
instance 0
bts 0
band 1800
ipa unit-id 1234 0
oml remote-ip 127.0.0.1
trx 0
phy 0 instance 0

View File

@@ -3,9 +3,8 @@
!! !!
! !
log stderr log stderr
logging color 0 logging color 1
logging timestamp 0 logging timestamp 0
logging level all everything
logging level rsl info logging level rsl info
logging level oml info logging level oml info
logging level rll notice logging level rll notice
@@ -14,13 +13,17 @@ log stderr
logging level pag info logging level pag info
logging level l1c info logging level l1c info
logging level l1p info logging level l1p info
logging level dsp debug logging level dsp info
logging level abis notice logging level abis notice
! !
line vty line vty
no login no login
! !
phy 0
instance 0
bts 0 bts 0
band 1800 band 1800
ipa unit-id 1234 0 ipa unit-id 666 0
oml remote-ip 192.168.100.11 oml remote-ip 10.1.2.3
trx 0
phy 0 instance 0

View File

@@ -6,7 +6,6 @@ log stderr
logging filter all 1 logging filter all 1
logging color 1 logging color 1
logging timestamp 0 logging timestamp 0
logging level all everything
logging level temp info logging level temp info
logging level fw info logging level fw info
logging level find info logging level find info

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,3 +1,5 @@
noinst_HEADERS = abis.h bts.h bts_model.h gsm_data.h logging.h measurement.h \ 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 amr.h pcu_if.h pcuif_proto.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 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

@@ -11,7 +11,8 @@ void amr_log_mr_conf(int ss, int logl, const char *pfx,
int amr_parse_mr_conf(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); 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); unsigned int amr_get_initial_mode(struct gsm_lchan *lchan);
#endif /* _OSMO_BTS_AMR_H */ #endif /* _OSMO_BTS_AMR_H */

View File

@@ -21,23 +21,29 @@ void destroy_bts(struct gsm_bts *bts);
int work_bts(struct gsm_bts *bts); int work_bts(struct gsm_bts *bts);
int bts_link_estab(struct gsm_bts *bts); int bts_link_estab(struct gsm_bts *bts);
int trx_link_estab(struct gsm_bts_trx *trx); 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_new_si(void *arg);
void bts_setup_slot(struct gsm_bts_trx_ts *slot, uint8_t comb); void bts_setup_slot(struct gsm_bts_trx_ts *slot, uint8_t comb);
int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg); int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg);
struct msgb *bts_agch_dequeue(struct gsm_bts *bts); struct msgb *bts_agch_dequeue(struct gsm_bts *bts);
void bts_update_agch_max_queue_length(struct gsm_bts *bts);
int bts_agch_max_queue_length(int T, int bcch_conf); 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 bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
int is_ag_res); int is_ag_res);
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, 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); uint8_t *lchan_sacch_get(struct gsm_lchan *lchan);
int lchan_init_lapdm(struct gsm_lchan *lchan); int lchan_init_lapdm(struct gsm_lchan *lchan);
void load_timer_start(struct gsm_bts *bts); 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); 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 */ #endif /* _BTS_H */

View File

@@ -8,12 +8,13 @@
#include <osmo-bts/gsm_data.h> #include <osmo-bts/gsm_data.h>
struct phy_link;
struct phy_instance;
/* BTS model specific functions needed by the common code */ /* BTS model specific functions needed by the common code */
int bts_model_init(struct gsm_bts *bts); 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, int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type,
struct tlv_parsed *old_attr, struct tlv_parsed *new_attr, struct tlv_parsed *old_attr, struct tlv_parsed *new_attr,
void *obj); void *obj);
@@ -27,25 +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, int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo,
void *obj, uint8_t adm_state); 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_chan_mod(struct gsm_lchan *lchan);
int bts_model_rsl_deact_sacch(struct gsm_lchan *lchan);
int bts_model_rsl_mode_modify(struct gsm_lchan *lchan);
int bts_model_trx_deact_rf(struct gsm_bts_trx *trx); int bts_model_trx_deact_rf(struct gsm_bts_trx *trx);
int bts_model_trx_close(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, const uint8_t *rtp_pl,
unsigned int rtp_pl_len);
int bts_model_vty_init(struct gsm_bts *bts); 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_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_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_oml_estab(struct gsm_bts *bts);
int bts_model_change_power(struct gsm_bts_trx *trx, int p_trxout_mdBm); 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 #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

@@ -1,4 +1,5 @@
#pragma once #pragma once
int bts_ctrl_cmds_install(struct gsm_bts *bts); int bts_ctrl_cmds_install(struct gsm_bts *bts);
struct ctrl_handle *bts_controlif_setup(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

@@ -8,12 +8,23 @@
#include <osmo-bts/paging.h> #include <osmo-bts/paging.h>
#include <osmo-bts/tx_power.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_DEFAULT 41
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE 999999 #define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE 999999
#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41 #define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41
#define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91 #define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91
struct pcu_sock_state; struct pcu_sock_state;
struct smscb_msg;
struct gsm_network { struct gsm_network {
struct llist_head bts_list; struct llist_head bts_list;
@@ -73,45 +84,66 @@ struct gsm_bts_role_bts {
struct paging_state *paging_state; struct paging_state *paging_state;
char *bsc_oml_host; char *bsc_oml_host;
struct llist_head oml_queue;
unsigned int rtp_jitter_buf_ms; unsigned int rtp_jitter_buf_ms;
bool rtp_jitter_adaptive;
struct { struct {
uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */ uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
} support; } support;
struct { struct {
uint8_t tc4_ctr; uint8_t tc4_ctr;
} si; } si;
uint8_t radio_link_timeout; 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 */ /* used by the sysmoBTS to adjust band */
uint8_t auto_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 { enum lchan_ciph_state {
LCHAN_CIPH_NONE, LCHAN_CIPH_NONE,
LCHAN_CIPH_RX_REQ, LCHAN_CIPH_RX_REQ,
LCHAN_CIPH_RX_CONF, LCHAN_CIPH_RX_CONF,
LCHAN_CIPH_TXRX_REQ, LCHAN_CIPH_RXTX_REQ,
LCHAN_CIPH_TXRX_CONF, LCHAN_CIPH_RX_CONF_TX_REQ,
LCHAN_CIPH_RXTX_CONF,
}; };
#define bts_role_bts(x) ((struct gsm_bts_role_bts *)(x)->role) #define bts_role_bts(x) ((struct gsm_bts_role_bts *)(x)->role)
#include "openbsc/gsm_data_shared.h" #include "openbsc/gsm_data_shared.h"
struct femtol1_hdl;
static inline struct femtol1_hdl *trx_femtol1_hdl(struct gsm_bts_trx *trx)
{
return trx->role_bts.l1h;
}
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state); 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);
/* cipher code */ /* cipher code */
#define CIPHER_A5(x) (1 << (x-1)) #define CIPHER_A5(x) (1 << (x-1))
int bts_supports_cipher(struct gsm_bts_role_bts *bts, int rsl_cipher); 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 */ #endif /* _GSM_DATA_H */

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

@@ -16,6 +16,8 @@ enum {
DDSP, DDSP,
DPCU, DPCU,
DHO, DHO,
DTRX,
DLOOP,
DABIS, DABIS,
DRTP, DRTP,
DSUM, DSUM,

View File

@@ -1,11 +1,11 @@
#ifndef OSMO_BTS_MEAS_H #ifndef OSMO_BTS_MEAS_H
#define 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_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm);
int trx_meas_check_compute(struct gsm_bts_trx *trx, uint32_t fn); int lchan_meas_check_compute(struct gsm_lchan *lchan, 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 #endif

View File

@@ -4,8 +4,24 @@
#pragma once #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; 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 * Classification of OML message. ETSI for plain GSM 12.21
* messages and IPA/Osmo for manufacturer messages. * messages and IPA/Osmo for manufacturer messages.
@@ -16,5 +32,17 @@ enum {
OML_MSG_TYPE_OSMO, 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_ipa_structure(struct msgb *msg);
int msg_verify_oml_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg);

View File

@@ -1,12 +1,15 @@
#ifndef _OML_H #ifndef _OML_H
#define _OML_H #define _OML_H
#include <osmocom/gsm/protocol/gsm_12_21.h>
struct gsm_bts; struct gsm_bts;
struct gsm_abis_mo; struct gsm_abis_mo;
struct msgb; struct msgb;
struct gsm_lchan;
int oml_init(void); int oml_init(struct gsm_abis_mo *mo);
int down_oml(struct gsm_bts *bts, struct msgb *msg); int down_oml(struct gsm_bts *bts, struct msgb *msg);
struct msgb *oml_msgb_alloc(void); struct msgb *oml_msgb_alloc(void);
@@ -37,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, int oml_mo_fom_ack_nack(struct gsm_abis_mo *mo, uint8_t orig_msg_type,
uint8_t cause); 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 */ #endif // _OML_H */

View File

@@ -1,18 +1,25 @@
#ifndef _PCU_IF_H #ifndef _PCU_IF_H
#define _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_info_ind(void);
int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, 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); 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, 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, uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len,
int8_t rssi); int8_t rssi, uint16_t ber10k, int16_t bto, int16_t lqual);
int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint8_t ra, uint32_t fn); 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_time_ind(uint32_t fn);
int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed); int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed);
int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len); int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len);
int pcu_sock_init(void); int pcu_sock_init(const char *path);
void pcu_sock_exit(void); void pcu_sock_exit(void);
bool pcu_connected(void);
#endif /* _PCU_IF_H */ #endif /* _PCU_IF_H */

View File

@@ -1,7 +1,10 @@
#ifndef _PCUIF_PROTO_H #ifndef _PCUIF_PROTO_H
#define _PCUIF_PROTO_H #define _PCUIF_PROTO_H
#define PCU_IF_VERSION 0x05 #include <osmocom/gsm/l1sap.h>
#define PCU_IF_VERSION 0x07
#define TXT_MAX_LEN 128
/* msg_type */ /* msg_type */
#define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */ #define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */
@@ -13,6 +16,7 @@
#define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */ #define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */
#define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */ #define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */
#define PCU_IF_MSG_PAG_REQ 0x60 /* paging request */ #define PCU_IF_MSG_PAG_REQ 0x60 /* paging request */
#define PCU_IF_MSG_TXT_IND 0x70 /* Text indication for BTS */
/* sapi */ /* sapi */
#define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */ #define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */
@@ -40,6 +44,16 @@
#define PCU_IF_FLAG_MCS8 (1 << 27) #define PCU_IF_FLAG_MCS8 (1 << 27)
#define PCU_IF_FLAG_MCS9 (1 << 28) #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 { struct gsm_pcu_if_data {
uint8_t sapi; uint8_t sapi;
uint8_t len; uint8_t len;
@@ -50,6 +64,9 @@ struct gsm_pcu_if_data {
uint8_t ts_nr; uint8_t ts_nr;
uint8_t block_nr; uint8_t block_nr;
int8_t rssi; 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)); } __attribute__ ((packed));
struct gsm_pcu_if_rts_req { struct gsm_pcu_if_rts_req {
@@ -64,10 +81,12 @@ struct gsm_pcu_if_rts_req {
struct gsm_pcu_if_rach_ind { struct gsm_pcu_if_rach_ind {
uint8_t sapi; uint8_t sapi;
uint8_t ra; uint16_t ra;
int16_t qta; int16_t qta;
uint32_t fn; uint32_t fn;
uint16_t arfcn; uint16_t arfcn;
uint8_t is_11bit;
uint8_t burst_type;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct gsm_pcu_if_info_trx { struct gsm_pcu_if_info_trx {
@@ -143,6 +162,7 @@ struct gsm_pcu_if {
struct gsm_pcu_if_data data_ind; struct gsm_pcu_if_data data_ind;
struct gsm_pcu_if_rts_req rts_req; struct gsm_pcu_if_rts_req rts_req;
struct gsm_pcu_if_rach_ind rach_ind; 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_info_ind info_ind;
struct gsm_pcu_if_act_req act_req; struct gsm_pcu_if_act_req act_req;
struct gsm_pcu_if_time_ind time_ind; struct gsm_pcu_if_time_ind time_ind;

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

@@ -9,20 +9,27 @@ enum {
LCHAN_REL_ACT_RSL, LCHAN_REL_ACT_RSL,
LCHAN_REL_ACT_PCU, LCHAN_REL_ACT_PCU,
LCHAN_REL_ACT_OML, 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 down_rsl(struct gsm_bts_trx *trx, struct msgb *msg);
int rsl_tx_rf_res(struct gsm_bts_trx *trx); int rsl_tx_rf_res(struct gsm_bts_trx *trx);
int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime, int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime,
uint8_t ra, uint8_t acc_delay); 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_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_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause);
int rsl_tx_conn_fail(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_rf_rel_ack(struct gsm_lchan *lchan);
int rsl_tx_hando_det(struct gsm_lchan *lchan, uint8_t *ho_delay); 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 */ /* 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 lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx);
@@ -31,7 +38,9 @@ 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, int rsl_tx_ccch_load_ind_rach(struct gsm_bts *bts, uint16_t total,
uint16_t busy, uint16_t access); 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 */ #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,6 +5,7 @@
enum sig_subsys { enum sig_subsys {
SS_GLOBAL, SS_GLOBAL,
SS_FAIL,
}; };
enum signals_global { enum signals_global {

View File

@@ -8,7 +8,7 @@
/* PA calibration table */ /* PA calibration table */
struct pa_calibration { struct pa_calibration {
int gain_mdB[1024]; /* gain provided at given ARFCN */ int delta_mdB[1024]; /* gain delta at given ARFCN */
/* FIXME: thermal calibration */ /* FIXME: thermal calibration */
}; };
@@ -74,3 +74,5 @@ 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); 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); 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,17 +5,27 @@
#include <osmocom/vty/command.h> #include <osmocom/vty/command.h>
enum bts_vty_node { 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, TRX_NODE,
}; };
extern struct cmd_element ournode_exit_cmd; extern struct cmd_element ournode_exit_cmd;
extern struct cmd_element ournode_end_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_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; extern struct vty_app_info bts_vty_info;

View File

@@ -1,5 +1,17 @@
SUBDIRS = common SUBDIRS = common osmo-bts-virtual
if ENABLE_SYSMOBTS if ENABLE_SYSMOBTS
SUBDIRS += osmo-bts-sysmo SUBDIRS += osmo-bts-sysmo
endif 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,10 +1,17 @@
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR)
AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS)
LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) 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 \ 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 amr.c lchan.c \ rsl.c vty.c paging.c measurement.c amr.c lchan.c \
load_indication.c pcu_sock.c handover.c msg_utils.c \ load_indication.c pcu_sock.c handover.c msg_utils.c \
load_indication.c pcu_sock.c handover.c msg_utils.c \ tx_power.c bts_ctrl_commands.c bts_ctrl_lookup.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

@@ -47,17 +47,38 @@
#include <osmo-bts/bts.h> #include <osmo-bts/bts.h>
#include <osmo-bts/rsl.h> #include <osmo-bts/rsl.h>
#include <osmo-bts/oml.h> #include <osmo-bts/oml.h>
#include <osmo-bts/bts_model.h>
static struct gsm_bts *g_bts; static struct gsm_bts *g_bts;
int abis_oml_sendmsg(struct msgb *msg) int abis_oml_sendmsg(struct msgb *msg)
{ {
struct gsm_bts *bts = msg->trx->bts; struct gsm_bts *bts = msg->trx->bts;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
/* osmo-bts uses msg->trx internally, but libosmo-abis uses if (!bts->oml_link) {
* the signalling link at msg->dst */ llist_add_tail(&msg->list, &btsb->oml_queue);
msg->dst = bts->oml_link; return 0;
return abis_sendmsg(msg); } 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);
}
}
static void drain_oml_queue(struct gsm_bts *bts)
{
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct msgb *msg, *msg2;
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);
}
} }
int abis_bts_rsl_sendmsg(struct msgb *msg) int abis_bts_rsl_sendmsg(struct msgb *msg)
@@ -72,6 +93,8 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
enum e1inp_sign_type type) enum e1inp_sign_type type)
{ {
struct e1inp_sign_link *sign_link = NULL; struct e1inp_sign_link *sign_link = NULL;
struct gsm_bts_trx *trx;
int trx_nr;
switch (type) { switch (type) {
case E1INP_SIGN_OML: case E1INP_SIGN_OML:
@@ -80,20 +103,26 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
sign_link = g_bts->oml_link = sign_link = g_bts->oml_link =
e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML-1], e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML-1],
E1INP_SIGN_OML, NULL, 255, 0); E1INP_SIGN_OML, NULL, 255, 0);
drain_oml_queue(g_bts);
sign_link->trx = g_bts->c0; sign_link->trx = g_bts->c0;
bts_link_estab(g_bts); bts_link_estab(g_bts);
break; break;
case E1INP_SIGN_RSL:
LOGP(DABIS, LOGL_INFO, "RSL Signalling link up\n");
e1inp_ts_config_sign(&line->ts[E1INP_SIGN_RSL-1], line);
sign_link = g_bts->c0->rsl_link =
e1inp_sign_link_create(&line->ts[E1INP_SIGN_RSL-1],
E1INP_SIGN_RSL, NULL, 0, 0);
/* FIXME: This assumes there is only one TRX! */
sign_link->trx = g_bts->c0;
trx_link_estab(sign_link->trx);
break;
default: default:
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; break;
} }
@@ -102,19 +131,23 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
static void sign_link_down(struct e1inp_line *line) static void sign_link_down(struct e1inp_line *line)
{ {
struct gsm_bts_trx *trx;
LOGP(DABIS, LOGL_ERROR, "Signalling link down\n"); LOGP(DABIS, LOGL_ERROR, "Signalling link down\n");
if (g_bts->c0->rsl_link) { /* First remove the OML signalling link */
e1inp_sign_link_destroy(g_bts->c0->rsl_link);
g_bts->c0->rsl_link = NULL;
trx_link_estab(g_bts->c0);
}
if (g_bts->oml_link) if (g_bts->oml_link)
e1inp_sign_link_destroy(g_bts->oml_link); e1inp_sign_link_destroy(g_bts->oml_link);
g_bts->oml_link = NULL; g_bts->oml_link = NULL;
bts_shutdown(g_bts, "Abis close"); /* 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;
}
}
bts_model_abis_close(g_bts);
} }
@@ -202,8 +235,7 @@ void abis_init(struct gsm_bts *bts)
{ {
g_bts = bts; g_bts = bts;
oml_init(); oml_init(&bts->mo);
e1inp_vty_init();
libosmo_abis_init(NULL); libosmo_abis_init(NULL);
osmo_signal_register_handler(SS_L_INPUT, &inp_s_cbfn, bts); osmo_signal_register_handler(SS_L_INPUT, &inp_s_cbfn, bts);

View File

@@ -16,11 +16,62 @@ void amr_log_mr_conf(int ss, int logl, const char *pfx,
for (i = 0; i < amr_mrc->num_modes; i++) for (i = 0; i < amr_mrc->num_modes; i++)
LOGPC(ss, logl, ", mode[%u] = %u/%u/%u", LOGPC(ss, logl, ", mode[%u] = %u/%u/%u",
i, amr_mrc->mode[i].mode, amr_mrc->mode[i].threshold, i, amr_mrc->bts_mode[i].mode,
amr_mrc->mode[i].hysteresis); amr_mrc->bts_mode[i].threshold,
amr_mrc->bts_mode[i].hysteresis);
LOGPC(ss, logl, "\n"); 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 /* parse a GSM 04.08 MultiRate Config IE (10.5.2.21aa) in a more
* comfortable internal data structure */ * comfortable internal data structure */
@@ -32,7 +83,7 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
int i, j = 0; int i, j = 0;
if (mr_version != 1) { if (mr_version != 1) {
LOGP(DRSL, LOGL_ERROR, "AMR Multirate Version %u unknonw\n", LOGP(DRSL, LOGL_ERROR, "AMR Multirate Version %u unknown\n",
mr_version); mr_version);
goto ret_einval; goto ret_einval;
} }
@@ -63,23 +114,23 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (mr_conf[1] & (1 << i)) { if (mr_conf[1] & (1 << i)) {
amr_mrc->mode[j++].mode = i; amr_mrc->bts_mode[j++].mode = i;
} }
} }
if (num_codecs >= 2) { if (num_codecs >= 2) {
amr_mrc->mode[0].threshold = mr_conf[1] & 0x3F; amr_mrc->bts_mode[0].threshold = mr_conf[1] & 0x3F;
amr_mrc->mode[0].hysteresis = mr_conf[2] >> 4; amr_mrc->bts_mode[0].hysteresis = mr_conf[2] >> 4;
} }
if (num_codecs >= 3) { if (num_codecs >= 3) {
amr_mrc->mode[1].threshold = amr_mrc->bts_mode[1].threshold =
((mr_conf[2] & 0xF) << 2) | (mr_conf[3] >> 6); ((mr_conf[2] & 0xF) << 2) | (mr_conf[3] >> 6);
amr_mrc->mode[1].hysteresis = (mr_conf[3] >> 2) & 0x7; amr_mrc->bts_mode[1].hysteresis = (mr_conf[3] >> 2) & 0xF;
} }
if (num_codecs >= 4) { if (num_codecs >= 4) {
amr_mrc->mode[3].threshold = amr_mrc->bts_mode[2].threshold =
((mr_conf[3] & 0x3) << 4) | (mr_conf[4] >> 4); ((mr_conf[3] & 0x3) << 4) | (mr_conf[4] >> 4);
amr_mrc->mode[3].hysteresis = mr_conf[4] & 0xF; amr_mrc->bts_mode[2].hysteresis = mr_conf[4] & 0xF;
} }
return num_codecs; return num_codecs;
@@ -94,10 +145,12 @@ ret_einval:
unsigned int amr_get_initial_mode(struct gsm_lchan *lchan) unsigned int amr_get_initial_mode(struct gsm_lchan *lchan)
{ {
struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; 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 (lchan->mr_conf.icmi) { if (mr_conf->icmi) {
/* initial mode given, coding in TS 05.09 3.4.1 */ /* initial mode given, coding in TS 05.09 3.4.1 */
return lchan->mr_conf.smod; return mr_conf->smod;
} else { } else {
/* implicit rule according to TS 05.09 Chapter 3.4.3 */ /* implicit rule according to TS 05.09 Chapter 3.4.3 */
switch (amr_mrc->num_modes) { switch (amr_mrc->num_modes) {

View File

@@ -40,10 +40,17 @@
#include <osmo-bts/abis.h> #include <osmo-bts/abis.h>
#include <osmo-bts/bts.h> #include <osmo-bts/bts.h>
#include <osmo-bts/bts_model.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/rsl.h>
#include <osmo-bts/oml.h> #include <osmo-bts/oml.h>
#include <osmo-bts/signal.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 = { struct gsm_network bts_gsmnet = {
.bts_list = { &bts_gsmnet.bts_list, &bts_gsmnet.bts_list }, .bts_list = { &bts_gsmnet.bts_list, &bts_gsmnet.bts_list },
@@ -72,12 +79,15 @@ static int bts_signal_cbfn(unsigned int subsys, unsigned int signal,
return 0; return 0;
} }
/* Initialize the BTS (and TRX) data structures, called before config
* file reading */
int bts_init(struct gsm_bts *bts) int bts_init(struct gsm_bts *bts)
{ {
struct gsm_bts_role_bts *btsb; struct gsm_bts_role_bts *btsb;
struct gsm_bts_trx *trx; struct gsm_bts_trx *trx;
int rc; int rc, i;
static int initialized = 0; static int initialized = 0;
void *tall_rtp_ctx;
/* add to list of BTSs */ /* add to list of BTSs */
llist_add_tail(&bts->list, &bts_gsmnet.bts_list); llist_add_tail(&bts->list, &bts_gsmnet.bts_list);
@@ -99,6 +109,8 @@ int bts_init(struct gsm_bts *bts)
/* configurable via VTY */ /* configurable via VTY */
btsb->paging_state = paging_init(btsb, 200, 0); btsb->paging_state = paging_init(btsb, 200, 0);
btsb->ul_power_target = -75; /* dBm default */
btsb->rtp_jitter_adaptive = false;
/* configurable via OML */ /* configurable via OML */
btsb->load.ccch.load_ind_period = 112; btsb->load.ccch.load_ind_period = 112;
@@ -107,6 +119,11 @@ int bts_init(struct gsm_bts *bts)
btsb->max_ta = 63; btsb->max_ta = 63;
btsb->ny1 = 4; btsb->ny1 = 4;
btsb->t3105_ms = 300; 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 */ /* default RADIO_LINK_TIMEOUT */
btsb->radio_link_timeout = 32; btsb->radio_link_timeout = 32;
@@ -136,12 +153,15 @@ int bts_init(struct gsm_bts *bts)
} }
} }
/* Default values for the power adjustments */ /* Default values for the power adjustments */
tpp->ramp.max_initial_pout_mdBm = to_mdB(23); tpp->ramp.max_initial_pout_mdBm = to_mdB(0);
tpp->ramp.step_size_mdB = to_mdB(2); tpp->ramp.step_size_mdB = to_mdB(2);
tpp->ramp.step_interval_sec = 1; 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); rc = bts_model_init(bts);
if (rc < 0) { if (rc < 0) {
@@ -156,6 +176,11 @@ int bts_init(struct gsm_bts *bts)
initialized = 1; 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; return rc;
} }
@@ -182,7 +207,7 @@ void bts_shutdown(struct gsm_bts *bts, const char *reason)
LOGP(DOML, LOGL_NOTICE, "Shutting down BTS %u, Reason %s\n", LOGP(DOML, LOGL_NOTICE, "Shutting down BTS %u, Reason %s\n",
bts->nr, reason); 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_deact_rf(trx);
bts_model_trx_close(trx); bts_model_trx_close(trx);
} }
@@ -231,6 +256,7 @@ int trx_link_estab(struct gsm_bts_trx *trx)
{ {
struct e1inp_sign_link *link = trx->rsl_link; struct e1inp_sign_link *link = trx->rsl_link;
uint8_t radio_state = link ? NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED; 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", LOGP(DSUM, LOGL_INFO, "RSL link (TRX %02x) state changed to %s, sending Status'.\n",
trx->nr, link ? "up" : "down"); trx->nr, link ? "up" : "down");
@@ -238,8 +264,38 @@ int trx_link_estab(struct gsm_bts_trx *trx)
oml_mo_state_chg(&trx->mo, radio_state, NM_AVSTATE_OK); oml_mo_state_chg(&trx->mo, radio_state, NM_AVSTATE_OK);
if (link) if (link)
rsl_tx_rf_res(trx); 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;
}
/* set the availability of the TRX (used by PHY driver) */
int trx_set_available(struct gsm_bts_trx *trx, int avail)
{
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
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; return 0;
} }
@@ -251,6 +307,7 @@ int lchan_init_lapdm(struct gsm_lchan *lchan)
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY); lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY);
lapdm_channel_set_l1(lc, NULL, lchan); lapdm_channel_set_l1(lc, NULL, lchan);
lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan); lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan);
oml_set_lchan_t200(lchan);
return 0; return 0;
} }
@@ -297,7 +354,7 @@ int bts_agch_max_queue_length(int T, int bcch_conf)
return (T + 2 * S) * ccch_rach_ratio256 / 256; return (T + 2 * S) * ccch_rach_ratio256 / 256;
} }
void bts_update_agch_max_queue_length(struct gsm_bts *bts) static void bts_update_agch_max_queue_length(struct gsm_bts *bts)
{ {
struct gsm_bts_role_bts *btsb = bts_role_bts(bts); struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct gsm48_system_information_type_3 *si3; struct gsm48_system_information_type_3 *si3;
@@ -604,3 +661,15 @@ int bts_supports_cipher(struct gsm_bts_role_bts *bts, int rsl_cipher)
sup = (1 << (rsl_cipher - 2)) & bts->support.ciphers; sup = (1 << (rsl_cipher - 2)) & bts->support.ciphers;
return sup > 0; 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

@@ -24,11 +24,15 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/ctrl/control_cmd.h> #include <osmocom/ctrl/control_cmd.h>
#include <osmo-bts/logging.h> #include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h> #include <osmo-bts/gsm_data.h>
#include <osmo-bts/tx_power.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"); CTRL_CMD_DEFINE(therm_att, "thermal-attenuation");
static int get_therm_att(struct ctrl_cmd *cmd, void *data) static int get_therm_att(struct ctrl_cmd *cmd, void *data)
@@ -67,12 +71,23 @@ static int verify_therm_att(struct ctrl_cmd *cmd, const char *value, void *data)
return 0; 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 bts_ctrl_cmds_install(struct gsm_bts *bts)
{ {
int rc = 0; int rc = 0;
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_therm_att); rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_therm_att);
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_oml_alert);
return rc; return rc;
} }

View File

@@ -24,8 +24,10 @@
#include <osmocom/vty/command.h> #include <osmocom/vty/command.h>
#include <osmocom/ctrl/control_if.h> #include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/ports.h> #include <osmocom/ctrl/ports.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/logging.h> #include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h> #include <osmo-bts/gsm_data.h>
#include <osmo-bts/control_if.h>
extern vector ctrl_node_vec; extern vector ctrl_node_vec;
@@ -85,12 +87,14 @@ err_index:
return -ERANGE; return -ERANGE;
} }
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts) struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
const char *bind_addr, uint16_t port)
{ {
struct ctrl_handle *hdl; struct ctrl_handle *hdl;
int rc = 0; int rc = 0;
hdl = ctrl_interface_setup(bts, OSMO_CTRL_PORT_BTS, bts_ctrl_node_lookup); hdl = ctrl_interface_setup_dynip(bts, bind_addr, port,
bts_ctrl_node_lookup);
if (!hdl) if (!hdl)
return NULL; return NULL;
@@ -100,5 +104,12 @@ struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts)
return NULL; return NULL;
} }
rc = bts_model_ctrl_cmds_install(bts);
if (rc) {
/* FIXME: cleanup generic control commands */
/* FIXME: close control interface */
return NULL;
}
return hdl; 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,
};

View File

@@ -33,6 +33,7 @@
#include <osmo-bts/rsl.h> #include <osmo-bts/rsl.h>
#include <osmo-bts/logging.h> #include <osmo-bts/logging.h>
#include <osmo-bts/handover.h> #include <osmo-bts/handover.h>
#include <osmo-bts/l1sap.h>
/* Transmit a handover related PHYS INFO on given lchan */ /* Transmit a handover related PHYS INFO on given lchan */
static int ho_tx_phys_info(struct gsm_lchan *lchan) static int ho_tx_phys_info(struct gsm_lchan *lchan)
@@ -105,16 +106,24 @@ void handover_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay)
return; 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, LOGP(DHO, LOGL_NOTICE,
"%s RACH on dedicated channel received with TA=%u\n", "%s RACH on dedicated channel type %s received with TA=%u, ref=%u\n",
gsm_lchan_name(lchan), acc_delay); gsm_lchan_name(lchan), gsm_lchant_name(lchan->type), acc_delay, ra);
/* Set timing advance */ /* Set timing advance */
lchan->rqd_ta = acc_delay; lchan->rqd_ta = acc_delay;
/* Stop handover detection, wait for valid frame */ /* Stop handover detection, wait for valid frame */
lchan->ho.active = HANDOVER_WAIT_FRAME; lchan->ho.active = HANDOVER_WAIT_FRAME;
if (bts_model_rsl_chan_mod(lchan) != 0) { if (l1sap_chan_modify(lchan->ts->trx, gsm_lchan2chan_nr(lchan)) != 0) {
LOGP(DHO, LOGL_ERROR, LOGP(DHO, LOGL_ERROR,
"%s failed to modify channel after handover\n", "%s failed to modify channel after handover\n",
gsm_lchan_name(lchan)); gsm_lchan_name(lchan));

1396
src/common/l1sap.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -19,9 +19,31 @@
* *
*/ */
#include <osmocom/core/logging.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h> #include <osmo-bts/gsm_data.h>
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state) 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; 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

@@ -107,6 +107,18 @@ static struct log_info_cat bts_log_info_cat[] = {
.color = "\033[0;37m", .color = "\033[0;37m",
.enabled = 1, .loglevel = LOGL_NOTICE, .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 #if 0
[DNS] = { [DNS] = {
.name = "DNS", .name = "DNS",
@@ -124,6 +136,12 @@ static struct log_info_cat bts_log_info_cat[] = {
.enabled = 1, .loglevel = LOGL_DEBUG, .enabled = 1, .loglevel = LOGL_DEBUG,
}, },
#endif #endif
[DSUM] = {
.name = "DSUM",
.description = "DSUM",
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
}; };
const struct log_info bts_log_info = { 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/logging.h>
#include <osmo-bts/measurement.h> #include <osmo-bts/measurement.h>
/* TS 05.08, Chapter 8.4.1 */ /* Measurment reporting period and mapping of SACCH message block for TCHF
/* measurement period ends at fn % 104 == ? */ * 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[] = { static const uint8_t tchf_meas_rep_fn104[] = {
[0] = 103, [0] = 90,
[1] = 12, [1] = 103,
[2] = 25, [2] = 12,
[3] = 38, [3] = 25,
[4] = 51, [4] = 38,
[5] = 64, [5] = 51,
[6] = 77, [6] = 64,
[7] = 90, [7] = 77,
}; };
static const uint8_t tchh0_meas_rep_fn104[] = { 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, [0] = 103,
[1] = 103, [1] = 103,
[2] = 25, [2] = 25,
@@ -30,59 +53,130 @@ static const uint8_t tchh0_meas_rep_fn104[] = {
[6] = 77, [6] = 77,
[7] = 77, [7] = 77,
}; };
static const uint8_t tchh1_meas_rep_fn104[] = {
[0] = 12, /* Measurment reporting period for SDCCH8 and SDCCH4 chan
[1] = 12, * As per in 3GPP TS 45.008, section 8.4.2.
[2] = 38, *
[3] = 38, * Logical Chan TDMA frame number
[4] = 64, * (FN) modulo 102
[5] = 64, *
[6] = 90, * SDCCH/8 12 to 11
[7] = 90, * 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 const uint8_t sdcch4_meas_rep_fn102[] = {
static int is_meas_complete(enum gsm_phys_chan_config pchan, unsigned int ts, [0] = 36 + 4,
unsigned int subch, uint32_t fn) [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; const uint8_t *tbl;
int rc = 0; int rc = 0;
enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
if (ts >= 8) if (lchan->ts->nr >= 8)
return -EINVAL; return -EINVAL;
if (pchan >= _GSM_PCHAN_MAX) if (pchan >= _GSM_PCHAN_MAX)
return -EINVAL; return -EINVAL;
switch (pchan) { switch (pchan) {
case GSM_PCHAN_TCH_F: case GSM_PCHAN_TCH_F:
fn_mod = fn % 104; fn_mod = translate_tch_meas_rep_fn104(fn % 104);
if (tchf_meas_rep_fn104[ts] == fn_mod) if (tchf_meas_rep_fn104[lchan->ts->nr] == fn_mod)
rc = 1; rc = 1;
break; break;
case GSM_PCHAN_TCH_H: case GSM_PCHAN_TCH_H:
fn_mod = fn % 104; fn_mod = translate_tch_meas_rep_fn104(fn % 104);
if (subch == 0) if (lchan->nr == 0)
tbl = tchh0_meas_rep_fn104; tbl = tchh0_meas_rep_fn104;
else else
tbl = tchh1_meas_rep_fn104; tbl = tchh1_meas_rep_fn104;
if (tbl[ts] == fn_mod) if (tbl[lchan->ts->nr] == fn_mod)
rc = 1; rc = 1;
break; break;
case GSM_PCHAN_SDCCH8_SACCH8C: case GSM_PCHAN_SDCCH8_SACCH8C:
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
fn_mod = fn % 102; fn_mod = fn % 102;
if (fn_mod == 11) if (sdcch8_meas_rep_fn102[lchan->nr] == fn_mod)
rc = 1; rc = 1;
break; break;
case GSM_PCHAN_CCCH_SDCCH4: case GSM_PCHAN_CCCH_SDCCH4:
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
fn_mod = fn % 102; fn_mod = fn % 102;
if (fn_mod == 36) if (sdcch4_meas_rep_fn102[lchan->nr] == fn_mod)
rc = 1; rc = 1;
break; break;
default: default:
rc = 0; rc = 0;
break; 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; return rc;
} }
@@ -93,13 +187,16 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm)
gsm_lchan_name(lchan), lchan->meas.num_ul_meas); gsm_lchan_name(lchan), lchan->meas.num_ul_meas);
if (lchan->state != LCHAN_S_ACTIVE) { if (lchan->state != LCHAN_S_ACTIVE) {
LOGP(DMEAS, LOGL_NOTICE, "%s measurement during state: %s\n", LOGP(DMEAS, LOGL_NOTICE,
gsm_lchan_name(lchan), gsm_lchans_name(lchan->state)); "%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)) { if (lchan->meas.num_ul_meas >= ARRAY_SIZE(lchan->meas.uplink)) {
LOGP(DMEAS, LOGL_NOTICE, "%s no space for uplink measurement\n", LOGP(DMEAS, LOGL_NOTICE,
gsm_lchan_name(lchan)); "%s no space for uplink measurement, num_ul_meas=%d\n",
gsm_lchan_name(lchan), lchan->meas.num_ul_meas);
return -ENOSPC; return -ENOSPC;
} }
@@ -112,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 */ /* input: BER in steps of .01%, i.e. percent/100 */
static uint8_t ber10k_to_rxqual(uint32_t ber10k) 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) if (ber10k < 20)
return 0; return 0;
if (ber10k < 40) if (ber10k < 40)
@@ -130,7 +240,51 @@ static uint8_t ber10k_to_rxqual(uint32_t ber10k)
return 7; return 7;
} }
static int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) /* 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; struct gsm_meas_rep_unidir *mru;
uint32_t ber_full_sum = 0; uint32_t ber_full_sum = 0;
@@ -142,8 +296,7 @@ static int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
int i; int i;
/* if measurement period is not complete, abort */ /* if measurement period is not complete, abort */
if (!is_meas_complete(lchan->ts->pchan, lchan->ts->nr, if (!is_meas_complete(lchan, fn))
lchan->nr, fn))
return 0; return 0;
/* if there are no measurements, skip computation */ /* if there are no measurements, skip computation */
@@ -175,6 +328,9 @@ static int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
if (num_meas_sub) { if (num_meas_sub) {
ber_sub_sum = ber_sub_sum / num_meas_sub; ber_sub_sum = ber_sub_sum / num_meas_sub;
irssi_sub_sum = irssi_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), " DEBUGP(DMEAS, "%s Computed TA(% 4dqb) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), "
@@ -183,6 +339,9 @@ static 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, ber_full_sum%100, irssi_full_sum, ber_sub_sum/100, ber_sub_sum%100,
irssi_sub_sum); irssi_sub_sum);
/* Update ordered TA for DL SACCH L1 Header */
lchan_meas_update_ordered_TA(lchan, taqb_sum);
/* store results */ /* store results */
mru = &lchan->meas.ul_res; mru = &lchan->meas.ul_res;
mru->full.rx_lev = dbm2rxlev((int)irssi_full_sum * -1); mru->full.rx_lev = dbm2rxlev((int)irssi_full_sum * -1);
@@ -190,6 +349,14 @@ static int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum); mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum);
mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_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.flags |= LC_UL_M_F_RES_VALID;
lchan->meas.num_ul_meas = 0; lchan->meas.num_ul_meas = 0;
@@ -197,63 +364,3 @@ static int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
return 1; return 1;
} }
/* build the 3 byte RSL uplinke measurement IE content */
int lchan_build_rsl_ul_meas(struct gsm_lchan *lchan, uint8_t *buf)
{
struct gsm_meas_rep_unidir *mru = &lchan->meas.ul_res;
buf[0] = (mru->full.rx_lev & 0x3f); /* FIXME: DTXu support */
buf[1] = (mru->sub.rx_lev & 0x3f);
buf[2] = ((mru->full.rx_qual & 7) << 3) | (mru->sub.rx_qual & 7);
return 3;
}
/* Copied from OpenBSC and enlarged to _GSM_PCHAN_MAX */
static const uint8_t subslots_per_pchan[_GSM_PCHAN_MAX] = {
[GSM_PCHAN_NONE] = 0,
[GSM_PCHAN_CCCH] = 0,
[GSM_PCHAN_CCCH_SDCCH4] = 4,
[GSM_PCHAN_TCH_F] = 1,
[GSM_PCHAN_TCH_H] = 2,
[GSM_PCHAN_SDCCH8_SACCH8C] = 8,
/* FIXME: what about dynamic TCH_F_TCH_H ? */
[GSM_PCHAN_TCH_F_PDCH] = 1,
};
static int ts_meas_check_compute(struct gsm_bts_trx_ts *ts, uint32_t fn)
{
int i;
const int num_subslots = subslots_per_pchan[ts->pchan];
for (i = 0; i < num_subslots; ++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:
case GSM_LCHAN_PDTCH:
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;
}

View File

@@ -17,17 +17,24 @@
* *
*/ */
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/msg_utils.h> #include <osmo-bts/msg_utils.h>
#include <osmo-bts/logging.h> #include <osmo-bts/logging.h>
#include <osmo-bts/oml.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/ipaccess.h>
#include <osmocom/gsm/protocol/gsm_12_21.h> #include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/gsm/abis_nm.h> #include <osmocom/gsm/abis_nm.h>
#include <osmocom/core/msgb.h> #include <osmocom/core/msgb.h>
#include <osmocom/core/fsm.h>
#include <osmocom/trau/osmo_ortp.h>
#include <arpa/inet.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) static int check_fom(struct abis_om_hdr *omh, size_t len)
{ {
@@ -86,6 +93,425 @@ static int check_manuf(struct msgb *msg, struct abis_om_hdr *omh, size_t msg_siz
return type; 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 * Return 0 in case the IPA structure is okay and in this
* case the l2h will be set to the beginning of the data. * case the l2h will be set to the beginning of the data.
@@ -96,28 +522,30 @@ int msg_verify_ipa_structure(struct msgb *msg)
if (msgb_l1len(msg) < sizeof(struct ipaccess_head)) { if (msgb_l1len(msg) < sizeof(struct ipaccess_head)) {
LOGP(DL1C, LOGL_ERROR, LOGP(DL1C, LOGL_ERROR,
"Ipa header insufficient space %d %d\n", "Ipa header insufficient space %d %zu\n",
msgb_l1len(msg), sizeof(struct ipaccess_head)); msgb_l1len(msg), sizeof(struct ipaccess_head));
return -1; return -1;
} }
hh = (struct ipaccess_head *) msg->l1h; hh = (struct ipaccess_head *) msg->l1h;
if (hh->proto != IPAC_PROTO_OML) {
LOGP(DL1C, LOGL_ERROR,
"Incorrect ipa header protocol 0x%x 0x%x\n",
hh->proto, IPAC_PROTO_OML);
return -1;
}
if (ntohs(hh->len) != msgb_l1len(msg) - sizeof(struct ipaccess_head)) { if (ntohs(hh->len) != msgb_l1len(msg) - sizeof(struct ipaccess_head)) {
LOGP(DL1C, LOGL_ERROR, LOGP(DL1C, LOGL_ERROR,
"Incorrect ipa header msg size %d %d\n", "Incorrect ipa header msg size %d %zu\n",
ntohs(hh->len), msgb_l1len(msg) - sizeof(struct ipaccess_head)); ntohs(hh->len), msgb_l1len(msg) - sizeof(struct ipaccess_head));
return -1; return -1;
} }
msg->l2h = hh->data; 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; return 0;
} }
@@ -140,7 +568,7 @@ int msg_verify_oml_structure(struct msgb *msg)
struct abis_om_hdr *omh; struct abis_om_hdr *omh;
if (msgb_l2len(msg) < sizeof(*omh)) { if (msgb_l2len(msg) < sizeof(*omh)) {
LOGP(DL1C, LOGL_ERROR, "Om header insufficient space %d %d\n", LOGP(DL1C, LOGL_ERROR, "Om header insufficient space %d %zu\n",
msgb_l2len(msg), sizeof(*omh)); msgb_l2len(msg), sizeof(*omh));
return -1; return -1;
} }

View File

@@ -24,11 +24,16 @@
* Operation and Maintainance Messages * Operation and Maintainance Messages
*/ */
#include "btsconfig.h"
#include <errno.h> #include <errno.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <osmocom/core/talloc.h> #include <osmocom/core/talloc.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/protocol/gsm_12_21.h> #include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/gsm/abis_nm.h> #include <osmocom/gsm/abis_nm.h>
#include <osmocom/abis/e1_input.h> #include <osmocom/abis/e1_input.h>
@@ -41,115 +46,19 @@
#include <osmo-bts/bts_model.h> #include <osmo-bts/bts_model.h>
#include <osmo-bts/bts.h> #include <osmo-bts/bts.h>
#include <osmo-bts/signal.h> #include <osmo-bts/signal.h>
#include <osmo-bts/phy_link.h>
/* FIXME: move this to libosmocore */
static struct tlv_definition abis_nm_att_tlvdef_ipa = {
.def = {
/* ip.access specifics */
[NM_ATT_IPACC_DST_IP] = { TLV_TYPE_FIXED, 4 },
[NM_ATT_IPACC_DST_IP_PORT] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_STREAM_ID] = { TLV_TYPE_TV, },
[NM_ATT_IPACC_SEC_OML_CFG] = { TLV_TYPE_FIXED, 6 },
[NM_ATT_IPACC_IP_IF_CFG] = { TLV_TYPE_FIXED, 8 },
[NM_ATT_IPACC_IP_GW_CFG] = { TLV_TYPE_FIXED, 12 },
[NM_ATT_IPACC_IN_SERV_TIME] = { TLV_TYPE_FIXED, 4 },
[NM_ATT_IPACC_LOCATION] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_PAGING_CFG] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_UNIT_ID] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_UNIT_NAME] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SNMP_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_PRIM_OML_CFG_LIST] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NV_FLAGS] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_PRIM_OML_FB_TOUT] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_CUR_SW_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_TIMING_BUS] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_CGI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RAC] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_OBJ_VERSION] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_GPRS_PAGING_CFG]= { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NSEI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_BVCI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NSVCI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NS_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_BSSGP_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NS_LINK_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RLC_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_ALM_THRESH_LIST]= { TLV_TYPE_TL16V },
[NM_ATT_IPACC_MONIT_VAL_LIST] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_TIB_CONTROL] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SUPP_FEATURES] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_CODING_SCHEMES] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RLC_CFG_2] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_HEARTB_TOUT] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_UPTIME] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RLC_CFG_3] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SSL_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SEC_POSSIBLE] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_IML_SSL_STATE] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
},
};
static int oml_ipa_set_attr(struct gsm_bts *bts, struct msgb *msg); static int oml_ipa_set_attr(struct gsm_bts *bts, struct msgb *msg);
static struct tlv_definition abis_nm_att_tlvdef_ipa_local = {};
/* /*
* support * support
*/ */
struct tlv_parsed *tlvp_copy(const struct tlv_parsed *tp_orig, void *ctx)
{
struct tlv_parsed *tp_out;
unsigned int i;
tp_out = talloc_zero(ctx, struct tlv_parsed);
if (!tp_out)
return NULL;
/* if the original is NULL, return empty tlvp */
if (!tp_orig)
return tp_out;
for (i = 0; i < ARRAY_SIZE(tp_orig->lv); i++) {
unsigned int len = tp_orig->lv[i].len;
tp_out->lv[i].len = len;
if (len && tp_out->lv[i].val) {
tp_out->lv[i].val = talloc_zero_size(tp_out, len);
if (!tp_out->lv[i].val) {
talloc_free(tp_out);
return NULL;
}
memcpy((uint8_t *)tp_out->lv[i].val, tp_orig->lv[i].val, len);
}
}
return tp_out;
}
/* merge all attributes of 'new' into 'out' */
int tlvp_merge(struct tlv_parsed *out, const struct tlv_parsed *new)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(out->lv); i++) {
unsigned int len = new->lv[i].len;
if (len == 0 || new->lv[i].val == NULL)
continue;
if (out->lv[i].val) {
talloc_free((uint8_t *) out->lv[i].val);
out->lv[i].len = 0;
}
out->lv[i].val = talloc_zero_size(out, len);
if (!out->lv[i].val)
return -ENOMEM;
memcpy((uint8_t *) out->lv[i].val, new->lv[i].val, len);
}
return 0;
}
static int oml_tlv_parse(struct tlv_parsed *tp, const uint8_t *buf, int len) static int oml_tlv_parse(struct tlv_parsed *tp, const uint8_t *buf, int len)
{ {
return tlv_parse(tp, &abis_nm_att_tlvdef_ipa, buf, len, 0, 0); return tlv_parse(tp, &abis_nm_att_tlvdef_ipa_local, buf, len, 0, 0);
} }
struct msgb *oml_msgb_alloc(void) struct msgb *oml_msgb_alloc(void)
@@ -157,6 +66,42 @@ struct msgb *oml_msgb_alloc(void)
return msgb_alloc_headroom(1024, 128, "OML"); return msgb_alloc_headroom(1024, 128, "OML");
} }
/* 3GPP TS 12.21 § 8.8.2 */
static int oml_tx_failure_event_rep(struct gsm_abis_mo *mo, uint16_t cause_value,
const char *fmt, ...)
{
struct msgb *nmsg;
va_list ap;
LOGP(DOML, LOGL_NOTICE, "Reporting FAILURE to BSC: ");
va_start(ap, fmt);
osmo_vlogp(DOML, LOGL_NOTICE, __FILE__, __LINE__, 1, fmt, ap);
nmsg = abis_nm_fail_evt_vrep(NM_EVT_PROC_FAIL, NM_SEVER_CRITICAL,
NM_PCAUSE_T_MANUF, cause_value, fmt, ap);
va_end(ap);
LOGPC(DOML, LOGL_NOTICE, "\n");
if (!nmsg)
return -ENOMEM;
return oml_mo_send_msg(mo, nmsg, NM_MT_FAILURE_EVENT_REP);
}
void oml_fail_rep(uint16_t cause_value, const char *fmt, ...)
{
va_list ap;
char *rep;
va_start(ap, fmt);
rep = talloc_asprintf(tall_bts_ctx, fmt, ap);
va_end(ap);
osmo_signal_dispatch(SS_FAIL, cause_value, rep);
/* signal dispatch is synchronous so all the signal handlers are
finished already: we're free to free */
talloc_free(rep);
}
int oml_send_msg(struct msgb *msg, int is_manuf) int oml_send_msg(struct msgb *msg, int is_manuf)
{ {
struct abis_om_hdr *omh; struct abis_om_hdr *omh;
@@ -209,6 +154,147 @@ char *gsm_abis_mo_name(const struct gsm_abis_mo *mo)
return mo_buf; return mo_buf;
} }
static inline void add_bts_attrs(struct msgb *msg, const struct gsm_bts *bts)
{
abis_nm_put_sw_file(msg, btstype2str(GSM_BTS_TYPE_OSMOBTS), PACKAGE_VERSION, true);
abis_nm_put_sw_file(msg, btsatttr2str(BTS_TYPE_VARIANT), btsvariant2str(bts->variant), true);
if (strlen(bts->sub_model))
abis_nm_put_sw_file(msg, btsatttr2str(BTS_SUB_MODEL), bts->sub_model, true);
}
/* Add BTS features as 3GPP TS 52.021 §9.4.30 Manufacturer Id */
static inline void add_bts_feat(struct msgb *msg, const struct gsm_bts *bts)
{
msgb_tl16v_put(msg, NM_ATT_MANUF_ID, _NUM_BTS_FEAT/8 + 1, bts->_features_data);
}
static inline void add_trx_attr(struct msgb *msg, struct gsm_bts_trx *trx)
{
const struct phy_instance *pinst = trx_phy_instance(trx);
abis_nm_put_sw_file(msg, btsatttr2str(TRX_PHY_VERSION), strlen(pinst->version) ? pinst->version : "Unknown",
true);
}
/* The number of attributes in §9.4.26 List of Required Attributes is 2 bytes,
but the Count of not-reported attributes from §9.4.64 is 1 byte */
static inline uint8_t pack_num_unreported_attr(uint16_t attrs)
{
if (attrs > 255) {
LOGP(DOML, LOGL_ERROR, "O&M Get Attributes, Count of not-reported attributes is too big: %u\n",
attrs);
return 255;
}
return attrs; /* Return number of unhandled attributes */
}
/* copy all the attributes accumulated in msg to out and return the total length of out buffer */
static inline int cleanup_attr_msg(uint8_t *out, int out_offset, struct msgb *msg)
{
int len = 0;
out[0] = pack_num_unreported_attr(out_offset - 1);
if (msg) {
memcpy(out + out_offset, msgb_data(msg), msg->len);
len = msg->len;
msgb_free(msg);
}
return len + out_offset + 1;
}
static inline int handle_attrs_trx(uint8_t *out, struct gsm_bts_trx *trx, const uint8_t *attr, uint16_t attr_len)
{
uint16_t i, attr_out_index = 1; /* byte 0 is reserved for unsupported attributes counter */
struct msgb *attr_buf = oml_msgb_alloc();
if (!attr_buf)
return -ENOMEM;
for (i = 0; i < attr_len; i++) {
switch (attr[i]) {
case NM_ATT_SW_CONFIG:
add_trx_attr(attr_buf, trx);
break;
default:
LOGP(DOML, LOGL_ERROR, "O&M Get Attributes [%u], %s is unsupported by TRX.\n", i,
get_value_string(abis_nm_att_names, attr[i]));
out[attr_out_index] = attr[i]; /* assemble values of supported attributes and list of unsupported ones */
attr_out_index++;
}
}
return cleanup_attr_msg(out, attr_out_index, attr_buf);
}
static inline int handle_attrs_bts(uint8_t *out, const struct gsm_bts *bts, const uint8_t *attr, uint16_t attr_len)
{
uint16_t i, attr_out_index = 1; /* byte 0 is reserved for unsupported attributes counter */
struct msgb *attr_buf = oml_msgb_alloc();
if (!attr_buf)
return -ENOMEM;
for (i = 0; i < attr_len; i++) {
switch (attr[i]) {
case NM_ATT_SW_CONFIG:
add_bts_attrs(attr_buf, bts);
break;
case NM_ATT_MANUF_ID:
add_bts_feat(attr_buf, bts);
break;
default:
LOGP(DOML, LOGL_ERROR, "O&M Get Attributes [%u], %s is unsupported by BTS.\n", i,
get_value_string(abis_nm_att_names, attr[i]));
out[attr_out_index] = attr[i]; /* assemble values of supported attributes and list of unsupported ones */
attr_out_index++;
}
}
return cleanup_attr_msg(out, attr_out_index, attr_buf);
}
/* send 3GPP TS 52.021 §8.11.2 Get Attribute Response */
static int oml_tx_attr_resp(struct gsm_bts *bts, const struct abis_om_fom_hdr *foh, const uint8_t *attr,
uint16_t attr_len)
{
struct msgb *nmsg = oml_msgb_alloc();
uint8_t resp[MAX_VERSION_LENGTH * attr_len * 2]; /* heuristic for Attribute Response Info space requirements */
int len;
LOGP(DOML, LOGL_INFO, "%s Tx Get Attribute Response\n",
get_value_string(abis_nm_obj_class_names, foh->obj_class));
if (!nmsg)
return -ENOMEM;
switch (foh->obj_class) {
case NM_OC_BTS:
len = handle_attrs_bts(resp, bts, attr, attr_len);
break;
case NM_OC_BASEB_TRANSC:
len = handle_attrs_trx(resp, gsm_bts_trx_num(bts, foh->obj_inst.trx_nr), attr, attr_len);
break;
default:
LOGP(DOML, LOGL_ERROR, "Unsupported MO class %s in Get Attribute Response\n",
get_value_string(abis_nm_obj_class_names, foh->obj_class));
len = -EINVAL;
}
if (len < 0) {
LOGP(DOML, LOGL_ERROR, "Tx Get Attribute Response FAILED with %d\n", len);
msgb_free(nmsg);
return len;
}
/* §9.4.64 Get Attribute Response Info */
msgb_tl16v_put(nmsg, NM_ATT_GET_ARI, len, resp);
return oml_mo_send_msg(&bts->mo, nmsg, NM_MT_GET_ATTR_RESP);
}
/* 8.8.1 sending State Changed Event Report */ /* 8.8.1 sending State Changed Event Report */
int oml_tx_state_changed(struct gsm_abis_mo *mo) int oml_tx_state_changed(struct gsm_abis_mo *mo)
{ {
@@ -369,27 +455,108 @@ int oml_mo_tx_sw_act_rep(struct gsm_abis_mo *mo)
return oml_mo_send_msg(mo, nmsg, NM_MT_SW_ACTIVATED_REP); return oml_mo_send_msg(mo, nmsg, NM_MT_SW_ACTIVATED_REP);
} }
/* TS 12.21 9.4.53 */ /* the below defaults correpsond to the libocmocore default of 1s for
enum abis_nm_t200_idx { * DCCH and 2s for ACCH. The BSC should overried this via OML anyway. */
T200_SDCCH = 0, const unsigned int oml_default_t200_ms[7] = {
T200_FACCH_F = 1, [T200_SDCCH] = 1000,
T200_FACCH_H = 2, [T200_FACCH_F] = 1000,
T200_SACCH_TCH_SAPI0 = 3, [T200_FACCH_H] = 1000,
T200_SACCH_SDCCH = 4, [T200_SACCH_TCH_SAPI0] = 2000,
T200_SDCCH_SAPI3 = 5, [T200_SACCH_SDCCH] = 2000,
T200_SACCH_TCH_SAPI3 = 6 [T200_SDCCH_SAPI3] = 1000,
[T200_SACCH_TCH_SAPI3] = 2000,
}; };
/* TS 12.21 9.4.53 */ static void dl_set_t200(struct lapdm_datalink *dl, unsigned int t200_msec)
static const uint8_t abis_nm_t200_mult[] = { {
[T200_SDCCH] = 5, dl->dl.t200_sec = t200_msec / 1000;
[T200_FACCH_F] = 5, dl->dl.t200_usec = (t200_msec % 1000) * 1000;
[T200_FACCH_H] = 5, }
[T200_SACCH_TCH_SAPI0] = 10,
[T200_SACCH_SDCCH] = 10, /* Configure LAPDm T200 timers for this lchan according to OML */
[T200_SDCCH_SAPI3] = 5, int oml_set_lchan_t200(struct gsm_lchan *lchan)
[T200_SACCH_TCH_SAPI3] = 10 {
}; struct gsm_bts *bts = lchan->ts->trx->bts;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct lapdm_channel *lc = &lchan->lapdm_ch;
unsigned int t200_dcch, t200_dcch_sapi3, t200_acch, t200_acch_sapi3;
/* set T200 for main and associated channel */
switch (lchan->type) {
case GSM_LCHAN_SDCCH:
t200_dcch = btsb->t200_ms[T200_SDCCH];
t200_dcch_sapi3 = btsb->t200_ms[T200_SDCCH_SAPI3];
t200_acch = btsb->t200_ms[T200_SACCH_SDCCH];
t200_acch_sapi3 = btsb->t200_ms[T200_SACCH_SDCCH];
break;
case GSM_LCHAN_TCH_F:
t200_dcch = btsb->t200_ms[T200_FACCH_F];
t200_dcch_sapi3 = btsb->t200_ms[T200_FACCH_F];
t200_acch = btsb->t200_ms[T200_SACCH_TCH_SAPI0];
t200_acch_sapi3 = btsb->t200_ms[T200_SACCH_TCH_SAPI3];
break;
case GSM_LCHAN_TCH_H:
t200_dcch = btsb->t200_ms[T200_FACCH_H];
t200_dcch_sapi3 = btsb->t200_ms[T200_FACCH_H];
t200_acch = btsb->t200_ms[T200_SACCH_TCH_SAPI0];
t200_acch_sapi3 = btsb->t200_ms[T200_SACCH_TCH_SAPI3];
break;
default:
return -1;
}
DEBUGP(DLLAPD, "%s: Setting T200 D0=%u, D3=%u, S0=%u, S3=%u"
"(all in ms)\n", gsm_lchan_name(lchan), t200_dcch,
t200_dcch_sapi3, t200_acch, t200_acch_sapi3);
dl_set_t200(&lc->lapdm_dcch.datalink[DL_SAPI0], t200_dcch);
dl_set_t200(&lc->lapdm_dcch.datalink[DL_SAPI3], t200_dcch_sapi3);
dl_set_t200(&lc->lapdm_acch.datalink[DL_SAPI0], t200_acch);
dl_set_t200(&lc->lapdm_acch.datalink[DL_SAPI3], t200_acch_sapi3);
return 0;
}
/* 3GPP TS 52.021 §8.11.1 Get Attributes has been received */
static int oml_rx_get_attr(struct gsm_bts *bts, struct msgb *msg)
{
struct abis_om_fom_hdr *foh = msgb_l3(msg);
struct tlv_parsed tp;
int rc;
if (!foh || !bts)
return -EINVAL;
abis_nm_debugp_foh(DOML, foh);
DEBUGPC(DOML, "Rx GET ATTR\n");
rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
if (rc < 0) {
oml_tx_failure_event_rep(&bts->mo, OSMO_EVT_MAJ_UNSUP_ATTR, "Get Attribute parsing failure");
return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
}
if (!TLVP_PRES_LEN(&tp, NM_ATT_LIST_REQ_ATTR, 1)) {
LOGP(DOML, LOGL_ERROR, "O&M Get Attributes message without Attribute List?!\n");
oml_tx_failure_event_rep(&bts->mo, OSMO_EVT_MAJ_UNSUP_ATTR, "Get Attribute without Attribute List");
return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
}
rc = oml_tx_attr_resp(bts, foh, TLVP_VAL(&tp, NM_ATT_LIST_REQ_ATTR), TLVP_LEN(&tp, NM_ATT_LIST_REQ_ATTR));
if (rc < 0) {
LOGP(DOML, LOGL_ERROR, "Failed to respond to O&M Get Attributes message: %s\n", strerror(-rc));
switch (-rc) {
case ENOMEM:
return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM);
case ENOTSUP:
return oml_fom_ack_nack(msg, NM_NACK_OBJCLASS_NOTSUPP);
default:
return oml_fom_ack_nack(msg, NM_NACK_RES_NOTIMPL);
}
}
return 0;
}
/* 8.6.1 Set BTS Attributes has been received */ /* 8.6.1 Set BTS Attributes has been received */
static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg) static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
@@ -404,31 +571,34 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
DEBUGPC(DOML, "Rx SET BTS ATTR\n"); DEBUGPC(DOML, "Rx SET BTS ATTR\n");
rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
if (rc < 0) if (rc < 0) {
oml_tx_failure_event_rep(&bts->mo, OSMO_EVT_MAJ_UNSUP_ATTR,
"New value for Attribute not supported");
return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
}
/* Test for globally unsupported stuff here */ /* Test for globally unsupported stuff here */
if (TLVP_PRESENT(&tp, NM_ATT_BCCH_ARFCN)) { if (TLVP_PRES_LEN(&tp, NM_ATT_BCCH_ARFCN, 2)) {
const uint16_t *value = (const uint16_t *) TLVP_VAL(&tp, NM_ATT_BCCH_ARFCN);
uint16_t arfcn = ntohs(tlvp_val16_unal(&tp, NM_ATT_BCCH_ARFCN)); uint16_t arfcn = ntohs(tlvp_val16_unal(&tp, NM_ATT_BCCH_ARFCN));
LOGP(DOML, LOGL_NOTICE, "MSG: %s\n", osmo_hexdump(msgb_l3(msg), msgb_l3len(msg)));
LOGP(DOML, LOGL_NOTICE, "L3=%p, VAL=%p, DIF=%tu\n", msgb_l3(msg), value,
(void *)value - (void *) msgb_l3(msg));
if (arfcn > 1024) { if (arfcn > 1024) {
oml_tx_failure_event_rep(&bts->mo, OSMO_EVT_WARN_SW_WARN,
"Given ARFCN %u is not supported",
arfcn);
LOGP(DOML, LOGL_NOTICE, "Given ARFCN %d is not supported.\n", arfcn); LOGP(DOML, LOGL_NOTICE, "Given ARFCN %d is not supported.\n", arfcn);
return oml_fom_ack_nack(msg, NM_NACK_FREQ_NOTAVAIL); return oml_fom_ack_nack(msg, NM_NACK_FREQ_NOTAVAIL);
} }
} }
/* 9.4.52 Starting Time */ /* 9.4.52 Starting Time */
if (TLVP_PRESENT(&tp, NM_ATT_START_TIME)) { if (TLVP_PRESENT(&tp, NM_ATT_START_TIME)) {
oml_tx_failure_event_rep(&bts->mo, OSMO_EVT_MAJ_UNSUP_ATTR,
"NM_ATT_START_TIME Attribute not "
"supported");
return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP); return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP);
} }
/* merge existing BTS attributes with new attributes */ /* merge existing BTS attributes with new attributes */
tp_merged = tlvp_copy(bts->mo.nm_attr, bts); tp_merged = osmo_tlvp_copy(bts->mo.nm_attr, bts);
tlvp_merge(tp_merged, &tp); osmo_tlvp_merge(tp_merged, &tp);
/* Ask BTS driver to validate new merged attributes */ /* Ask BTS driver to validate new merged attributes */
rc = bts_model_check_oml(bts, foh->msg_type, bts->mo.nm_attr, tp_merged, bts); rc = bts_model_check_oml(bts, foh->msg_type, bts->mo.nm_attr, tp_merged, bts);
@@ -444,7 +614,7 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
/* ... and actually still parse them */ /* ... and actually still parse them */
/* 9.4.25 Interference Level Boundaries */ /* 9.4.25 Interference Level Boundaries */
if (TLVP_PRESENT(&tp, NM_ATT_INTERF_BOUND)) { if (TLVP_PRES_LEN(&tp, NM_ATT_INTERF_BOUND, 6)) {
payload = TLVP_VAL(&tp, NM_ATT_INTERF_BOUND); payload = TLVP_VAL(&tp, NM_ATT_INTERF_BOUND);
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
int16_t boundary = *payload; int16_t boundary = *payload;
@@ -452,62 +622,87 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
} }
} }
/* 9.4.24 Intave Parameter */ /* 9.4.24 Intave Parameter */
if (TLVP_PRESENT(&tp, NM_ATT_INTAVE_PARAM)) if (TLVP_PRES_LEN(&tp, NM_ATT_INTAVE_PARAM, 1))
btsb->interference.intave = *TLVP_VAL(&tp, NM_ATT_INTAVE_PARAM); btsb->interference.intave = *TLVP_VAL(&tp, NM_ATT_INTAVE_PARAM);
/* 9.4.14 Connection Failure Criterion */ /* 9.4.14 Connection Failure Criterion */
if (TLVP_PRESENT(&tp, NM_ATT_CONN_FAIL_CRIT)) { if (TLVP_PRES_LEN(&tp, NM_ATT_CONN_FAIL_CRIT, 1)) {
const uint8_t *val = TLVP_VAL(&tp, NM_ATT_CONN_FAIL_CRIT); const uint8_t *val = TLVP_VAL(&tp, NM_ATT_CONN_FAIL_CRIT);
if (TLVP_LEN(&tp, NM_ATT_CONN_FAIL_CRIT) < 2 switch (val[0]) {
|| val[0] != 0x01 || val[1] < 4 || val[1] > 64) { case 0xFF: /* Osmocom specific Extension of TS 12.21 */
LOGP(DOML, LOGL_NOTICE, "WARNING: Radio Link Timeout "
"explicitly disabled, only use this for lab testing!\n");
btsb->radio_link_timeout = -1;
break;
case 0x01: /* Based on uplink SACCH (radio link timeout) */
if (TLVP_LEN(&tp, NM_ATT_CONN_FAIL_CRIT) >= 2 &&
val[1] >= 4 && val[1] <= 64) {
btsb->radio_link_timeout = val[1];
break;
}
/* fall-through */
case 0x02: /* Based on RXLEV/RXQUAL measurements */
default:
LOGP(DOML, LOGL_NOTICE, "Given Conn. Failure Criterion " LOGP(DOML, LOGL_NOTICE, "Given Conn. Failure Criterion "
"not supported. Please use critetion 0x01 with " "not supported. Please use critetion 0x01 with "
"RADIO_LINK_TIMEOUT value of 4..64\n"); "RADIO_LINK_TIMEOUT value of 4..64\n");
return oml_fom_ack_nack(msg, NM_NACK_PARAM_RANGE); return oml_fom_ack_nack(msg, NM_NACK_PARAM_RANGE);
} }
btsb->radio_link_timeout = val[1];
} }
/* if val[0] != 0x01: can be 'operator dependent' and needs to
* be parsed by bts driver */
/* 9.4.53 T200 */ /* 9.4.53 T200 */
if (TLVP_PRESENT(&tp, NM_ATT_T200)) { if (TLVP_PRES_LEN(&tp, NM_ATT_T200, ARRAY_SIZE(btsb->t200_ms))) {
payload = TLVP_VAL(&tp, NM_ATT_T200); payload = TLVP_VAL(&tp, NM_ATT_T200);
for (i = 0; i < ARRAY_SIZE(btsb->t200_ms); i++) for (i = 0; i < ARRAY_SIZE(btsb->t200_ms); i++) {
btsb->t200_ms[i] = payload[i] * abis_nm_t200_mult[i]; uint32_t t200_ms = payload[i] * abis_nm_t200_ms[i];
#if 0
btsb->t200_ms[i] = t200_ms;
DEBUGP(DOML, "T200[%u]: OML=%u, mult=%u => %u ms\n",
i, payload[i], abis_nm_t200_mult[i],
btsb->t200_ms[i]);
#else
/* we'd rather use the 1s/2s (long) defaults by
* libosmocore, as we appear to have some bug(s)
* related to handling T200 expiration in
* libosmogsm lapd(m) code? */
LOGP(DOML, LOGL_NOTICE, "Ignoring T200[%u] (%u ms) "
"as sent by BSC due to suspected LAPDm bug!\n",
i, t200_ms);
#endif
}
} }
/* 9.4.31 Maximum Timing Advance */ /* 9.4.31 Maximum Timing Advance */
if (TLVP_PRESENT(&tp, NM_ATT_MAX_TA)) if (TLVP_PRES_LEN(&tp, NM_ATT_MAX_TA, 1))
btsb->max_ta = *TLVP_VAL(&tp, NM_ATT_MAX_TA); btsb->max_ta = *TLVP_VAL(&tp, NM_ATT_MAX_TA);
/* 9.4.39 Overload Period */ /* 9.4.39 Overload Period */
if (TLVP_PRESENT(&tp, NM_ATT_OVERL_PERIOD)) if (TLVP_PRES_LEN(&tp, NM_ATT_OVERL_PERIOD, 1))
btsb->load.overload_period = *TLVP_VAL(&tp, NM_ATT_OVERL_PERIOD); btsb->load.overload_period = *TLVP_VAL(&tp, NM_ATT_OVERL_PERIOD);
/* 9.4.12 CCCH Load Threshold */ /* 9.4.12 CCCH Load Threshold */
if (TLVP_PRESENT(&tp, NM_ATT_CCCH_L_T)) if (TLVP_PRES_LEN(&tp, NM_ATT_CCCH_L_T, 1))
btsb->load.ccch.load_ind_thresh = *TLVP_VAL(&tp, NM_ATT_CCCH_L_T); btsb->load.ccch.load_ind_thresh = *TLVP_VAL(&tp, NM_ATT_CCCH_L_T);
/* 9.4.11 CCCH Load Indication Period */ /* 9.4.11 CCCH Load Indication Period */
if (TLVP_PRESENT(&tp, NM_ATT_CCCH_L_I_P)) if (TLVP_PRES_LEN(&tp, NM_ATT_CCCH_L_I_P, 1))
btsb->load.ccch.load_ind_period = *TLVP_VAL(&tp, NM_ATT_CCCH_L_I_P); btsb->load.ccch.load_ind_period = *TLVP_VAL(&tp, NM_ATT_CCCH_L_I_P);
/* 9.4.44 RACH Busy Threshold */ /* 9.4.44 RACH Busy Threshold */
if (TLVP_PRESENT(&tp, NM_ATT_RACH_B_THRESH)) { if (TLVP_PRES_LEN(&tp, NM_ATT_RACH_B_THRESH, 1)) {
int16_t thresh = *TLVP_VAL(&tp, NM_ATT_RACH_B_THRESH); int16_t thresh = *TLVP_VAL(&tp, NM_ATT_RACH_B_THRESH);
btsb->load.rach.busy_thresh = -1 * thresh; btsb->load.rach.busy_thresh = -1 * thresh;
} }
/* 9.4.45 RACH Load Averaging Slots */ /* 9.4.45 RACH Load Averaging Slots */
if (TLVP_PRESENT(&tp, NM_ATT_LDAVG_SLOTS)) { if (TLVP_PRES_LEN(&tp, NM_ATT_LDAVG_SLOTS, 2)) {
btsb->load.rach.averaging_slots = btsb->load.rach.averaging_slots =
ntohs(tlvp_val16_unal(&tp, NM_ATT_LDAVG_SLOTS)); ntohs(tlvp_val16_unal(&tp, NM_ATT_LDAVG_SLOTS));
} }
/* 9.4.10 BTS Air Timer */ /* 9.4.10 BTS Air Timer */
if (TLVP_PRESENT(&tp, NM_ATT_BTS_AIR_TIMER)) { if (TLVP_PRES_LEN(&tp, NM_ATT_BTS_AIR_TIMER, 1)) {
uint8_t t3105 = *TLVP_VAL(&tp, NM_ATT_BTS_AIR_TIMER); uint8_t t3105 = *TLVP_VAL(&tp, NM_ATT_BTS_AIR_TIMER);
if (t3105 == 0) { if (t3105 == 0) {
LOGP(DOML, LOGL_NOTICE, LOGP(DOML, LOGL_NOTICE,
@@ -518,15 +713,15 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
} }
/* 9.4.37 NY1 */ /* 9.4.37 NY1 */
if (TLVP_PRESENT(&tp, NM_ATT_NY1)) if (TLVP_PRES_LEN(&tp, NM_ATT_NY1, 1))
btsb->ny1 = *TLVP_VAL(&tp, NM_ATT_NY1); btsb->ny1 = *TLVP_VAL(&tp, NM_ATT_NY1);
/* 9.4.8 BCCH ARFCN */ /* 9.4.8 BCCH ARFCN */
if (TLVP_PRESENT(&tp, NM_ATT_BCCH_ARFCN)) if (TLVP_PRES_LEN(&tp, NM_ATT_BCCH_ARFCN, 2))
bts->c0->arfcn = ntohs(tlvp_val16_unal(&tp, NM_ATT_BCCH_ARFCN)); bts->c0->arfcn = ntohs(tlvp_val16_unal(&tp, NM_ATT_BCCH_ARFCN));
/* 9.4.9 BSIC */ /* 9.4.9 BSIC */
if (TLVP_PRESENT(&tp, NM_ATT_BSIC)) if (TLVP_PRES_LEN(&tp, NM_ATT_BSIC, 1))
bts->bsic = *TLVP_VAL(&tp, NM_ATT_BSIC); bts->bsic = *TLVP_VAL(&tp, NM_ATT_BSIC);
/* call into BTS driver to apply new attributes to hardware */ /* call into BTS driver to apply new attributes to hardware */
@@ -544,12 +739,16 @@ static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg)
DEBUGPC(DOML, "Rx SET RADIO CARRIER ATTR\n"); DEBUGPC(DOML, "Rx SET RADIO CARRIER ATTR\n");
rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
if (rc < 0) if (rc < 0) {
oml_tx_failure_event_rep(&trx->mo, OSMO_EVT_MAJ_UNSUP_ATTR,
"New value for Set Radio Attribute not"
" supported");
return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
}
/* merge existing BTS attributes with new attributes */ /* merge existing BTS attributes with new attributes */
tp_merged = tlvp_copy(trx->mo.nm_attr, trx->bts); tp_merged = osmo_tlvp_copy(trx->mo.nm_attr, trx->bts);
tlvp_merge(tp_merged, &tp); osmo_tlvp_merge(tp_merged, &tp);
/* Ask BTS driver to validate new merged attributes */ /* Ask BTS driver to validate new merged attributes */
rc = bts_model_check_oml(trx->bts, foh->msg_type, trx->mo.nm_attr, tp_merged, trx); rc = bts_model_check_oml(trx->bts, foh->msg_type, trx->mo.nm_attr, tp_merged, trx);
@@ -565,7 +764,7 @@ static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg)
/* ... and actually still parse them */ /* ... and actually still parse them */
/* 9.4.47 RF Max Power Reduction */ /* 9.4.47 RF Max Power Reduction */
if (TLVP_PRESENT(&tp, NM_ATT_RF_MAXPOWR_R)) { if (TLVP_PRES_LEN(&tp, NM_ATT_RF_MAXPOWR_R, 1)) {
trx->max_power_red = *TLVP_VAL(&tp, NM_ATT_RF_MAXPOWR_R) * 2; trx->max_power_red = *TLVP_VAL(&tp, NM_ATT_RF_MAXPOWR_R) * 2;
LOGP(DOML, LOGL_INFO, "Set RF Max Power Reduction = %d dBm\n", LOGP(DOML, LOGL_INFO, "Set RF Max Power Reduction = %d dBm\n",
trx->max_power_red); trx->max_power_red);
@@ -590,25 +789,80 @@ static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg)
trx->arfcn_num = length; trx->arfcn_num = length;
} else } else
trx->arfcn_num = 0; trx->arfcn_num = 0;
#else
if (trx != trx->bts->c0 && TLVP_PRESENT(&tp, NM_ATT_ARFCN_LIST)) {
const uint8_t *value = TLVP_VAL(&tp, NM_ATT_ARFCN_LIST);
uint16_t _value;
uint16_t length = TLVP_LEN(&tp, NM_ATT_ARFCN_LIST);
uint16_t arfcn;
if (length != 2) {
LOGP(DOML, LOGL_ERROR, "Expecting only one ARFCN, "
"because hopping not supported\n");
/* FIXME: send NACK */
return -ENOTSUP;
}
memcpy(&_value, value, 2);
arfcn = ntohs(_value);
value += 2;
if (arfcn > 1024) {
oml_tx_failure_event_rep(&trx->bts->mo,
OSMO_EVT_WARN_SW_WARN,
"Given ARFCN %u is unsupported",
arfcn);
LOGP(DOML, LOGL_NOTICE,
"Given ARFCN %u is unsupported.\n", arfcn);
return oml_fom_ack_nack(msg, NM_NACK_FREQ_NOTAVAIL);
}
trx->arfcn = arfcn;
}
#endif #endif
/* call into BTS driver to apply new attributes to hardware */ /* call into BTS driver to apply new attributes to hardware */
return bts_model_apply_oml(trx->bts, msg, tp_merged, NM_OC_RADIO_CARRIER, trx); return bts_model_apply_oml(trx->bts, msg, tp_merged, NM_OC_RADIO_CARRIER, trx);
} }
static int conf_lchans_for_pchan(struct gsm_bts_trx_ts *ts) static int conf_lchans(struct gsm_bts_trx_ts *ts)
{
enum gsm_phys_chan_config pchan = ts->pchan;
/* RSL_MT_IPAC_PDCH_ACT style dyn PDCH */
if (pchan == GSM_PCHAN_TCH_F_PDCH)
pchan = ts->flags & TS_F_PDCH_ACTIVE? GSM_PCHAN_PDCH
: GSM_PCHAN_TCH_F;
/* Osmocom RSL CHAN ACT style dyn TS */
if (pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
pchan = ts->dyn.pchan_is;
/* If the dyn TS doesn't have a pchan yet, do nothing. */
if (pchan == GSM_PCHAN_NONE)
return 0;
}
return conf_lchans_as_pchan(ts, pchan);
}
int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts,
enum gsm_phys_chan_config pchan)
{ {
struct gsm_lchan *lchan; struct gsm_lchan *lchan;
unsigned int i; unsigned int i;
switch (ts->pchan) { switch (pchan) {
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
/* fallthrough */
case GSM_PCHAN_CCCH_SDCCH4: case GSM_PCHAN_CCCH_SDCCH4:
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
lchan = &ts->lchan[i]; lchan = &ts->lchan[i];
lchan->type = GSM_LCHAN_SDCCH; if (pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH
&& i == 2) {
lchan->type = GSM_LCHAN_CBCH;
} else {
lchan->type = GSM_LCHAN_SDCCH;
}
} }
/* fallthrough */ /* fallthrough */
case GSM_PCHAN_CCCH: case GSM_PCHAN_CCCH:
lchan = &ts->lchan[4]; lchan = &ts->lchan[CCCH_LCHAN];
lchan->type = GSM_LCHAN_CCCH; lchan->type = GSM_LCHAN_CCCH;
break; break;
case GSM_PCHAN_TCH_F: case GSM_PCHAN_TCH_F:
@@ -621,10 +875,17 @@ static int conf_lchans_for_pchan(struct gsm_bts_trx_ts *ts)
lchan->type = GSM_LCHAN_TCH_H; lchan->type = GSM_LCHAN_TCH_H;
} }
break; break;
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
/* fallthrough */
case GSM_PCHAN_SDCCH8_SACCH8C: case GSM_PCHAN_SDCCH8_SACCH8C:
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
lchan = &ts->lchan[i]; lchan = &ts->lchan[i];
lchan->type = GSM_LCHAN_SDCCH; if (pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH
&& i == 2) {
lchan->type = GSM_LCHAN_CBCH;
} else {
lchan->type = GSM_LCHAN_SDCCH;
}
} }
break; break;
case GSM_PCHAN_PDCH: case GSM_PCHAN_PDCH:
@@ -632,8 +893,9 @@ static int conf_lchans_for_pchan(struct gsm_bts_trx_ts *ts)
lchan->type = GSM_LCHAN_PDTCH; lchan->type = GSM_LCHAN_PDTCH;
break; break;
default: default:
/* FIXME */ LOGP(DOML, LOGL_ERROR, "Unknown/unhandled PCHAN type: %u %s\n",
break; ts->pchan, gsm_pchan_name(ts->pchan));
return -NM_NACK_PARAM_RANGE;
} }
return 0; return 0;
} }
@@ -650,8 +912,12 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg)
DEBUGPC(DOML, "Rx SET CHAN ATTR\n"); DEBUGPC(DOML, "Rx SET CHAN ATTR\n");
rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
if (rc < 0) if (rc < 0) {
oml_tx_failure_event_rep(&ts->mo, OSMO_EVT_MAJ_UNSUP_ATTR,
"New value for Set Channel Attribute "
"not supported");
return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
}
/* 9.4.21 HSN... */ /* 9.4.21 HSN... */
/* 9.4.27 MAIO */ /* 9.4.27 MAIO */
@@ -667,8 +933,8 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg)
} }
/* merge existing BTS attributes with new attributes */ /* merge existing BTS attributes with new attributes */
tp_merged = tlvp_copy(ts->mo.nm_attr, bts); tp_merged = osmo_tlvp_copy(ts->mo.nm_attr, bts);
tlvp_merge(tp_merged, &tp); osmo_tlvp_merge(tp_merged, &tp);
/* Call into BTS driver to check attribute values */ /* Call into BTS driver to check attribute values */
rc = bts_model_check_oml(bts, foh->msg_type, ts->mo.nm_attr, tp_merged, ts); rc = bts_model_check_oml(bts, foh->msg_type, ts->mo.nm_attr, tp_merged, ts);
@@ -683,16 +949,21 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg)
ts->mo.nm_attr = tp_merged; ts->mo.nm_attr = tp_merged;
/* 9.4.13 Channel Combination */ /* 9.4.13 Channel Combination */
if (TLVP_PRESENT(&tp, NM_ATT_CHAN_COMB)) { if (TLVP_PRES_LEN(&tp, NM_ATT_CHAN_COMB, 1)) {
uint8_t comb = *TLVP_VAL(&tp, NM_ATT_CHAN_COMB); uint8_t comb = *TLVP_VAL(&tp, NM_ATT_CHAN_COMB);
ts->pchan = abis_nm_pchan4chcomb(comb); ts->pchan = abis_nm_pchan4chcomb(comb);
conf_lchans_for_pchan(ts); rc = conf_lchans(ts);
if (rc < 0) {
talloc_free(tp_merged);
/* Send NACK */
return oml_fom_ack_nack(msg, -rc);
}
} }
/* 9.4.5 ARFCN List */ /* 9.4.5 ARFCN List */
/* 9.4.60 TSC */ /* 9.4.60 TSC */
if (TLVP_PRESENT(&tp, NM_ATT_TSC) && TLVP_LEN(&tp, NM_ATT_TSC) >= 1) { if (TLVP_PRES_LEN(&tp, NM_ATT_TSC, 1)) {
ts->tsc = *TLVP_VAL(&tp, NM_ATT_TSC); ts->tsc = *TLVP_VAL(&tp, NM_ATT_TSC);
} else { } else {
/* If there is no TSC specified, use the BCC */ /* If there is no TSC specified, use the BCC */
@@ -772,6 +1043,38 @@ static int oml_rx_chg_adm_state(struct gsm_bts *bts, struct msgb *msg)
return bts_model_chg_adm_state(bts, mo, obj, adm_state); return bts_model_chg_adm_state(bts, mo, obj, adm_state);
} }
/* Check and report if the BTS number received via OML is incorrect:
according to 3GPP TS 52.021 §9.3 BTS number is used to distinguish between different BTS of the same Site Manager.
As we always have only single BTS per Site Manager (in case of Abis/IP with each BTS having dedicated OML connection
to BSC), the only valid values are 0 and 0xFF (means all BTS' of a given Site Manager). */
static inline bool report_bts_number_incorrect(struct gsm_bts *bts, const struct abis_om_fom_hdr *foh, bool is_formatted)
{
struct gsm_bts_trx *trx;
struct gsm_abis_mo *mo = &bts->mo;
const char *form = is_formatted ?
"Unexpected BTS %d in formatted O&M %s (exp. 0 or 0xFF)" :
"Unexpected BTS %d in manufacturer O&M %s (exp. 0 or 0xFF)";
if (foh->obj_inst.bts_nr != 0 && foh->obj_inst.bts_nr != 0xff) {
LOGP(DOML, LOGL_ERROR, form, foh->obj_inst.bts_nr, get_value_string(abis_nm_msgtype_names,
foh->msg_type));
LOGPC(DOML, LOGL_ERROR, "\n");
trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
if (trx) {
trx->mo.obj_inst.bts_nr = 0;
trx->mo.obj_inst.trx_nr = foh->obj_inst.trx_nr;
trx->mo.obj_inst.ts_nr = 0xff;
mo = &trx->mo;
}
oml_tx_failure_event_rep(mo, OSMO_EVT_MAJ_UKWN_MSG, form, foh->obj_inst.bts_nr,
get_value_string(abis_nm_msgtype_names, foh->msg_type));
return true;
}
return false;
}
static int down_fom(struct gsm_bts *bts, struct msgb *msg) static int down_fom(struct gsm_bts *bts, struct msgb *msg)
{ {
struct abis_om_fom_hdr *foh = msgb_l3(msg); struct abis_om_fom_hdr *foh = msgb_l3(msg);
@@ -780,13 +1083,19 @@ static int down_fom(struct gsm_bts *bts, struct msgb *msg)
if (msgb_l2len(msg) < sizeof(*foh)) { if (msgb_l2len(msg) < sizeof(*foh)) {
LOGP(DOML, LOGL_NOTICE, "Formatted O&M message too short\n"); LOGP(DOML, LOGL_NOTICE, "Formatted O&M message too short\n");
trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
if (trx) {
trx->mo.obj_inst.bts_nr = 0;
trx->mo.obj_inst.trx_nr = foh->obj_inst.trx_nr;
trx->mo.obj_inst.ts_nr = 0xff;
oml_tx_failure_event_rep(&trx->mo, OSMO_EVT_MAJ_UKWN_MSG,
"Formatted O&M message too short");
}
return -EIO; return -EIO;
} }
if (foh->obj_inst.bts_nr != 0 && foh->obj_inst.bts_nr != 0xff) { if (report_bts_number_incorrect(bts, foh, true))
LOGP(DOML, LOGL_INFO, "Formatted O&M with BTS %d out of range.\n", foh->obj_inst.bts_nr);
return oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN); return oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN);
}
switch (foh->msg_type) { switch (foh->msg_type) {
case NM_MT_SET_BTS_ATTR: case NM_MT_SET_BTS_ATTR:
@@ -815,9 +1124,26 @@ static int down_fom(struct gsm_bts *bts, struct msgb *msg)
case NM_MT_IPACC_SET_ATTR: case NM_MT_IPACC_SET_ATTR:
ret = oml_ipa_set_attr(bts, msg); ret = oml_ipa_set_attr(bts, msg);
break; break;
case NM_MT_GET_ATTR:
ret = oml_rx_get_attr(bts, msg);
break;
default: default:
LOGP(DOML, LOGL_INFO, "unknown Formatted O&M msg_type 0x%02x\n", LOGP(DOML, LOGL_INFO, "unknown Formatted O&M msg_type 0x%02x\n",
foh->msg_type); foh->msg_type);
trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
if (trx) {
trx->mo.obj_inst.bts_nr = 0;
trx->mo.obj_inst.trx_nr = foh->obj_inst.trx_nr;
trx->mo.obj_inst.ts_nr = 0xff;
oml_tx_failure_event_rep(&trx->mo, OSMO_EVT_MAJ_UKWN_MSG,
"unknown Formatted O&M "
"msg_type 0x%02x",
foh->msg_type);
} else
oml_tx_failure_event_rep(&bts->mo, OSMO_EVT_MAJ_UKWN_MSG,
"unknown Formatted O&M "
"msg_type 0x%02x",
foh->msg_type);
ret = oml_fom_ack_nack(msg, NM_NACK_MSGTYPE_INVAL); ret = oml_fom_ack_nack(msg, NM_NACK_MSGTYPE_INVAL);
} }
@@ -828,11 +1154,6 @@ static int down_fom(struct gsm_bts *bts, struct msgb *msg)
* manufacturer related messages * manufacturer related messages
*/ */
#ifndef TLVP_PRES_LEN /* old libosmocore */
#define TLVP_PRES_LEN(tp, tag, min_len) \
(TLVP_PRESENT(tp, tag) && TLVP_LEN(tp, tag) >= min_len)
#endif
static int oml_ipa_mo_set_attr_nse(void *obj, struct tlv_parsed *tp) static int oml_ipa_mo_set_attr_nse(void *obj, struct tlv_parsed *tp)
{ {
struct gsm_bts *bts = container_of(obj, struct gsm_bts, gprs.nse); struct gsm_bts *bts = container_of(obj, struct gsm_bts, gprs.nse);
@@ -986,8 +1307,15 @@ static int oml_ipa_set_attr(struct gsm_bts *bts, struct msgb *msg)
DEBUGPC(DOML, "Rx IPA SET ATTR\n"); DEBUGPC(DOML, "Rx IPA SET ATTR\n");
rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
if (rc < 0) if (rc < 0) {
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
if (!mo)
return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN);
oml_tx_failure_event_rep(mo, OSMO_EVT_MAJ_UNSUP_ATTR,
"New value for IPAC Set Attribute not "
"supported\n");
return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
}
/* Resolve MO by obj_class/obj_inst */ /* Resolve MO by obj_class/obj_inst */
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst); mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
@@ -1011,13 +1339,13 @@ static int rx_oml_ipa_rsl_connect(struct gsm_bts_trx *trx, struct msgb *msg,
uint8_t stream_id = 0; uint8_t stream_id = 0;
if (TLVP_PRESENT(tp, NM_ATT_IPACC_DST_IP)) { if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_DST_IP, 4)) {
ip = ntohl(tlvp_val32_unal(tp, NM_ATT_IPACC_DST_IP)); ip = ntohl(tlvp_val32_unal(tp, NM_ATT_IPACC_DST_IP));
} }
if (TLVP_PRESENT(tp, NM_ATT_IPACC_DST_IP_PORT)) { if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_DST_IP_PORT, 2)) {
port = ntohs(tlvp_val16_unal(tp, NM_ATT_IPACC_DST_IP_PORT)); port = ntohs(tlvp_val16_unal(tp, NM_ATT_IPACC_DST_IP_PORT));
} }
if (TLVP_PRESENT(tp, NM_ATT_IPACC_STREAM_ID)) { if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_STREAM_ID, 1)) {
stream_id = *TLVP_VAL(tp, NM_ATT_IPACC_STREAM_ID); stream_id = *TLVP_VAL(tp, NM_ATT_IPACC_STREAM_ID);
} }
@@ -1025,7 +1353,8 @@ static int rx_oml_ipa_rsl_connect(struct gsm_bts_trx *trx, struct msgb *msg,
LOGP(DOML, LOGL_INFO, "Rx IPA RSL CONNECT IP=%s PORT=%u STREAM=0x%02x\n", LOGP(DOML, LOGL_INFO, "Rx IPA RSL CONNECT IP=%s PORT=%u STREAM=0x%02x\n",
inet_ntoa(in), port, stream_id); inet_ntoa(in), port, stream_id);
rc = e1inp_ipa_bts_rsl_connect(oml_link->ts->line, inet_ntoa(in), port); rc = e1inp_ipa_bts_rsl_connect_n(oml_link->ts->line, inet_ntoa(in), port,
trx->nr);
if (rc < 0) { if (rc < 0) {
LOGP(DOML, LOGL_ERROR, "Error in abis_open(RSL): %d\n", rc); LOGP(DOML, LOGL_ERROR, "Error in abis_open(RSL): %d\n", rc);
return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM); return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM);
@@ -1056,10 +1385,8 @@ static int down_mom(struct gsm_bts *bts, struct msgb *msg)
msg->l3h = oh->data + 1 + idstrlen; msg->l3h = oh->data + 1 + idstrlen;
foh = (struct abis_om_fom_hdr *) msg->l3h; foh = (struct abis_om_fom_hdr *) msg->l3h;
if (foh->obj_inst.bts_nr != 0 && foh->obj_inst.bts_nr != 0xff) { if (report_bts_number_incorrect(bts, foh, false))
LOGP(DOML, LOGL_INFO, "Manufacturer O&M with BTS %d out of range.\n", foh->obj_inst.bts_nr);
return oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN); return oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN);
}
ret = oml_tlv_parse(&tp, foh->data, oh->length - sizeof(*foh)); ret = oml_tlv_parse(&tp, foh->data, oh->length - sizeof(*foh));
if (ret < 0) { if (ret < 0) {
@@ -1128,10 +1455,23 @@ int down_oml(struct gsm_bts *bts, struct msgb *msg)
return ret; return ret;
} }
int oml_init(void) static int handle_fail_sig(unsigned int subsys, unsigned int signal, void *handle,
void *signal_data)
{ {
DEBUGP(DOML, "Initializing OML attribute definitions\n"); if (signal_data)
tlv_def_patch(&abis_nm_att_tlvdef_ipa, &abis_nm_att_tlvdef); oml_tx_failure_event_rep(handle, signal, "%s", signal_data);
else
oml_tx_failure_event_rep(handle, signal, "");
return 0;
}
int oml_init(struct gsm_abis_mo *mo)
{
DEBUGP(DOML, "Initializing OML attribute definitions\n");
tlv_def_patch(&abis_nm_att_tlvdef_ipa_local, &abis_nm_att_tlvdef_ipa);
tlv_def_patch(&abis_nm_att_tlvdef_ipa_local, &abis_nm_att_tlvdef);
osmo_signal_register_handler(SS_FAIL, handle_fail_sig, mo);
return 0; return 0;
} }

View File

@@ -538,12 +538,6 @@ static int paging_signal_cbfn(unsigned int subsys, unsigned int signal, void *hd
struct paging_state *ps = btsb->paging_state; struct paging_state *ps = btsb->paging_state;
struct gsm48_system_information_type_3 *si3 = (void *) bts->si_buf[SYSINFO_TYPE_3]; struct gsm48_system_information_type_3 *si3 = (void *) bts->si_buf[SYSINFO_TYPE_3];
#warning "TODO: Remove this when setting u8NbrOfAgch is implemented properly"
if (si3->control_channel_desc.bs_ag_blks_res != 1)
LOGP(DPAG, LOGL_ERROR,
"Paging: BS_AG_BLKS_RES = %d != 1 not fully supported\n",
si3->control_channel_desc.bs_ag_blks_res);
paging_si_update(ps, &si3->control_channel_desc); paging_si_update(ps, &si3->control_channel_desc);
} }
return 0; return 0;

View File

@@ -29,9 +29,11 @@
#include <assert.h> #include <assert.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <inttypes.h>
#include <osmocom/core/talloc.h> #include <osmocom/core/talloc.h>
#include <osmocom/core/select.h> #include <osmocom/core/select.h>
#include <osmocom/core/socket.h>
#include <osmo-bts/logging.h> #include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h> #include <osmo-bts/gsm_data.h>
#include <osmo-bts/pcu_if.h> #include <osmo-bts/pcu_if.h>
@@ -39,12 +41,12 @@
#include <osmo-bts/bts.h> #include <osmo-bts/bts.h>
#include <osmo-bts/rsl.h> #include <osmo-bts/rsl.h>
#include <osmo-bts/signal.h> #include <osmo-bts/signal.h>
#include <osmo-bts/bts_model.h> #include <osmo-bts/l1sap.h>
uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx); uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx);
extern struct gsm_network bts_gsmnet; extern struct gsm_network bts_gsmnet;
extern int pcu_direct; int pcu_direct = 0;
static int avail_lai = 0, avail_nse = 0, avail_cell = 0, avail_nsvc[2] = {0, 0}; static int avail_lai = 0, avail_nse = 0, avail_cell = 0, avail_nsvc[2] = {0, 0};
static const char *sapi_string[] = { static const char *sapi_string[] = {
@@ -57,27 +59,7 @@ static const char *sapi_string[] = {
[PCU_IF_SAPI_PTCCH] = "PTCCH", [PCU_IF_SAPI_PTCCH] = "PTCCH",
}; };
/* FIXME: common l1if include ? */
int l1if_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);
static int pcu_sock_send(struct gsm_network *net, struct msgb *msg); static int pcu_sock_send(struct gsm_network *net, struct msgb *msg);
/* FIXME: move this to libosmocore */
int osmo_unixsock_listen(struct osmo_fd *bfd, int type, const char *path);
static struct gsm_bts_trx *trx_by_nr(struct gsm_bts *bts, uint8_t trx_nr)
{
struct gsm_bts_trx *trx;
llist_for_each_entry(trx, &bts->trx_list, list) {
if (trx->nr == trx_nr)
return trx;
}
return NULL;
}
/* /*
* PCU messages * PCU messages
@@ -99,6 +81,32 @@ struct msgb *pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr)
return msg; 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) int pcu_tx_info_ind(void)
{ {
struct gsm_network *net = &bts_gsmnet; struct gsm_network *net = &bts_gsmnet;
@@ -202,7 +210,7 @@ int pcu_tx_info_ind(void)
} }
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
trx = trx_by_nr(bts, i); trx = gsm_bts_trx_num(bts, i);
if (!trx) if (!trx)
break; break;
info_ind->trx[i].pdch_mask = 0; info_ind->trx[i].pdch_mask = 0;
@@ -211,10 +219,10 @@ int pcu_tx_info_ind(void)
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
ts = &trx->ts[j]; ts = &trx->ts[j];
if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED
&& ts->pchan == GSM_PCHAN_PDCH) { && ts_should_be_pdch(ts)) {
info_ind->trx[i].pdch_mask |= (1 << j); info_ind->trx[i].pdch_mask |= (1 << j);
info_ind->trx[i].tsc[j] = info_ind->trx[i].tsc[j] =
(ts->tsc >= 0) ? ts->tsc : bts->tsc; (ts->tsc >= 0) ? ts->tsc : bts->bsic & 7;
LOGP(DPCU, LOGL_INFO, "trx=%d ts=%d: " LOGP(DPCU, LOGL_INFO, "trx=%d ts=%d: "
"available (tsc=%d arfcn=%d)\n", "available (tsc=%d arfcn=%d)\n",
trx->nr, ts->nr, trx->nr, ts->nr,
@@ -316,17 +324,24 @@ int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, 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, uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len,
int8_t rssi) int8_t rssi, uint16_t ber10k, int16_t bto, int16_t lqual)
{ {
struct msgb *msg; struct msgb *msg;
struct gsm_pcu_if *pcu_prim; struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_data *data_ind; struct gsm_pcu_if_data *data_ind;
struct gsm_bts *bts = ts->trx->bts; 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 " LOGP(DPCU, LOGL_DEBUG, "Sending data indication: is_ptcch=%d arfcn=%d "
"block=%d data=%s\n", is_ptcch, arfcn, block_nr, "block=%d data=%s\n", is_ptcch, arfcn, block_nr,
osmo_hexdump(data, len)); 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); msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_IND, bts->nr);
if (!msg) if (!msg)
return -ENOMEM; return -ENOMEM;
@@ -334,19 +349,24 @@ int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
data_ind = &pcu_prim->u.data_ind; data_ind = &pcu_prim->u.data_ind;
data_ind->sapi = (is_ptcch) ? PCU_IF_SAPI_PTCCH : PCU_IF_SAPI_PDTCH; data_ind->sapi = (is_ptcch) ? PCU_IF_SAPI_PTCCH : PCU_IF_SAPI_PDTCH;
data_ind->rssi = rssi;
data_ind->fn = fn; data_ind->fn = fn;
data_ind->arfcn = arfcn; data_ind->arfcn = arfcn;
data_ind->trx_nr = ts->trx->nr; data_ind->trx_nr = ts->trx->nr;
data_ind->ts_nr = ts->nr; data_ind->ts_nr = ts->nr;
data_ind->block_nr = block_nr; data_ind->block_nr = block_nr;
data_ind->rssi = rssi; 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); memcpy(data_ind->data, data, len);
data_ind->len = len; data_ind->len = len;
return pcu_sock_send(&bts_gsmnet, msg); return pcu_sock_send(&bts_gsmnet, msg);
} }
int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint8_t ra, uint32_t fn) 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 msgb *msg;
struct gsm_pcu_if *pcu_prim; struct gsm_pcu_if *pcu_prim;
@@ -365,6 +385,8 @@ int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint8_t ra, uint32_t fn)
rach_ind->ra = ra; rach_ind->ra = ra;
rach_ind->qta = qta; rach_ind->qta = qta;
rach_ind->fn = fn; rach_ind->fn = fn;
rach_ind->is_11bit = is_11bit;
rach_ind->burst_type = burst_type;
return pcu_sock_send(&bts_gsmnet, msg); return pcu_sock_send(&bts_gsmnet, msg);
} }
@@ -503,7 +525,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
break; break;
case PCU_IF_SAPI_PDTCH: case PCU_IF_SAPI_PDTCH:
case PCU_IF_SAPI_PTCCH: case PCU_IF_SAPI_PTCCH:
trx = trx_by_nr(bts, data_req->trx_nr); trx = gsm_bts_trx_num(bts, data_req->trx_nr);
if (!trx) { if (!trx) {
LOGP(DPCU, LOGL_ERROR, "Received PCU data request with " LOGP(DPCU, LOGL_ERROR, "Received PCU data request with "
"not existing TRX %d\n", data_req->trx_nr); "not existing TRX %d\n", data_req->trx_nr);
@@ -512,7 +534,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
} }
ts = &trx->ts[data_req->ts_nr]; ts = &trx->ts[data_req->ts_nr];
is_ptcch = (data_req->sapi == PCU_IF_SAPI_PTCCH); is_ptcch = (data_req->sapi == PCU_IF_SAPI_PTCCH);
rc = l1if_pdch_req(ts, is_ptcch, data_req->fn, data_req->arfcn, rc = l1sap_pdch_req(ts, is_ptcch, data_req->fn, data_req->arfcn,
data_req->block_nr, data_req->data, data_req->len); data_req->block_nr, data_req->data, data_req->len);
break; break;
default: default:
@@ -524,6 +546,28 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
return rc; 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, static int pcu_rx_act_req(struct gsm_bts *bts,
struct gsm_pcu_if_act_req *act_req) struct gsm_pcu_if_act_req *act_req)
{ {
@@ -534,21 +578,23 @@ static int pcu_rx_act_req(struct gsm_bts *bts,
(act_req->activate) ? "Activate" : "Deactivate", (act_req->activate) ? "Activate" : "Deactivate",
act_req->trx_nr, act_req->ts_nr); act_req->trx_nr, act_req->ts_nr);
trx = trx_by_nr(bts, act_req->trx_nr); trx = gsm_bts_trx_num(bts, act_req->trx_nr);
if (!trx || act_req->ts_nr >= 8) if (!trx || act_req->ts_nr >= 8)
return -EINVAL; return -EINVAL;
lchan = trx->ts[act_req->ts_nr].lchan; lchan = trx->ts[act_req->ts_nr].lchan;
lchan->rel_act_kind = LCHAN_REL_ACT_PCU; lchan->rel_act_kind = LCHAN_REL_ACT_PCU;
if (lchan->type != GSM_LCHAN_PDTCH) { if (lchan->type != GSM_LCHAN_PDTCH) {
LOGP(DPCU, LOGL_ERROR, "Lchan is not of type PDCH, but %d.\n", LOGP(DPCU, LOGL_ERROR,
lchan->type); "%s request, but lchan is not of type PDTCH (is %s)\n",
(act_req->activate) ? "Activate" : "Deactivate",
gsm_lchant_name(lchan->type));
return -EINVAL; return -EINVAL;
} }
if (act_req->activate) if (act_req->activate)
bts_model_rsl_chan_act(lchan, NULL); l1sap_chan_act(trx, gsm_lchan2chan_nr(lchan), NULL);
else else
bts_model_rsl_chan_rel(lchan); l1sap_chan_rel(trx, gsm_lchan2chan_nr(lchan));
return 0; return 0;
} }
@@ -570,6 +616,9 @@ static int pcu_rx(struct gsm_network *net, uint8_t msg_type,
case PCU_IF_MSG_ACT_REQ: case PCU_IF_MSG_ACT_REQ:
rc = pcu_rx_act_req(bts, &pcu_prim->u.act_req); rc = pcu_rx_act_req(bts, &pcu_prim->u.act_req);
break; break;
case PCU_IF_MSG_TXT_IND:
rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind);
break;
default: default:
LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n", LOGP(DPCU, LOGL_ERROR, "Received unknwon PCU msg type %d\n",
msg_type); msg_type);
@@ -629,6 +678,8 @@ static void pcu_sock_close(struct pcu_sock_state *state)
bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list); bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list);
LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n"); 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); close(bfd->fd);
bfd->fd = -1; bfd->fd = -1;
@@ -645,7 +696,7 @@ static void pcu_sock_close(struct pcu_sock_state *state)
/* release PDCH */ /* release PDCH */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
trx = trx_by_nr(bts, i); trx = gsm_bts_trx_num(bts, i);
if (!trx) if (!trx)
break; break;
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
@@ -653,7 +704,8 @@ static void pcu_sock_close(struct pcu_sock_state *state)
if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED
&& ts->pchan == GSM_PCHAN_PDCH) { && ts->pchan == GSM_PCHAN_PDCH) {
ts->lchan->rel_act_kind = LCHAN_REL_ACT_PCU; ts->lchan->rel_act_kind = LCHAN_REL_ACT_PCU;
bts_model_rsl_chan_rel(ts->lchan); l1sap_chan_rel(trx,
gsm_lchan2chan_nr(ts->lchan));
} }
} }
} }
@@ -811,7 +863,7 @@ static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags)
return 0; return 0;
} }
int pcu_sock_init(void) int pcu_sock_init(const char *path)
{ {
struct pcu_sock_state *state; struct pcu_sock_state *state;
struct osmo_fd *bfd; struct osmo_fd *bfd;
@@ -827,12 +879,13 @@ int pcu_sock_init(void)
bfd = &state->listen_bfd; bfd = &state->listen_bfd;
rc = osmo_unixsock_listen(bfd, SOCK_SEQPACKET, "/tmp/pcu_bts"); bfd->fd = osmo_sock_unix_init(SOCK_SEQPACKET, 0, path,
if (rc < 0) { OSMO_SOCK_F_BIND);
LOGP(DPCU, LOGL_ERROR, "Could not create unix socket: %s\n", if (bfd->fd < 0) {
strerror(errno)); LOGP(DPCU, LOGL_ERROR, "Could not create %s unix socket: %s\n",
path, strerror(errno));
talloc_free(state); talloc_free(state);
return rc; return -1;
} }
bfd->when = BSC_FD_READ; bfd->when = BSC_FD_READ;
@@ -874,53 +927,13 @@ void pcu_sock_exit(void)
bts_gsmnet.pcu_state = NULL; bts_gsmnet.pcu_state = NULL;
} }
/* FIXME: move this to libosmocore */ bool pcu_connected(void) {
int osmo_unixsock_listen(struct osmo_fd *bfd, int type, const char *path) struct gsm_network *net = &bts_gsmnet;
{ struct pcu_sock_state *state = net->pcu_state;
struct sockaddr_un local;
unsigned int namelen;
int rc;
bfd->fd = socket(AF_UNIX, type, 0); if (!state)
return false;
if (bfd->fd < 0) { if (state->conn_bfd.fd <= 0)
fprintf(stderr, "Failed to create Unix Domain Socket.\n"); return false;
return -1; return true;
}
local.sun_family = AF_UNIX;
strncpy(local.sun_path, path, sizeof(local.sun_path));
local.sun_path[sizeof(local.sun_path) - 1] = '\0';
unlink(local.sun_path);
/* we use the same magic that X11 uses in Xtranssock.c for
* calculating the proper length of the sockaddr */
#if defined(BSD44SOCKETS) || defined(__UNIXWARE__)
local.sun_len = strlen(local.sun_path);
#endif
#if defined(BSD44SOCKETS) || defined(SUN_LEN)
namelen = SUN_LEN(&local);
#else
namelen = strlen(local.sun_path) +
offsetof(struct sockaddr_un, sun_path);
#endif
rc = bind(bfd->fd, (struct sockaddr *) &local, namelen);
if (rc != 0) {
fprintf(stderr, "Failed to bind the unix domain socket. '%s'\n",
local.sun_path);
close(bfd->fd);
bfd->fd = -1;
return -1;
}
if (listen(bfd->fd, 0) != 0) {
fprintf(stderr, "Failed to listen.\n");
close(bfd->fd);
bfd->fd = -1;
return -1;
}
return 0;
} }

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;
}

View File

@@ -0,0 +1,99 @@
/* MS Power Control Loop L1 */
/* (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 <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/measurement.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/l1sap.h>
/*
* Check if manual power control is needed
* Check if fixed power was selected
* Check if the MS is already using our level if not
* the value is bogus..
* TODO: Add a timeout.. e.g. if the ms is not capable of reaching
* the value we have set.
*/
int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan,
const uint8_t ms_power, const int rxLevel)
{
int rx;
int cur_dBm, new_dBm, new_pwr;
struct gsm_bts *bts = lchan->ts->trx->bts;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
const enum gsm_band band = bts->band;
if (!trx_ms_pwr_ctrl_is_osmo(lchan->ts->trx))
return 0;
if (lchan->ms_power_ctrl.fixed)
return 0;
/* The phone hasn't reached the power level yet */
if (lchan->ms_power_ctrl.current != ms_power)
return 0;
/*
* What is the difference between what we want and received?
* Ignore a margin that is within the range of measurement
* and MS output issues.
*/
rx = btsb->ul_power_target - rxLevel;
if (rx >= 0 && rx < 1)
return 0;
if (rx < 0 && rx > -1)
return 0;
/* We don't really care about the truncation of int + float */
cur_dBm = ms_pwr_dbm(band, ms_power);
new_dBm = cur_dBm + rx;
/* Clamp negative values and do it depending on the band */
if (new_dBm < 0)
new_dBm = 0;
switch (band) {
case GSM_BAND_1800:
/* If MS_TX_PWR_MAX_CCH is set the values 29,
* 30, 31 are not used. Avoid specifying a dBm
* that would lead to these power levels. The
* phone might not be able to reach them. */
if (new_dBm > 30)
new_dBm = 30;
break;
default:
break;
}
new_pwr = ms_pwr_ctl_lvl(band, new_dBm);
if (lchan->ms_power_ctrl.current != new_pwr) {
lchan->ms_power_ctrl.current = new_pwr;
bts_model_adjst_ms_pwr(lchan);
return 1;
}
return 0;
}

File diff suppressed because it is too large Load Diff

1712
src/common/scheduler.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,82 +0,0 @@
/* (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU 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 <sys/types.h>
#include <string.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
//#include <osmocom/bb/common/osmocom_data.h>
#include <osmo-bts/support.h>
struct bts_support bts_support;
void bts_support_init(void)
{
struct bts_support *sup = &bts_support;
int i;
memset(sup, 0, sizeof(*sup));
/* crypto supprot */
sup->a5_1 = 0;
sup->a5_2 = 0;
sup->a5_3 = 0;
sup->a5_4 = 0;
sup->a5_5 = 0;
sup->a5_6 = 0;
sup->a5_7 = 0;
/* set supported frequencies */
for(i = 1; i <= 124; i++) // P-GSM
sup->freq_map[i >> 3] |= (1 << (i & 7));
for(i = 512; i <= 885; i++) // DCS
sup->freq_map[i >> 3] |= (1 << (i & 7));
for(i = 975; i <= 1023; i++) // E-GSM extension
sup->freq_map[i >> 3] |= (1 << (i & 7));
sup->freq_map[0] |= 1; // channel 0
for(i = 955; i <= 974; i++) // R-GSM extension
sup->freq_map[i >> 3] |= (1 << (i & 7));
/* channel combinations */
sup->chan_comb[NM_CHANC_mainBCCH] = 1;
sup->chan_comb[NM_CHANC_BCCHComb] = 1;
sup->chan_comb[NM_CHANC_SDCCH] = 1;
sup->chan_comb[NM_CHANC_TCHFull] = 1;
sup->chan_comb[NM_CHANC_TCHHalf] = 1;
/* codec */
sup->full_v1 = 1;
sup->full_v2 = 1;
sup->full_v3 = 1;
sup->half_v1 = 1;
sup->half_v3 = 1;
}
char *bts_support_comb_name(uint8_t chan_comb)
{
if (chan_comb == NM_CHANC_mainBCCH)
return("BCCH");
if (chan_comb == NM_CHANC_BCCHComb)
return("BCCH+SDCCH/4");
if (chan_comb == NM_CHANC_SDCCH)
return("SDCCH/8");
if (chan_comb == NM_CHANC_TCHFull)
return("TCH/F");
if (chan_comb == NM_CHANC_TCHHalf)
return("TCH/H");
return "Unknown";
}

View File

@@ -22,12 +22,21 @@
#include <osmocom/gsm/gsm_utils.h> #include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/sysinfo.h> #include <osmocom/gsm/sysinfo.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h> #include <osmo-bts/gsm_data.h>
#define BTS_HAS_SI(bts, sinum) ((bts)->si_valid & (1 << sinum)) /* properly increment SI2q index and return SI2q data for scheduling */
static inline uint8_t *get_si2q_inc_index(struct gsm_bts *bts)
{
uint8_t i = bts->si2q_index;
/* si2q_count is the max si2q_index value, not the number of messages */
bts->si2q_index = (bts->si2q_index + 1) % (bts->si2q_count + 1);
return (uint8_t *)GSM_BTS_SI2Q(bts, i);
}
/* Apply the rules from 05.02 6.3.1.3 Mapping of BCCH Data */ /* Apply the rules from 05.02 6.3.1.3 Mapping of BCCH Data */
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, struct gsm_time *g_time) uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time)
{ {
struct gsm_bts_role_bts *btsb = bts_role_bts(bts); struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
unsigned int tc4_cnt = 0; unsigned int tc4_cnt = 0;
@@ -76,21 +85,20 @@ uint8_t *bts_sysinfo_get(struct gsm_bts *bts, struct gsm_time *g_time)
/* iterate over 2ter, 2quater, 9, 13 */ /* iterate over 2ter, 2quater, 9, 13 */
/* determine how many SI we need to send on TC=4, /* determine how many SI we need to send on TC=4,
* and which of them we send when */ * and which of them we send when */
if (BTS_HAS_SI(bts, SYSINFO_TYPE_2ter)) { if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2ter) && GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2bis)) {
tc4_sub[tc4_cnt] = SYSINFO_TYPE_2ter; tc4_sub[tc4_cnt] = SYSINFO_TYPE_2ter;
tc4_cnt += 1; /* 2bis */ tc4_cnt += 1;
} }
if (BTS_HAS_SI(bts, SYSINFO_TYPE_2quater) && if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2quater) &&
(BTS_HAS_SI(bts, SYSINFO_TYPE_2bis) || (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2bis) || GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2ter))) {
BTS_HAS_SI(bts, SYSINFO_TYPE_2bis))) {
tc4_sub[tc4_cnt] = SYSINFO_TYPE_2quater; tc4_sub[tc4_cnt] = SYSINFO_TYPE_2quater;
tc4_cnt += 1; tc4_cnt += 1;
} }
if (BTS_HAS_SI(bts, SYSINFO_TYPE_13)) { if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_13)) {
tc4_sub[tc4_cnt] = SYSINFO_TYPE_13; tc4_sub[tc4_cnt] = SYSINFO_TYPE_13;
tc4_cnt += 1; tc4_cnt += 1;
} }
if (BTS_HAS_SI(bts, SYSINFO_TYPE_9)) { if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_9)) {
/* FIXME: check SI3 scheduling info! */ /* FIXME: check SI3 scheduling info! */
tc4_sub[tc4_cnt] = SYSINFO_TYPE_9; tc4_sub[tc4_cnt] = SYSINFO_TYPE_9;
tc4_cnt += 1; tc4_cnt += 1;
@@ -101,26 +109,30 @@ uint8_t *bts_sysinfo_get(struct gsm_bts *bts, struct gsm_time *g_time)
else { else {
/* increment static counter by one, modulo count */ /* increment static counter by one, modulo count */
btsb->si.tc4_ctr = (btsb->si.tc4_ctr + 1) % tc4_cnt; btsb->si.tc4_ctr = (btsb->si.tc4_ctr + 1) % tc4_cnt;
if (tc4_sub[btsb->si.tc4_ctr] == SYSINFO_TYPE_2quater)
return get_si2q_inc_index(bts);
return GSM_BTS_SI(bts, tc4_sub[btsb->si.tc4_ctr]); return GSM_BTS_SI(bts, tc4_sub[btsb->si.tc4_ctr]);
} }
case 5: case 5:
/* 2bis, 2ter, 2quater */ /* 2bis, 2ter, 2quater */
if (BTS_HAS_SI(bts, SYSINFO_TYPE_2bis) && if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2bis) && !GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2ter))
!BTS_HAS_SI(bts, SYSINFO_TYPE_2ter))
return GSM_BTS_SI(bts, SYSINFO_TYPE_2bis); return GSM_BTS_SI(bts, SYSINFO_TYPE_2bis);
else if (BTS_HAS_SI(bts, SYSINFO_TYPE_2ter) && else if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2ter) && !GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2bis))
!BTS_HAS_SI(bts, SYSINFO_TYPE_2bis))
return GSM_BTS_SI(bts, SYSINFO_TYPE_2ter); return GSM_BTS_SI(bts, SYSINFO_TYPE_2ter);
else if (BTS_HAS_SI(bts, SYSINFO_TYPE_2bis) && else if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2bis) && GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2ter))
BTS_HAS_SI(bts, SYSINFO_TYPE_2ter))
return GSM_BTS_SI(bts, SYSINFO_TYPE_2bis); return GSM_BTS_SI(bts, SYSINFO_TYPE_2bis);
else if (BTS_HAS_SI(bts, SYSINFO_TYPE_2quater) && else if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2quater) &&
!BTS_HAS_SI(bts, SYSINFO_TYPE_2bis) && !GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2bis) && !GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_2ter))
!BTS_HAS_SI(bts, SYSINFO_TYPE_2ter)) return get_si2q_inc_index(bts);
return GSM_BTS_SI(bts, SYSINFO_TYPE_2quater);
/* simply send SI2 if we have nothing else to send */
else
return GSM_BTS_SI(bts, SYSINFO_TYPE_2);
break; break;
case 6: case 6:
return GSM_BTS_SI(bts, SYSINFO_TYPE_3); return GSM_BTS_SI(bts, SYSINFO_TYPE_3);
@@ -128,7 +140,22 @@ uint8_t *bts_sysinfo_get(struct gsm_bts *bts, struct gsm_time *g_time)
return GSM_BTS_SI(bts, SYSINFO_TYPE_4); return GSM_BTS_SI(bts, SYSINFO_TYPE_4);
} }
return NULL; /* this should never bve reached. We must transmit a BCCH
* message on the normal BCCH in all cases. */
OSMO_ASSERT(0);
}
uint8_t num_agch(struct gsm_bts_trx *trx, const char * arg)
{
struct gsm_bts *b = trx->bts;
struct gsm48_system_information_type_3 *si3;
if (GSM_BTS_HAS_SI(b, SYSINFO_TYPE_3)) {
si3 = GSM_BTS_SI(b, SYSINFO_TYPE_3);
return si3->control_channel_desc.bs_ag_blks_res;
}
LOGP(DL1P, LOGL_ERROR, "%s: Unable to determine actual BS_AG_BLKS_RES "
"value as SI3 is not available yet, fallback to 1\n", arg);
return 1;
} }
uint8_t *lchan_sacch_get(struct gsm_lchan *lchan) uint8_t *lchan_sacch_get(struct gsm_lchan *lchan)
@@ -136,10 +163,10 @@ uint8_t *lchan_sacch_get(struct gsm_lchan *lchan)
uint32_t tmp; uint32_t tmp;
for (tmp = lchan->si.last + 1; tmp != lchan->si.last; tmp = (tmp + 1) % _MAX_SYSINFO_TYPE) { for (tmp = lchan->si.last + 1; tmp != lchan->si.last; tmp = (tmp + 1) % _MAX_SYSINFO_TYPE) {
if (lchan->si.valid & (1 << tmp)) { if (!(lchan->si.valid & (1 << tmp)))
lchan->si.last = tmp; continue;
return lchan->si.buf[tmp]; lchan->si.last = tmp;
} return GSM_LCHAN_SI(lchan, tmp);
} }
return NULL; return NULL;
} }

View File

@@ -33,12 +33,12 @@
static int get_pa_drive_level_mdBm(const struct power_amp *pa, static int get_pa_drive_level_mdBm(const struct power_amp *pa,
int desired_p_out_mdBm, unsigned int arfcn) int desired_p_out_mdBm, unsigned int arfcn)
{ {
if (arfcn >= ARRAY_SIZE(pa->calib.gain_mdB)) if (arfcn >= ARRAY_SIZE(pa->calib.delta_mdB))
return INT_MIN; return INT_MIN;
/* FIXME: temperature compensation */ /* FIXME: temperature compensation */
return desired_p_out_mdBm - pa->calib.gain_mdB[arfcn]; return desired_p_out_mdBm - pa->nominal_gain_mdB - pa->calib.delta_mdB[arfcn];
} }
/* maximum output power of the system */ /* maximum output power of the system */
@@ -58,7 +58,7 @@ int get_p_nominal_mdBm(struct gsm_bts_trx *trx)
} }
/* calculate the target total output power required, reduced by both /* calculate the target total output power required, reduced by both
* OML and RSL, but ignoring the attenutation required for power ramping and * OML and RSL, but ignoring the attenuation required for power ramping and
* thermal management */ * thermal management */
int get_p_target_mdBm(struct gsm_bts_trx *trx, uint8_t bs_power_ie) int get_p_target_mdBm(struct gsm_bts_trx *trx, uint8_t bs_power_ie)
{ {
@@ -71,7 +71,7 @@ int get_p_target_mdBm_lchan(struct gsm_lchan *lchan)
} }
/* calculate the actual total output power required, taking into account the /* calculate the actual total output power required, taking into account the
* attenutation required for power ramping but not thermal management */ * attenuation required for power ramping but not thermal management */
int get_p_actual_mdBm(struct gsm_bts_trx *trx, int p_target_mdBm) int get_p_actual_mdBm(struct gsm_bts_trx *trx, int p_target_mdBm)
{ {
struct trx_power_params *tpp = &trx->power_params; struct trx_power_params *tpp = &trx->power_params;
@@ -81,7 +81,7 @@ int get_p_actual_mdBm(struct gsm_bts_trx *trx, int p_target_mdBm)
} }
/* calculate the effective total output power required, taking into account the /* calculate the effective total output power required, taking into account the
* attenutation required for power ramping and thermal management */ * attenuation required for power ramping and thermal management */
int get_p_eff_mdBm(struct gsm_bts_trx *trx, int p_target_mdBm) int get_p_eff_mdBm(struct gsm_bts_trx *trx, int p_target_mdBm)
{ {
struct trx_power_params *tpp = &trx->power_params; struct trx_power_params *tpp = &trx->power_params;
@@ -144,7 +144,7 @@ int get_p_trxout_target_mdBm_lchan(struct gsm_lchan *lchan)
* one hand side to avoid very fast dynamic load changes towards the PA power * one hand side to avoid very fast dynamic load changes towards the PA power
* supply, but is also needed in order to avoid a DoS by too many subscriber * supply, but is also needed in order to avoid a DoS by too many subscriber
* attempting to register at the same time. Rather, grow the cell slowly in * attempting to register at the same time. Rather, grow the cell slowly in
* radius than start with the full raduis at once. */ * radius than start with the full radius at once. */
static int we_are_ramping_up(struct gsm_bts_trx *trx) static int we_are_ramping_up(struct gsm_bts_trx *trx)
{ {
@@ -158,7 +158,7 @@ static int we_are_ramping_up(struct gsm_bts_trx *trx)
static void power_ramp_do_step(struct gsm_bts_trx *trx, int first); static void power_ramp_do_step(struct gsm_bts_trx *trx, int first);
/* timer call-back for the ramp tumer */ /* timer call-back for the ramp timer */
static void power_ramp_timer_cb(void *_trx) static void power_ramp_timer_cb(void *_trx)
{ {
struct gsm_bts_trx *trx = _trx; struct gsm_bts_trx *trx = _trx;
@@ -289,3 +289,18 @@ int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass)
return 0; return 0;
} }
/* determine the initial transceiver output power at start-up time */
int power_ramp_initial_power_mdBm(struct gsm_bts_trx *trx)
{
struct trx_power_params *tpp = &trx->power_params;
int pout_mdBm;
/* this is the maximum initial output on the antenna connector
* towards the antenna */
pout_mdBm = tpp->ramp.max_initial_pout_mdBm;
/* use this as input to compute transceiver board power
* (reflecting gains in internal/external amplifiers */
return get_p_trxout_eff_mdBm(trx, pout_mdBm);
}

View File

@@ -1,6 +1,6 @@
/* OsmoBTS VTY interface */ /* OsmoBTS VTY interface */
/* (C) 2011 by Harald Welte <laforge@gnumonks.org> /* (C) 2011-2014 by Harald Welte <laforge@gnumonks.org>
* *
* All Rights Reserved * All Rights Reserved
* *
@@ -21,34 +21,72 @@
#include "btsconfig.h" #include "btsconfig.h"
#include <inttypes.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <ctype.h>
#include <osmocom/core/talloc.h> #include <osmocom/core/talloc.h>
#include <osmocom/gsm/abis_nm.h> #include <osmocom/gsm/abis_nm.h>
#include <osmocom/vty/vty.h> #include <osmocom/vty/vty.h>
#include <osmocom/vty/command.h> #include <osmocom/vty/command.h>
#include <osmocom/vty/logging.h> #include <osmocom/vty/logging.h>
#include <osmocom/vty/misc.h>
#include <osmocom/vty/ports.h>
#include <osmocom/core/gsmtap.h>
#include <osmocom/core/utils.h>
#include <osmocom/trau/osmo_ortp.h> #include <osmocom/trau/osmo_ortp.h>
#include <osmo-bts/logging.h> #include <osmo-bts/logging.h>
#include <osmo-bts/gsm_data.h> #include <osmo-bts/gsm_data.h>
#include <osmo-bts/phy_link.h>
#include <osmo-bts/abis.h> #include <osmo-bts/abis.h>
#include <osmo-bts/bts.h> #include <osmo-bts/bts.h>
#include <osmo-bts/rsl.h> #include <osmo-bts/rsl.h>
#include <osmo-bts/oml.h> #include <osmo-bts/oml.h>
#include <osmo-bts/signal.h> #include <osmo-bts/signal.h>
#include <osmo-bts/bts_model.h> #include <osmo-bts/bts_model.h>
#include <osmo-bts/pcu_if.h>
#include <osmo-bts/measurement.h> #include <osmo-bts/measurement.h>
#include <osmo-bts/vty.h> #include <osmo-bts/vty.h>
#include <osmo-bts/l1sap.h>
#define VTY_STR "Configure the VTY\n"
enum node_type bts_vty_go_parent(struct vty *vty) int g_vty_port_num = OSMO_VTY_PORT_BTS;
struct phy_instance *vty_get_phy_instance(struct vty *vty, int phy_nr, int inst_nr)
{
struct phy_link *plink = phy_link_by_num(phy_nr);
struct phy_instance *pinst;
if (!plink) {
vty_out(vty, "Cannot find PHY link number %d%s",
phy_nr, VTY_NEWLINE);
return NULL;
}
pinst = phy_instance_by_num(plink, inst_nr);
if (!pinst) {
vty_out(vty, "Cannot find PHY instance number %d%s",
inst_nr, VTY_NEWLINE);
return NULL;
}
return pinst;
}
int bts_vty_go_parent(struct vty *vty)
{ {
switch (vty->node) { switch (vty->node) {
case PHY_INST_NODE:
vty->node = PHY_NODE;
{
struct phy_instance *pinst = vty->index;
vty->index = pinst->phy_link;
}
break;
case TRX_NODE: case TRX_NODE:
vty->node = BTS_NODE; vty->node = BTS_NODE;
{ {
@@ -56,6 +94,7 @@ enum node_type bts_vty_go_parent(struct vty *vty)
vty->index = trx->bts; vty->index = trx->bts;
} }
break; break;
case PHY_NODE:
default: default:
vty->node = CONFIG_NODE; vty->node = CONFIG_NODE;
} }
@@ -67,6 +106,8 @@ int bts_vty_is_config_node(struct vty *vty, int node)
switch (node) { switch (node) {
case TRX_NODE: case TRX_NODE:
case BTS_NODE: case BTS_NODE:
case PHY_NODE:
case PHY_INST_NODE:
return 1; return 1;
default: default:
return 0; return 0;
@@ -77,6 +118,17 @@ gDEFUN(ournode_exit, ournode_exit_cmd, "exit",
"Exit current node, go down to provious node") "Exit current node, go down to provious node")
{ {
switch (vty->node) { switch (vty->node) {
case PHY_INST_NODE:
vty->node = PHY_NODE;
{
struct phy_instance *pinst = vty->index;
vty->index = pinst->phy_link;
}
break;
case PHY_NODE:
vty->node = CONFIG_NODE;
vty->index = NULL;
break;
case TRX_NODE: case TRX_NODE:
vty->node = BTS_NODE; vty->node = BTS_NODE;
{ {
@@ -127,18 +179,41 @@ struct gsm_network *gsmnet_from_vty(struct vty *v)
static struct cmd_node bts_node = { static struct cmd_node bts_node = {
BTS_NODE, BTS_NODE,
"%s(bts)#", "%s(bts)# ",
1, 1,
}; };
static struct cmd_node trx_node = { static struct cmd_node trx_node = {
TRX_NODE, TRX_NODE,
"%s(trx)#", "%s(trx)# ",
1, 1,
}; };
gDEFUN(cfg_bts_auto_band, cfg_bts_auto_band_cmd,
"auto-band",
"Automatically select band for ARFCN based on configured band\n")
{
struct gsm_bts *bts = vty->index;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
btsb->auto_band = 1;
return CMD_SUCCESS;
}
gDEFUN(cfg_bts_no_auto_band, cfg_bts_no_auto_band_cmd,
"no auto-band",
NO_STR "Automatically select band for ARFCN based on configured band\n")
{
struct gsm_bts *bts = vty->index;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
btsb->auto_band = 0;
return CMD_SUCCESS;
}
DEFUN(cfg_bts_trx, cfg_bts_trx_cmd, DEFUN(cfg_bts_trx, cfg_bts_trx_cmd,
"trx <0-0>", "trx <0-254>",
"Select a TRX to configure\n" "TRX number\n") "Select a TRX to configure\n" "TRX number\n")
{ {
int trx_nr = atoi(argv[0]); int trx_nr = atoi(argv[0]);
@@ -147,7 +222,10 @@ DEFUN(cfg_bts_trx, cfg_bts_trx_cmd,
trx = gsm_bts_trx_num(bts, trx_nr); trx = gsm_bts_trx_num(bts, trx_nr);
if (!trx) { if (!trx) {
vty_out(vty, "Unknown TRX %u%s", trx_nr, VTY_NEWLINE); vty_out(vty, "Unknown TRX %u. Available TRX are: 0..%u%s",
trx_nr, bts->num_trx - 1, VTY_NEWLINE);
vty_out(vty, "Hint: Check if commandline option -t matches the"
"number of available transceivers!%s", VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
@@ -162,20 +240,27 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
{ {
struct gsm_bts_role_bts *btsb = bts_role_bts(bts); struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
struct gsm_bts_trx *trx; struct gsm_bts_trx *trx;
char buf_casecnvt[256];
int i;
vty_out(vty, "bts %u%s", bts->nr, VTY_NEWLINE); vty_out(vty, "bts %u%s", bts->nr, VTY_NEWLINE);
if (bts->description) if (bts->description)
vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE); vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE);
vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE); vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
if (btsb->auto_band)
vty_out(vty, " auto-band%s", VTY_NEWLINE);
vty_out(vty, " ipa unit-id %u %u%s", vty_out(vty, " ipa unit-id %u %u%s",
bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE); bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
vty_out(vty, " oml remote-ip %s%s", btsb->bsc_oml_host, VTY_NEWLINE); vty_out(vty, " oml remote-ip %s%s", btsb->bsc_oml_host, VTY_NEWLINE);
vty_out(vty, " rtp jitter-buffer %u%s", btsb->rtp_jitter_buf_ms, vty_out(vty, " rtp jitter-buffer %u", btsb->rtp_jitter_buf_ms);
VTY_NEWLINE); if (btsb->rtp_jitter_adaptive)
vty_out(vty, " adaptive");
vty_out(vty, "%s", VTY_NEWLINE);
vty_out(vty, " paging queue-size %u%s", paging_get_queue_max(btsb->paging_state), vty_out(vty, " paging queue-size %u%s", paging_get_queue_max(btsb->paging_state),
VTY_NEWLINE); VTY_NEWLINE);
vty_out(vty, " paging lifetime %u%s", paging_get_lifetime(btsb->paging_state), vty_out(vty, " paging lifetime %u%s", paging_get_lifetime(btsb->paging_state),
VTY_NEWLINE); VTY_NEWLINE);
vty_out(vty, " uplink-power-target %d%s", btsb->ul_power_target, VTY_NEWLINE);
if (btsb->agch_queue_thresh_level != GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT if (btsb->agch_queue_thresh_level != GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT
|| btsb->agch_queue_low_level != GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT || 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_high_level != GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT)
@@ -183,10 +268,28 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
btsb->agch_queue_thresh_level, btsb->agch_queue_low_level, btsb->agch_queue_thresh_level, btsb->agch_queue_low_level,
btsb->agch_queue_high_level, VTY_NEWLINE); btsb->agch_queue_high_level, VTY_NEWLINE);
for (i = 0; i < 32; i++) {
if (gsmtap_sapi_mask & (1 << i)) {
osmo_str2lower(buf_casecnvt, get_value_string(gsmtap_sapi_names, i));
vty_out(vty, " gsmtap-sapi %s%s", buf_casecnvt, VTY_NEWLINE);
}
}
if (gsmtap_sapi_acch) {
osmo_str2lower(buf_casecnvt, get_value_string(gsmtap_sapi_names, GSMTAP_CHANNEL_ACCH));
vty_out(vty, " gsmtap-sapi %s%s", buf_casecnvt, VTY_NEWLINE);
}
vty_out(vty, " min-qual-rach %.0f%s", btsb->min_qual_rach * 10.0f,
VTY_NEWLINE);
vty_out(vty, " min-qual-norm %.0f%s", btsb->min_qual_norm * 10.0f,
VTY_NEWLINE);
if (strcmp(btsb->pcu.sock_path, PCU_SOCK_DEFAULT))
vty_out(vty, " pcu-socket %s%s", btsb->pcu.sock_path, VTY_NEWLINE);
bts_model_config_write_bts(vty, bts); bts_model_config_write_bts(vty, bts);
llist_for_each_entry(trx, &bts->trx_list, list) { llist_for_each_entry(trx, &bts->trx_list, list) {
struct trx_power_params *tpp = &trx->power_params; struct trx_power_params *tpp = &trx->power_params;
struct phy_instance *pinst = trx_phy_instance(trx);
vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE); vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
if (trx->power_params.user_gain_mdB) if (trx->power_params.user_gain_mdB)
@@ -198,6 +301,11 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
tpp->ramp.step_size_mdB, VTY_NEWLINE); tpp->ramp.step_size_mdB, VTY_NEWLINE);
vty_out(vty, " power-ramp step-interval %d%s", vty_out(vty, " power-ramp step-interval %d%s",
tpp->ramp.step_interval_sec, VTY_NEWLINE); tpp->ramp.step_interval_sec, VTY_NEWLINE);
vty_out(vty, " ms-power-control %s%s",
trx->ms_power_control == 0 ? "dsp" : "osmo",
VTY_NEWLINE);
vty_out(vty, " phy %u instance %u%s", pinst->phy_link->num,
pinst->num, VTY_NEWLINE);
bts_model_config_write_trx(vty, trx); bts_model_config_write_trx(vty, trx);
} }
@@ -214,11 +322,50 @@ static int config_write_bts(struct vty *vty)
return CMD_SUCCESS; return CMD_SUCCESS;
} }
static void config_write_phy_single(struct vty *vty, struct phy_link *plink)
{
int i;
vty_out(vty, "phy %u%s", plink->num, VTY_NEWLINE);
bts_model_config_write_phy(vty, plink);
for (i = 0; i < 255; i++) {
struct phy_instance *pinst = phy_instance_by_num(plink, i);
if (!pinst)
break;
vty_out(vty, " instance %u%s", pinst->num, VTY_NEWLINE);
bts_model_config_write_phy_inst(vty, pinst);
}
}
static int config_write_phy(struct vty *vty)
{
int i;
for (i = 0; i < 255; i++) {
struct phy_link *plink = phy_link_by_num(i);
if (!plink)
break;
config_write_phy_single(vty, plink);
}
return CMD_SUCCESS;
}
static int config_write_dummy(struct vty *vty) static int config_write_dummy(struct vty *vty)
{ {
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN(cfg_vty_telnet_port, cfg_vty_telnet_port_cmd,
"vty telnet-port <0-65535>",
VTY_STR "Set the VTY telnet port\n"
"TCP Port number\n")
{
g_vty_port_num = atoi(argv[0]);
return CMD_SUCCESS;
}
/* per-BTS configuration */ /* per-BTS configuration */
DEFUN(cfg_bts, DEFUN(cfg_bts,
cfg_bts_cmd, cfg_bts_cmd,
@@ -319,13 +466,15 @@ DEFUN_HIDDEN(cfg_bts_rtp_bind_ip,
DEFUN(cfg_bts_rtp_jitbuf, DEFUN(cfg_bts_rtp_jitbuf,
cfg_bts_rtp_jitbuf_cmd, cfg_bts_rtp_jitbuf_cmd,
"rtp jitter-buffer <0-10000>", "rtp jitter-buffer <0-10000> [adaptive]",
RTP_STR "RTP jitter buffer\n" "jitter buffer in ms\n") RTP_STR "RTP jitter buffer\n" "jitter buffer in ms\n")
{ {
struct gsm_bts *bts = vty->index; struct gsm_bts *bts = vty->index;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts); struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
btsb->rtp_jitter_buf_ms = atoi(argv[0]); btsb->rtp_jitter_buf_ms = atoi(argv[0]);
if (argc > 1)
btsb->rtp_jitter_adaptive = true;
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@@ -396,6 +545,63 @@ DEFUN(cfg_bts_agch_queue_mgmt_default,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN(cfg_bts_ul_power_target, cfg_bts_ul_power_target_cmd,
"uplink-power-target <-110-0>",
"Set the nominal target Rx Level for uplink power control loop\n"
"Target uplink Rx level in dBm\n")
{
struct gsm_bts *bts = vty->index;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
btsb->ul_power_target = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_bts_min_qual_rach, cfg_bts_min_qual_rach_cmd,
"min-qual-rach <-100-100>",
"Set the minimum quality level of RACH burst to be accpeted\n"
"C/I level in tenth of dB\n")
{
struct gsm_bts *bts = vty->index;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
btsb->min_qual_rach = strtof(argv[0], NULL) / 10.0f;
return CMD_SUCCESS;
}
DEFUN(cfg_bts_min_qual_norm, cfg_bts_min_qual_norm_cmd,
"min-qual-norm <-100-100>",
"Set the minimum quality level of normal burst to be accpeted\n"
"C/I level in tenth of dB\n")
{
struct gsm_bts *bts = vty->index;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
btsb->min_qual_norm = strtof(argv[0], NULL) / 10.0f;
return CMD_SUCCESS;
}
DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd,
"pcu-socket PATH",
"Configure the PCU socket file/path name\n")
{
struct gsm_bts *bts = vty->index;
struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
if (btsb->pcu.sock_path) {
/* FIXME: close the interface? */
talloc_free(btsb->pcu.sock_path);
}
btsb->pcu.sock_path = talloc_strdup(btsb, argv[0]);
/* FIXME: re-open the interface? */
return CMD_SUCCESS;
}
#define DB_DBM_STR \ #define DB_DBM_STR \
"Unit is dB (decibels)\n" \ "Unit is dB (decibels)\n" \
"Unit is mdB (milli-decibels, or rather 1/10000 bel)\n" "Unit is mdB (milli-decibels, or rather 1/10000 bel)\n"
@@ -460,7 +666,44 @@ DEFUN(cfg_trx_pr_step_interval, cfg_trx_pr_step_interval_cmd,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN(cfg_trx_ms_power_control, cfg_trx_ms_power_control_cmd,
"ms-power-control (dsp|osmo)",
"Mobile Station Power Level Control (change requires restart)\n"
"Handled by DSP\n" "Handled by OsmoBTS\n")
{
struct gsm_bts_trx *trx = vty->index;
trx->ms_power_control = argv[0][0] == 'd' ? 0 : 1;
return CMD_SUCCESS;
}
DEFUN(cfg_trx_phy, cfg_trx_phy_cmd,
"phy <0-255> instance <0-255>",
"Configure PHY Link+Instance for this TRX\n"
"PHY Link number\n" "PHY instance\n" "PHY Instance number")
{
struct gsm_bts_trx *trx = vty->index;
struct phy_link *plink = phy_link_by_num(atoi(argv[0]));
struct phy_instance *pinst;
if (!plink) {
vty_out(vty, "phy%s does not exist%s",
argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
pinst = phy_instance_by_num(plink, atoi(argv[1]));
if (!pinst) {
vty_out(vty, "phy%s instance %s does not exit%s",
argv[0], argv[1], VTY_NEWLINE);
return CMD_WARNING;
}
trx->role_bts.l1h = pinst;
pinst->trx = trx;
return CMD_SUCCESS;
}
/* ====================================================================== /* ======================================================================
* SHOW * SHOW
@@ -473,15 +716,26 @@ static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
abis_nm_avail_name(nms->availability), VTY_NEWLINE); abis_nm_avail_name(nms->availability), VTY_NEWLINE);
} }
static unsigned int llist_length(struct llist_head *list)
{
unsigned int len = 0;
struct llist_head *pos;
llist_for_each(pos, list)
len++;
return len;
}
static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts) static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
{ {
struct gsm_bts_role_bts *btsb = bts->role; struct gsm_bts_role_bts *btsb = bts->role;
vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, " vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, "
"BSIC %u, TSC %u and %u TRX%s", "BSIC %u and %u TRX%s",
bts->nr, "FIXME", gsm_band_name(bts->band), bts->nr, "FIXME", gsm_band_name(bts->band),
bts->cell_identity, bts->cell_identity,
bts->location_area_code, bts->bsic, bts->tsc, bts->location_area_code, bts->bsic,
bts->num_trx, VTY_NEWLINE); bts->num_trx, VTY_NEWLINE);
vty_out(vty, " Description: %s%s", vty_out(vty, " Description: %s%s",
bts->description ? bts->description : "(null)", VTY_NEWLINE); bts->description ? bts->description : "(null)", VTY_NEWLINE);
@@ -492,17 +746,22 @@ static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
net_dump_nmstate(vty, &bts->mo.nm_state); net_dump_nmstate(vty, &bts->mo.nm_state);
vty_out(vty, " Site Mgr NM State: "); vty_out(vty, " Site Mgr NM State: ");
net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state); net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state);
if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH))
vty_out(vty, " PCU version %s connected%s",
bts->pcu_version, VTY_NEWLINE);
vty_out(vty, " Paging: Queue size %u, occupied %u, lifetime %us%s", vty_out(vty, " Paging: Queue size %u, occupied %u, lifetime %us%s",
paging_get_queue_max(btsb->paging_state), paging_queue_length(btsb->paging_state), paging_get_queue_max(btsb->paging_state), paging_queue_length(btsb->paging_state),
paging_get_lifetime(btsb->paging_state), VTY_NEWLINE); paging_get_lifetime(btsb->paging_state), VTY_NEWLINE);
vty_out(vty, " AGCH: Queue limit %u, occupied %d, " vty_out(vty, " AGCH: Queue limit %u, occupied %d, "
"dropped %llu, merged %llu, rejected %llu, " "dropped %"PRIu64", merged %"PRIu64", rejected %"PRIu64", "
"ag-res %llu, non-res %llu%s", "ag-res %"PRIu64", non-res %"PRIu64"%s",
btsb->agch_max_queue_length, btsb->agch_queue_length, btsb->agch_max_queue_length, btsb->agch_queue_length,
btsb->agch_queue_dropped_msgs, btsb->agch_queue_merged_msgs, btsb->agch_queue_dropped_msgs, btsb->agch_queue_merged_msgs,
btsb->agch_queue_rejected_msgs, btsb->agch_queue_agch_msgs, btsb->agch_queue_rejected_msgs, btsb->agch_queue_agch_msgs,
btsb->agch_queue_pch_msgs, btsb->agch_queue_pch_msgs,
VTY_NEWLINE); VTY_NEWLINE);
vty_out(vty, " CBCH backlog queue length: %u%s",
llist_length(&btsb->smscb_state.queue), VTY_NEWLINE);
#if 0 #if 0
vty_out(vty, " Paging: %u pending requests, %u free slots%s", vty_out(vty, " Paging: %u pending requests, %u free slots%s",
paging_pending_requests_nr(bts), paging_pending_requests_nr(bts),
@@ -588,6 +847,138 @@ static struct gsm_lchan *resolve_lchan(struct gsm_network *net,
"logical channel commands\n" \ "logical channel commands\n" \
"logical channel number\n" "logical channel number\n"
DEFUN(cfg_trx_gsmtap_sapi, cfg_trx_gsmtap_sapi_cmd,
"HIDDEN", "HIDDEN")
{
int sapi;
sapi = get_string_value(gsmtap_sapi_names, argv[0]);
OSMO_ASSERT(sapi >= 0);
if (sapi == GSMTAP_CHANNEL_ACCH)
gsmtap_sapi_acch = 1;
else
gsmtap_sapi_mask |= (1 << sapi);
return CMD_SUCCESS;
}
DEFUN(cfg_trx_no_gsmtap_sapi, cfg_trx_no_gsmtap_sapi_cmd,
"HIDDEN", "HIDDEN")
{
int sapi;
sapi = get_string_value(gsmtap_sapi_names, argv[0]);
OSMO_ASSERT(sapi >= 0);
if (sapi == GSMTAP_CHANNEL_ACCH)
gsmtap_sapi_acch = 0;
else
gsmtap_sapi_mask &= ~(1 << sapi);
return CMD_SUCCESS;
}
static struct cmd_node phy_node = {
PHY_NODE,
"%s(phy)# ",
1,
};
static struct cmd_node phy_inst_node = {
PHY_INST_NODE,
"%s(phy-inst)# ",
1,
};
DEFUN(cfg_phy, cfg_phy_cmd,
"phy <0-255>",
"Select a PHY to configure\n" "PHY number\n")
{
int phy_nr = atoi(argv[0]);
struct phy_link *plink;
plink = phy_link_by_num(phy_nr);
if (!plink)
plink = phy_link_create(tall_bts_ctx, phy_nr);
if (!plink)
return CMD_WARNING;
vty->index = plink;
vty->index_sub = &plink->description;
vty->node = PHY_NODE;
return CMD_SUCCESS;
}
DEFUN(cfg_phy_inst, cfg_phy_inst_cmd,
"instance <0-255>",
"Select a PHY instance to configure\n" "PHY Instance number\n")
{
int inst_nr = atoi(argv[0]);
struct phy_link *plink = vty->index;
struct phy_instance *pinst;
pinst = phy_instance_by_num(plink, inst_nr);
if (!pinst) {
pinst = phy_instance_create(plink, inst_nr);
if (!pinst) {
vty_out(vty, "Unable to create phy%u instance %u%s",
plink->num, inst_nr, VTY_NEWLINE);
return CMD_WARNING;
}
}
vty->index = pinst;
vty->index_sub = &pinst->description;
vty->node = PHY_INST_NODE;
return CMD_SUCCESS;
}
DEFUN(cfg_phy_no_inst, cfg_phy_no_inst_cmd,
"no instance <0-255>"
NO_STR "Select a PHY instance to remove\n", "PHY Instance number\n")
{
int inst_nr = atoi(argv[0]);
struct phy_link *plink = vty->index;
struct phy_instance *pinst;
pinst = phy_instance_by_num(plink, inst_nr);
if (!pinst) {
vty_out(vty, "No such instance %u%s", inst_nr, VTY_NEWLINE);
return CMD_WARNING;
}
phy_instance_destroy(pinst);
return CMD_SUCCESS;
}
#if 0
DEFUN(cfg_phy_type, cfg_phy_type_cmd,
"type (sysmobts|osmo-trx|virtual)",
"configure the type of the PHY\n"
"sysmocom sysmoBTS PHY\n"
"OsmoTRX based PHY\n"
"Virtual PHY (GSMTAP based)\n")
{
struct phy_link *plink = vty->index;
if (plink->state != PHY_LINK_SHUTDOWN) {
vty_out(vty, "Cannot change type of active PHY%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (!strcmp(argv[0], "sysmobts"))
plink->type = PHY_LINK_T_SYSMOBTS;
else if (!strcmp(argv[0], "osmo-trx"))
plink->type = PHY_LINK_T_OSMOTRX;
else if (!strcmp(argv[0], "virtual"))
plink->type = PHY_LINK_T_VIRTUAL;
}
#endif
DEFUN(bts_t_t_l_jitter_buf, DEFUN(bts_t_t_l_jitter_buf,
bts_t_t_l_jitter_buf_cmd, bts_t_t_l_jitter_buf_cmd,
"bts <0-0> trx <0-0> ts <0-7> lchan <0-1> rtp jitter-buffer <0-10000>", "bts <0-0> trx <0-0> ts <0-7> lchan <0-1> rtp jitter-buffer <0-10000>",
@@ -596,7 +987,8 @@ DEFUN(bts_t_t_l_jitter_buf,
{ {
struct gsm_network *net = gsmnet_from_vty(vty); struct gsm_network *net = gsmnet_from_vty(vty);
struct gsm_lchan *lchan; struct gsm_lchan *lchan;
int jitbuf_ms = atoi(argv[4]); struct gsm_bts_role_bts *btsb;
int jitbuf_ms = atoi(argv[4]), rc;
lchan = resolve_lchan(net, argv, 0); lchan = resolve_lchan(net, argv, 0);
if (!lchan) { if (!lchan) {
@@ -608,20 +1000,79 @@ DEFUN(bts_t_t_l_jitter_buf,
VTY_NEWLINE); VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
osmo_rtp_socket_set_param(lchan->abis_ip.rtp_socket, btsb = bts_role_bts(lchan->ts->trx->bts);
OSMO_RTP_P_JITBUF, jitbuf_ms); rc = osmo_rtp_socket_set_param(lchan->abis_ip.rtp_socket,
btsb->rtp_jitter_adaptive ?
OSMO_RTP_P_JIT_ADAP : OSMO_RTP_P_JITBUF,
jitbuf_ms);
if (rc < 0)
vty_out(vty, "%% error setting jitter parameters: %s%s",
strerror(-rc), VTY_NEWLINE);
else
vty_out(vty, "%% jitter parameters set: %d%s", rc, VTY_NEWLINE);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
int bts_vty_init(const struct log_info *cat) DEFUN(bts_t_t_l_loopback,
bts_t_t_l_loopback_cmd,
"bts <0-0> trx <0-0> ts <0-7> lchan <0-1> loopback",
BTS_T_T_L_STR "Set loopback\n")
{ {
struct gsm_network *net = gsmnet_from_vty(vty);
struct gsm_lchan *lchan;
lchan = resolve_lchan(net, argv, 0);
if (!lchan) {
vty_out(vty, "%% can't find BTS%s", VTY_NEWLINE);
return CMD_WARNING;
}
lchan->loopback = 1;
return CMD_SUCCESS;
}
DEFUN(no_bts_t_t_l_loopback,
no_bts_t_t_l_loopback_cmd,
"no bts <0-0> trx <0-0> ts <0-7> lchan <0-1> loopback",
NO_STR BTS_T_T_L_STR "Set loopback\n")
{
struct gsm_network *net = gsmnet_from_vty(vty);
struct gsm_lchan *lchan;
lchan = resolve_lchan(net, argv, 0);
if (!lchan) {
vty_out(vty, "%% can't find BTS%s", VTY_NEWLINE);
return CMD_WARNING;
}
lchan->loopback = 0;
return CMD_SUCCESS;
}
int bts_vty_init(struct gsm_bts *bts, const struct log_info *cat)
{
cfg_trx_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(bts, gsmtap_sapi_names,
"gsmtap-sapi (",
"|",")", VTY_DO_LOWER);
cfg_trx_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(bts, gsmtap_sapi_names,
"GSMTAP SAPI\n",
"\n", "", 0);
cfg_trx_no_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(bts, gsmtap_sapi_names,
"no gsmtap-sapi (",
"|",")", VTY_DO_LOWER);
cfg_trx_no_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(bts, gsmtap_sapi_names,
NO_STR "GSMTAP SAPI\n",
"\n", "", 0);
install_element_ve(&show_bts_cmd); install_element_ve(&show_bts_cmd);
logging_vty_add_cmds(cat); logging_vty_add_cmds(cat);
install_node(&bts_node, config_write_bts); install_node(&bts_node, config_write_bts);
install_element(CONFIG_NODE, &cfg_bts_cmd); install_element(CONFIG_NODE, &cfg_bts_cmd);
install_element(CONFIG_NODE, &cfg_vty_telnet_port_cmd);
install_default(BTS_NODE); install_default(BTS_NODE);
install_element(BTS_NODE, &cfg_bts_unit_id_cmd); install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
install_element(BTS_NODE, &cfg_bts_oml_ip_cmd); install_element(BTS_NODE, &cfg_bts_oml_ip_cmd);
@@ -634,6 +1085,13 @@ int bts_vty_init(const struct log_info *cat)
install_element(BTS_NODE, &cfg_bts_paging_lifetime_cmd); install_element(BTS_NODE, &cfg_bts_paging_lifetime_cmd);
install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_default_cmd); install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_default_cmd);
install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_params_cmd); install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_params_cmd);
install_element(BTS_NODE, &cfg_bts_ul_power_target_cmd);
install_element(BTS_NODE, &cfg_bts_min_qual_rach_cmd);
install_element(BTS_NODE, &cfg_bts_min_qual_norm_cmd);
install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
install_element(BTS_NODE, &cfg_trx_gsmtap_sapi_cmd);
install_element(BTS_NODE, &cfg_trx_no_gsmtap_sapi_cmd);
/* add and link to TRX config node */ /* add and link to TRX config node */
install_element(BTS_NODE, &cfg_bts_trx_cmd); install_element(BTS_NODE, &cfg_bts_trx_cmd);
@@ -644,8 +1102,21 @@ int bts_vty_init(const struct log_info *cat)
install_element(TRX_NODE, &cfg_trx_pr_max_initial_cmd); install_element(TRX_NODE, &cfg_trx_pr_max_initial_cmd);
install_element(TRX_NODE, &cfg_trx_pr_step_size_cmd); install_element(TRX_NODE, &cfg_trx_pr_step_size_cmd);
install_element(TRX_NODE, &cfg_trx_pr_step_interval_cmd); install_element(TRX_NODE, &cfg_trx_pr_step_interval_cmd);
install_element(TRX_NODE, &cfg_trx_ms_power_control_cmd);
install_element(TRX_NODE, &cfg_trx_phy_cmd);
install_element(ENABLE_NODE, &bts_t_t_l_jitter_buf_cmd); install_element(ENABLE_NODE, &bts_t_t_l_jitter_buf_cmd);
install_element(ENABLE_NODE, &bts_t_t_l_loopback_cmd);
install_element(ENABLE_NODE, &no_bts_t_t_l_loopback_cmd);
install_element(CONFIG_NODE, &cfg_phy_cmd);
install_node(&phy_node, config_write_phy);
install_default(PHY_NODE);
install_element(PHY_NODE, &cfg_phy_inst_cmd);
install_element(PHY_NODE, &cfg_phy_no_inst_cmd);
install_node(&phy_inst_node, config_write_dummy);
install_default(PHY_INST_NODE);
return 0; return 0;
} }

View File

@@ -0,0 +1,38 @@
AUTOMAKE_OPTIONS = subdir-objects
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -I$(LITECELL15_INCDIR)
AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) $(ORTP_CFLAGS) $(LIBSYSTEMD_CFLAGS)
COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) $(ORTP_LIBS)
AM_CFLAGS += -DENABLE_LC15BTS
EXTRA_DIST = misc/lc15bts_mgr.h misc/lc15bts_misc.h misc/lc15bts_par.h misc/lc15bts_led.h \
misc/lc15bts_temp.h misc/lc15bts_power.h misc/lc15bts_clock.h \
misc/lc15bts_bid.h misc/lc15bts_nl.h misc/lc15bts_bts.h misc/lc15bts_swd.h \
hw_misc.h l1_if.h l1_transp.h lc15bts.h oml_router.h utils.h
bin_PROGRAMS = osmo-bts-lc15 lc15bts-mgr lc15bts-util
COMMON_SOURCES = main.c lc15bts.c l1_if.c oml.c lc15bts_vty.c tch.c hw_misc.c calib_file.c \
utils.c misc/lc15bts_par.c misc/lc15bts_bid.c oml_router.c
osmo_bts_lc15_SOURCES = $(COMMON_SOURCES) l1_transp_hw.c
osmo_bts_lc15_LDADD = $(top_builddir)/src/common/libbts.a $(COMMON_LDADD)
lc15bts_mgr_SOURCES = \
misc/lc15bts_mgr.c misc/lc15bts_misc.c \
misc/lc15bts_par.c misc/lc15bts_nl.c \
misc/lc15bts_temp.c misc/lc15bts_power.c \
misc/lc15bts_clock.c misc/lc15bts_bid.c \
misc/lc15bts_mgr_vty.c \
misc/lc15bts_mgr_nl.c \
misc/lc15bts_mgr_temp.c \
misc/lc15bts_mgr_calib.c \
misc/lc15bts_led.c \
misc/lc15bts_bts.c \
misc/lc15bts_swd.c
lc15bts_mgr_LDADD = $(top_builddir)/src/common/libbts.a $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(LIBSYSTEMD_LIBS) $(COMMON_LDADD)
lc15bts_util_SOURCES = misc/lc15bts_util.c misc/lc15bts_par.c
lc15bts_util_LDADD = $(LIBOSMOCORE_LIBS)

View File

@@ -0,0 +1,456 @@
/* NuRAN Wireless Litecell 1.5 BTS L1 calibration file routines*/
/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
* Copyright (C) 2016 by Harald Welte <laforge@gnumonks.org>
*
* Based on sysmoBTS:
* (C) 2012 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <osmocom/core/utils.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/logging.h>
#include <nrw/litecell15/litecell15.h>
#include <nrw/litecell15/gsml1const.h>
#include "l1_if.h"
#include "lc15bts.h"
#include "utils.h"
/* Maximum calibration data chunk size */
#define MAX_CALIB_TBL_SIZE 65536
/* Calibration header version */
#define CALIB_HDR_V1 0x01
struct calib_file_desc {
const char *fname;
int rx;
int trx;
int rxpath;
};
static const struct calib_file_desc calib_files[] = {
{
.fname = "calib_rx0a.conf",
.rx = 1,
.trx = 0,
.rxpath = 0,
}, {
.fname = "calib_rx0b.conf",
.rx = 1,
.trx = 0,
.rxpath = 1,
}, {
.fname = "calib_rx1a.conf",
.rx = 1,
.trx = 1,
.rxpath = 0,
}, {
.fname = "calib_rx1b.conf",
.rx = 1,
.trx = 1,
.rxpath = 1,
}, {
.fname = "calib_tx0.conf",
.rx = 0,
.trx = 0,
}, {
.fname = "calib_tx1.conf",
.rx = 0,
.trx = 1,
},
};
struct calTbl_t
{
union
{
struct
{
uint8_t u8Version; /* Header version (1) */
uint8_t u8Parity; /* Parity byte (xor) */
uint8_t u8Type; /* Table type (0:TX Downlink, 1:RX-A Uplink, 2:RX-B Uplink) */
uint8_t u8Band; /* GSM Band (0:GSM-850, 1:EGSM-900, 2:DCS-1800, 3:PCS-1900) */
uint32_t u32Len; /* Table length in bytes including the header */
struct
{
uint32_t u32DescOfst; /* Description section offset */
uint32_t u32DateOfst; /* Date section offset */
uint32_t u32StationOfst; /* Calibration test station section offset */
uint32_t u32FpgaFwVerOfst; /* Calibration FPGA firmware version section offset */
uint32_t u32DspFwVerOfst; /* Calibration DSP firmware section offset */
uint32_t u32DataOfst; /* Calibration data section offset */
} toc;
} v1;
} hdr;
uint8_t u8RawData[MAX_CALIB_TBL_SIZE - 32];
};
static int calib_file_send(struct lc15l1_hdl *fl1h,
const struct calib_file_desc *desc);
static int calib_verify(struct lc15l1_hdl *fl1h,
const struct calib_file_desc *desc);
/* determine next calibration file index based on supported bands */
static int get_next_calib_file_idx(struct lc15l1_hdl *fl1h, int last_idx)
{
struct phy_link *plink = fl1h->phy_inst->phy_link;
int i;
for (i = last_idx+1; i < ARRAY_SIZE(calib_files); i++) {
if (calib_files[i].trx == plink->num)
return i;
}
return -1;
}
static int calib_file_open(struct lc15l1_hdl *fl1h,
const struct calib_file_desc *desc)
{
struct calib_send_state *st = &fl1h->st;
char *calib_path = fl1h->phy_inst->u.lc15.calib_path;
char fname[PATH_MAX];
if (st->fp) {
LOGP(DL1C, LOGL_NOTICE, "L1 calibration file was left opened !!\n");
fclose(st->fp);
st->fp = NULL;
}
fname[0] = '\0';
snprintf(fname, sizeof(fname)-1, "%s/%s", calib_path, desc->fname);
fname[sizeof(fname)-1] = '\0';
st->fp = fopen(fname, "rb");
if (!st->fp) {
LOGP(DL1C, LOGL_ERROR,
"Failed to open '%s' for calibration data.\n", fname);
return -1;
}
return 0;
}
static int calib_file_close(struct lc15l1_hdl *fl1h)
{
struct calib_send_state *st = &fl1h->st;
if (st->fp) {
fclose(st->fp);
st->fp = NULL;
}
return 0;
}
/* iteratively download the calibration data into the L1 */
static int calib_send_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
void *data);
/* send a chunk of calibration tabledata for a single specified file */
static int calib_file_send_next_chunk(struct lc15l1_hdl *fl1h)
{
struct calib_send_state *st = &fl1h->st;
Litecell15_Prim_t *prim;
struct msgb *msg;
size_t n;
msg = sysp_msgb_alloc();
prim = msgb_sysprim(msg);
prim->id = Litecell15_PrimId_SetCalibTblReq;
prim->u.setCalibTblReq.offset = (uint32_t)ftell(st->fp);
n = fread(prim->u.setCalibTblReq.u8Data, 1,
sizeof(prim->u.setCalibTblReq.u8Data), st->fp);
prim->u.setCalibTblReq.length = n;
if (n == 0) {
/* The table data has been completely sent and acknowledged */
LOGP(DL1C, LOGL_NOTICE, "L1 calibration table %s loaded\n",
calib_files[st->last_file_idx].fname);
calib_file_close(fl1h);
msgb_free(msg);
/* Send the next one if any */
st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
if (st->last_file_idx >= 0) {
return calib_file_send(fl1h,
&calib_files[st->last_file_idx]);
}
LOGP(DL1C, LOGL_INFO, "L1 calibration table loading complete!\n");
return 0;
}
return l1if_req_compl(fl1h, msg, calib_send_compl_cb, NULL);
}
/* send the calibration table for a single specified file */
static int calib_file_send(struct lc15l1_hdl *fl1h,
const struct calib_file_desc *desc)
{
struct calib_send_state *st = &fl1h->st;
int rc;
rc = calib_file_open(fl1h, desc);
if (rc < 0) {
/* still, we'd like to continue trying to load
* calibration for all other bands */
st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
if (st->last_file_idx >= 0)
return calib_file_send(fl1h,
&calib_files[st->last_file_idx]);
LOGP(DL1C, LOGL_INFO, "L1 calibration table loading complete!\n");
return 0;
}
rc = calib_verify(fl1h, desc);
if ( rc < 0 ) {
LOGP(DL1C, LOGL_ERROR, "Verify L1 calibration table %s -> failed (%d)\n", desc->fname, rc);
st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
if (st->last_file_idx >= 0)
return calib_file_send(fl1h,
&calib_files[st->last_file_idx]);
return 0;
}
LOGP(DL1C, LOGL_INFO, "Verify L1 calibration table %s -> done\n", desc->fname);
return calib_file_send_next_chunk(fl1h);
}
/* completion callback after every SetCalibTbl is confirmed */
static int calib_send_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
void *data)
{
struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);
struct calib_send_state *st = &fl1h->st;
Litecell15_Prim_t *prim = msgb_sysprim(l1_msg);
if (prim->u.setCalibTblCnf.status != GsmL1_Status_Success) {
LOGP(DL1C, LOGL_ERROR, "L1 rejected calibration table\n");
msgb_free(l1_msg);
calib_file_close(fl1h);
/* Skip this one and try the next one */
st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
if (st->last_file_idx >= 0) {
return calib_file_send(fl1h,
&calib_files[st->last_file_idx]);
}
LOGP(DL1C, LOGL_INFO, "L1 calibration table loading complete!\n");
return 0;
}
msgb_free(l1_msg);
/* Keep sending the calibration file data */
return calib_file_send_next_chunk(fl1h);
}
int calib_load(struct lc15l1_hdl *fl1h)
{
int rc;
struct calib_send_state *st = &fl1h->st;
char *calib_path = fl1h->phy_inst->u.lc15.calib_path;
if (!calib_path) {
LOGP(DL1C, LOGL_ERROR, "Calibration file path not specified\n");
return -1;
}
rc = get_next_calib_file_idx(fl1h, -1);
if (rc < 0) {
return -1;
}
st->last_file_idx = rc;
return calib_file_send(fl1h, &calib_files[st->last_file_idx]);
}
static int calib_verify(struct lc15l1_hdl *fl1h, const struct calib_file_desc *desc)
{
int rc, sz;
struct calib_send_state *st = &fl1h->st;
struct phy_link *plink = fl1h->phy_inst->phy_link;
char *rbuf;
struct calTbl_t *calTbl;
char calChkSum ;
/* calculate file size in bytes */
fseek(st->fp, 0L, SEEK_END);
sz = ftell(st->fp);
/* rewind read poiner */
fseek(st->fp, 0L, SEEK_SET);
/* read file */
rbuf = (char *) malloc( sizeof(char) * sz );
rc = fread(rbuf, 1, sizeof(char) * sz, st->fp);
if ( rc != sz) {
LOGP(DL1C, LOGL_ERROR, "%s reading error\n", desc->fname);
free(rbuf);
/* close file */
rc = calib_file_close(fl1h);
if (rc < 0 ) {
LOGP(DL1C, LOGL_ERROR, "%s can not close\n", desc->fname);
return rc;
}
return -2;
}
calTbl = (struct calTbl_t*) rbuf;
/* calculate file checksum */
calChkSum = 0;
while ( sz-- ) {
calChkSum ^= rbuf[sz];
}
/* validate Tx calibration parity */
if ( calChkSum ) {
LOGP(DL1C, LOGL_ERROR, "%s has invalid checksum %x.\n", desc->fname, calChkSum);
return -4;
}
/* validate Tx calibration header */
if ( calTbl->hdr.v1.u8Version != CALIB_HDR_V1 ) {
LOGP(DL1C, LOGL_ERROR, "%s has invalid header version %u.\n", desc->fname, calTbl->hdr.v1.u8Version);
return -5;
}
/* validate calibration description */
if ( calTbl->hdr.v1.toc.u32DescOfst == 0xFFFFFFFF ) {
LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration description offset.\n", desc->fname);
return -6;
}
/* validate calibration date */
if ( calTbl->hdr.v1.toc.u32DateOfst == 0xFFFFFFFF ) {
LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration date offset.\n", desc->fname);
return -7;
}
LOGP(DL1C, LOGL_INFO, "L1 calibration table %s created on %s\n",
desc->fname,
calTbl->u8RawData + calTbl->hdr.v1.toc.u32DateOfst);
/* validate calibration station */
if ( calTbl->hdr.v1.toc.u32StationOfst == 0xFFFFFFFF ) {
LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration station ID offset.\n", desc->fname);
return -8;
}
/* validate FPGA FW version */
if ( calTbl->hdr.v1.toc.u32FpgaFwVerOfst == 0xFFFFFFFF ) {
LOGP(DL1C, LOGL_ERROR, "%s has invalid FPGA FW version offset.\n", desc->fname);
return -9;
}
/* validate DSP FW version */
if ( calTbl->hdr.v1.toc.u32DspFwVerOfst == 0xFFFFFFFF ) {
LOGP(DL1C, LOGL_ERROR, "%s has invalid DSP FW version offset.\n", desc->fname);
return -10;
}
/* validate Tx calibration data offset */
if ( calTbl->hdr.v1.toc.u32DataOfst == 0xFFFFFFFF ) {
LOGP(DL1C, LOGL_ERROR, "%s has invalid calibration data offset.\n", desc->fname);
return -11;
}
if ( !desc->rx ) {
/* parse min/max Tx power */
fl1h->phy_inst->u.lc15.minTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (5 << 2)];
fl1h->phy_inst->u.lc15.maxTxPower = calTbl->u8RawData[calTbl->hdr.v1.toc.u32DataOfst + (6 << 2)];
/* override nominal Tx power of given TRX if needed */
if ( fl1h->phy_inst->trx->nominal_power > fl1h->phy_inst->u.lc15.maxTxPower) {
LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n",
plink->num,
fl1h->phy_inst->u.lc15.maxTxPower,
fl1h->phy_inst->trx->nominal_power);
fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.maxTxPower;
}
if ( fl1h->phy_inst->trx->nominal_power < fl1h->phy_inst->u.lc15.minTxPower) {
LOGP(DL1C, LOGL_INFO, "Set TRX %u nominal Tx power to %d dBm (%d)\n",
plink->num,
fl1h->phy_inst->u.lc15.minTxPower,
fl1h->phy_inst->trx->nominal_power);
fl1h->phy_inst->trx->nominal_power = fl1h->phy_inst->u.lc15.minTxPower;
}
if ( fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm > to_mdB(fl1h->phy_inst->u.lc15.maxTxPower) ) {
LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n",
plink->num,
to_mdB(fl1h->phy_inst->u.lc15.maxTxPower),
fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm);
fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.maxTxPower);
}
if ( fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm < to_mdB(fl1h->phy_inst->u.lc15.minTxPower) ) {
LOGP(DL1C, LOGL_INFO, "Set TRX %u Tx power parameter to %d dBm (%d)\n",
plink->num,
to_mdB(fl1h->phy_inst->u.lc15.minTxPower),
fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm);
fl1h->phy_inst->trx->power_params.trx_p_max_out_mdBm = to_mdB(fl1h->phy_inst->u.lc15.minTxPower);
}
LOGP(DL1C, LOGL_DEBUG, "%s: minTxPower=%d, maxTxPower=%d\n",
desc->fname,
fl1h->phy_inst->u.lc15.minTxPower,
fl1h->phy_inst->u.lc15.maxTxPower );
}
/* rewind read pointer for subsequence tasks */
fseek(st->fp, 0L, SEEK_SET);
free(rbuf);
return 0;
}

View File

@@ -0,0 +1,88 @@
/* Misc HW routines for NuRAN Wireless Litecell 1.5 BTS */
/* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com>
*
* Based on sysmoBTS:
* (C) 2012 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 <limits.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <osmocom/core/utils.h>
#include "hw_misc.h"
int lc15bts_led_set(enum lc15bts_led_color c)
{
int fd, rc;
uint8_t cmd[2];
switch (c) {
case LED_OFF:
cmd[0] = 0;
cmd[1] = 0;
break;
case LED_RED:
cmd[0] = 1;
cmd[1] = 0;
break;
case LED_GREEN:
cmd[0] = 0;
cmd[1] = 1;
break;
case LED_ORANGE:
cmd[0] = 1;
cmd[1] = 1;
break;
default:
return -EINVAL;
}
fd = open("/var/lc15/leds/led0/brightness", O_WRONLY);
if (fd < 0)
return -ENODEV;
rc = write(fd, cmd[0] ? "1" : "0", 2);
if (rc != 2) {
close(fd);
return -1;
}
close(fd);
fd = open("/var/lc15/leds/led1/brightness", O_WRONLY);
if (fd < 0)
return -ENODEV;
rc = write(fd, cmd[1] ? "1" : "0", 2);
if (rc != 2) {
close(fd);
return -1;
}
close(fd);
return 0;
}

View File

@@ -0,0 +1,13 @@
#ifndef _HW_MISC_H
#define _HW_MISC_H
enum lc15bts_led_color {
LED_OFF,
LED_RED,
LED_GREEN,
LED_ORANGE,
};
int lc15bts_led_set(enum lc15bts_led_color c);
#endif

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More