Compare commits

...

444 Commits

Author SHA1 Message Date
Vadim Yanitskiy 076324446d tests/osmo-bts.vty: aligh with recent libosmovty changes
A new command was recently added to libosmovty:

  show fsm-state-graph NAME

This is now the longest command, affecting spacing in the output
of 'show ?' command.  Align spacing to make the test pass again.

Change-Id: I80f896e45a88550909c5767169286fc321a36e56
Related: libosmocore.git I09ee0a8c3fc4b1aa991ab5c93c0b654fccd7ea4c
2024-05-09 11:57:47 +02:00
Vadim Yanitskiy 18e5eb668e osmo-bts-{trx,virtual}: do not advertise TCH/F14.4 NT
This mode is currently not supported.

Change-Id: I8a068162400c8efb194f2a169a67ee6ea5f081ca
Related: OS#6167
2024-05-09 08:35:33 +00:00
Mychaela N. Falconia 38dbebc48c rsl.adoc: mention currently undocumented IEs
RSL_IE_OSMO_TEMP_OVP_ACCH_CAP and RSL_IE_OSMO_OSMUX_CID have been
defined for a while now, but are still not documented.  Until someone
who knows them can document them properly, we need to at least
acknowledge their existence, and show the IEI code points that
have been allocated to them, so it is clear from the documentation
what IEI code points have already been allocated and where new
extensions are to be added.

Change-Id: I55d7eef946c24cd0e224157d95fdac3243a374ef
2024-05-07 18:03:15 +00:00
Keith Whyte 65337b739a vty info: MS power levels in dBm are not negative
Change-Id: Ib928a1378bc00b8ccb0365e5536f010e1f8a3d43
2024-03-31 12:38:05 -06:00
Harald Welte 3c09964b11 README.md: Add Forum + Issue Tracker sections
Change-Id: I2a25ae51cd5c9fdd48575715f3fa11c8631af32d
2024-03-23 12:10:23 +01:00
Harald Welte 798b28728b Add funding link to github mirror
see https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository

Change-Id: Ib500e79ae7cc93ff0fc24db47f76d27109eb01f9
2024-03-23 12:07:42 +01:00
Harald Welte aec0422c8f common: Add RTP related rate counters
Let's add some rate counters to add visibility to the BTS on what is
happening in terms of received and/or transmitted RTP packets.

This should help during debugging any RTP related issues.

Change-Id: Ide674bde10b0e4b501d6a48947b983090342dfec
2024-03-18 10:09:47 +01:00
Harald Welte 3c133dc386 osmo-bts-virtual: Port over to osmo_io
osmo_io permits us to use the io_uring backend, which should
significantly speed up the many small read/writes we're doing
on virt-um.

Change-Id: Icfe42da00fd446c38090055e2baa5d5e0ae5b70c
2024-03-16 21:08:22 +01:00
Harald Welte 3af73977dd sysmobts_mgr_temp: Migrate to ctrl_cmd_send2()
ctrl_cmd_send() is now a deprecated API function.

Change-Id: I663669a1bcf7b58d6a6175cbb51c333f5cfaedd7
Depends: libosmocore.git Change-Id Ic81af56e7ea6921ba39168727ef64c308e9c6754
2024-03-02 19:05:07 +01:00
Harald Welte a7263b6474 Fix license headers.
We have licensed the code under GNU Afffero Public License,
and state that in the first paragraph as well as in the link
to the license.  However, a paragraph in the middle stated
"see the GNU General Public License", which is somewhat misleading.

Let's fix that.

Change-Id: I37e503b195fe43e1da42c080900504ca8e682e76
2024-02-17 10:21:30 +01:00
Vadim Yanitskiy 82a2a8d9b4 doc/examples: fix missing config files in release tarballs
All config file examples must be listed in EXTRA_DIST unconditionally.
Adding them conditionally results in incomplete release tarballs,
containing only 'osmo-bts-virtual.cfg' and failing to build.

Change-Id: I167027afde3cee40a3b52adfaec7bde91ba896da
Related: OS#6349
2024-01-28 23:16:42 +07:00
Vadim Yanitskiy e94553a547 osmo-bts-trx: add test VTY command to send arbitrary TRXC messages
Change-Id: Iabc9b702e5f1513187e24f45d9ffe06ea940c3ec
2024-01-23 04:01:27 +07:00
Neels Hofmeyr 088f4ffd57 early-IA: use the correct TRX
In early-Immediate-Assignment, the BSC sends the IMM ASS message
directly after it sent the Channel Activation message, and osmo-bts
should cache it until the Channel Activation is complete.

So far the code had a bug: it assumed that the lchan was on the same TRX
where the IMM ASS is transmitted -- but actually, 'trx' refers to the
BCCH channel's TRX, i.e. always c0.

Instead, look up the correct TRX by the ARFCN in the IMM ASS message.

Now, when frequency hopping is enabled, there will be no ARFCN in the
IMM ASS message, hence this fix does not work with frequency hopping.
Related osmo-bsc patch disallows this combination.

(To also support frequency hopping, osmo-bsc would need to modify the
RSL protocol: send the IMM ASS message as a custom IE directly as part
of the Channel Activation. Then it is always possible to correllate the
IMM ASS with a specific trx and lchan, no matter what information it
contains. However, early-IA is a "bad" feature in itself as it
"promotes" having high latency on Abis. It seems unnecessary to do extra
work to also support this odd use case for frequency hopping.)

Related: osmo-bsc I8d375e5155be7b53034d5c0be5566d2f33af5db0
Related: SYS#6655
Change-Id: Id9a930e5c67122812b229dc27ea2bfe246b67611
2024-01-10 07:56:23 +00:00
Vadim Yanitskiy 950ed8bc4d l1sap: fix logic error in gsmtap_csd_rlp_process()
Current code evaluates as follows:

   (trx->arfcn | is_uplink) ? GSMTAP_ARFCN_F_UPLINK : 0

while we want it to be evaluated as follows:

   trx->arfcn | (is_uplink ? GSMTAP_ARFCN_F_UPLINK : 0)

Change-Id: Ida3d684968a3e4a45531d4b6d7b6af170e3e39f4
Fixes: CID#338165
2024-01-06 16:40:13 +00:00
Matan Perelman 59c641d20e ctrl: Add max ber10k rach
Change-Id: I466ee7ab0f8b24f14a91875ae2c720da3e506bd1
2024-01-04 19:09:06 +02:00
Harald Welte 1f755bcfee gsmtap-rlp: Add support for skipping generating NULL frames
If there's nothing to transmit over a CSD NT channel, both ends generate
NULL frames.  Let's add an option to suppress GSMTAP output for those,
creating pcap files with less noise.

Change-Id: I85a2159cfaa01bfb4205c1462e3a9dbda68e4bad
Depends: libosmocore.git I2d9bd8eb4f0cd0f72c436996767b199429596917
2023-12-21 11:37:41 +00:00
Harald Welte 7786d9b673 Add GSMTAP encapsulation of RLP frames in CSD NT mode
In CSD (Circuit Switched Data) NT (Non-Transparent) mode, there
are RLP (Radio Link Protocol) frames inside the modified V.110.

wireshark alrady has a dissector for this, and we've introduced
a GSMTAP type for RLP some time ago.  So with this patch, we now
generate such GSMTAP RLP frames.

Change-Id: I6a258458822bcb3fe7290a9b9b3d104beecda219
2023-12-21 11:37:41 +00:00
Andreas Eversberg f60f45e7ab OML: Add Get Attributes for supported MOs for Channel Object Class
Get Attributes of Channel Object class that osmo-bts supports are added:

* ARFCN List
* Channel Combinations
* TSC
* HSN
* MAIO

Related: OS#6172
Change-Id: I56e067be9e5c17625c7da4e982b90927802f57b4
2023-12-19 14:19:06 +01:00
Andreas Eversberg 722767a49d OML: Add Get Attributes for supported MOs for Radio Carrier Object Class
Two Get Attributes of Radio Carrier Object class that osmo-bts supports
are added:

* RF Max Power Reduction
* ARFCN List

Note: Only one ARFCN is reported, because synthesizer hopping is not
      supported. The NM_ATT_ARFCN_LIST in the Set Radio Carrier
      Attributes message currently allowes one ARFCN only.

Related: OS#6172
Change-Id: I49ab516c38a986520f1d3f6e26ddd20ee16688ac
2023-12-19 14:19:05 +01:00
Andreas Eversberg 90f6ebcd3b OML: Add Get Attributes for supported MOs for BTS Object Class
Most Get Attributes of BTS Object class that osmo-bts supports are
added. Not supported attributes are:

* T200
* Starting Time
* HW Configuration

Related: OS#6172
Change-Id: I067c6bdea3c44d5a731bcfdcfe304c14629eb3db
2023-12-16 11:53:25 +01:00
Andreas Eversberg 17fe7d6841 Use polling based LAPDm with frame numbers
Osmo-bts uses the new polling based LAPDm implementation.

The OML message NM_ATT_T200 is ignored, because T200 timeouts are set to
the minimal response time. Longer timeouts would cause lower throughput
in case of lost frames. Shorter timeouts would cause LAPDm to fail.

Related: OS#4074
Depends: libosmocore.git I6ebe83f829d7751ea9de1d90eb478c7a628db64c
Change-Id: Ic6d7902b13cf491daaa8752db78f9875387aeffd
2023-12-11 10:06:21 +01:00
Andreas Eversberg 1013ca3b8b Handle empty (idle) PDCH blocks gracefully
An empty PDCH block contains no payload, sysmo-bts and similar BTS
models crash, because they expect the msg->l2h to be set. The function
l1sap_pdch_req() will not set msg->l2h for empty PDCH blocks, so these
models crash.

The current osmo-pcu does not send empty PDCH blocks to these BTS
models. But there shouldn't be a crash, if we receive empty PDCH blocks
over the PCU socket interface.

Change-Id: Icb52c896766425fcf453c65530c4c0b8d06b8821
2023-12-11 10:06:19 +01:00
Andreas Eversberg 647b8d0978 LAPDm: Reject (release) establishment on DCCH, SAPI 0 without L3 payload
If the channel is activated for immediate assignment, the initial data
link establishment on main signaling link with SAPI 0 must have L3
infomation included in the SABM message. If this is not the case,
release the data link without notifying BSC.

Related: OS#5971
Change-Id: I6819b51a876b8743c2d4a04165b7900723a1631c
2023-12-11 10:06:16 +01:00
Andreas Eversberg bc6cc67115 Transmit invalid AMR speech blocks instead of dummy FACCH
Every BTS needs to have some graceful handling for the scenario
where it is time to send out a speech frame on TCH DL, but there is
no frame to be sent. One possible solution is to transmit dummy
FACCH, but this option is unattractive for TCH/AHS where FACCH
displaces two speech frames rather than one. A more elegant solution
is to emit a speech frame that is bad, causing the MS receiver to
declare a BFI condition to trigger substitution and muting procedure.
A bad frame is generated by gsm0503_tch_{afs,ahs}_encode() by setting
the payload length to 0.

Depends: libosmocore.git I82ce2adf995a4b42d1f378c5819f88d773b9104a
Related: OS#6049
Change-Id: I056f379715c91ad968f198e112d363a9009dc1c3
2023-12-06 16:33:00 +00:00
Andreas Eversberg bc4ca18a31 Use uniform log format for default config files
Related: OS#6272
Change-Id: I08b297ea78e7cd60f28f0df79f2096f70c0692c6
2023-12-01 11:50:12 +01:00
Philipp Maier 4a6a2fdf7e pcuif_proto: signal BTS model via PCUIF
At the moment the PCU has no way of knowing with which BTS model it is
used with. However, some BTS models may require slightly different
behaviour by the PCU, depending on which BTS model is used. So, lets add
an additional bts_model field to struct gsm_pcu_if_info_ind in order to
convey the exact BTS model to the PCU.

Related: OS#6191
Depends: osmo-pcu.git I48eb75f65ab54fdec41ef913e24c1f18cd4a4047
Change-Id: Ib51238a0e09d4484a539a7f822864189872698b6
2023-11-21 09:17:00 +00:00
Vadim Yanitskiy 28b8759465 osmo-bts-trx: eliminate ul_bursts_prev, use the primary buffer
When adding support for Circuit Switched Data calls, we had to enlarge
the burst buffer size to accommodate bits for a maximum of 24 bursts.

Let's take advantage of this by utilizing the currently unused part of
the Uplink burst buffer for storing bits of previously decoded blocks.
This eliminates the need to allocate additional memory for SACCH.

Change-Id: I15047cd1df4476054b36f05616e41f5297d9bfe5
Related: SYS#5114, OS#4794, OS#4795, OS#4796
2023-11-14 12:22:32 +00:00
Vadim Yanitskiy 25aae40e17 osmo-bts-trx: use BPLEN macro instead of magic numbers
Change-Id: I7d89b2e50c7eeb54b734c4959eeeb1c63a51a315
2023-11-14 12:22:21 +00:00
Vadim Yanitskiy dc3b78da01 osmo-bts-trx: add_sbits(): simplify, improve coding style
Change-Id: I518a8ea268a9a6d48b04c291a03e5efbed5f571d
2023-11-14 12:22:21 +00:00
Vadim Yanitskiy 7c76630024 osmo-bts-trx: tx_tch[fh]_fn(): fix sending idle CSD frames
In accordance with 3GPP TS 44.021, sections 8.1.6 and 10.2.3, the
transmission of idle frames to the DTE is mandated when no data is
received from the radio interface.  An idle frame has all data,
status, and E-bits to binary '1' (excluding the alignment pattern).
This requirement is currently implemented for the Uplink, see
function csd_v110_rtp_encode().

However, 3GPP TS 44.021 does not explicitly specify whether the same
rule is applicable to the Downlink, perhaps assuming a continuous
stream of bits on the CSD-over-TDM link.  Currently, we transmit
a sequence of binary '0' on the Downlink instead of idle frames.

* In non-transparent (RLP) mode, whether all bits in a block are
  set to binary '0' or '1' has no impact, as both scenarios lead
  to an incorrect FCS.
* In transparent sync mode, any filling be it binary '0' or '1'
  is perceived as incorrect or unexpected.
* In transparent async mode, it is more logical to transmit a
  sequence of binary '1,' which will be interpreted as
  a sequence of stop bits.

Let's align the Downlink with the Uplink for consistency and transmit
idle frames when no data is available for transmission.  The modified
60-bit V.110 frames exclude the alignment pattern, so sending a
sequence of binary '1' is enough to achieve the intended goal.

Change-Id: I0b25cfac41b6d8dcf3bfd9d46d51a9665f1b047a
Related: OS#1572
2023-11-10 02:19:37 +07:00
Vadim Yanitskiy bcb9875176 osmo-bts-trx: tx_tch[fh]_fn(): rework generation of dummy FACCH
Even though it might have a somewhat higher performance impact,
opting for the common code path for FACCH by allocating a msgb
on heap is more favorable for both readability and maintainability.

This choice is preferred over directly calling
gsm0503_tch_fr_encode() and then using a 'goto' statement.
A similar strategy will be adopted in an follow up patch for CSD.

Change-Id: I67cb5c6f4d15149996e17c78a59d66db396da8ff
Related: OS#1572
2023-11-10 02:07:37 +07:00
Vadim Yanitskiy 863d4d933e osmo-bts-trx: tx_tch[fh]_fn(): use BUFPOS macro everywhere
For the sake of consistency.

Change-Id: I16ce4c979c5b44fd67324eb2ed3da28a4b78221b
Related: OS#1572
2023-11-09 19:28:48 +07:00
Andreas Eversberg 791d121bd9 ASCI: Add library requirements for uplink access to TODO-RELEASE
Related: OS#4851
Depends: libosmocore.git Ibd6a1d468a70126a8f67e944fcb916969cc3c36b
Change-Id: Ic7807b69bbecd84b7a30d45b599b688acfd2ddc0
2023-10-27 10:35:21 +00:00
Andreas Eversberg 771e9f2838 ASCI: Control uplink access bursts detection of physical interface
An MPH-INFO message is used to turn detection of uplink access bursts on
or off. Whenever the uplink on a voice group channel is free, the uplink
access burst detection is turned on. When the uplink access is granted
to a talker or when the calling subscriber has been assigned to the
channel, the uplink access burst detection is turned off until the
uplink becomes free again.

Related: OS#4851
Depends: libosmocore.git Ibd6a1d468a70126a8f67e944fcb916969cc3c36b
Change-Id: I92d6773a3a463eb747143c85aa149e54c1fda122
2023-10-27 10:35:21 +00:00
Andreas Eversberg e5d8a469d2 ASCI: Enable voice group/broadcast call feature at osmo-bts-trx
Related: OS#4851
Change-Id: I3a2e3f94812cec0bbf7e3674172437fa359d014c
2023-10-27 10:35:21 +00:00
Andreas Eversberg 8fafc1a74c ASCI: Add control of uplink access to osmo-bts-sysmo
An MPH-INFO message is used to turn detection of uplink access bursts on
or off. This is required for voice group/broadcast channels.

Related: OS#4851
Depends: libosmocore.git Ibd6a1d468a70126a8f67e944fcb916969cc3c36b
Change-Id: I61f232aa91191dae08404c1f08cad91964d74568
2023-10-27 10:35:21 +00:00
Andreas Eversberg d88cc624ed ASCI: Add control of uplink access to osmo-bts-trx
An MPH-INFO message is used to turn detection of uplink access bursts on
or off. This is required for voice group/broadcast channels.

Related: OS#4851
Depends: libosmocore.git Ibd6a1d468a70126a8f67e944fcb916969cc3c36b
Change-Id: I9045437d52984b7abe00fbc815d7f83c62c0fb5a
2023-10-27 10:35:21 +00:00
Pau Espin bd777b0276 trx_if: Allow calling trx_if_flush/close from within TRXC callback (v2)
- If the llist is flushed during rx rsp callback, when the flow is
  returned to trx_ctrl_read_cb() it would access tcm which was in the
llist and end up in use-after-free.
- We need to store state on whether code path is inside the read_cb in
  order to:
-- Delay transmission of new message if callback calls trx_if_flush()
   followed by trx_ctrl_send(), since the trx_ctrl_send() at the end of
   trx_ctrl_read_cb would retransmit it again immediatelly.
-- Avoid accessing tcm pointer if the callback called trx_if_flush(),
   since it has been freed.

Related: OS#6020
Change-Id: Ibdffa4644aa3a7d219452644d3e74b411734f1df
2023-10-25 16:00:59 +00:00
Pau Espin 3bd97d839e Revert "trx_if: Allow calling trx_if_flush/close from within TRXC callback"
This reverts commit 4444262a6a.
This commit introduced several side effects:
- tcm is left out of the l1h->trx_ctrl_list and hence won't be ever
  retransmitted.
- Since tcm is removed before rsp callback, the llist may become empty
  and if somehwere in the rsp callback a new message is enqueud it will
  be sent immediatelly, and will be retransmitted again when
trx_ctrl_read_cb() calls trx_ctrl_send() at the end.

Change-Id: Ideb2d08ac8a2902bceeabfb055c59c9a13dbe3c0
Related: OS#6020
2023-10-25 16:00:59 +00:00
Philipp Maier 6ed4a9a1eb pcuif_proto: clean up last remains of old PCUIF v10
There are still some remains that are related to the old PCUIF v10
protocol version. Let's clean those up.

Related: OS#5927
Depends: osmo-pcu.git I68a3f59d5c960ae3a4fbd74f9d4a894295cb9ed8
Change-Id: I04f7108c94c99c9920192177087748e8b89b3106
2023-10-16 11:54:14 +02:00
Andreas Eversberg d265ce68b2 Increase RR scheduler priority to 20, to avoid dropped bursts
If frames are not deliverd fast enough to the DSP, bursts will get
dropped. The osmo-bts-sysmo process must have priority over other
processes, so it can deliver frames fast enough.

Related: OS#6199
Change-Id: I2394e6bbc00a1d47987dbe7b70f4b5cbedf69b10
2023-10-09 08:04:56 +00:00
Pau Espin 586e897eea Drop use of deprectated vty callback is_config_node
While compiling:
vty.c:169:3: warning: 'is_config_node' is deprecated: Implicit parent
node tracking has replaced the use of this callback. This callback is
no longer called, ever, and can be left NULL. [-Wdeprecated-declarations]
        .is_config_node = bts_vty_is_config_node,
         ^

Change-Id: I54c5aa5911611b181f80e76556b150f25dd5b60c
2023-10-05 09:39:31 +00:00
Philipp Maier 955b7dc637 pcuif_proto: rename PCU_IF_FLAG_SYSMO to PCU_IF_FLAG_DIRECT_PHY
The PCUIF flag PCU_IF_FLAG_SYSMO was originally used by osmo-bts-sysmo
to signal to the PCU that the direct PHY access for the sysmo-bts DSP
should be enabled. With time, support for other BTS models was added and
the flag became a synonym for "direct PHY access", so it makes sense to
rename it to "PCU_IF_FLAG_DIRECT_PHY"

Related: OS#6191
Depends: osmo-pcu.git I29b7b78a3a91d062b9ea3cd72623d30618cd3f0b
Change-Id: Ib556a93f7d7d7dbe1e96c4a0802bc802241b2b2d
2023-10-04 14:46:53 +00:00
Vadim Yanitskiy 695080745c meas: lchan_meas_sub_num_expected(): handle CSD modes
Change-Id: Iba5314dc89d65ab4a3706b6ef11994b6fa95162c
Related: OS#6168
2023-10-04 09:18:11 +00:00
Vadim Yanitskiy fe005cb76e meas: ts45008_83_is_sub(): properly handle CSD modes
Change-Id: Ic3b1e27be2dece3605657fd91d7addebb1e554e8
Related: OS#6168
2023-10-04 09:18:11 +00:00
Vadim Yanitskiy b960c7558a meas: fix ts45008_83_is_sub(): DTX is permitted on TCH/F sign
DTX is not allowed for TCH/H in signalling mode, but *is* allowed
for TCH/F in signalling mode.

Change-Id: I91cfd8f561eb47a5fc48c0682d56331a1d69aded
Related: OS#6168
2023-10-04 09:18:11 +00:00
Vadim Yanitskiy b8a185cc12 meas: handle VAMOS specific chan modes
Treat the VAMOS channel modes same as their non-VAMOS counterparts.

Change-Id: I8ecaf87c7cda4c10dd411e7539382274715bce57
Related: OS#6168
2023-10-04 09:18:11 +00:00
Vadim Yanitskiy 08f058789f meas: lchan_meas_check_compute(): fix -SUB frame substitution
The current implementation does substitute all missing meas samples
with dummy -SUB measurements and then complain about exceeding
amount of -SUB samples.

Change-Id: Iab84f4b64b645486e2f115b0f82ee2f27eb992bc
Related: OS#6168
2023-10-04 09:18:11 +00:00
Vadim Yanitskiy 8bff3b6898 meas: lchan_meas_sub_num_expected(): proper cmode enforcement
3GPP TS 45.008, section 8.3 defines TDMA Fn subsets, which shall
always be transmitted when DTX is employed, only for:

* TCH/F in signalling mode (but not for TCH/H),
* TCH/H and TCH/F in data mode (CSD) [*],
* TCH/FS, TCH/EFS, and TCH/HS.

For channel modes employing AMR codec, in particular:

* TCH/AFS, TCH/WFS, O-TCH/WFS,
* TCH/AHS, O-TCH/AHS, O-TCH/WHS,

there exist no fixed TDMA Fn subsets, but DTX is still permitted.
For those we expect at least one SACCH frame, plus a variable
number of speech frames (0 or more).

[*] Handling of data modes is fixed in a follow-up patch.

Change-Id: Ied477528d77871dd7e3b5b7b433a4e33bca40011
Related: OS#6168
2023-10-04 09:18:11 +00:00
Vadim Yanitskiy aaa1f26e52 meas: also match stderr logging for meas_test
Change-Id: Id1ce154a65b194ce5fd9257c9c1b26d62aad1e0d
Related: OS#6168
2023-10-04 09:18:11 +00:00
Vadim Yanitskiy 40ba43a2e8 osmo-bts-trx: rx_tchh_fn(): fix copy-pasted comment
Change-Id: Idba18c217187f7aacc2fcb0c330814f3802a9306
2023-10-03 13:36:40 +00:00
Pau Espin c6211a8bec cosmetic: oc2g_mgr: fix trailing whitespace
Change-Id: I918cbe32d1be692a1747c9721f680ed8a336bf6f
2023-10-03 14:19:53 +02:00
Vadim Yanitskiy aa06f97326 l1sap: l1sap_tch_ind(): fix segfault on stale TCH.ind
It was reported that osmo-bts-sysmo is crashing due to a TCH.ind
primitive being received by l1sap_tch_ind() for an lchan, which
is operating neither in speech nor data, but in signalling mode.

It's not clear which scenario is causing this situation.  My best
guess is that one or more TCH.ind primitive(s) remain waiting in
the lower layers and bob up right after the channel mode change.

This can happen, for instance, when a dynamic timeslot gets
switched from TCH/F or TCH/H to PDCH or SDCCH/8.

Change-Id: I2d270ab654fdd9d19d1708ff6c4b4e902bd5d0a3
Fixes: d1f8f3429 "l1sap: proper rate adaptation for CSD"
Closes: OS#6180
2023-09-28 14:43:22 +00:00
Oliver Smith 188f76275a systemd: remove RestartPreventExitStatus=1
Fix OsmoBTS not restarting if e.g. an external gsmtap IP is configured
that is currently not available. Also make the service files more
consistent with other Osmocom projects.

Partial revert of ae2473c2 ("systemd: Do not restart with a broken
config file or such").

Related: SYS#6581
Change-Id: Ieeed858c159839ebaa27b2be35a597fb86874c4b
2023-09-27 10:06:54 +02:00
Andreas Eversberg ddc15996dd Do not prefix UI header to System Information Type 10
System Information Type 10 uses short L2 header that is transmitted as
Bter UI frame. The complete frame is sent by BSC, including short L2
header. Only the SACCH layer 1 header is added by the BTS.

A switch() statement is used, so other System Information with short L2
header can be added in the future.

Change-Id: Ifede42bfd84ea5914b559a20ae68f594d2ee1a5c
2023-09-25 08:25:58 +02:00
Andreas Eversberg f5c1cd3889 ASCI: Ignore LAPD frames from MS, while the uplink is not active
Do not forward any message that is received on the uplink to LAPD while
the uplink is not active. If the MS did not recognize (fast enough) that
the uplink is free, it may continue to transmit LAPD messages. A
response by LAPD to these messages is not desired and not required. If
LAPD would respond, it would cause stopping transmission of UPLINK FREE
messages. No MS could access the uplink anymore.

Note: UPLINK FREE messages are repeated automatically until a different
      message is transmitted.

Related: OS#5781
Change-Id: I5075115123055b2997481f56ddf473430a1dc9e3
2023-09-25 06:22:35 +00:00
Vadim Yanitskiy 0978d1df71 oml: implement handling of NM_ATT_IPACC_SUPP_FEATURES
Change-Id: I88c6c6af18be054bd152832e60c8afbbd16098a3
Depends: libosmocore.git Ia4208e10d61843dd6ae77398f6624c918dc81ea4
Depends: libosmocore.git I85316af9b57e8113077305798cb2d82a24e48e00
2023-09-21 06:47:27 +07:00
Pau Espin 852b2cbadc nm: delay RSL connect until BBTRANSC object is OPSTARTed
Have same behavior as nanoBTS.

Related: OS#5253
Change-Id: Idefc65a8812abd49fb5f0cd7b0bef423536b86e0
2023-09-19 09:15:08 +00:00
Pau Espin c4e836838d Move trx->rsl_link to trx->bb_transc.rsl.link
The RSL link is configured/set up by the BBTRANSC NM object, hence move
it to the appropiate substruct.

Related: OS#5253
Change-Id: I62937cbd81c27274b9f5f70d454d5319a6898c7b
2023-09-19 09:15:08 +00:00
Pau Espin 9aaaacc7aa oml: Store RSL connect related fields in bb_transc
This is a preparation commit towards delaying connection of RSL tcp
socket until the BBTRANSC object is OPSTARTed, as it is the case already
in nanoBTS.

Related: OS#5253
Change-Id: Ia571ec19e9e8f8a6d7c2554642aab0afe1b4b917
2023-09-19 09:15:08 +00:00
Vadim Yanitskiy 9d9d9e2f27 oml: oml_tx_attr_resp(): handle common nm_state attributes
These attributes are listed in 3GPP TS 52.021, Table 2/GSM 12.21.
Many attributes are still unhandled, but at least something.

Change-Id: I94702c503fea5b42d84673ccd7065c9323b733b8
Related: OS#4505
2023-09-15 05:13:11 +07:00
Vadim Yanitskiy fbd8aa8a77 oml: refactor generation of Get Attribute Response
Change-Id: I531e88e789d09f8828a53813e3b2863faf0cc572
Related: OS#4505
2023-09-15 04:49:54 +07:00
Vadim Yanitskiy e8518ae375 oml: oml_tx_attr_resp(): pass *mo to handle_attrs_{bts,trx}()
Change-Id: I78555d7226afd0c25efc100d95642634323a7b95
2023-09-15 01:39:06 +07:00
Vadim Yanitskiy fd4654e1b8 osmo-bts-{oc2g,lc15}: signal CBCH support to BSC
The model specific code seems to have everything needed for CBCH.

Change-Id: I6b4d82223dc0bdcd94cd1269bfb02047cbebe480
2023-09-15 01:39:06 +07:00
Pau Espin e97834f2db Bump version: 1.6.0.210-8a1f-dirty → 1.7.0
Change-Id: I3137362f3933aad20e3000a2fab4af82fe4fb649
2023-09-12 16:05:31 +02:00
Pau Espin 8a1f740dfc rsl: Improve logic reactivating CCCH upon SI3 BS_AG_BLKS_RES change
The previous logic was wrong, since it was only reactivating the channel
if the provided BS_AG_BLKS_RES was != 1.
Example previously broken scenario:

1- osmo-bsc user sets "channel-descrption bs-ag-blks-res 2" during
   osmo-bsc startup in osmo-bsc.cfg
2- osmo-bsc user uses VTY to change it to "channel-descrption
   bs-ag-blks-res 1"
3- osmo-bsc user uses VTY to deploy the new config: "bts <0-255>
   resend-system-information"

Step 3 would fail beforehand, ending up in a NO-OP.

Change-Id: Ibc118e11c64f04de55cb7b94d8bf2c84b431774d
2023-09-07 18:34:25 +02:00
Pau Espin 1d53d231da bts-trx: Fix CCCH not enabled if BS_AG_BLKS_RES!=1 is provided by BSC
Other bts models like sysmo,lc15,oc2g properly handled
rel_act_kind=LCHAN_REL_ACT_REACT under the bts_model_lchan_deactivate()
implementation, but bts-trx didn't.

As a result, when BCCH_INFO(SYSINFO_TYPE_3) coming from BSC (RSL)
containing a different BS_AG_BLKS_RES triggers CCCH re-activation,
it would only deactivate it but not re-activate it.
That means no SIs were being scheduled if bts was configured with
"channel-descrption bs-ag-blks-res 2" in osmo-bsc.cfg, and phones would
not see the cell.

Related: OS#1575
Change-Id: I61e1681fbaa2c993b529d58b581c99166b62bda3
2023-09-07 18:15:03 +02:00
Philipp Maier d2d938c261 pcu_sock: print SAPI and msg_id when sending confirmation
At the moment we do not print the SAPI, nor the msg_id when we send a
confirmation back to the PCU

Change-Id: Ibd5b4225e597b69eaabaeee437fb637943a55602
elated: OS#5927
2023-08-31 11:02:03 +02:00
Philipp Maier f20e13d160 pcu_sock: use PCU_IF_SAPI_AGCH_2 instead PCU_IF_SAPI_AGCH
In PCUIF v.11 we use PCU_IF_SAPI_AGCH_2 exclusively. We use this SAPI
to transfer IMMEDIATE ASSIGNMENT messages for uplink and downlink. In
both cases we send a confirmation back to the PCU. For details see
coresponding patch in osmo-pcu.git (see Depends)

CAUTION: This patch breaks compatibility to current master osmo-pcu (See
also "Depends")

Related: OS#5927
Depends: osmo-pcu.git I9effdcec1da91a6e2e7a7c41f95d3300ad1bb292
Depends: osmo-ttcn3-hacks.git Iec00d8144dfb2cd8bcee9093c96a3cc98aea6458
Change-Id: I29858fa20ad8bd0aefe81a5c40ad77a2559a8c10
2023-08-31 11:01:25 +02:00
Philipp Maier 55a21dc1c3 pcuif_proto: use confirm flag in struct gsm_pcu_if_pch
The PCU now sets a confirm flag in struct gsm_pcu_if_pch in case the MAC
block (data) requires a confirmation when sent. Use this confirm flag
instead of making the decision locally based on the MAC block contents.

Related: OS#5927
Depends: osmo-pcu.git Ia202862aafc1f0cb6601574ef61eb9155de11f04
Change-Id: I3364d2268bdef9c4d2feeb8e3d51a64e34bca68c
2023-08-29 11:13:13 +02:00
Vadim Yanitskiy b33502a39b csd_v110: handle empty/incomplete Uplink frames gracefully
Change-Id: I7cbf868df3ba5d390cea3d529eef26d18dbe55ab
Related: OS#1572
2023-08-26 04:11:33 +07:00
Vadim Yanitskiy 183c088864 csd_v110: properly set E1/E2/E3 for non-transparent data
Change-Id: Ie38c12e462654cd9fe83a0420bc8ea8b476214b8
Related: OS#1572
2023-08-26 03:12:03 +07:00
Vadim Yanitskiy 37e639cb8f csd_v110: fix comments in csd_v110_rtp_{en,de}code()
Change-Id: I6fee665e587bfa76058187e13f0cdafaea991940
Related: OS#1572
2023-08-26 03:10:20 +07:00
Philipp Maier 7e5a62e9f3 bts: make bts_agch_dequeue static
The function bts_agch_dequeue() is not used outside of bts.c, so it can
be a static function.

Change-Id: If86293ebbd99d6550022aeb8721d40bca5fc04fc
Related: OS#5927
2023-08-22 14:53:11 +02:00
Philipp Maier 9171e37aff pcuif_proto: get rid of _DT, _dt (Direct TLLI)
Since we now no longer refer to TLLI when we mean "message ID" (msg_id),
we should also remove the "_DT" / "_dt" suffix from structs and define
constants and replace it with "_2" if required.

Depends: osmo-pcu.git If641b507dcb6b176109c99dce7cff2a7561364b0
Change-Id: Icf85f60ae86fbe1f3b98e1457c0598bb09cb08c5
Related: OS#5927
2023-08-10 15:08:11 +02:00
Philipp Maier 086b46a77f pcuif_proto: remove unnecessary members from gsm_pcu_if_data_cnf_dt
The struct gsm_pcu_if_data_cnf_dt was added when the first experiments
mit Ericsson RBS base stations were made. It is essentially a copy of
gsm_pcu_if_data, where the mamber "data" was replaced with a member
"msg_id" (which was originally called "tlli"). Since we didn't know
back then which parameters we would still need at some later point we
kept all the other parameters. However, to this day we never used the
parameters below fn. Even fn was only used for logging purposes, but is
now also unused.

Let's remove all those unused members.

(Since all removed members are at the tail of the struct,
compatibility with other programs that use the PCUIF should not break.)

Related: OS#5927
Change-Id: I779605858648e2a1c202c37e197a6e32e6ea3786
2023-08-08 17:34:20 +02:00
Philipp Maier ff085f63c9 pcu_sock: get rid of fn parameter in pcu_tx_pch_data_cnf
The function pcu_tx_pch_data_cnf() gets a parameter fn (frame number).
This parameter is then used to populate the member fn in
gsm_pcu_if_data_cnf_dt of the PCUIF protocol. However, the PCU only uses
this parameter for logging and nothing else. Hence it it is not needed
and we can remove it.

Related: OS#5927
Depends: osmo-pcu.git I35bc99eaec5d0287ae3916bc668f0babaddfd6ce
Change-Id: Id1c8fa77725129ec2ea7e92e1df493f35a277659
2023-08-08 17:04:12 +02:00
Philipp Maier bbb3a1ed17 pcuif_proto: rename tlli to msg_id
To confirm downlink IMMEDIATE ASSIGNMENT messages, we use the TLLI as an
identifier and the related struct member is also called "tlli".
Unfortunately this is misleading since the message identifier does not
necessarly have to be a TLLI. It is just an implementation detail that
osmo-pcu uses the TLLI as a message identifier.

To make that clear, lets rename the tlli member (and variable and
parameter names where it is passed on) to "msg_id".

(Since this change only renames variables and struct members it will not
break compatibility with other programs that use the PCUIF)

Related: OS#5927
Depends: osmo-pcu.git I4a25039dfe329e68879bc68936e49c4b190625e6
Change-Id: Ie6b34d5df64f4bed6b14581c7957dcba6af44136
2023-08-08 16:11:50 +02:00
Vadim Yanitskiy 88de4d6789 rsl: rsl_handle_chan_mod_ie(): do not use legacy defines
Change-Id: I4e8f9ff5189af80bce13cfd1b27585aabda03f7a
Related: OS#1572
2023-08-07 14:50:10 +00:00
Vadim Yanitskiy 66eae187b9 rsl: rsl_handle_chan_mod_ie(): set lchan->csd_mode
Change-Id: I6b1b44cffae1484098709efe496efafacbd354a8
Related: ca418643 "csd_v110_rtp_encode(): properly set E1/E2/E3 bits"
Related: OS#1572
2023-08-07 14:50:10 +00:00
Keith Whyte 8ae829cabc Fix incorrect order of params passed to logging macro
Stops log lines like:
'DOML unknown 0x239616 (bts=0,trx=0,ts=1,ss=0) [....]'

Change-Id: Ie1ad41210280ae5dbe693de6bdc4378ff34621b7
2023-08-04 15:53:39 -06:00
Vadim Yanitskiy 007e72d5bc osmo-bts-trx: bts_supports_cm_data(): allow non-transparent modes
The rate adaptation algorithm is the same for both transparent and
non-transparent channel modes.  The only difference is that the
E-bits in the modified CSD frames carry data, like the D-bits.

Change-Id: Ib0d9346d7a8e30b8a8e4b08ee04846ba7d12b3fb
Related: OS#1572
2023-07-30 20:32:20 +07:00
Vadim Yanitskiy ca418643b3 csd_v110_rtp_encode(): properly set E1/E2/E3 bits
The E1/E2/E3 bits are set based on out-of-band knowledge of the
current user data rate.  The actual bit values are defined in
3GPP TS 44.021, Figure 4 "Coding of data rates".

TODO: this is only valid for transparent services,
      for non-transparent services see 3GPP TS 48.020.
TODO: lchan->csd_mode is never set to the actual CSD mode...

Change-Id: I1a14597dff746cf975140b294400a2cc05badccd
Related: OS#1572
2023-07-30 20:29:12 +07:00
Vadim Yanitskiy d1f8f3429c l1sap: proper rate adaptation for CSD (RFC4040 'clearmode')
Since 95407f3f osmo-bts-trx supports scheduling all CSD specific
channel rates, however the rate adaptation was missing.

On the radio interface we deal with CSD-modified V.110 frames, which
need to be converted to normal 80-bit V.110 frames (RA1'/RA1), which
in turn need to be batched and sent in RFC4040 "clearmode" 160 octet
RTP payloads (RA1/RA2 as per I.460).

Note that this patch comments out TCH/F14.4 in bts_supports_cm_data(),
so that all channel allocations for this mode would be NACKed.  The
reason for this is that the rate adaptation functions for TCH/F14.4
are different than the RA1'/RA1 and the RA1/RA2.

For more information, see:

* 3GPP TS 44.021, section 8 (functions RA1'/RA1)
* ITU-T I.460, section 1.1 "Rate adaption of 8, 16 and 32 kbit/s streams"

Change-Id: I5e3701ad52d5d428fd02caff037881045f2d0a02
Related: OS#1572
2023-07-30 16:08:01 +07:00
Andreas Eversberg 97d3bd3e62 ASCI: Enable UPLINK ACCESS on various BTS models
UPLINK ACCESS (RACH on TCH) was enabled for osmo-bts-sysmo only. Now it
is also enabled for:
* osmo-bts-lc15
* osmo-bts-oc2g
* osmo-bts-trx
* osmo-bts-virtual

Change-Id: Iae0db6bfcf6629c114436a79648e832c82835abe
2023-07-21 13:20:13 +02:00
Andreas Eversberg 467d63e387 Add test cases for rest octets of Paging Requests
The abstract representation of the rest octets are moved to the header
file, so that the test case can include it. append_p*_rest_octets()
function become externally available for test.

Change-Id: Ifa5be8998b671160e38af1be707e040b00d407b8
Related: OS#5781
2023-07-21 13:20:12 +02:00
Andreas Eversberg be93b87a64 ASCI: Repeat UPLINK FREE message until uplink becomes busy
According to TS 44.018 the UPLINK FREE message must be repeated when the
uplink is marked as free. The BSC sends the UPLINK FREE message once and
the BTS repeats it until UPLINK BUSY (uplink blocked by BSC) or
VGCS UPLINK GRANT (talker accesses the uplink) is sent.

It is important to stop sending UPLINK FREE message when a talker
accesses the uplink and before the VGCS UPLINK GRANT message is sent, so
that stopping must be controlled by the BTS.

Related: OS#5781
Change-Id: Ia23c59f5e9a73bbc384fbc317a2cfcf707e3c28f
2023-07-21 13:20:11 +02:00
Andreas Eversberg ba5d2e4a5f ASCI: Add Notification/FACCH support
When a VGCS/VBS call is established in a cell, NCH is used to notify
about ongoing calls to idle subscribers. Additionally Notification/FACCH
is used to notify subscribers in dedicated mode. This is performed by
broadcasting this messages to all active dedicated channels. The mobile
station can then indicate the call, so the user can join the call.

More importaint is the notification of the calling subscriber's MS,
which initiated the call. This is done on the early assigned channel.
The MS must know on which channel the call is placed. After leaving the
uplink, it must know where to access the uplink the next time.

Change-Id: I3ed14fa54a907891e492a7ada8e745a2c56cd46d
Related: OS#4851, OS#5781
2023-07-21 13:20:10 +02:00
Andreas Eversberg 0a2b0a20b3 ASCI: Send only NLN on Paging request type 1 rest octets
Do not send notifications here. The notifications are sent on the NCH.
The NLN is used to indicate a change on the NCH, so that the MS will
read the NCH then.

If NLN is not sent towards MS, it will not read NCH to get an updated
list of ongoing calls. Also, it will not allow making VGCS/VBS calls and
might indicate that ASCI is not supported in this call. (Tested with
GPH-610R.)

Change-Id: I22e584b70fd14d8bdabb28cf5de3d4647f37425a
Related: OS#5781
2023-07-21 13:20:07 +02:00
Andreas Eversberg 290085787a ASCI: Add support for rest octets in Paging request type 2 and 3
Currently the rest octets contain Notification List Number (NLN) and
NLN status and the "Channel Needed" (CN3 / CN4) fields for mobile
identities.

The existing encoding of CN3 / CN4 in Paging request type 3 has been
replaced.

The missing encoding of CN3 in Paging request type 2 has been added.

Change-Id: I6e33a6d38d4c7b124de35b53d219b64bb881ba66
Related: OS#5781
2023-07-21 13:20:07 +02:00
Andreas Eversberg 6fa1dfce61 ASCI: Add Notification CHannel (NCH) support
The location of the NCH is defined by the rest octet of System
Information 1. If NCH is defined, the given CCCH blocks are used for NCH
instead of AGCH/PCH.

The current list of VGCS/VBS call notifications is transmitted on the
NCH. If there is no notification, an empty notification is transmitted
on the NCH.

The Notification List Number (NLN) is used to indicated new
notificaitons. Only the last notification (or empty notification)
indicates NLN. This way the MS can determine after two equal NLN that
the complete list has been recevied.

Change-Id: I82fdaba3faaced76267a99ae14a5458a1b41fdaa
Related: OS#5781
2023-07-21 13:20:06 +02:00
Andreas Eversberg 65c8f0de94 ASCI: Retrieve NCH position from System Information 1
When BCCH INFO is received via RSL message, the rest octet of the System
Information 1 message is parsed to get the position of the NCH. The
position is stored in the gsm_bts structure. If the position is not
present int the rest octet, the stored value is set to negative.

Change-Id: I799a27179d478d4ff577d8bc47ae524834851e85
Related: OS#5781
2023-07-21 13:20:05 +02:00
Vadim Yanitskiy 98e5d6f7c6 osmo-bts-trx: document/clarify the meaning of BUFMAX=24
Change-Id: I95d4e4ee3938cfabc1695959cc82a1efbbf0d7ed
Related: OS#1572
2023-07-21 11:12:50 +00:00
Vadim Yanitskiy 29fcae8632 osmo-bts-trx: tx_tch[fh]_fn(): fix NULL pointer dereference
It may happen that only FACCH is available for transmission, so msg_tch
would be NULL in this case.  Check it before dereferencing.

Change-Id: I0e7d5634b5223bc246badbb8e94b620c967ab121
Related: OS#1572
2023-07-21 11:06:00 +00:00
Harald Welte fa90ff3e67 omldummy: Claim to support VBS + VGCS towards BSC
This tells our TTCN3 BSC tests to perform VBS/VGCS related procedures on
RSL.

Change-Id: I9ed1b20985d2ce3be31942d3e9df5cad513a0bfd
Related: OS#5778, OS#5779
2023-07-21 10:52:07 +00:00
Harald Welte 15330e2368 sysmo: Enable VGSCS + VBS feature flags
This tells the BSC that osmo-bts-sysmo supports VBS/VGCS

Change-Id: I1625d2a0f4905437fad0b5220a551f81eba9a00e
Related: OS#4851
2023-07-21 10:52:07 +00:00
Andreas Eversberg cdbd83affd ASCI: Add function to reactivate channel
Reactivation will modify parameters on an already activated channel. On
a VGCS/VBS channel it can be used to prepare channel for assignment of
the mobile station to it.

During assignment the channel is reactivated. The timing advance of the
mobile station is given. The uplink is activated and is waiting for the
mobile station to establish, to complete the assignment.

For reference see patent EP 1 858 275 A1.

Change-Id: I77f413cf70c2f5f8e8f525686eee40548521c71b
Related: OS#4851
2023-07-21 10:52:07 +00:00
Harald Welte 2ae45aba3f ASCI: VGCS/VBS RACH -> RSL TALKER/LISTENER DETECT
Random access is allowed on VGCS / VBS channels to access the uplink or
to detect listeners. Uplink Access from a listener is only reported once
after activating the channel. Uplink Access from a talker is reported
each time the uplink becomes occupied. RSL TALKER/LISTENER DETECT
messages are sent to the bsc.

The VGCS UPLINK GRANT message is sent by the BTS itself. Timer T3115 is
used to repeat the message up to NY2 times until one valid frame is
received from the MS (CM service request). The UPLINK BUSY / UPLINK FREE
message must be sent by the BSC.

The uplink is released by UPLINK RELEASE message from the MS or from the
BSC. Afterwards the UPLINK FREE message causes the MS to leave the
uplink without any acknowlege. An RSL REL-REQ must be used to terminate
the link locally. (Without layer 2 DISC procedure.)

Change-Id: I1bd07ab6802341b09a06e89df356665ffaf6d2bf
Related: OS#4851
2023-07-21 10:52:07 +00:00
Philipp Maier 6c83527e62 paging: also accept zero length IMSI strings 3
When an IMMEDIATE ASSIGNMENT MAC block (from PCUIF) is added to the
paging queue, then also an IMSI is required. The paging queue uses the
last three digits of the IMSI to calculate the paging group. In case no
IMSI is given, the MAC block is rejected. This was handeled differently
before. Even an IMSI of length 0 would still be interpreted as "000" and
not rejected. See also:

I9f3799916e8102bf1ce0f21891f2d24f43091f01

Let's restore the behaviour we had before and accept short IMSI
strings again.

Change-Id: Iab1c3f1c39dd59bb53aa74b2c9e9e135e3985e0b
Related: OS#6099
2023-07-17 14:15:20 +02:00
Vadim Yanitskiy d04e3e708b osmo-bts-trx: change 'Received bad data' back to LOGL_DEBUG
In f2c902c2 I accidentally bumped the logging level for PDCH decoding
errors to LOGL_NOTICE, making osmo-bts-trx spam the logging with
hundreds of 'Received bad data' messsages.  Revert this.

Change-Id: Idb963f1a779dfa172825f6d481740cb0c4165485
Fixes: f2c902c2 "osmo-bts-trx: unify and enrich 'Received bad data' logging"
2023-07-15 01:20:15 +07:00
Vadim Yanitskiy 4344f323f2 osmo-bts-trx: rx_tch[fh]_fn(): combine rc-checking ifs
Change-Id: I7bb341867e362bf2061608ff54c3596ad209af90
2023-07-13 13:18:02 +00:00
Vadim Yanitskiy 17087a08c7 osmo-bts-trx: rx_tchf_fn(): move compute_ber10k() above
... for the sake of consistency with rx_tchh_fn().

Change-Id: Ie331da78eb3831e35d255583466e0d09b093b132
2023-07-13 13:18:02 +00:00
Vadim Yanitskiy f2c902c2af osmo-bts-trx: unify and enrich 'Received bad data' logging
Change-Id: I7902f382e1d83ef9ad2cf6f92e31eeb16f6b797c
2023-07-13 13:18:02 +00:00
Vadim Yanitskiy bb596dddc7 osmo-bts-trx: visualize rx_tch[fh]_fn() functions
Change-Id: I373dbbc3d427858f76d07ff85633e07fe2600770
Related: OS#1572
2023-07-13 03:42:29 +07:00
Vadim Yanitskiy 4bbfb904b8 osmo-bts-trx: implement TCH/F2.4 support for CSD
Change-Id: I31c59a78a362986b0cd1bc6650c325ee9f206519
Depends: libosmocore.git I4685376c8deb04db670684c9ebf685ad6fc989fa
Related: OS#1572
2023-07-13 03:42:29 +07:00
Vadim Yanitskiy deef79ffae osmo-bts-trx: implement FACCH/[FH] support for CSD
The FACCH/[FH] coding rules are specified in 3GPP TS 45.003, sections
4.2 and 4.3.  The key difference is that unlike with speech channels,
FACCH does not replace data frames completely, but disturb a fixed
amount of bits fom them.  This is why we need to use separate
gsm0503_tch_[fh]r_facch_{en,de}code() API for data channels.

Change-Id: I4c6736e84c271240d457998de688c0baf59fe578
Depends: libosmocore.git I0c7a9c180dcafe64e6aebe53518d3d11e1f29886
Related: OS#1572
2023-07-13 03:42:29 +07:00
Vadim Yanitskiy 95407f3f63 osmo-bts-trx: implement CSD scheduling support
* enlarge the maximum burst buffer size to 24 * (2 * 58) bytes;
* enlarge per-l1cs Uplink burst mask to hold up to 32 bits;
* enlarge per-l1cs Uplink meas ring buffer to 24 entries;
* add new meas modes: SCHED_MEAS_AVG_M_{S22N22,S24N22};

Change-Id: I08ffbf8e79ce76a586d61f5463890c6e72a6d9b9
Depends: libosmocore.git Ib482817b5f6a4e3c7299f6e0b3841143b60fc93d
Related: OS#1572
2023-07-13 03:42:29 +07:00
Vadim Yanitskiy f3a63758d1 osmo-bts-trx: pull the AMR header in tch_dl_dequeue()
The goal is to unify encoding functions in tx_tch[fh]_fn(), so that
in a follow-up change adding CSD we could use a switch statement.

Change-Id: I15318e497b236128f779769e4fa99f307ea431ea
Related: OS#1572
2023-07-13 03:42:29 +07:00
arehbein 34077236f2 common: Make socket queue max. length configurable
Title refers to the maximum length of the osmo_wqueue used for
the PCU socket connection.

Related: OS#5774
Change-Id: Id6ba6e4eadce9ce82ef2407f4e28346e7fe4abfa
2023-07-12 07:46:05 +00:00
Vadim Yanitskiy d53a084fd6 measurement: suppress unsupported tch_mode warnings for CSD
Change-Id: If6896b420d0fa50fa6622d24ef679ca65ef2dc50
Related: OS#1572
2023-07-11 04:12:45 +07:00
Vadim Yanitskiy 2bdb2201f6 fix bts_supports_cm(): properly check feature flags for VGCS/VBS
cm->spd_ind can take only three values defined in enum rsl_cmod_spd:

  0000 0001   RSL_CMOD_SPD_SPEECH
  0000 0010   RSL_CMOD_SPD_DATA
  0000 0011   RSL_CMOD_SPD_SIGN

According to 3GPP TS 48.058, section 9.3.6, all other values are
reserved, so expecting RSL_CMOD_CRT_TCH_{GROUP,BCAST}_{Lm,Bm} there
is wrong.  These values are part of enum rsl_cmod_crt, so the right
field would be not cm->spd_ind, but cm->chan_rt.

Let's check these channel types in a separate stage, before checking
the requested codec.  Group them with VAMOS specific types for the
sake of consistency.

Change-Id: I914c84be04da819df9e60e2f5ecc5bac9b61b2e5
Fixes: 44c94fdea "validate RSL "channel rate and type" against VGCS/VBS flags"
Related: OS#4851
2023-07-11 04:09:31 +07:00
Harald Welte 84d220abc1 Store "Channel rate and type" from RSL Channel Mode IE in BTS
The RSL "Channel rate and type" field from the RSL Channel Mode IE
in RSL_CHAN_ACTIV and RSL_MODE_MODIFY_REQ messages is the only place
where the BSC differentiates between a normal TCH and the special
TCH modes used in VGCS or VBS.  Let's copy this field from the RSL
message into the lchan state, so that BTS models can actually (in
subsequent patches) reflect it when activating the L1.

Change-Id: I6d531bf528bcb81f44d91336471a46ef790d7646
Related: OS#4851
2023-07-10 18:06:19 +00:00
Andreas Eversberg 34838ee4e9 Change return value of bts_supports_cm() from int to bool
Change-Id: I72e30fe852ab69a162b117a534071ebddd4b16ba
2023-07-10 18:06:19 +00:00
Harald Welte 44c94fdeae validate RSL "channel rate and type" against VGCS/VBS flags
We already have specfied (but not yet implemented BTS_FEAT_{VBS,VGCS}).

Let's add code to validate "channel rate and type" compatibility
in bts_supports_cm() once a BTS model would actually exhibit those
feature flags.

Change-Id: I5e7f65b44cef6e2f7ad4f152f80a1686a4f511e3
Related: OS#4851
2023-07-10 18:06:19 +00:00
Harald Welte f0510b6207 ASCI: NCH / NOTIFICATION support
This adds very minimalistic support for notification of VBS/VGCS calls.

Minimalistic in that we
* only notify via PCH (not via NCH or FACCH)
* only include notification in otherwise empty PAGING TYPE 1

This means that notification will cease to work once the PCH becomes too
loaded and we never would send otherwise empty PAGING TYPE 1 anymore.

Change-Id: I6f6f72d9a0123cb519b341d72a124aaa2117370e
Requires: libosmocore.git I9586b5cb8514010d9358fcfc97c3d34741294522
Related: OS#5781
2023-07-10 18:06:19 +00:00
Harald Welte 3480a2ab4c Add ASCI (advanced speech call items) log sub-system
As we subsequently add ASCI related features to the code, it makes
sense to have a specific log sub-system for it.

Change-Id: I8ea3e61df35175bd74110b2f41994c99da3e2858
Related: OS#4851
2023-07-10 18:06:19 +00:00
Harald Welte ad15414fd9 paging: Add support for generating NLN/NLN-Status in P1 Rest Octets
The NLN + NLN-Status are optional parts of P1 rest octets; they can
be used to support the "Reduced NCH monitoring mechanism" as described
in Section 3.3.3.3 of TS 48.018.

The patch just adds encoder capability but doesn't yet make use of it.

Change-Id: I961842c3fec151e149f72a4f36279ce4b979795e
Related: OS#5781
2023-07-10 18:06:19 +00:00
Philipp Maier f98a55b713 pcu_sock: use PCUIF version 11 (direct TLLI)
OsmoBTS still uses the deprecated version 10 of the PCUIF protocol.
OsmoPCU is still compatible to version 10, but to maintain a clean
interface it is planned to drop the support for version 10 in the near
future.

Moving to PCUIF v.11 essentially means using the "Direct TLLI" method to
convey IMMEDIATE ASSIGNMENT and also PAGING COMMAND messages through the
PCU socket. This means in particular that we use a TLLI as an identifier
to confirm IMMEDIATE ASSIGNMENT messages towards the PCU (PAGING COMMAND
is not confirmed at all). Also we now use struct gsm_pcu_if_pch_dt to
parse the incoming PCU_IF_SAPI_PCH_DT, which is much cleaner than using
offsets in a buffer.

Change-Id: I25816ac12e63cc6b641eb414e6bc7eaa9c85fc25
Depends: osmo-ttcn3-hacks.git I08de02e951e10bc8b4381cc2ad32e63f2747e3c4
Depends: docker-playground.git Ia28bc0d6d3cbfe63be19443db86631fb67bb80fb
Related: OS#5927
2023-07-10 12:06:18 +00:00
Vadim Yanitskiy 1f5fdf8c8d scheduler: use size_t for data_len in _sched_compose_*_ind()
The payload size for some CSD channel types is bigger than what an
uint8_t can represent, for instance 290 bytes for TCH/F14.4.

Change-Id: Id75c55509a017d14dfab2a7b4c67e0742125a113
Related: OS#1572
2023-07-06 00:51:10 +07:00
Vadim Yanitskiy d78968422f scheduler: constify *data pointer in _sched_compose_*_ind()
Change-Id: I617e7ed50d27e047cc2851f5d44d31ad3111ce0a
Related: OS#1572
2023-07-06 00:50:11 +07:00
Vadim Yanitskiy c860309aea scheduler: unify argument names/order for _sched_compose_*_ind()
This commit aims to make the argument naming/ordering more consistent:

* rename l2/l2_len and tch/tch_len to data/data_len;
* common arguments first (consistent ordering), specific last.

Change-Id: I3d8c90b82f2a55b0c5c2d6b4efb8fd962508534d
Related: OS#1572
2023-07-06 00:43:36 +07:00
Vadim Yanitskiy 5c1401d6f3 scheduler: use msgb_hexdump_l2() in _sched_compose_tch_ind()
Change-Id: Iec8b6edaeb516eb5dc65eab52e3450e7330a6504
Related: OS#1572
2023-07-06 00:01:35 +07:00
Vadim Yanitskiy 477fb3d9a4 scheduler: fix wrong union field in _sched_compose_tch_ind()
Change-Id: I2f6794d229ad8219e3835a6eb74513672e497d5d
Related: OS#1572
2023-07-05 23:59:50 +07:00
Pau Espin e5c2bc346b Increase PCUIF wqueue size
The default of 10 messages introduced recently is too small, specially
when using osmo-bts-trx, where clock drifting and CPU scheduling can
cause skewing and hence generation of 2-3 FNs (* up to 8 TS) at once,
hence filling the PCUIF queue with more than 10 messages in a given
moment.

Fixes: c938a95e25
Change-Id: I7ababfc6cdf20196889fb542a8040128b3c118b5
2023-07-04 12:16:10 +02:00
arehbein c938a95e25 common: Have PCU socket connection use osmo_wqueue
Fixes memleak in case of connected PCU process being suspended without proper close on socket

Related: OS#5774
Change-Id: Ia6e61dda4b3cd4bba76e6acb7771d70335062fe1
2023-07-02 17:46:51 +00:00
Mychaela N. Falconia 4c3b4e2868 ECU in UL path: move it from trx model to l1sap
With this change the application of ECU in the uplink path becomes
consistent across all OsmoBTS models, enabled or disabled per vty
config setting "rtp internal-uplink-ecu".  An additional behavioral
change from the previous trx-model-only implementation is that ECU
insertion is now done after the link quality check in l1sap, thereby
fixing the bug where this quality check would sometimes suppress
ECU output and replace it with BFI markers in RTP.

In the new implementation when the internal ECU is enabled and
available for the selected codec (currently FRv1 only), the RTP output
will gap (standard representation of BFI in RTP) only during DTXu
pauses as indicated by a received SID frame (either valid or invalid),
and the SID frame that triggers the switch from ECU mode into pause
mode is reliably emitted in RTP.

Related: OS#6040
Depends: I3857be84bba12aaca0c2cca91458b7e13c5a642a (libosmocore)
Change-Id: Iac577975c9ab50cb8ebbc035c661c1880e7cecec
2023-06-28 16:29:00 +00:00
Mychaela N. Falconia 676e9e5804 ECU in UL path: move state alloc/free to l1sap
In preparation for moving the now-optional application of ECU in UL
path from osmo-bts-trx model-specific code to the common layer,
move ECU state allocation and freeing from trx model to l1sap.

Related: OS#6040
Change-Id: Ic98a2eb26b5a99bc4a89ad07ae87c9a86b921418
2023-06-28 16:29:00 +00:00
Mychaela N. Falconia f0f91fc66c ECU in UL path: make it optional per vty config
Current osmo-bts-trx includes a provision for invoking ECUs from
libosmocodec in the UL path from the channel decoder to the RTP
output.  This pre-existing implementation is counter to the spirit
of 3GPP specs (a BTS should merely mark BFI conditions in its UL
output, as opposed to actively modifying the frame stream with an ECU),
inconsistent between different osmo-bts models (only in -trx and no
others), and inconsistent even within osmo-bts-trx itself, where
the link quality check in l1sap will sometimes suppress the output
of the ECU - a quirk which the designers of the current mechanism
most certainly did not intend.

The solution decided upon in OsmoDevCall on 2023-06-21 is to make
this ECU optional per vty config, and move it from the trx model
to the common layer to resolve the inconsistencies.  Implement the
first part: make the ECU application optional per vty config.

For backward compatibility with existing deployments, the new
"rtp internal-uplink-ecu" setting is enabled by default on osmo-bts-trx
but not on any other models.

Related: OS#6040
Change-Id: I0acca9c6d7da966a623287563e0789db9e0fae8e
2023-06-28 16:29:00 +00:00
Oliver Smith 805340cb9c osmo-bts-sysmo: mute PHY until OML is ready
Connecting to OML and PHY is done in parallel. The PHY connection will
always be done first, mute PHY until OML is also ready.

As Pau suggested, move dispatch of NM_EV_SW_ACT to a callback of
trx_rf_lock to have the events serialized and therefore deterministic.

Fixes: SYS#6496
Change-Id: Ia1769f952fa787202a442a33db5ed4a1f7cbe9c3
2023-06-27 15:08:17 +02:00
Oliver Smith 81ebfb34b4 osmo-bts-sysmo/l1_if: move mute_rf_compl_cb up
Prepare to use it in a new function above activate_rf_compl_cb.

Change-Id: I19dbfbd595d3b42c0634a4c38e39cdb314a54266
2023-06-26 17:23:17 +02:00
Oliver Smith 07c3d86356 osmo-bts-sysmo: activate_rf: no dispatch on fail
Do not dispatch NM_EV_SW_ACT to trx->mo.fi and trx->bb_transc.mo.fi when
RF-ACT.conf was not successful. Running this code path anyway looks like
a leftover from when bts_shutdown used to exit osmo-bts.

Change-Id: I342187604f4c72303e393ce6925b94d610bfa8fa
2023-06-26 15:06:02 +00:00
Vadim Yanitskiy 34ab6f1470 l1sap: use gsm0502_fn2ccch_block() from libosmogsm
Keep the l1sap specific wrapper because we still want to assert().

Change-Id: I7097ba87f42689d2336014da9173cadbdaa9fdab
Depends: libosmocore.git I8cbd31226754e95887358ed83a928e2f567f4cf3
2023-06-26 14:59:49 +00:00
Oliver Smith 235d2bfbc4 osmo-bts-sysmo: trx_mute_on_init_cb: call bts_update_status
Run bts_update_status in trx_mute_on_init_cb like in the default
callback mute_rf_compl_cb.

Related: SYS#6496
Change-Id: Ib73a33a82fbb86ead3569a6bb22fb001c55354d4
2023-06-23 13:18:38 +02:00
Oliver Smith fd544caae1 gitignore: add arm-poky-linux-gnueabi-libtool
This file gets copied into the tree when building with the SDK.

Change-Id: I0fe4f96175ee94eb0a131c425bbeb110f1d55402
2023-06-23 13:18:38 +02:00
Philipp Maier 3f9e507d77 l1sap: cosmetic: rename payload_len to rtp_pl_len
The function signature of rtppayload_is_octet_aligned has a parameter
rtp_pl for the payload and a parameter payload_len for the length of the
payload, while other functions use rtp_pl and rtp_pl_len.

Change-Id: I8a0e0357aab2a78e25811f66b1b870e8c6ebffe9
2023-06-14 10:21:22 +02:00
Philipp Maier b2c6b68a10 pcu_sock: move variable declaration of imsi[4] into related scope
The variable imsi[4] may be moved into the scope of case PCU_IF_SAPI_PCH

Related: OS#5927
Change-Id: I62aed4f1c600ce2a80d2df928a60b6a2e0ae1889
2023-06-07 12:25:31 +02:00
Philipp Maier c9a8eca543 paging: do not confirm PAGING COMMAND messages
when osmo-bts receives a MAC block from osmo-pcu through the PCUIF it
puts it in the review queue without further interpreting it. This also
means that it will send confirmations to the PCU for IMMEDIATE
ASSIGNMENT and PAGING COMMAND. This is not entirely correct because only
IMMEDIATE ASSIGNMENT messages should be confirmed. osmo-pcu has no
problem with this since it silently drops the confirmations for PAGING
COMMAND messages. This peculiarity of the PCUIF implementation makes the
confirmation logic hard to understand, so let's add some logic to
osmo-bts that makes sure that only IMMEDIATE ASSIGNMENT messages are
confirmed.

Related: OS#5927
Change-Id: I8b8264d28b1b1deb08774cdba58dd4c6dafe115d
2023-06-07 12:25:27 +02:00
Philipp Maier 9b5721b3fb paging: parse PCUIF data indication outside of paging.c
The function paging_add_macblock takes a data and length parameter. The
first three byte of that string are the last three digits of the IMSI
from which the paging group is calculated.

As the layout of this data buffer is a property of the PCUIF interface
API, we should do this separation outside of paging.c. Also we should
supply the IMSI as a valid null terminated string since PCUIF v.11 also
uses this format.

Change-Id: I9f3799916e8102bf1ce0f21891f2d24f43091f01
Related: OS#5927
2023-06-07 11:26:48 +02:00
Vadim Yanitskiy 194d1e8bc2 osmo-bts-trx: remove redundant memset() on receipt of NOPE.ind
In all Uplink lchan handlers we do memset() the Rx burst buffer on
bid=0 and there is no need to do that again for NOPE.ind.

Change-Id: Ia6803b8606d86bd2d011fe21f7a540d2115aa654
2023-06-06 10:20:36 +00:00
Vadim Yanitskiy 282c87ab2d osmo-bts-trx: fix recent regression in Tx lchan handlers
In my recent patch a0770250, among with the new burst buffer
allocation/release strategy, I introduced a regression:

        /* send burst, if we already got a frame */
-       if (br->bid > 0) {
-               if (!*bursts_p)
-                       return -ENODEV;
+       if (br->bid > 0)
                goto send_burst;
-       }

We used to allocate the burst buffers in Rx/Tx lchan handlers, and
release them in case of an error, e.g. when no block is available
for transmission.  In the case of Tx burst buffers, the state of
Tx burst buffer was additionally used to check if we have a valid
Tx block for transmission, as can be seen in the code snippet above.

As a side effect of my patch, osmo-bts-trx now keeps transmitting
3 out of 4 bursts (br->bid > 0) of the last valid block, until the
next valid Tx block is available for transmission.

This problem was not affecting the CS domain, where it's expected to
have a more or less constant pressure of Tx blocks.  However it did
show up in the PS domain, where in the absence of active TBFs the
PCU may omit DL blocks.

Add a new field 'dl_mask' to struct l1sched_chan_state, similar to
the existing 'ul_mask', and use it to reconstruct the removed logic.

Change-Id: I4538a8fe6b29f8d6eca33ad27d4a9852e3a3e86c
Fixes: a0770250 "osmo-bts-trx: alloc/free burst buffers in trx_sched_set_lchan()"
2023-06-03 14:56:42 +07:00
Vadim Yanitskiy 785e731def osmo-bts-trx: tx_pdtch_fn(): use msgb_l2len()
Change-Id: If3c2d9d93399411d4466779ce8e8987843b521b1
2023-06-02 18:50:40 +07:00
Mychaela N. Falconia 592030eee7 trx TCH DL: transmit invalid speech blocks instead of dummy FACCH
In speech TCH operation, there will always be times when a speech frame
needs to be transmitted on the downlink, but there is no frame available
to transmit (gap in the incoming RTP stream), or the logic of DTXd says
that no frame shall be transmitted at this FN, but we are not doing
physical DTXd.  Previous osmo-bts-trx code sent dummy FACCH during such
conditions, but this approach is bad for TCH/HS where we would like to
transmit good speech frames or speech frame gaps one 20 ms frame at a
time, rather than take out pairs of frames for dummy FACCH/H.  Other
BTS models (sysmoBTS PHY) send out invalid speech blocks with inverted
CRC3 under the conditions in question - do the same in osmo-bts-trx.

The present change modifies osmo-bts-trx TCH DL frame gap behavior
only for TCH/FS, TCH/HS and TCH/EFS; for all other channel modes,
including AMR speech, the previous behavior of sending dummy FACCH
is left unchanged.

Depends: Iade3310e16b906efb6892d28f474a0d15204e861 (libosmocore)
Change-Id: I78106802a0aa4af39859c75d29fe0e77037899fe
2023-05-31 17:40:43 +00:00
Vadim Yanitskiy 3302d4adfe osmo-bts-trx: tch_dl_dequeue(): do not drop CSD frames
Change-Id: I382b9994db01d58515c89c8de6250cd3239b8861
Related: OS#1572
2023-05-30 11:08:25 +00:00
Mychaela N. Falconia 405368b697 HR1 codec: act on SID indication in RFC5993 RTP input
Suppose we receive RTP from the uplink of another BTS, and the
UL-handling BTS has channel-decoded an HR1 frame which it deems
(per GSM 06.41 section 6.1.1) to be a valid SID, even though it is
not a perfect, error-free SID.  How will this SID frame be
represented in RFC 5993 transport?  My reading of the RFC tells me
that the UL-handling BTS will need to apply an operation like our
osmo_hr_sid_reset() to the payload before sending it out in RTP -
but because the text of the RFC does not explicitly address this
scenario, others may have interpreted it differently.

If we receive an RFC 5993 RTP payload in which FT is set to 2,
indicating good SID, but the actual HR payload is not a perfect SID
(the SID field is not all 1s), the only reasonable interpretation
of such occurrence is that the sender of this payload was another
BTS whose implementors interpreted the RFC as not requiring them
to rejuvenate the SID codeword prior to RTP output.  Therefore, let's
treat such payloads as valid SID for our DTXd logic, and rejuvenate
the SID codeword ourselves.

Change-Id: Ife00de6220a8ca7cc180a61734497f1acb7f5b83
2023-05-29 21:04:07 +00:00
Mychaela N. Falconia 1dd710944f HR1 codec: validate ToC header in RFC5993 RTP input
osmo-bts-trx always accepted (and previously required) HR1 codec RTP
input in RFC 5993 format; currently we accept this RTP format as
input for all BTS models, but no longer require it.  However, we
have never applied any checks to this format's ToC header, even
when we previously required it in osmo-bts-trx.  Check this header
and reject invalid payloads that just happen to have the same octet
length as valid ones.

Change-Id: If16d38641913bb46bcd7cc11685407ed17136bfe
2023-05-29 20:28:57 +00:00
Mychaela N. Falconia a84b9a0261 FR/HR/EFR TCH DL: implement DTX rules
GSM 06.31, 06.41 and 06.81 are the respective DTX specs for FR, HR
and EFR.  In each of these specs, section 5.1.2 specifies the
expected shape of radio downlink in the presence of SIDs: one SID
frame after each talkspurt (after speech frames), and one SID frame
in every SACCH-aligned position every 480 ms (every 240 ms for HR),
or if the actual SACCH-aligned position is taken up by FACCH,
then just one SID frame as soon as possible after that FACCH -
and no transmitted SID frames in other positions.

This just-referenced spec section was written with the assumption
that it will only be applied when DTXd is enabled - however, if
the RTP stream for call leg B DL comes from call leg A UL (TrFO),
then we are going to receive SID frames in the stream intended for
our DL even when DTXd is disabled or not supported altogether.
The easiest solution is to apply FR/HR/EFR DTXd logic whenever
the incoming RTP stream contains SID frames, irrespective of physical
DTXd enable/disable state.  If we apply such "logical DTXd" when
physical DTXd is disabled, the BTS model PHY will end up transmitting
induced BFIs (dummy FACCH or inverted CRC3) in those frame positions
where the "logical DTXd" function says "please transmit nothing".

The point remains, however, that the prescribed SID shape on the
radio downlink (expected positions of SID frames) won't happen on its
own: in the case of TrFO, whichever SID frames are present will be
in wrong positions for leg B DL, and even in the case of transcoded
calls the responsibility for DL SID shaping cannot be placed on the
RTP stream source because that source won't know where SACCH alignment
will lie.  Therefore, the necessary DL SID reshaping has to be done
in the RTP stream receiver in OsmoBTS.

Related: OS#5996
Change-Id: I924ab21952dcf8bb03ba7ccef790474bf66fc9e5
2023-05-29 16:21:36 +00:00
Vadim Yanitskiy d9de1a5b28 osmo-bts-trx: use direct pointer to chan_state->{ul,dl}_bursts
There is no more need to access the UL/DL buffers via pointer to pointer
thanks to the previous patch [1] moving the memory management routines
out of the logical channel specific Rx/Tx handlers.

Change-Id: Ib1e8e86ac60a7ac9b0415ef66b609eaa33443c19
Related: [1] c45e03726af8a2b46b7166b3c47bc666ba933a69
2023-05-27 22:40:58 +07:00
Vadim Yanitskiy a0770250bc osmo-bts-trx: alloc/free burst buffers in trx_sched_set_lchan()
It's a lot cleaner if the Rx/Tx burst buffers are allocated and free()d
in one place rather than in each lchan handler individually.  Allocate
the buffer(s) during the lchan activation, free() on deactivation.

Regardless of lchan type, allocate the maximim size of 4 * (3 * 2 * 58)
bytes, which is sufficient to store 4 8PSK modulated bursts.  This way
we reduce the load on the memory allocator at the cost of memory
consumption, what should not be a big problem.

Change-Id: I6a5f76023fc492786076a63016f81285b3576c33
Depends: libosmocore.git I1c38ccc2b64ba9046bb3b1221d99cc55ec493802
Related: OS#1572
2023-05-27 22:39:50 +07:00
Mychaela N. Falconia c18f9f256c all models, HR1 codec: select RTP output format via vty option
The new vty option "rtp hr-format (rfc5993|ts101318)" selects the
RTP output format to be used for HR1 codec, consistently across
all models.  The default is set to match legacy behavior: ts101318
on osmo-bts-{lc15,oc2g,sysmo} and rfc5993 on osmo-bts-trx.
On models where no legacy behavior is applicable, the default is
set to rfc5993 as a forward-looking measure - see OS#6036.

Closes: OS#5688
Change-Id: I168191874a062429a57904511a1e89e3f588732e
2023-05-27 10:24:09 +00:00
Mychaela N. Falconia 44d47b2cdd trx, HR1 codec: change UL PHY output format to TS 101 318
As a preliminary step before making the RTP output format from
OsmoBTS configurable with a vty option, we need to make the internal
format consistent across all models.  The "natural" output from a
"pure" GSM 05.03 channel decoder is TS 101 318, which is also the
output format of all currently supported proprietary PHYs - adopt
it as our internal format.

Related: OS#5688
Depends: I6e75ca95409b5c368e8e04d0e0aba41e0331d9e6 (libosmocore)
Change-Id: I41bce6226964975cb85aea89e4c0f9e11e4929b8
2023-05-27 10:24:09 +00:00
Mychaela N. Falconia 4b945ec327 trx: fix HR1 codec breakage from format change
As of commit 1160cabefb, the common layer of osmo-bts accepts both
TS 101 318 and RFC 5993 formats for HR1 codec, and always passes
the more basic TS 101 318 format to the BTS model.  Unfortunately,
osmo-bts-trx has model-specific code checking the payload length
that was overlooked in that patch, causing breakage.  Fix that bug.
(The actual channel encoding function in libosmocoding already
accepts 14-byte payloads.)

Related: OS#5688
Fixes: I702e26c3ad5b9d8347e73c6cd23efa38a3a3407e
Change-Id: I0e251faeffb76d2604a4100c848141d239d1d86f
2023-05-26 22:05:15 +00:00
Mychaela N. Falconia 1160cabefb all models, HR1 codec: accept both TS101318 and RFC5993 formats
There exist two different RTP encoding formats for HR1 codec: one
"simple" format defined in ETSI TS 101 318, and an extended format
(adding a ToC octet) defined in IETF RFC 5993.  Following the
liberal-accept clause of Postel's law, we would like to accept
both formats.  Implement this feature by first converting all HR1
RTP inputs to the more basic TS 101 318 format at the point of
input preening, and then consistently using this basic format
internally.

Related: OS#5688
Depends: I13eaad366f9f68615b9e9e4a5f87396a0e9dea0f (libosmocore)
Change-Id: I702e26c3ad5b9d8347e73c6cd23efa38a3a3407e
2023-05-26 16:05:23 +00:00
Mychaela N. Falconia 208127986e refactor: replace rtppayload_is_valid() with preening before enqueue
Up until now, our approach to validating incoming RTP payloads and
dropping invalid ones has been to apply the preening function inside
l1sap_tch_rts_ind(), at the point of dequeueing from the DL input queue.
However, there are some RTP formats where we need to strip one byte
of header from the payload before passing the rest to our innards:
there is RFC 5993 for HR codec, and there also exists a non-standard
extension (rtp_traulike) that does a similar deal for FR and EFR.
Because of alignment issues, it will be more efficient (avoids memmove)
if we can do this header octet stripping before we copy the payload
into msgb - but doing so requires that we move this preening logic
to the point of RTP input before enqueueing.  Make this change.

Related: OS#5688
Change-Id: I7fc99aeecba8303b56d397b8952de5eea82b301e
2023-05-26 16:05:23 +00:00
Oliver Smith 05b4629166 systemd: depend on networking-online.target
Related: SYS#6400
Change-Id: I9c0cc0779f9ddb7520a565668b7cde07c6ad55d8
2023-05-26 14:10:44 +02:00
Mychaela N. Falconia 9cc85c1a6a trx: remove model-specific BFI packet formats
As detailed in OS#6033, osmo-bts-trx was emitting its own invented
packet formats to signal BFIs (bad frame indications), different
from the vty-configured ("rtp continuous-streaming" or not) BFI
signaling method implemented in l1sap and used by all other BTS models.

In the case of EFR codec, the made-up BFI format previously used by
osmo-bts-trx caused EFR operation to be broken: a spec-compliant EFR
decoder on the receiving end of the RTP stream (a network transcoder
or the MS on the other GSM call leg) would receive and decode garbage
EFR frames of 244 zero bits instead of invoking the spec-defined bad
frame handler, causing bad audio artifacts for the user.  The same
situation would also happen for FR1 codec, but the application of
ECU masked this bug: with the ECU invoked in the UL output path,
the BFI emitting code for FR1 never executed.

In the case of AMR and HR1 codecs, the model-specific BFI packet
format of osmo-bts-trx is currently harmless, but:

* The extra code adds unnecessary complexity;

* BFI packet formats are inconsistent between osmo-bts-trx and
  other OsmoBTS models;

* BFI format is even inconsistent within osmo-bts-trx itself, as
  under certain conditions the common code in l1sap will override
  the UL payload from the BTS model and emit its own form of BFI
  instead.

Fix all of the above by removing trx model-specific BFI formats
for all codecs, and let l1sap handle all BFIs.

Related: OS#6033
Change-Id: I8f9fb5b8c5b2cad4b92ac693c0040779f811981a
2023-05-19 15:07:09 +00:00
Vadim Yanitskiy 2c511d5755 copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH
Change-Id: Ib0bed7a4196305e2b413ca657f4fa8fb6f0d39f6
2023-05-19 08:50:18 +00:00
Philipp Maier 0eb90a0a98 paging: cosmetic: rename all IMM.ASS references to MAC block
The paging interface towards the PCU has a confusing API. In fact what
the PCU does when it wants to page or do an immediate assignment is
sending a ready formatted MAC block to the BTS. The BTS then puts this
MAC block in the paging queue and then eventually it justs sends it
without looking at the contents. For the code in paging.c it is not
imortant if the MAC block is an immediate assignment, it only cares if
the paging record contains a MAC block or paging parameters.

Related: OS#5927
Change-Id: Ifab37fdedaba98b160718113767e4ef6ee7d16ad
2023-05-16 11:38:56 +02:00
arehbein 7f03444d8b PCU interface: Log version when starting listener
Change-Id: Ieba46cc7eee7758033815014ee38bf4751a0f26f
2023-05-10 12:33:53 +00:00
Mychaela N. Falconia 81cfbb10cb all models, FR/EFR UL: change SID check to _is_any_sid()
In all OsmoBTS models in FR and EFR speech modes, as the UL traffic
frame stream is passed from the PHY to l1sap and ultimately to RTP
output, all passed frames are checked for SID.  The Boolean result
of this SID check is used in two ways:

* RFC 3551 instructs that the Marker bit in the RTP header SHOULD be
  set in the first packet of a talkspurt after a period of silence
  suppression.  OsmoBTS implements this recommendation by setting
  the Marker bit in the first RTP-transmitted non-SID UL packet
  that was preceded by SID.

* In osmo-bts-trx only, this same SID check serves a second purpose:
  handling of BFI conditions depends on whether or not the last received
  good traffic frame was a SID.  If a BFI condition is received after
  a non-SID traffic frame, the ECU is invoked, and if this ECU fails
  or when libosmocodec does not provide an ECU for the codec in use,
  a special FR (EFR) BFI frame of 260 (244) zero bits is emitted.
  Both the ECU call and the peculiar form of BFI are skipped when the
  last received good traffic frame was a SID.

For both of the above purposes, in all BTS models, change the SID check
from osmo_{fr,efr}_check_sid() to osmo_{fr,efr}_is_any_sid().  The
effect of this change is that "what counts as a SID" for the just-listed
purposes changes from recognizing only perfectly uncorrupted SID frames
without any bit errors to recognizing all frames which the rules of
GSM 06.31 (FR) or 06.81 (EFR) classify as either valid or invalid SID.

Change-Id: I5c24b379deda8ae551f9924d10770da50e6acbbd
2023-05-10 00:26:31 +00:00
Mychaela N. Falconia e38618f7cc lc15,oc2g: fix handling of SID in EFR
Commit 32682c63f6 fixed EFR SID handling in osmo-bts-sysmo,
but that fix was never propagated into osmo-bts-{lc15,oc2g} versions,
which are essentially copies of osmo-bts-sysmo.  Fix that oversight.

Change-Id: I509c1ea374e640d819952d58592b12fa884ad9d8
2023-05-09 23:52:35 +00:00
Mychaela N. Falconia 5755946beb RTP input, FR & EFR: preen incoming payloads for SID errors
Those network elements which receive a stream of codec frames that
may come from the uplink of GSM call A and which are responsible
for preparing the frame stream for the downlink of GSM call B
(such as OsmoBTS receiving RTP and feeding DL to its PHY) must be
prepared for the possibility that their incoming frame stream may
contain corrupted SID frames, presumably from bit errors on radio
link A.  Per the rules of section 6.1.1 of GSM 06.31 for FR and
GSM 06.81 for EFR, SID frames with just one errored bit are still
to be accepted as valid, whereas frames with more corrupted bits
which are still recognizable as SID are classified as invalid SID.

In the case of a TrFO call, the entity switching from leg A UL to
leg B DL is responsible for *not* transmitting invalid SID frames
on the destination leg (they should be treated like BFIs), and any
deemed-valid SID frames that are forwarded should be preened,
correcting that one bit error they may exhibit.  Implement this
functionality in OsmoBTS.

Change-Id: I89df2f12c49dd5378667cf149d19bde654f80134
2023-05-08 19:09:16 +00:00
Pau Espin 8b306b6f93 bbtransc/rcarrier: Fix statechg done twice upon NM_EV_RX_OPSTART
When the NM_EV_RX_OPSTART event is received, it will call bts model
specific function bts_model_opstart(), which is responisble for
answering back with NM_EV_OPSTART_ACK or NM_EV_OPSTART_NACK.
Since that answer could be done sequentially in same callback code path,
we could end up twice at the end of the st_op_disabled_offline()
function checking for statechg (due to reentring that function).
As a result, one can see the following message appear during OML
bring up:
nm_bb_transc_fsm.c:185 NM_BBTRANSC_OP(bts0-trx0){ENABLED}: transition to state ENABLED not permitted!

Fix the issue by avoiding ending up at the end of the function in code
paths which should not be triggering any change.
The case of bbtransc is a bit different than that of rcarrier for
NM_EV_RX_SETATTR, since the former really doesn't receive any such
message from the BSC yet, so if we checked for that one before
continuing, it would never go on.

Change-Id: I5184a33dd8da9244e8aacf3ab8bb8930f732a136
2023-05-05 14:33:52 +00:00
Philipp Maier 267c2606ad pcu_sock: don not continue when running out of TRX space
The info indication on pcu_sock cann only support a limited but
sufficient number of TRXs, when we detect that we overflow the maxiumum
number of TRXs, then break and do not continue.

(this is more or less a cosmetic problem)

Change-Id: If4d7eecaded22f86750283f7aa13072064724537
2023-05-05 10:31:30 +00:00
Philipp Maier 04a373cf6a l1sap: fix wording in comment
The function rtppayload_is_valid() is called from the receiving RTP code
path. Lets use the word "forwarding" instead of "sending" to avoid the
impression something is sent (like sending RTP packets to the outside
world)

Change-Id: Ie7fcc53dea462b0d575b0c9ca73ba7507289eefe
2023-05-04 17:41:56 +02:00
Pau Espin 3f5a343098 octphy: Fix clearly wrong noop assignment
This code has been there since first octphy support was added.
New gcc 13.1.1 is catching this and reporting compilation errors:
"""
/osmo-bts/src/osmo-bts-octphy/l1_oml.c: In function ‘ts_connect_as’:
/osmo-bts/src/osmo-bts-octphy/l1_oml.c:1518:60: error: ‘oc’ is used uninitialized [-Werror=uninitialized]
 1518 |         tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *oc =
      |                                                            ^~
/osmo-bts/src/osmo-bts-octphy/l1_oml.c:1518:60: note: ‘oc’ was declared here
 1518 |         tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *oc =
      |                                                            ^~
/osmo-bts/src/osmo-bts-octphy/l1_oml.c: In function ‘bts_model_ts_disconnect’:
/osmo-bts/src/osmo-bts-octphy/l1_oml.c:1803:62: error: ‘oc’ is used uninitialized [-Werror=uninitialized]
 1803 |         tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *oc =
      |                                                              ^~
/osmo-bts/src/osmo-bts-octphy/l1_oml.c:1803:62: note: ‘oc’ was declared here
 1803 |         tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *oc =
      |                                                              ^~
"""
Change-Id: I0da7d3a94e9eba15b8d3d3d995bba532170d9df7
2023-05-04 14:48:57 +02:00
Philipp Maier 2a60cc3087 sched_lchan_tchx: use GSM_HR_BYTES_RTP_RFC5993 constant
osmo-bts-trx uses the RFC5993 RTP payload format, so when handling the
RTP payload use GSM_HR_BYTES_RTP_RFC5993, instead of GSM_HR_BYTES + 1

Depends: libosmocore.git I125ef9cdab98c073971841c175b1a7dcd927f9c2
Related: OS#5688
Change-Id: I54dd3adab88e2262913f7b1e89340a0246c88a8a
2023-05-04 05:30:51 +00:00
Vadim Yanitskiy acaf6c563b oml: reset BCCH carrier power reduction mode (if enabled)
We should not maintain BCCH carrier power reduction mode if we loose
connection to the BSC.  When entering NM_BTS_ST_OP_DISABLED_OFFLINE,
reset the related state fields if it was enabled.

Change-Id: I34468e3fccc490f48e30b159b63308a395b65fa9
Related: SYS#6435
2023-05-02 16:36:07 +07:00
Vadim Yanitskiy dfd6224484 oml: gsm_objclass2{mo,obj}(): set cause for unknown obj_class
This patch makes BTS_Tests_OML.TC_wrong_obj_class pass.

Change-Id: I30e109a7c86e651fb7055a80ef0656d8563475c8
Fixes: OS#5966
2023-05-01 23:59:06 +07:00
Vadim Yanitskiy 8b535ee77a oml: gsm_objclass2{mo,obj}(): cosmetic: return immediately
Change-Id: Ie2fb927ac7f71103a1e0e693718771dd36139223
Related: OS#5966
2023-05-01 23:59:06 +07:00
arehbein cf8736e916 gsm_objclass2obj(): Change signature/set NACK cause
- Add out-parameter to enable returning a NACK cause (ignored if NULL)
 - Return appropriate NACK cause if TRX number is unknown (fixes OS#5967
   together with change I37e6b23ed95260a8188910cf9754faffcba519c5)

Change-Id: If734ea2c8cae4c1f99b02520dffa4e3862a67745
Related: OS#5961, OS#5967
2023-04-29 02:51:12 +07:00
arehbein 204cd4d7e3 gsm_objclass2mo(): Change signature/set NACK cause
- Add out-parameter to enable returning a NACK cause (ignored if NULL)
 - Return appropriate NACK cause if TRX number is unknown (part of fix
   for OS#5967)

Change-Id: I37e6b23ed95260a8188910cf9754faffcba519c5
Related: OS#5961, OS#5967
2023-04-29 02:51:12 +07:00
Vadim Yanitskiy 1d7133e936 fixup: common: Remove unused function gsm_objclass2nmstate()
Change-Id: I31b948f2aeb18ac8069fc019285be7991cffe064
2023-04-29 02:49:34 +07:00
arehbein a4a9c28f15 common: Remove unused function gsm_objclass2nmstate()
Change-Id: Ia538e3f3d416408f69f9d8e6c8c746eddd9f005a
2023-04-28 12:21:15 +00:00
Oliver Smith f729ff970a debian: set compat level to 10
Related: OS#5958
Change-Id: Id0f168a7d3c2ae6869121397e65ca1d0cfea30d3
2023-04-25 16:48:21 +02:00
Max bbdb10ee48 license: fix typos
Change-Id: I450919973bbd31bce44c0b6606f457581e2f71df
2023-04-23 15:08:00 +03:00
Vadim Yanitskiy ac1eb71d78 flags: ensure completeness of bts_impl_flag_desc[]
Change-Id: I049df344c8c0b0d6cd122e2f2d705e0f7ee5990c
2023-04-21 17:07:33 +07:00
Vadim Yanitskiy 11ec99d419 flags: group BTS_INTERNAL_FLAG_* into an enum
Change-Id: I4c7d9f6dce61f7690b86c3973b13ddb63cdace04
2023-04-21 17:07:33 +07:00
Vadim Yanitskiy fad8986f06 flags: add missing entries to bts_impl_flag_desc[]
The following output can be seen when doing 'show bts' in the VTY:

  BTS model specific (internal) flags:
    001 Measurement and Payload data combined
    003 unknown 0x8

Fix this by adding the missing values to the value-string array.

Change-Id: I83e5065f9f80b4f81e9767f184c8dc027883025a
Fixes: 0277cddab "sysmo,oc2g,lc15: Make RadioChannel MO depend on RadioCarrier MO"
Fixes: ee5eb6169 "l1sap: check if BTS model supports interference reporting"
2023-04-21 17:07:25 +07:00
arehbein b96d975f7d common: Remove redundant checks
Remove checks that are performed in gsm_bts_trx_num() already.

Related: OS#5961
Related: OS#5967
Change-Id: I9f21f1a0a9dab897d4fd89ab6b7341ca4aec8b22
2023-04-20 23:17:45 +00:00
Pau Espin 30601ccaf4 vty.c: Use already available tpp pointer
Change-Id: I54b4b995c3296d8a38ee72604dedbde77c5d0722
2023-04-18 13:24:39 +02:00
Vadim Yanitskiy a1927f32f7 osmo-bts-virtual: properly activate [CBCH/]BCCH/CCCH
In change 8e04613e I overlooked that osmo-bts-virtual is re-using the
scheduler of osmo-bts-trx and forgot to update its OML logic.  As a
result, osmo-bts-virtual is broken and does not transmit anything on
the broadcast channels.

Change-Id: I2276f7e5e4042e56ddf1fd1642c917dba0005ac4
Fixes: 8e04613e "osmo-bts-trx: properly activate [CBCH/]BCCH/CCCH"
Related: OS#6001, OS#1572
2023-04-13 02:52:07 +07:00
Pau Espin be18d2b275 bts-sysmo: Delay marking phy_link as connected until L1 reset + got info
Better wait until the DSP is reset and all the information is retrieved
before telling upper layers that the phy is ready. Keep it in CONNECTING
state meanwhile.

Change-Id: Ifdc791336fb8efd42f4428893f687093085af129
2023-04-11 17:19:48 +02:00
Pau Espin cb0c0dfa15 bts-sysmo: Fix pinst->version filled too early
The fields used to fill in pinst->version are set when info_compl_cb()
is called, which happens asynchronously and hence later than when in
bts_model_phy_link_open().
Hence, copying the values when in bts_model_phy_link_open()
(l1if_open()) makes no sense at all.
Fill in pinst->version in info_compl_cb(), just when the layer receives
the required information.

Related: OS#5978
Change-Id: Ica53a5d852214b24de7f75b08ad7e595ce5236ee
2023-04-11 17:05:33 +02:00
Pau Espin 8a21e7c27a oml: Fix potential null ptr access on trx object
If the TRX_NR had no matching TRX it would access a NULL pointer trx
after failing to resolve it.
This commit refactors the code path to only require the trx pointer at
the very end, and NACKs the message if TRX fails to be resolved.

Change-Id: If27639ae1727fc5232e1a964a1b29f50c8805d80
2023-04-11 15:47:47 +02:00
Pau Espin 4c56bed4d7 pcu_sock: Drop bts_sm pointer
It is not really needed since the object is global.

Change-Id: I17f7c42dc9f38485dbcc8595a3a3dbf5a80a7961
2023-04-11 11:46:27 +02:00
Pau Espin 31c759165a pcu_sock: Allocate pcu_sock_state using g_bts_sm talloc context
Change-Id: I29eae7bcc66dc5e646b8a4703871682202259bed
2023-04-11 11:36:19 +02:00
Pau Espin 38491d813b Move pcu_sock_state to gprs section of bts_sm
Change-Id: I7d739287fd11f81ce657bac362e55fa822fb0ef5
2023-04-11 11:35:34 +02:00
Pau Espin 1dc9e3f2f8 Update g_bts_sm->num_bts when bts is added/removed from bts list
Change-Id: Ifa162d01d908eba8cadd8f01dd4d698491176fe8
2023-04-11 11:29:06 +02:00
Pau Espin b07e19d185 Properly report all states through NM FSM upon OML link up
Change-Id: Ic3358629d17baab46f467a1ab82eea1837ad7390
2023-04-11 11:16:21 +02:00
Pau Espin c3e059ce04 nm: Document current state of SW_ACT in TRX related objects
Change-Id: Ie24503b25b9c8042edae696d5b002933c73d00fb
2023-04-11 11:16:21 +02:00
Pau Espin 36ef885a6c Drop NM_EV_BBTRANSC_INSTALLED in favour of generic NM_EV_SW_ACT
All the other objects already use that one; there's no need to have a
specific one for the NM Channel FSM.

Change-Id: Ic5fd37367b500c75a0a53b1d868ba2aed3edef1b
2023-04-11 11:16:21 +02:00
Pau Espin 7cd45a7cfe Move GPRS NSE under BTS SiteMgr
As per ipaccess expectancies and following TS 12.21.

Change-Id: If44d8f256cab7b2660900cedfb0ed9fe67eb3420
2023-04-11 11:15:07 +02:00
Pau Espin 6be13437b7 Merge gsm_network into gsm_bts_sm and place gsm_bts under it
This way the data model in TS 12.21 (Figure 1) is followed, where
there's a BTS Site Manager containing one or more BTS. In our case we
only support 1 BTS (cell) so far.

Change-Id: Ideb0d458ec631008223f861cf8b46d09524a1a21
Related: OS#5994
2023-04-11 11:11:45 +02:00
Pau Espin 3481dd40b3 nm: Dispatch NM_EV_SW_ACT in cascade to BTS SiteMgr children
Change-Id: I97445812bb1b6de450411aceaeece2427027ae67
Related: OS#5994
2023-04-11 08:11:43 +00:00
Pau Espin 66543fe422 Introduce NM FSM for GPRS NSVC object
Change-Id: I684482064136a461d01cace3cd37afc8b68458cc
Related: OS#5994
2023-04-11 08:11:43 +00:00
Harald Welte c3d839be9e cosmetic: Change LOGPLCFN argument order
As it has come up during code review of Change-ID
I214af0448652a9f321ccbab77977b67663ba28f9 introducing LOGPLCNF, my
approach to the strict preserval of argument order (lchan first from
LOGPLCHAN and fn *after* loglevel from LOGPFN) was considered
sub-optimal.

I used the following spatch rule to clean this up:

@@
expression lc, ss, logl, fn;
expression list trailer;
@@

-LOGPLCFN(lc, ss, logl, fn, trailer);
+LOGPLCFN(lc, fn, ss, logl, trailer);

Change-Id: Iba4a8416545673d03cb057e4855f8b1ecae3e1ec
2023-04-09 14:10:09 +00:00
Pau Espin 5b75e5dc8d bts: Simplify lifecycle of BTS inside bts_list
Add the BTS object to the BTS list as the first thing after it is created,
this way it's always attached and hence simply always detach it during
object free.

Change-Id: Ica4fe2a4be0c85b10702011e978be03bf970b0c8
2023-04-06 10:28:22 +00:00
Pau Espin 9c4b472179 Move NSVC structs to be part of NSE
The NSVCs exist inside an NSE. Rearrange data model to have proper
relations.

Change-Id: I1cfe9366594836c622673d461ab8b2edd1a2b58a
2023-04-06 10:28:22 +00:00
Pau Espin 10d5499d03 Rearrange declaration of struct gsm_bts_gprs_nsvc
Move it together with the other similar objects like gprs_nse and
gprs_cell.
Move the "mo" field to the start of the struct, similar to the other
types.

Change-Id: I5dc020a6bab8c94ab831b6ca506bc5cb681d07a3
2023-04-06 10:28:22 +00:00
Pau Espin d50d239914 Introduce NM FSM for GPRS Cell object
Change-Id: I5fd1d17da09a5f0eee3d69fcb4788c106a240e21
Related: OS#5994
2023-04-06 10:28:22 +00:00
Pau Espin 989d99ca00 Fix octet 2 of NM GPRS Cell
Octet 2 should contain the address of the GPRS cell in the GPRS NSE
object. Since there's 1 GPRS Cell per BTS and we have only 1 BTS in
osmo-bts, then this address should be 0.
Otherwise, osmo-bts answers sometimes using (0x00, 0xff,0xff) instead of
requested (0x00, 0x00, 0xff), for instance when ACKing an Admin Unlock.
This is kinda still fine since value 0xff has the meaning of "all"
addresses, and that means the only one available.
Still, it's not the proper way to identify the object, so this patch
fixes it.

Change-Id: I2ea05778f5b5ac335c75f3958324664553da7f0d
2023-04-06 10:28:22 +00:00
Pau Espin 633bbf174a Introduce NM FSM for GPRS NSE object
Related: OS#5994
Change-Id: I01eadc63214a2eb5e1bce455c7e5b62bd41905ea
2023-04-06 10:28:22 +00:00
Pau Espin 4190537d7d NM: NACK received OML OPSTART if no attributes were set beforehand
Related: OS#5992
Change-Id: I771ecc2f60873a3549e8a07a2e57c7948dfc993e
2023-04-06 10:28:22 +00:00
Pau Espin cea6c230ad nm: Apply OPSTART through NM FSMs
This way we have further control on how to handle the OPSTART messages
received. For instance, NACK them if the NM object FSMs are not at the
expected correct state.

Related: OS#5992
Change-Id: I5df0bfb4cc812c11c7a00a8ffa882ae1915d562f
2023-04-06 10:28:22 +00:00
Pau Espin 92d1d1582b Simplify implementation of bts_model_opstart() in all bts types
Use mo->fi directly to avoid repeating code paths for each obj_class.

Change-Id: I54632201afe87eb3e02bc75cbade163917239ab6
2023-04-06 10:28:22 +00:00
Pau Espin f4505f6caf lc15,oc2g,sysmo: Update GPRS NM object state at the right time
Change-Id: I2f331954835496504f1fafa572bd46ee83b03a63
2023-04-06 10:28:22 +00:00
Pau Espin 91a1295a5a bts_model_apply_oml(): Improve definition of parameter
The param is usually called obj_class, but here it is called kind.
In any case, change the param to pass the related struct gsm_abis_mo
(which still contains mo->obj_class), similar to what's done in other
bts_model functions such as bts_model_opstart().

Change-Id: Ife2e98a791455d5f7e7052356d559af2f1d4d185
2023-04-06 10:28:22 +00:00
Pau Espin 8894fe6f4c oml: Get rid of unused tlv_parsed param in bts_model_apply_oml()
This way we simplify the common lower level interface. It can be added
in the future again if it is really required at any point to pass/use
specific TLV values in the device-specific code.

Change-Id: I64c6c6834e277b1d75a97d6f408e7e1b7ca85832
2023-04-06 10:28:22 +00:00
Pau Espin aebd2a21b5 nm: Drop NM_EV_SETATTR_{ACK/NACK}
Simply return error codes from lower layer implementations, and do
the OML handling in the common NM TS 12.21 FSMs.

As a result, we simplify the logic in the lower layers.

Change-Id: I281c07bb5ad88ee03542f092141cebe036d10aee
2023-04-06 10:28:22 +00:00
Harald Welte 8c397da917 logging: Introduce LOGPLCGT()
We have LOGPLCHAN and LOGPGT, but not a combined version for logging
both the lchan and the gsm_time.  Let's resolve this.

Log messages without indicating the lchan name are pretty useless if you
have multiple concurrently active lchans...

Change-Id: I4bf3363f92acdf67d8e7333e30ac2209e31cb287
2023-04-05 17:56:00 +00:00
Pau Espin c4a17d35ec nm: Apply BTS/TRX/TS OML Attributes through NM FSMs
This way we have further control on how to handle the SetAttr meessages
received. For instance, NACK them if the NM object FSMs are not at the expected
correct state.

The originating msgs are now kept owned and freed by the OML layer
(oml.c), and the NM FSMs only uses them and create new OML msgb when
answering with ACK/NACK.

Related: OS#5992
Change-Id: Id68868e25bbf96227ab6459fcd3c9181852ed28e
2023-04-05 13:21:14 +02:00
Pau Espin c12bc93db8 oml.c: Remove dot character at the end of log lines
Change-Id: Iaf061bb752f9808a6ab31049b9e87920a6b07f3d
2023-04-05 13:10:05 +02:00
Pau Espin 7a646f963b bts_model_apply_oml(): Drop unneded code
Calls to bts_model_apply_oml() are done only for BTS, RCARRIER and
RCHANNEL NM Objects in their respective Rx code paths (and they will
be moved to respective FSMs in follow up patches). This function is
never called with any of the GPRS NM objects.

These NM Objectes have the NM_MT_IPACC_SET_ATTR msg ACKED/NACKED in its
own path:
oml_ipa_set_attr()
	rc = oml_ipa_mo_set_attr()
	return oml_fom_ack_nack(msg, rc);

Change-Id: I1a0d38a122f50ffe749ebc4f1cc11235ca516586
2023-04-04 20:26:23 +02:00
Pau Espin 914e55caf3 Clarify configuration of TSC on each timeslot
Related: OS#5856
Change-Id: Ief21daf63ba76725de9117cbe14ada8b75f147df
2023-04-04 12:50:20 +02:00
Pau Espin 0350824203 bts-trx: Drop unused param to internal function
Change-Id: Id7ad7629ec13bcec618055c41083cdac0a3102be
2023-04-04 12:50:19 +02:00
Mychaela N. Falconia 4ff6888a81 bts-{lc15,oc2g,sysmo}: support EFR in repeat_last_sid()
The function repeat_last_sid() is implemented in the common part,
but is only used by osmo-bts-{lc15,oc2g,sysmo} models.  These BTS
models call this function when they are looking to see if a
previously cached SID frame needs to retransmitted on the DL
because it is that time according to the SACCH multiframe.
Out of non-AMR codecs, this function previously supported only
FR1 and HR1, but failed to support EFR.  Fix that omission.

Change-Id: Iebcd28e65af889254740757eed9c579392eb1c33
2023-04-03 15:15:48 +00:00
Vadim Yanitskiy 5f556af232 tests: $(BUILT_SOURCES) is not defined, depend on osmo-bts-virtual
Change-Id: I4ace06e115a2689bde9afd9f99ecee99d796360b
2023-04-03 13:33:25 +00:00
Pau Espin 909d943fe8 contrib/ber: Avoid regenerating codec_bit_class.h every build
Automatic generation of a header file using a C program built during
build of osmo-bts creates several problems when cross-compiling.

The generated header file is only 59 lines long, so let's have it
generated in order to avoid having to call the helper program every
time.

A Makefile target is added to easily regenerate the file manually in
case it's needed:
make -C contrib/ber/ update_codec_bit_class_h

Fixes: acf0f0f0bb
Change-Id: I97efdb4ee00537fcae191b4267d0211d582ef372
2023-04-01 21:18:25 +00:00
Harald Welte 1266c068d7 Replace explicit gsm_lchan_name() calls with LOGPLCHAN
There was a surprising number of explicit gsm_lchan_name() calls
from within log message code.  Let's avoid that whenever possible and
use a LOGPLCHAN() or related macro.

Change-Id: If4f4f555f5ca61dfa624b298805f5375efc0b137
2023-03-31 11:56:35 +00:00
Mychaela N. Falconia 61e7fdbb3f sysmo: emit empty RTP ticks during FACCH stealing on TCH/F
When FACCH stealing occurs and sysmoBTS L1 delivers GsmL1_Sapi_FacchF
instead of GsmL1_Sapi_TchF, that 20 ms unit still needs to be
accounted for in the RTP timestamp cadence, and if we run with
rtp continuous-streaming enabled, then an actual BFI packet needs
to be emitted.  The original code failed to do either; the present
change implements correct behavior for TCH/F.

The present patch only covers the case of TCH/F; handling of TCH/H
is left as a FIXME for other/later developers.

Related: OS#5974
Change-Id: I39d15faade28fb7d670493a99a0e0bdb654e2a4a
2023-03-30 17:30:53 +00:00
Mychaela N. Falconia 50710f4e8e rtp continuous-streaming: fix BFI in the quality-suppressed case
The check for (tch_ind->lqual_cb >= bts->min_qual_norm) in
l1sap_tch_ind() has the intent of suppressing valid-seeming
speech frame output from lower layers when the link quality is
too low; this check is particularly important for FR1 codec
where the intrinsic validity check is only a 3-bit CRC which has
1/8 probability of indicating "correct" when decoding radio noise
during DTXu silence.

However, this check is effectively defeated in the current
implementation of rtp continuous-streaming: the RTP packet being
output is the presumed-bogus speech frame from lower layers,
rather than the intended zero-length payload.  Fix this bug.

Related: OS#5975
Change-Id: Icee0f57be289a0592a0197469432a012d15f224c
2023-03-30 17:30:53 +00:00
Sylvain Munaut acf0f0f0bb contrib: Add BER testing tool
This implements RTP based GSM BER testing for osmo-bts, implementing
ideas described in https://osmocom.org/projects/osmobts/wiki/BER_Testing

In short: The command transmits a PRBS sequence encapsulated in RTP
frames, which are sent to the BTS, which transmits that data in the
(unimpaired) downlink.  The mobile station receives the data and is
instructed to loop it back in the (possibly impaired) uplink.  The BTS
receives that uplink, puts in in RTP frames which end up being received
back by this very tool.  By correlating the received RTP with the PRBS
sequence, this tool can compute the BER (Bit Error Rate) of the
(possibly impaired) uplink.  Doing this with different RF channel model
simulators in the uplink allows to establish BER at different levels and
channel conditions.

Original code by Sylvain Munaut extended with some comments and Automake
integration by Harald Welte.

Change-Id: I1cffa0ae959e29ec61775b13185fd1057ed7485a
2023-03-30 12:56:14 +02:00
Harald Welte f06b959c7d lc15: fix compiler warning about unused variable cell_size
oml.c: In function ‘bts_model_apply_oml’:
oml.c:1814:17: error: variable ‘cell_size’ set but not used [-Werror=unused-but-set-variable]
 1814 |         uint8_t cell_size;
      |                 ^~~~~~~~~

Change-Id: I0bf1542f613f613d03609d50836137ff440401af
2023-03-29 14:02:50 +02:00
Harald Welte 2551882c1c cosmetic: Remove "FIXME?" from Odd AMR CMI phase
This default phase of the Codec Mode Indication in downlink direction is
called "odd", which is defined by starting with CMC in every 26
multiframe.

At call set-up, after every successful handover and after a channel mode
modify, the default phase (odd) shall be used in downlink direction.
During a call, the phase of Codec Mode Indication may be changed in
downlink by using a RATSCCH message.

As we don't implement RATSCCH, odd is always correct.

Change-Id: Ia64767fbfdc3fb067d72dbf5eabb1d84e3868ce5
2023-03-29 12:02:10 +00:00
Harald Welte 96263aa908 oc2g: Fix 'unused variable' compiler warning
oml.c: In function ‘bts_model_opstart’:
oml.c:1883:32: warning: variable ‘ts’ set but not used [-Wunused-but-set-variable]
 1883 |         struct gsm_bts_trx_ts *ts;
      |                                ^~

Change-Id: Ifd5552f2dd56f4f9bf4c17d25b741f694f4f2168
2023-03-29 12:02:10 +00:00
Harald Welte 362f2e50c2 lc15/oc2g: remove unused variables
oml.c: In function ‘l1if_rsl_chan_mod’:
oml.c:1980:22: error: unused variable ‘i’ [-Werror=unused-variable]
 1980 |         unsigned int i;
      |                      ^
oml.c:1979:35: error: unused variable ‘s4l’ [-Werror=unused-variable]
 1979 |         const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type];
      |                                   ^~~

oml.c: In function ‘l1if_rsl_chan_mod’:
oml.c:1985:22: warning: unused variable ‘i’ [-Wunused-variable]
 1985 |         unsigned int i;
      |                      ^
oml.c:1984:35: warning: unused variable ‘s4l’ [-Wunused-variable]
 1984 |         const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type];
      |                                   ^~~

Change-Id: Ieb8882bbade7f6d6628c9c00150bcf54e3a9dc75
2023-03-29 12:02:10 +00:00
Harald Welte 3d2c107922 lc15: Remove unused warning
l1_if.c: In function ‘activate_rf_compl_cb’:
l1_if.c:1251:22: error: unused variable ‘i’ [-Werror=unused-variable]
 1251 |         unsigned int i;
      |                      ^

Change-Id: I23270dfe6779321e514c71184b3c71f52a9b4c4a
2023-03-29 12:02:10 +00:00
Harald Welte 9584980ea2 lc15: fix compiler warning about wrong indent
l1_if.c: In function ‘activate_rf_compl_cb’:
l1_if.c:1280:17: error: this ‘if’ clause does not guard... [-Werror=misleading-indentation]
 1280 |                 if (bts_lc15->led_ctrl_mode == LC15_LED_CONTROL_BTS)
      |                 ^~
In file included from ../../include/osmo-bts/dtx_dl_amr_fsm.h:3,
                 from ../../include/osmo-bts/msg_utils.h:8,
                 from l1_if.c:55:
l1_if.c:1282:25: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
 1282 |                         osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL);
      |                         ^~~~~~~~~~~~~~~~~~~~~~

Change-Id: I00ae3faf0f85fecf6e15e71dff071165725e547c
2023-03-29 12:02:10 +00:00
Harald Welte 80c605dd0b cosmetic: use __func__ instead of __FUNCTION__
Our linter would complain about this these days:

	__func__ should be used instead of gcc specific __FUNCTION__

Change-Id: I80bf6d0a89ce6454ae063759d6088a28b04670c0
2023-03-29 12:02:10 +00:00
Mychaela N. Falconia c29ca5eb7d common: implement rtp continuous-streaming mode
In some environments it is highly desirable for the RTP stream
coming from each GSM call UL on a BTS to be fully continuous,
without any gaps, with _some_ RTP packet emitted every 20 ms,
even if there is no speech or SID frame to be sent in that frame
time window.  The present change adds an rtp continuous-streaming
vty option which, when enabled, causes the BTS to emit RTP packets
with a zero-length payload, instead of producing gaps in the RTP
stream, when it has nothing else to send.

Related: OS#5975
Change-Id: Ic0e2edf2ed90ba0ac6bee5e7d9629bf0255e256d
2023-03-29 12:01:26 +00:00
Mychaela N. Falconia 32682c63f6 sysmo: fix handling of SID in EFR
Handling of SID in EFR mode was broken in osmo-bts-sysmo.
l1_to_rtppayload_efr(), the function for UL Rx, was using completely
bogus logic (passing bits in ETSI TS 101 318 EFR format to an AMR
decoding function), whereas l1if_tch_encode(), the function for
DL Tx, had missing SID logic for EFR while supporting SID detection
for all other codecs.  The fix is to use the new osmo_efr_check_sid()
function in libosmocodec.

Change-Id: Ia56c1bb7432968685110456961d24a907b0a201f
2023-03-29 11:59:28 +00:00
Mychaela N. Falconia e1e204fae3 trx: detect UL SID in EFR just like in FR
The TCH/F Rx code in osmo-bts-trx uses osmo_fr_check_sid() to detect
when the MS sends SID, and passes the flag to lchan_set_marker().
However, equivalent logic was missing for EFR, as until recently
there was no EFR SID check function in libosmocodec.  Now that
we have osmo_efr_check_sid(), use it.

Change-Id: Ib043e00dbf92145c2a6c32f6365517244472a922
2023-03-29 11:59:28 +00:00
Harald Welte ac23ce2e03 bts-{sysmo,oc2g,lc15}: Dump logical channel params during MPH-ACTIVATE.req
So far we only printed it during later modification.  Let's print
it also during initial activation of a logical channel.

Change-Id: I6982a52905e4719e2e9c40630252ffef2ff9fbed
2023-03-28 15:13:34 +02:00
Harald Welte c17697d337 common/vty: Print AMR MultiRate Configuration in "show lchan"
It can be useful to introspect the current active AMR mode set.

Related: OS#5944
Change-Id: I630af8c3835c2fcbea325c07db269d25e4e18f62
2023-03-28 15:12:10 +02:00
Harald Welte bb3ed23e71 bts-{sysmo,oc2g,lc15}: Fix RTP of AMR SID_FIRST_P1
When we receive a SID_FIRST_P1 frame from the PHY (during AMR/HR DTXu),
we must generate a SID frame on the RTP side.

The existing code
* ignored that the Amr_SidFirstP1 PHYIF message actually contains the
  RTP payload
* manually generated the same content using osmo_amr_rtp_enc()
* forgot to prefix that with the AMR CMR+TOC
* in the end, sent a completely broken (too short) AMR SID frame over RTP

Let's fix this by simply using the 7-byte RTP payload with CMR+TOC that
the PHY is providing to us.

Change-Id: I90479efcc002d497648a71e73847af54e6208358
Related: OS#5944
2023-03-28 15:12:10 +02:00
Harald Welte a563640f86 Introduce LOGPLCFN() for logging lchan-name + frame number
So far, we've had LOGPLCHAN() and LOGPFN().  This resulted in a number
of log lines containing frame numbers *not* containing the lchan
context, which makes it difficult to deterine which of potentially many
concurrently active lchans is logging.

Let's introduce LOGPLCFN() for a FN-extended version of LOGPLCHAN(),
and convert all callers that have the related context.

Change-Id: I214af0448652a9f321ccbab77977b67663ba28f9
2023-03-28 15:12:10 +02:00
Harald Welte 61b005193c cosmetic: Replace %i with %d
Our linter will fail on %i, so let's replace any legacy occurrences with %d

Change-Id: Ic302915bd5576d3e1f77668918f005d651daf21a
2023-03-28 12:44:22 +00:00
Harald Welte d47d288630 DTX: bts-{sysmo,oc2g,lc15}: Print DEBUG messages about ONSET
We're printing DEBUG messages for all other DTX frames, but not for
ONSET.  This made me think that we never received any ONSET frames
when looking at log output.

Let's add ONSET for completeness.

Related: OS#5944
Change-Id: I9a1511d9929444cef96388492d907e8f3a082311
2023-03-27 20:00:00 +02:00
Vadim Yanitskiy e464ef6524 osmo-bts-{sysmo,lc15,oc2g}: fix segfault in ph_tch_req()
ph_tch_req() is a recursive function and conditionally calls itself at
the very bottom.  The recursive call happens iff all of the following
conditions are met:

* DTXd is enabled,
* AMR codec is in use,
* DTX DL AMR FSM state is recursive.

The problem is that ph_tch_req() may pull sizeof(*lsap) from the given
msgb twice: during the initial and the recursive calls.  The second
attempt to pull sizeof(*lsap) causes the process to abort, because
the remaining room is less than it's attempting to pull.

AFAICT, doing msgb_pull() is not really necessary, given that
l1sap_tch_rts_ind() thankfully does set msg->l2h before pushing
the lsap header in front of the actual frame.

Update osmo-bts-sysmo and its copy-pasted siblings, which are likely
affected too, except osmo-bts-octphy which does not do the recursion.

Change-Id: Ib349b74a9e4bd48c902286f872d3b0e9a068256c
Related: OS#5925
2023-03-24 18:24:01 +00:00
Vadim Yanitskiy dbd70bca75 rsl: rsl_handle_chan_mod_ie(): add missing GSM48_CMODE_* values
Change-Id: Iec397f1ef4cb5ac1c48abf869f54e272ed0fbb55
Depends: libosmocore.git I6adda28698c0e479ef20f5d090c1f7f76a2ec97e
Depends: libosmocore.git Ia6b428e5b6aaecf151cbfa980b89eff6d0fe6006
Related: OS#1572
2023-03-23 20:09:49 +00:00
Pau Espin 8fe6479358 bts-trx: Avoid pushing interf_meas for disabled TRX
It makes no sense to push interference meas results for those TRX since
they are disabled, unused and hence won't be reported in RSL RF Res Ind.

Related: SYS#6370
Change-Id: Ie3fd80970585cb30808b0644568dbc8936a57721
2023-03-23 12:38:26 +01:00
Vadim Yanitskiy 8e04613e4f osmo-bts-trx: properly activate [CBCH/]BCCH/CCCH
The timeslot carrying BCCH/CCCH on C0 is a bit special in a way that
it's being activated implicitly - there is no explicit RSL CHANnel
ACTIVation for that.  This is why we have TRX_CHAN_FLAG_AUTO_ACTIVE,
which marks sub-channels of BCCH/CCCH in the trx_chan_desc[].

The upcoming patch changes the burst buffer allocation strategy, so
that the memory is allocated on channel activation and then free()d
on channel release.  This patch facilitates that by making the
activation/deactivation logic consistent for all sub-channels.

Change-Id: Id0c70d6a2b777a5117c85149bfa1b3a997299d1d
Related: OS#1572
2023-03-22 12:14:25 +00:00
Vadim Yanitskiy e7085d1699 contrib/osmo-bts.spec.in: do not depend on libosmogb
The header file <osmocom/gprs/protocol/gsm_04_60.h> was recently
deprecated and moved to <osmocom/gsm/protocol/gsm_44_060.h>, so
it's now part of libosmogsn and depending libosmogb is not needed.

Change-Id: I823de7ebac2fe5dfddb88d533f1a9419f4a605db
Related: libosmocore.git I70cc21bf25a7081070738abacb409ed19094c3b2
Related: OS#5312
2023-03-21 12:26:21 +00:00
Vadim Yanitskiy ef9b27526c osmo-bts-virtual: properly handle dynamic TS in vbts_set_ts()
This change fixes a problem that prevents osmo-bts-virtual from
starting when dynamic (ipa/osmo) timeslots are in use.

Change-Id: I5db5b7dd6a8e84cf9a0d84f04a650c2ed8a4e368
2023-03-20 23:08:33 +07:00
Vadim Yanitskiy 4bdc5a74cc scheduler: log pchan value in trx_sched_set_pchan()
Change-Id: Ia31e53552208a9d57e2fc5473440840d38945d00
2023-03-20 03:59:11 +07:00
Pau Espin 767f690f05 Avoid tx RF Resource Ind for disabled TRX
Related: SYS#6370
Change-Id: I887e0cb03b2a5654accccf7a55fac51319981bfb
2023-03-17 17:02:47 +01:00
Pau Espin 48b00783f8 cosmetic: bts_trx.h: Fix whitespace
Change-Id: Ibcc3578cce23767445e53149796d0bd79f81ead8
2023-03-17 15:47:49 +01:00
Pau Espin c88ed31d9e cosmetic: gsm_pchan2chan_nr(): Update spec documentation
Change-Id: If1de230f022c69f3dfce8a7c66d494a984e7f3f9
2023-03-17 15:29:17 +01:00
Pau Espin 149de0c113 lchan: Improve error path logging in gsm_pchan2chan_nr()
Change-Id: I8d9da8e8433feb1f022dc2f5199f9c15c01e9312
2023-03-17 15:14:19 +01:00
Pau Espin ca72961bbd Rewrite pcu_sock_write()
The code in that function is pretty rotten:
* osmo_fd_write_disable() is called for each message in the queue,
  there's no need for that. Let's simply call it at the end if the queue
  is empty.
* Asserting for obvious stuff like dequeue returning the first entry in
  the list.
* Having error code path for empty message: That shouldn't happen, abort
  immediately.

With all thse changes, the function is way simpler, easy to read and
more efficient.

Change-Id: I7ffff98cd8cdf2041bff486c3fde6f16365028d5
2023-03-15 17:45:35 +01:00
Vadim Yanitskiy 50de553a1f tests: use -no-install libtool flag to avoid ./lt-* scripts
This option should be used for any executables which are used only
for testing, or for generating other files and are consequently never
installed.  By specifying this option, we are telling Libtool that
the executable it links will only ever be executed from where it is
built in the build tree.  Libtool is usually able to considerably
speed up the link process for such executables.

Change-Id: I06d3d5ab1dd21400a72f76eecc508886617ef4c6
2023-03-14 20:09:44 +00:00
Vadim Yanitskiy c1909e7258 rsl: reduce logging verbosity on some messages
These two messages indicate that no ACK/NACK message is going to be
sent to the BSC because activation/deactivation was requested by the
PCU.  This is absolutely normal and requires no attention from the
user/operator, so better use LOGL_INFO.

Change-Id: I6eaf3a6c07fb30b31c045729c935c8ad6735e5c8
2023-03-14 21:14:54 +07:00
Vadim Yanitskiy 729037de0a rsl: remove redundant gsm_lchan_name() in rsl_tx_rf_rel_ack()
Change-Id: I69dc11c66a774ddb7364d6ecd9bdb2e94e6cad66
2023-03-14 21:10:27 +07:00
Pau Espin 33956215a7 pcu_sock.c: Call osmo_fd_unregister() before closing and changing bfd->fd
Change-Id: I692bbb5b7c06b5528a36c09a99a7580cbafa3cc0
2023-03-14 11:29:42 +01:00
Oliver Smith f162fa9009 rsl_rx_ipac_XXcx: parse csd_fmt_d/ir
Parse the RTP CSD Format and reply with NACK if the mode is not
RSL_IPAC_RTP_CSD_TRAU_BTS, which is the only one we plan to implement
for now.

Related: OS#4393
Change-Id: Ibfc7811387df5224682d7e6a313d38648d3d8c48
2023-03-14 09:59:15 +00:00
Oliver Smith 9b88fd8481 doc: rsl: add RSL_IE_IPAC_RTP_CSD_FORMAT
Add documentation for rsl_ipac_rtp_csd_format_d/_ir from
libosmocore.git, include/osmocom/gsm/protocol/gsm_08_58.h and
wireshark.git, epan/dissectors/packet-rsl.c.

Related: OS#4393
Change-Id: Ic8f40076698f2b341cc0096fd96ba2051a41f077
2023-03-14 09:59:15 +00:00
Vadim Yanitskiy 61933e6a7a osmo-bts-virtual: indicate BTS_FEAT_[E]GPRS to the BSC
Forwarding of PDCH related data over multicast works for me.
Without these features osmo-bsc would reject the OML connection
if it's configured with [E]GPRS enabled.

Change-Id: I5e13c153805c56904e51d222007228e1c2872c88
Related: OS#5500
2023-03-11 06:57:13 +07:00
Oliver Smith a023df5c7f gitignore: add vty pdf
Change-Id: I8653d5521680bb6ac2b32371b5428263082bc7f3
2023-03-10 10:18:41 +00:00
Pau Espin a21545e374 pcu_sock: Submit all DATA.ind regardless of link quality
osmo-pcu requires to get DATA.ind for all FN/TS it manages in order to
tick its internal FN clock and trigger timeouts. Without this, some
events are ticked in a delay fashion when osmo-pcu detects FN jumps.

Change-Id: I8f1856dd9061c1bfca8b15be30df7a51760231b0
2023-03-09 17:52:53 +00:00
Pau Espin 72f991f541 bts-trx: Fix no NM Radio{Carrier,Channel} switching to Enabled if one TRX is rf_locked
Differentiate in each TRX between being provisioned (configuration available) and being provisioned *plus enabled*.
TRX0 waits for all other TRX to be ready before sending POWERON, since
all TRX need to have been minimally configured over TRXC before POWERON
is called. This "ready" state though, doesn't necessarily mean the
TRX!=0 are enabled (aka NM Enabled and rf_locked=0). With them being
configured it es enough to start the whole PHY.

With the old logic, given any TRX was rf_locked=1 at startup, the PHY
would not become UP because it the TRX_PROV FSM was waiting for OPSTART
to arrive on all TRX, which wouldn't happen on TRX that had rf_locked=1.

So in summary, the desired requirements to start the PHY are (in any
order):
1- Wait all TRX are configured
2- Wait for TRX0 OPSTART

Related: SYS#6370
Change-Id: Ie4836f5721ce8227a63c267730aeb17228994214
2023-03-09 11:27:51 +01:00
Philipp Maier a981e28128 pcu_sock: do not mess with the osmo fd flags directly
When we disable the old socket connection, let's use
osmo_fd_read_disable().

Change-Id: I6b6854e9881c79b5c4794bde4ba4f6841dd06386
2023-03-07 14:09:53 +00:00
Vadim Yanitskiy c48b4651a1 GSMTAP: print 'gsmtap-local-host' if not NULL
Change-Id: If4f5a419b5af3f185219a879dcb2abb4eea45f1c
Fixes: f19f5331 "GSMTAP: allow configuring local address"
2023-03-07 20:32:36 +07:00
Vadim Yanitskiy fa109255ac osmo-bts-{trx,virtual}: set rc on error in bts_model_l1sap_down()
Change-Id: If3016bae9d03a9972c04b748fc9efab56a412e0e
Related: OS#1572
2023-03-07 09:43:21 +00:00
Vadim Yanitskiy 69bca44a84 osmo-bts-{trx,virtual}: check lchan against NULL in bts_model_l1sap_down()
Even though it's unlikely, get_lchan_by_chan_nr() *may* return NULL.

Change-Id: I1a815c9675eebc16640b62308499dd784fc206bd
Related: OS#1572
2023-03-07 09:43:21 +00:00
Vadim Yanitskiy 54840a203b osmo-bts-{trx,virtual}: clean up bts_model_l1sap_down()
Having a common body for PRIM_INFO_{ACTIVATE,DEACTIVATE,MODIFY},
but then branching using if-statements is a bit confusing.

Change-Id: I915c8a541249249e3c0b1f2eda4535e7c52db79f
Related: OS#1572
2023-03-07 09:43:21 +00:00
Philipp Maier 66bcdd839c pcu_sock: cosmetic: remove unnecessary line breaks
Change-Id: I8cb2979c62ebb05d06af49b40b145b7dee826cb1
2023-03-06 12:43:50 +01:00
Philipp Maier cc13ea8b66 pcu_sock: cosmetic: remove whitespace after type cast
Change-Id: I373b510efab4874f59f75385bd0e1229692299ec
2023-03-06 12:26:46 +01:00
Philipp Maier bdc438299b pcu_sock: rename rc to fd
The variable rc holds the return code of accept(), which returns a file
descriptor on success. So lets call the variable "fd" to make this
clear.

Change-Id: Ibc359d941786b1d1d52b356e239a76a090b52c1f
2023-03-06 12:23:08 +01:00
Max f19f533139 GSMTAP: allow configuring local address
Change-Id: If047cbaf95b343ee115690bf7a724a8edc5df735
2023-03-04 11:24:37 +00:00
Max af9466159e osmo-bts-trx: use bool for true/false flags
Change-Id: Iaa97dc36e92797db5f348e0bb79d2191ca0a58b5
2023-03-04 11:18:42 +00:00
Max 633c09ee50 osmo-bts-trx: log TRXC/TRXD connection address
Change-Id: Id53c1dd58b95c45f261fa9bfae16cc53b20edd18
2023-03-04 11:18:42 +00:00
Vadim Yanitskiy dfe96b786f paging_add_imm_ass(): remove meaningless from_pcu argument
A request to send an Immediate Assignment over the PCH (not AGCH)
is always coming from the PCU.  It's used for DL TBF assignment.

Change-Id: If4b0aa01532ab65b96201ff8829e724c67df6993
2023-03-01 03:01:46 +07:00
arehbein d28ce3287f doc: Adapt to use of 'telnet_init_default'
Related: OS#5809
Change-Id: I1ae5a7169d864e5dbd052437addd167ffa2c510d
2023-02-25 02:04:18 +01:00
Max 495cf39cb9 bts-virtual: fix segfault
Premature activation of virtual scheduler in bts_model_phy_link_open()
leads to segfault in vbts_sched_start(). Fix this by moving scheduler
activation to bts_model_oml_estab()

Change-Id: I116c2548dd4d05df90c16e81fa2e85ed6027a2e1
2023-02-19 18:56:56 +03:00
arehbein 2f6e105956 common: Fix memleak in get_smscb_block()
Fix condition `block_nr == 4`, which was never reached, by effectively
replacing
 - `4` by `msg->num_segs`, so we truly check if the current
   block is the last of this message
 - the index `block_nr` (which starts at zero) by `block_nr + 1`,
   so it is comparable to `msg->num_segs`

Related: OS#5354

Change-Id: I3dc116d6c16c80b31712b2a969f0b2a6998b03f0
2023-02-10 19:56:53 +00:00
Pau Espin c66b812c16 Bump version: 1.5.0.64-7571-dirty → 1.6.0
Change-Id: Iaa207d4996a00befd99194c65fc6e6cd9dbaa340
2023-02-07 17:15:53 +01:00
Max 757180beba Add SI10 support
Related: OS#5783
Change-Id: I268ba716ded330a024a8f3c0d1bd2f28622cecab
2023-02-01 11:12:32 +00:00
Philipp Maier f1b7ee6a63 pcu_sock: use ARRAY_SIZE rather then magic number
Lets use ARRAY_SIZE instead of magic number (8) to determine the
number of timeslots to iterate.

Change-Id: I0e016e6fff420851dfabebef5d8d43c735b968b2
2023-01-31 18:12:27 +01:00
Pau Espin 809879daae vty: Fix typo in symbol name
Change-Id: Ib33ffba348d6e9414eb904bfb7a2bd7ba2f55344
2023-01-30 14:19:52 +01:00
Oliver Smith 0701788724 contrib/jenkins: build libosmo-abis without dahdi
Looks like this is not needed, so make the jenkins build work without
installing dahdi-source.

Related: OS#5863
Change-Id: I61c483983a4793e0429bb37804dee0a128125daf
2023-01-18 14:29:54 +01:00
Pau Espin 0336b6e8e5 vty: Fix typo in write-config: osmux / local-port
The VTY command is "local-port", but write-config would write "port"
instead, which would fail when re-reading the config file.

Realted: SYS#6237
Change-Id: Id08530b626b0e69c3b3bb9d8bb9e16080a73e74d
2023-01-03 16:30:09 +01:00
arehbein a743ae1c1e osmo-bts: Transition to use of 'telnet_init_default'
Related: OS#5809
Change-Id: I2da7d7bf2b07b6736ab09a11ec37afc12f5ec075
2023-01-02 23:08:32 +00:00
Max 6a6a47f554 ctrl: take both address and port from vty config
Change-Id: Ieca05004255c40287e6427560c2636b39529cf07
2022-12-22 09:40:08 +00:00
Daniel Willmann 63baf960c6 shutdown_fsm: Add power_ramp_force() to jump straight to the tgt power
Both power_ramp_start() and power_ramp_force() are now small macros
around _power_ramp_start()

The new behavior is:
* ramp down power when stopping bts through Ctrl-C
* the other shutdown causes skip power ramping

This will cause the bts to reconnect faster when the oml link is
dropped and power ramping is enabled.

Change-Id: Ida1d7bbf094958b9142af306dbf84206729a609e
Related: SYS#6237
2022-12-21 23:51:51 +00:00
Oliver Smith 7377344771 oc2gbts_mgr_calib: fix build against gpsd >= 3.20
Fixes: OS#5832
Related: https://gitlab.com/gpsd/gpsd/-/blob/release-3.20/gps.h#L63
Change-Id: I6dc8ce303e5cb0fb412857a7f2c925e8cfe9b1e0
2022-12-21 10:43:48 +00:00
Alexander Couzens c8e2b021a9 OML: NSVC[1] MO should have the same initial state as NVSC[0]
There is no reason why they should have different initial
states. Keep it consistent with the other MOs.

Change-Id: I9fd744ec79da9fc26d3ebe9857b2b0bbd5fcd1ff
2022-12-19 22:01:45 +01:00
Daniel Willmann 300b72b44c Revert "shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C"
This reverts commit c96d34f828.

Reason for revert: This breaks ramping up power since the power ramp logic still assumes the output is full power.

Change-Id: I47a16a4b3ba02d74473569c0f4350a41fc12a464
2022-12-17 13:21:17 +00:00
Daniel Willmann c96d34f828 shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C
For the other shutdown causes power ramping doesn't make sense. Instead
shutdown quickly so we can reconnect faster

Change-Id: I71c46478b8f3b236dba3e959fc75e58c0409517f
Related: SYS#6237
2022-12-15 11:26:22 +01:00
Philipp Maier c2261bb62e pcuif_proto: use define constant to specify nax number of trx
The array of trx in gsm_pcu_if_info_ind can hold trx 8 items. Lets use a
define constant to specify the size of that array.

Change-Id: I5fdd5b9e59865fabd0340650ecb347d52208ebe9
2022-12-14 12:43:50 +01:00
Philipp Maier 82d92f703a l1sap: remove unused pointer variable
The pointer variable l1sap is only used to determine the size of the
related struct but for nothing else.  We can use the struct name in
sizeof also directly and get rid of it.

Change-Id: I93abdce1dec60d53ddceb1fce6e9e7451ba6283a
2022-12-08 17:02:13 +01:00
Philipp Maier ffe2b28c9b sched_lchan_tchf: replace numeric constant with define constant
An RFC 5993 HR GSM payload is 15 bytes long. That is GSM_HR_BYTES + 1

Change-Id: I7008ba7e50562e9366fd9ecc97e2e22fad4aa641
2022-12-08 17:02:05 +01:00
Pau Espin 5b9a5f569a osmux: Use new osmux_xfrm_input API to set name on each link
Change-Id: Iaea980a2e11282add12f9af585500d90f0462279
Depends: libosmo-netif.git Change-Id 8bb688e4827f345416c2a4526ced956a07fcc60b
2022-11-21 10:51:33 +01:00
Pau Espin 035080e4f4 osmux: Rotate over available Osmux CID when allocating a new one
Before this patch, the free CID with the smallest number was always
selected to be used. This caused more or less the same subset of CIDs to
be used all the time, while the CIDs with bigger numbers were mostly
unused.
Let's distribute the use so that all CIDs are used roughly the same.
This has the advantage, among others, that the same CID will not be
re-used immediatelly after being freed if a new call is established.
It is useful to leave the CIDs unused for some time since the other end
peer may know of the call being tear down with some delay.
Hence if a new call is established immediately after the CID was
released, the same CID would be allocated and passed at the peer, which
would then detect that the old call (in its view still active) would
already make use of that remote CID.

Related: SYS#6161
Change-Id: I72803fb172accbabfc81923572890f8ecb06cefd
2022-11-15 18:10:14 +01:00
Harald Welte a590b1a15a update outdated vty copyright statement
Change-Id: Ia12a012c229f883286e96a90132adcc5e8c0c5da
2022-11-11 18:22:45 +01:00
Max eba8816d51 Update realtime scheduling priority in service file
Related: OS#5687
Change-Id: I64a8c1e9c5b4ca7b51956d195964124d3a8ef768
2022-11-06 12:49:28 +00:00
Vadim Yanitskiy 8ec66a7f58 osmo-bts-trx: drop ul_amr_fn_is_cmi() / dl_amr_fn_is_cmi()
The scheduler is now using the lookup tables instead of these
functions.  The only part using them is the AMR unit test.

Change-Id: I1a9c80dd12252e7befe9c9bc8e8f7ee8648b5465
2022-11-01 01:09:20 +07:00
Vadim Yanitskiy c33ff98d39 osmo-bts-trx: use lookup tables for checking AMR CMI/CMR on Downlink
Change-Id: I75ecf5369f31c8b8e9519d2b580355fa80c24196
2022-11-01 01:04:25 +07:00
Philipp Maier aa8779b824 pcuif_proto: cosmetic: add constant PCU_IF_NUM_NSVC and replace magic numbers
The number of NSVCs is fixed but lets not use magic numbers to define
the sizes of the arrays that hold the config values. In osmo-pcu there
is already a define constant, so lets use a define here as well.

Change-Id: If7fa44abb86c18900110d7ee81fe6140c8c4635b
2022-10-31 10:22:17 +00:00
Pau Espin 764820e742 osmux: Fix null ptr dereference sending UL data before the remote is configured
Related: SYS#6161
Change-Id: I5d7971c0ed9b22d35d8965af54031a43c6388762
2022-10-29 01:06:27 +02:00
Keith Whyte 77fd0a589c osmo-bts-trx: respond to tx-attenuation config in real time.
Some osmo-bts varieties have a method to make an immediate change to
TX power from the vty. In osmo-bts-trx there does not seem to be any
way, so lets start the power ramp loop when the parameter
osmotrx tx-attenution is changed on a running TRX.

Change-Id: I1fa5e8130202fb509593db4132863b762b0f40b7
2022-10-13 14:34:15 +00:00
Philipp Maier ea35b26b35 rsl: use unsigned int
The parameter l3_len in rsl_tx_meas_res() is defined as int, even though
it can't be negative. Lets use unsigned int for l3_len.

Change-Id: I99068a36e74a557000f406154dce32300615086c
2022-10-12 18:20:14 +07:00
Philipp Maier 59e147e7ad l1sap: do not call msgb_l2hlen without checking
We request the length using msgb_l2len() in two locations where whe
cannot be sure that l2h is populated. Lets check this first.

Change-Id: Ie13d0724f183ff240714dcdbd24e5a21b4276bfe
Related: OS#5645
2022-10-12 18:19:25 +07:00
Philipp Maier 0087a1137e measurement: do not call msgb_l3len without checking
The function lchan_meas_handle_sacch() calls msgb_l3len without checking
if l3h is even populated. Lets add a check to be sure.

Change-Id: Ie5a9fe1ba880e68edb74f5f4ca559ac191330d4f
2022-10-11 11:45:14 +02:00
Vadim Yanitskiy 2950c0363d osmo-bts-trx: handle MTS 0b0110 indicating an Access Burst
The PCU may poll the MS requesting an ACKnowledgment message to be
sent in form of four Access Bursts instead of Normal Bursts.  The
BTS has no prior knowledge of the Uplink burst type, so a new MTS
value was specified in order to prevent the BTS from trying to
decode Access Bursts as a PDTCH block.

This patch implements parsing of the new MTS value 0b0110.
Signalling RACH.ind to the PCU is to be implemented.

Change-Id: I0fbb63006797e6be386d1f76ed97fff098c036fc
Related: OS#4006, SYS#4794
2022-10-04 16:33:10 +00:00
Vadim Yanitskiy 493ff0000b osmo-bts-trx: rx_rach_fn(): properly detect handover RACH
Checking if (bi->chan != TRXC_RACH) is not enough to detect HANDOVER
ACCESS.  Receiving this message is only possible on CS channels.

Change-Id: Ice1674fd4fed8c54d605ff19d568f6e46b4c5783
2022-10-04 14:57:57 +00:00
Pau Espin 8396471638 osmux: Close osmux socket when bts is freed
Related: SYS#5987
Change-Id: Ibd3faa33b28d45048c340b177f13d5685f41a784
2022-10-04 16:12:38 +02:00
Pau Espin 0db38d6521 osmux: Skip lchans in lookup which still have no remote associated
Lchans which are marked as non-connected have not yet received
information about its remote peer, hence they may not have some fields
available yet. Let's skip them to avoid accessing such fields
(lchan->abis_ip.osmux.in).

Related: SYS#5987
Change-Id: Id53822c4a0486b0090df2db3d185e047d14fc90a
2022-10-03 18:54:11 +02:00
Pau Espin 943ef9665e osmux: nullify osmux.rtpst after freeing it
Change-Id: I806cbe42cfc8fe59134ae842f3d7398acb1a1848
2022-10-03 18:43:52 +02:00
Pau Espin 65f63a55c7 osmux: Lower log level when osmux batch received for unknown CID
This is actually quite common, since our peer may be sending some osmux
packets to us a while after we have closed the conn on our side,
specially if latency is high in the network (eg satellite links).

Related: SYS#598

Change-Id: I102047685b9b9f4cba43970945f955c4fe9c4c95
2022-10-03 18:29:34 +02:00
Pau Espin b73c46ae97 osmux: Log remote address upon rx of osmux pkt
Related: SYS#5987
Change-Id: I391bc02a16eae1602680cb96128252f262852e14
2022-10-03 18:26:00 +02:00
Pau Espin 3fd60a5784 osmux: Match remote address in osmux_lchan_find()
Related: SYS#5987
Depends: libosmo-netif.git I95433b18802f73fa70e758f4aa02128eee940d88
Change-Id: I6813686b55fc3a74f1676a7965186e1e5fa00481
2022-10-03 18:24:36 +02:00
Pau Espin 53e566247d osmux: Drop logging of osmux internal counters
This way we have no more access to internal osmux structures.
If those counters are needed in the future they can be counted by
osmo-bts by means of adding rate counters to the caller of
osmux_xfrm_input() and deliver_cb.

Change-Id: Ib952437ea3aa2770c96bddb667491e7675a6a06e
2022-09-29 14:38:57 +02:00
Pau Espin fd356bdcd2 Allocate struct osmux_in_handle through new libosmo-netif APIs
Depends: libosmo-netif.git I752ab031f935f04731bb1a354333f1682a1aa5bd
Change-Id: I132a7c03213cb20dfe118616c8cfd7032b075507
2022-09-29 14:25:04 +02:00
Philipp Maier ae6ae89a19 pcu_sock: fix sourcecode formatting
Change-Id: Ib88173363fc11ad44a5bdbcd85ea8ca075db7997
2022-09-26 13:02:34 +02:00
Pau Espin 8cfb8bcc6c vty: Print Osmux CID on lchans using Osmux
Related: SYS#5987
Change-Id: Ide6edefda828e9ce04fbb60cf547857f322d5f40
2022-09-22 13:26:44 +02:00
Pau Espin ff5c8787dd vty: Fix SPEECH_MODE printed with hex prefix but dec value
Change-Id: I597ff582f47b00d895611eae8a810fe3ebfe8339
2022-09-22 13:25:49 +02:00
Pau Espin bbec5df6c7 lchan: Reset Abis RTP/Osmux config during lchan release
Otherwise some shared variables used by both Osmux and RTP was left set,
like connect_ip and connect_port, and next time the lchan was selected,
those were already configured even if they didn't come in IPAC CRCX.
This is specially bad if the channel was reused to set up an Osmux call,
since the osmux code path relied on those fields being properly reset
until set by IPAC CRCX.

Change-Id: I414bd0bc801451357bb45b89197a95e51b7c97f1
2022-09-20 17:33:07 +02:00
Pau Espin 9108eed3e4 osmux: Log sendto() error
Change-Id: I195ebe0fdb05195a7f3b1390630e83084b5dea3a
2022-09-20 16:55:42 +02:00
Pau Espin cd3d71b318 abis: Avoid TCP/IPA RSL sockets continue conn establishment while shutting down
when something fails in osmo-bts during startup and it goes into SHUTDOWN state,
it is desirable to close new RSL links (sockets) which are in progress to connect,
while it waits for a while to complete shutdown (power ramping down, etc.).
This way we don't end up with new interactions and new state against a BSC if we
are shutting down.

The new libosmo-abis API is used since the higher layer struct e1inp_sign_link assigned
to each struct gsm_bts_trx is not provided to the osmo-bts code layer by libosmo-abis API
until the TCP+IPA handshake in the socket becomes fully established (sign_link_up()
callback).

Depends: libosmo-abis.git Ia6418321f3b6f1f7274efd414625a4b10a09a362
Change-Id: I599d074f51f490b43c9a89b105d1823391926947
2022-09-16 20:56:00 +02:00
Max e826d78399 Document realtime options in .service units
It's not immediately obvious what numeric values mean for CPU scheduling policy.
Let's document this and add doc reference.

Related: OS#4107
Change-Id: Ib047762a336851e6205d77c83068a99d8a868e8b
2022-09-16 01:16:29 +00:00
Max 9b7a48421c Don't manually create pid file
Previously osmo-bts created /var/run/osmo-bts.pid which
isn't used by anything and makes it hard to run as non-root
user. Let's get rid of this pre-systemd relic.

Related: OS#4107
Change-Id: I86bcaedbc8cb1297476ad741eaa45585fea3c380
2022-09-14 08:30:11 +00:00
Pau Espin 2201900f94 Introduce Osmux support
Related: SYS#5987
Requires: libosmo-netif.git Change-Id I632654221826340423e1e97b0f8ed9a2baf6c6c3
Change-Id: Ib80be434c06d07b3611bd18ae25dff8b14a7aad9
2022-09-13 17:32:22 +02:00
Pau Espin 0908c7da22 oc2g: Makefile.am Fix typo in LIBOSMONETIF_LIBS
Change-Id: I6d316ffaff0ad7881b694f4d6427434bb9a0684c
2022-09-12 17:35:01 +02:00
Pau Espin d48d4beb56 tests/*/Makefile.am: Add missing libosmo-netif cflags
Change-Id: I7a2a846c2d68a4d6d77c4be62969238069d6cf95
2022-09-12 13:29:52 +02:00
Pau Espin 1176d1a626 tests/*/Makefile.am: Fix typo in LIBOSMONETIF_CFLAGS
Change-Id: I29d52bdacdebc0495d11425399e796fa7aef3ac4
2022-09-12 12:51:30 +02:00
Max 0ccd8781b1 Set working directory in systemd service file
By default systemd will execute service with root directory
(or home directory for user instance) which might result in
attempts to create files in unexpected place. Let's set it
to 'osmocom' subdir of state directory
(/var/lib for system instance) instead.

Related: OS#4821
Change-Id: I4b7bcd441e5da81c4c5267715675041171a1ce1e
2022-09-09 20:46:33 +07:00
Pau Espin e9bdd73fdc Clarify RTP AMR header offset in TCH enc/dec
This helps understand the origin/purpose of those 2 bytes and
what's contained in them.

Related: SYS#5987
Change-Id: I607fdf6d627242e010fba35be1b9b0ffde820d08
2022-09-07 10:22:01 +02:00
Pau Espin a2dc808acc Depend on libosmo-netif
This library will be used soon when adding Osmux support to osmo-bts.
Furthermore, it nice to have it available to make use of other general
interfaces to create connections, primitives, RTP and AMR related
functionalities, etc.

Related: SYS#5987
Change-Id: I49db4de715065c083e1249cbeae6298d6868e229
2022-09-06 09:14:40 +02:00
Pau Espin ebecff4a5a cosmetic: Fix formatting of if-else block brackets
Change-Id: Ifec6674ba04109f6b8a039679caff08f060d83d9
2022-09-01 17:05:20 +02:00
Vadim Yanitskiy 52da5b6f64 osmo-bts-trx: fix handling of ciphering params in PRIM_INFO_MODIFY
The PRIM_INFO_MODIFY is sent on receipt of the RSL MODE MODIFY message,
which may optionally contain new ciphering parameters.  Before this
patch, osmo-bts-trx would ignore the new parameters and continue using
the old ciphering key/algorithm.

* Modify l1if_set_ciphering() to allow updating ciphering params.
* Call l1if_set_ciphering() when handling PRIM_INFO_MODIFY.

This problem was uncovered by BTS_Tests.TC_rsl_modify_encr, which has
been failing ever since it was introduced [1].  This patch makes it pass.

Change-Id: I2278703b487374c0de4cfc42b22e70aaf6548589
Related: [1] I4cbea499bb6a331d314e6573548a4540945208b5 osmo-ttcn3-hacks.git
Related: OS#3750
2022-08-27 18:56:33 +07:00
Pau Espin 755546028e Move lchan_dl_tch_queue_enqueue to lchan.c and make it public
It will be used too by osmux code present in another file. This is a
preparation commit to simplify the one adding osmux support.

Change-Id: Ie7fa57bb04db9ad9b03971467e12ee7b8e4c190a
2022-08-11 23:04:46 +02:00
Pau Espin fff806bc92 rsl: Reduce scope of variable
The function is long/complex enough, so having one extra struct in_addr
declared the function top only used in one specific small path to print
the variable is unnecesary.
Let's move it to the conditional path where it is used to print the
ip address.

Change-Id: I4c16bbca6a6779537517b6b196828b47eddaa516
2022-08-11 23:04:46 +02:00
Pau Espin 7593cc743d Use libosmocore API msgb_queue_free() to free lists
There's no need to maintain a duplicate msgb_queue_flush(), which
returns the amount of freed messages (feature not used at all by the
callers).

Change-Id: I9841e18ca0b7b852130bbb02a510e43a3b3fd93f
2022-08-11 23:04:46 +02:00
Pau Espin 9ea93c7e20 Avoid counting lchan->dl_tch_queue length every time a msg is enqueued
The queue_limit_to method iterates the entire list of messages every
time a new message is added. Let's use msgb_{enqueue,dequeue}_count()
APIs to do that in constant time. It is true that since the queue is
limited to 1, there's usually at most 1 item in the queue so it's not a
real problem. However, when we add Osmux in the future, we may need to
tweak the amount of messages which can be in the list, due to Osmux
batching mechansim which may be more bursty sometimes.
In any case, this change doesn't make things worse for sure.

The patch also takes the chance to group the queue_limit_to + enqueue
into one function to avoid having the code spread several times.

Change-Id: I61818a3bb521c27bd21a8b6fa70581d27638ec9b
2022-08-11 23:04:35 +02:00
Pau Espin 5a1b14fa4f Split out lchan rtp socket creation from rsl handling code
This makes the code more clear, as well as allows adding Osmux in the
future.

Change-Id: Iade43fde7f6113f9d68539f7d6cc9843783c2b3f
2022-08-11 21:02:06 +02:00
Pau Espin d9f2cf2df6 Clean up osmo-bts-*/Makefile.am
Make them more easy to read and edit by splitting to one element per
line when several elements are present.

Change-Id: I24ecfa1167b806dcb3a5a0c00343299df842a78b
2022-08-11 21:02:00 +02:00
Pau Espin 311f9ffcf8 logging: Move category descriptions to be in order with enum
Change-Id: I3a1922fcd695e08ca42ece8cf0a1804d1a00f450
2022-08-10 18:12:44 +02:00
Pau Espin db8a676844 rsl: rx ipac crcx/mdcx: Log payload_type2
Change-Id: Id3afee50aa112051aacb9016183a78374e5ba7fc
2022-08-10 16:25:48 +02:00
Vadim Yanitskiy 541b7525ae osmo-bts-trx: amr_loop: trigger the loop unconditionally
The logic responsible for enabling and disabling the loop appears
to be broken: during my experiments trx_loop_amr_set() was never
called with loop=1.  It's not clear what's the motivation behind
this breaker, so I propose to rip it out for now.  This patch
finally makes the loop work (confirmed with a TEMS phone).

Change-Id: I09b649973d4269c4082a4fafa493c37825f95a9c
Related: SYS#5917, OS#4984
2022-08-08 05:43:20 +00:00
Vadim Yanitskiy a5a150c7ee osmo-bts-trx: call osmo_timer_del() unconditionally
osmo_timer_del() does check if a timer is active internally.

Change-Id: I16dca28120061ffc1f118d1e4a1ea986c1639bf7
2022-07-22 03:42:28 +07:00
Pau Espin 7243cada6a Bump version: 1.4.0.103-b8ae-dirty → 1.5.0
Change-Id: I920a834912cd6da66daae6a896f0789059698ba0
2022-06-29 09:41:38 +02:00
Pau Espin b8ae49d0ca bts-sysmo: Replace use of deprecated ipa_client_conn_create API
"""
osmo-bts/src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c:544:9: warning:
‘ipa_client_conn_create’ is deprecated: Use ipa_client_conn_create2()
instead [-Wdeprecated-declarations]
"""

Change-Id: Ief4d629f366e4f69ccd489198302568a919b2f0c
2022-06-21 09:38:42 +00:00
Harald Welte b90e1ef2d0 update git URLs (git -> https; gitea)
Change-Id: Ibd00975142ee6a2ca96453d7baf5b7164ccdd289
2022-06-18 11:39:25 +02:00
Vadim Yanitskiy 2baf54dd46 Revert "osmo-bts-trx: rx_tchf_fn(): do not treat AFS_SID_UPDATE as SUB frame"
This reverts commit 1f9fbd8816, which
was a workaround rather than a proper fix.  The root problem has
been fixed in libosmocoding [1], so ~50% BER is not the case for
AFS_SID_UPDATE frames anymore.

Related: I813081a4c0865958eee2496fe251ae17235ac842 (libosmocore.git)
Change-Id: Iebe139632daf1d1f72e39fe9d1497059f68625b9
2022-05-17 03:32:21 +03:00
Vadim Yanitskiy 1f9fbd8816 osmo-bts-trx: rx_tchf_fn(): do not treat AFS_SID_UPDATE as SUB frame
We have two similar values in enum gsm0503_amr_dtx_frames:

  * AFS_SID_UPDATE - precursor of SID UPDATE,
  * AFS_SID_UPDATE_CN - the actual SID UPDATE.

The former is internally used by libosmocoding to mark the current
frame as a precursor of the actual SID UPDATE frame - the later.

  +---+---+---+---+---+---+---+---+
  | _ | _ | _ | _ | a | b | c | d |  AFS_SID_UPDATE
  +---+---+---+---+---+---+---+---+
  | a | b | c | d | _ | _ | _ | _ |  AFS_SID_UPDATE_CN
  +---+---+---+---+---+---+---+---+
  ^
  |
  | We're here.

Do not treat the precursor frames as a SUB frames, as they contain
no information (rc=-1) and usually have *expected* BER ~50%.  This
fixes unexpected RXQUAL-SUB > 0 in the Uplink measurements during DTX.

Change-Id: I46f32bbbcb6284615d05b8703945c5ca4da55b92
Related: SYS#5853
2022-05-15 08:10:10 +00:00
Vadim Yanitskiy 284f16e7d7 measurement: fix matching of SUB frames by TDMA FN
3GPP TS 45.008, section 8.3 defines active TDMA frame subsets for
TCH channels, which shall always be transmitted even during the
silence periods in DTX mode of operation.  Each frame number
listed in this section corresponds to a single burst.

The Uplink measurements always contain TDMA FN of the *first* burst
of a block, so it does not make sense to match the given FN against
all FNs in the respective subset.  Instead, we should match only
specific FNs in accordance with the block mapping rules defined in
3GPP TS 45.002, section 7, table 1.

In the active subset for TCH/F there is only one *complete* block
starting at FN=52.  Incomplete blocks {52, 53, 54, 55} and {56, 57,
58, 59} contain only 50% of the useful bits (partial SID) and thus
~50% BER, so we don't treat them as SUB.

In the active subsets for TCH/H there are two *complete* blocks
for each sub-slot.  Their respective first FNs can be efficiently
defined in a lookup table (see ts45008_dtx_tchh_fn_map[]).  Note
that we can use a single lookup table for both sub-slots of TCH/H
because their TDMA FNs do not overlap.

This patch fixes unexpected SUB-RxQual values > 0 on TCH channels
with DTXu enabled and other than AMR (HR, FR, EFR) codec in use.

Change-Id: I8cc3a755a8ad4dc564439aab2298c1e97ac0592d
Related: SYS#5853
2022-05-10 16:49:16 +03:00
Vadim Yanitskiy 991f3f64d9 measurement: move SACCH detection to process_l1sap_meas_data()
SACCH detection can be simplified by checking the RSL Link ID in
process_l1sap_meas_data().  This eliminates the need to lookup
the multiframe position by calling trx_sched_is_sacch_fn(), which
definitely takes more CPU time than just L1SAP_IS_LINK_SACCH().

Calling trx_sched_is_sacch_fn() is still required for BTS models
reporting the measurements via PRIM_MPH_INFO (legacy way),
separately from the related Uplink blocks.

This patch can be summarized as follows:

* detect SACCH and set .is_sub=1 in process_l1sap_meas_data();
** for PRIM_MPH_INFO use trx_sched_is_sacch_fn();
** for PRIM_PH_DATA use L1SAP_IS_LINK_SACCH();
* do not call trx_sched_is_sacch_fn() from ts45008_83_is_sub();
* modify the unit test - test_ts45008_83_is_sub_single();
** remove test_ts45008_83_is_sub_is_sacch().

Change-Id: I507e96ee34ac0f8b7a2a6f16a8c7f92bc467df60
Related: SYS#5853
2022-05-10 16:30:39 +03:00
Vadim Yanitskiy 0ad31d8956 measurement: log SUB/FULL as text in lchan_new_ul_meas()
Change-Id: Idfaf8ad2ac0fd4da57a0981563e6ad6104fa4e41
Related: SYS#5853
2022-05-10 01:19:18 +03:00
Vadim Yanitskiy 7bf970ede4 tests/meas: improve test_ts45008_83_is_sub_is_sub()
This function should also take lchan type into account.

Change-Id: I6920a04e0a6c846647fa1b6b3a3c80bbd6617b99
Related: SYS#5853
2022-05-10 01:19:17 +03:00
Vadim Yanitskiy d399f49261 tests/meas: improve logging in test_ts45008_83_is_sub_single()
* Print unexpected TDMA FNs, each on a separate new line.
* Do not abort() on mismatch, keep running.

Change-Id: I32c104b139f32a39c8347de19de6ad7caec811de
Related: SYS#5853
2022-05-10 01:19:17 +03:00
Vadim Yanitskiy 523b6de593 struct bts_ul_meas: reflect C/I units in field name s/c_i/ci_cb/
Change-Id: If07f7f2a3ea996cbfc6a9087fa34402e38a7fd9f
Related: SYS#5853
2022-05-10 01:19:17 +03:00
Vadim Yanitskiy cf09b0cb50 scheduler: trx_sched_is_sacch_fn(): make ts pointer const
Change-Id: I48a1a549d7c1553bccaa01cdc818873a4c6cdf0a
2022-05-10 01:19:17 +03:00
Vadim Yanitskiy 8aab8d484b osmo-bts-trx: drop Uplink loss detection from Downlink path
Attempting to detect missing Uplink frames in the *Downlink* path
is an ugly hack, that was needed before we had proper per-lchan
detection of missing bursts and NOPE indications in TRXDv1.

* [1] per-lchan detection of missing bursts was fixed in Aug 2018.
* [2] TRXDv1 support was introduced in Jul 2019.

Today is 2022 and it makes no sense to keep this hack.  Even if
the transceiver does not support TRXDv1, per-lchan detection
will compensate the missing Uplink bursts.

Change-Id: Ic292d180ba64206fb4d88adb284f9f9d058b4587
Related: [1] I70d05b67a35ddcbdd1b6394dbd7198404a440e76
Related: [2] If61c71d20d590bf07bfd019afb33000a0b6135bd
2022-05-06 12:55:18 +00:00
Vadim Yanitskiy 4cbc2acde8 pcu_sock: comment out {dl,ul}_tbf_ext related warnings
The gitlog shows that these warnings were added in
744f745d7a by jolly (in 2012!).

As nobody has bothered for the past ten years, degrade them to comments.

Change-Id: Iebf9961cffbd7aa20b263f7dc0016a44782dec60
Related: osmo-bsc.git I9ef7e18f56aa86b48f0ffeec58406260736170f3
2022-04-29 13:32:04 +03:00
Vadim Yanitskiy e178269890 osmo-bts-trx: rx_{tchh,tchf}_fn(): improve logging of AMR DTX frames
Change-Id: I0ec06113fff2a89d7810cd4d8c26d6e0c74f93bd
Related: SYS#5853
2022-04-29 08:02:30 +00:00
Oliver Smith d99e20f97a src/common/bts.c: set BTS_FEAT_CCN
OsmoBSC assumed since If91d85331d402c3ab9c32b70c2c66cd7ba6ceb28 that
OsmoBTS has CCN (NACC, Network Assisted Cell Change). With OsmoBSC
Idf2d933aa8b03b1f708e56a08707fe6c620a97aa, instead of hardcoding some
features for OsmoBTS in OsmoBSC, only the features reported by the
BTS are used. Therefore report that BTS_FEATURE_CCN is supported in
OsmoBTS.

For previous OsmoBSC versions, this fixes the message:
  Get Attributes Response: reported feature 'CCN' is not supported, while we thought it is.

Related: SYS#5922, OS#5538
Change-Id: Ic407e3be82afe61ed64b1cecf3dc94d2caff380a
2022-04-26 15:15:05 +02:00
Oliver Smith 162ca199e0 src/common/bts.c: set BTS_FEAT_PAGING_COORDINATION
I did not realize with my previous patch that there's a common place
where features available for all backends should be enabled. So move it
there.

Related: SYS#5922, OS#5538
Change-Id: Id688ddae5cd714355fcc5324f33c9397fecae261
2022-04-25 11:27:54 +02:00
Oliver Smith 8630f898b2 model_init: order features alphabetically, part 2
Order the ones I've overlooked as well.

Related: SYS#5922, OS#5538
Change-Id: I0aa344de9ea4849de0fcd7b44bfaa70274af594b
2022-04-25 11:14:30 +02:00
Oliver Smith 0f075a1e2d model_init: set BTS_FEAT_PAGINATION_COORDINATION
According to osmo-bsc I0e80ca5afc06737273b6699bde6e325e454b57f6, the
PAGING_COORDINATION feature should be well supported in osmo-bts. Adjust
the bts_model_init functions to report this to the BSC, so it properly
sets this in SI13 and so we can avoid this notice in the log:
  Get Attributes Response: reported feature 'PAGING_COORDINATION' is not supported, while we thought it is.

Related: SYS#5922, OS#5538
Change-Id: Ib06829501f4221a7f7b0344ec7991ceba74e7641
2022-04-21 17:36:53 +02:00
Oliver Smith 7d2193b467 model_init: order features alphabetically
Make it easier to compare the lists of features.

Related: SYS#5922, OS#5538
Change-Id: I67887d89912d963fbbe90590c8467cbbd2566e09
2022-04-21 17:36:46 +02:00
Vadim Yanitskiy 11fb108221 osmo-bts-trx: check if scheduling of [dummy] FACCH/H is allowed
Currently (without this patch) if tch_dl_dequeue() yields nothing we're
scheduling dummy FACCH/H *regardless* if it's permitted to start at the
given TDMA FN or not.  This may result in misaligned FACCH transmission,
so the MS will not able to decode anything and will report BER>0.

With this patch applied we schedule FACCH/H if it's allowed to start
at the current TDMA FN;  otherwise send half-filled bursts with even
numbered bits contaning 232 encoded bits of the previous L2 frame
and 232 odd numbered bits all set to 0.

This patch does not guard against sporadic gaps in the Downlink TCH
queue.  However when tch_dl_dequeue() constantly yields nothing, e.g.
when we end up with a codec mismatch, then this additional check saves
us from starting misaligned FACCH/H transmission.  If we start at a wrong
TDMA offset, then all subsequent FACCH frames will be scheduled at wrong
offsets and thus none of them will be decoded by the MS.

Change-Id: I6f8af140a6ccf3d5fd7b98f6cb5c18e2c5e2f61b
Related: SYS#5919, OS#4823
2022-04-21 06:23:48 +00:00
Vadim Yanitskiy 0fb9517fed VTY: fix NULL-pointer dereference in 'show transceiver'
Change-Id: I403a027f064a4898eb74a11381bab3c884ec8ccf
2022-04-21 00:23:05 +03:00
Vadim Yanitskiy 1422a80cae osmo-bts-trx: fix scheduling of dummy FACCH/H and FACCH/F
* dl_ongoing_facch must be set for correct FACCH/H scheduling;
* dl_facch_bursts must be set for FACCH overpower to work.

Change-Id: Ief12eb67ad80de3b71f5226858dc2e0c8ae76948
Related: SYS#5919, OS#4823
2022-04-20 19:51:25 +00:00
Vadim Yanitskiy 5a9eaf7088 osmo-bts-trx: tx_tchh_fn(): make handling of FACCH/H cleaner
If set, chan_state->dl_ongoing_facch indicates that we're sending
the 2 (out of 6) middle bursts of FACCH/H.  In this case there is
no room for encoding an additional frame, because both even and
odd numbered bits are occupied by a previously encoded FACCH/H.

Right after calling tch_dl_dequeue():

* do not check the dequeued message against NULL,
* do not compare the message length to GSM_MACBLOCK_LEN,
* immediately free() it and jump to the sending part.

Change-Id: Ib923b8f5cc1063e9fc18acd2bdd003fd09f4b70f
Related: SYS#5919, OS#4823
2022-04-20 19:51:25 +00:00
Vadim Yanitskiy fbbc019f7d osmo-bts-trx: prioritize FACCH in s/tx_tch_common()/tch_dl_dequeue()/s
Unlike SACCH, FACCH has no dedicated slots on the multiframe layout.
It's multiplexed together with TCH (speech or data) frames basically
by replacing (stealing) them.  This is common for both TCH/F and
TCH/H, with the only difference that FACCH/H steals two TCH frames
(not just one) due to a longer interleaving period.

Let's implement the multiplexing in the common function, which is
used to dequeue to be transmitted frames - this slightly reduces
code duplication.  Use a new name, so that it's clear what it does.

Change-Id: I9822b1a17185d5487f0f6d3ed0203e806c053d7d
Related: SYS#5919, OS#4823
2022-04-20 19:51:25 +00:00
Pau Espin 0f3d7ea35b bts-trx: sched_lchan_tchh.c: Workaround gcc false positive error
Manual analysis of code didn't end up in finding any issue, so this
seems a false positive (I can really understand gcc failing to do proper
job here, this function has way to many jumps here and there.

"""
/sched_lchan_tchh.c:88:13: error: ‘rc’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   88 |         int rc, amr = 0;
      |             ^~
"""

Change-Id: Ifebaee63a9dad04976ffb4438c32360687ef095a
2022-04-20 16:09:31 +02:00
Vadim Yanitskiy 8b83a4a70f osmo-bts-trx: amr_loop: do not miss C/I samples
Keep collecting C/I samples even if the MS has not yet applied
previously requested codec mode.  The C/I ratio is expected to
stay more or less the same, no matter which codec mode is used.

Change-Id: Ieb5473ead7200f652b5d0e339e4e252d6567482d
Related: SYS#5917, OS#4984
2022-04-20 15:39:30 +03:00
Vadim Yanitskiy b1d5b8639c osmo-bts-trx: amr_loop: log if AMR mode remains unchanged
Change-Id: I0272d11cfaad0e1c13d2858b3bc61d6527898018
Related: SYS#5917, OS#4984
2022-04-20 15:18:32 +03:00
Vadim Yanitskiy 64192c26e6 osmo-bts-trx: amr_loop: allow upgrading codec mode > 0
With the current implementation the AMR loop is unable to upgrade
the current codec mode unless it reaches the worst possible value.
The problem is in the 'else' statement connection both 'if's.

Change-Id: I4c0fb28813373c3d4addd28c66f5136d2c4f9ed8
Related: SYS#5917, OS#4984
2022-04-20 15:18:32 +03:00
Vadim Yanitskiy 95f2201148 osmo-bts-trx: amr_loop: improve logging in trx_loop_amr_input()
Currently we're logging AMR mode *indexes*, not the actual modes.
Let's make it cleaner for the user by logging both mode and index.

Change-Id: I4feb3a3823799a290a50a48275e45f3331874d1a
Related: SYS#5917, OS#4984
2022-04-20 12:18:08 +00:00
Vadim Yanitskiy 44cb0113cf osmo-bts-trx: use C/I in the AMR link adaptation loop
Change-Id: Ide84bf864f56020c0265cfb9731615d4f7bad7f5
Related: SYS#5917, OS#4984
2022-04-20 12:18:08 +00:00
Vadim Yanitskiy cfabf6275e osmo-bts-trx: amr_loop: simplify trx_loop_amr_set()
Change-Id: Ibeed00ef48450edfe1e0d4e179fb4c777b11beb9
Related: SYS#5917, OS#4984
2022-04-20 12:18:08 +00:00
Vadim Yanitskiy 5c95312487 common: fix coding style: if is not a function
Change-Id: I890d7734c83d108d3c2cd2c7699ace880f13ca8b
2022-04-19 04:04:36 +03:00
Vadim Yanitskiy fe21e88630 struct amr_multirate_conf: remove ms_mode[], raname bts_mode[]
Looks like this structure was copied from openbsc/osmo-bsc as-is.
The ms_mode[] makes no sense in the context of BTS, so remove it
and rename bts_mode[] to mode[] for the sake of brevity.

Change-Id: I7442360ed857554440a0b9854f2d2bbab9dc5a71
Related: SYS#5917, OS#4984
2022-04-17 13:14:59 +00:00
Vadim Yanitskiy c350b9a9f6 tests: use 'check_PROGRAMS' instead of 'noinst_PROGRAMS'
When using 'check_PROGRAMS', autoconf/automake generates smarter
Makefiles, so that the test programs are not being compiled during
the normal 'make all', but only during 'make check'.

Change-Id: I18ebb7395024a490da743c0bcb20959e6e9c7017
2022-04-15 01:01:16 +03:00
Vadim Yanitskiy 56585bb351 amr: fix parsing of threshold and hysteresis in amr_parse_mr_conf()
Change-Id: I8febb60b0ad91903c7869871f41d1c123dbe5ce3
Related: SYS#5917, OS#4984
2022-04-13 18:04:20 +03:00
Vadim Yanitskiy 4765a5d195 tests/amr: add a unit test for amr_parse_mr_conf()
This unit test demonstrates a problem in amr_parse_mr_conf(): the
threshold and hysteresis values are parsed incorrectly.  They are
expected to match what we have in amr_fr_bts_mode_def[]:

  Mode[0] = 0/13/4
  Mode[1] = 2/25/4
  Mode[2] = 5/37/4

This will be fixed in a follow-up patch.

Change-Id: Iab7e8878e62f598959e80fcb7e729b7f496962a2
Related: SYS#5917, OS#4984
2022-04-13 18:04:20 +03:00
Vadim Yanitskiy f576e673a3 tests/amr/Makefile.am: use proper binary name prefix 'amr_test_'
Both misc_test_{SOURCES,LDADD} were simply ignored because
binary 'misc_test' is not listed in noinst_PROGRAMS...

Change-Id: Ia1739bab76261ff6d50824462b8ed2e0b34fb464
Related: SYS#5917, OS#4984
2022-04-13 18:04:20 +03:00
Vadim Yanitskiy cf3d314501 rsl: use hard-coded defaults if the MultiRate conf IE is absent
This configuration will be used as a fall-back when the MultiRate
configuration IE is not included in the CHAN ACT/MODIFY messages.

Change-Id: Ie96af636105ee1ffe2d9a0bd9eea375faebad149
Related: osmo-bsc.git Ic5f8d55d250976d8d4c9cae2d89480fd52326717
Related: SYS#5917, OS#4984
2022-04-13 18:04:20 +03:00
Vadim Yanitskiy c02876eae2 osmo-bts-trx: bts_report_interf_meas(): remove unused fn param
Change-Id: Iec25b28e418ce1f66bbc7e0696a3ceebb02e9c82
2022-04-13 15:03:20 +00:00
Vadim Yanitskiy bab872cc0d l1sap: l1sap_chan_act(): remove unused *tp argument
Change-Id: I2030f05b55fc9370e71ff12b26ffe1142f4acfc8
2022-04-13 15:03:20 +00:00
Vadim Yanitskiy 7af62e2d0f l1sap: l1sap_chan_act(): alloc DTX FSM only for TCH
Change-Id: Ieb5728b7a9e7d7c58449deaa5a6c4d8755b6e213
2022-04-13 15:03:20 +00:00
Vadim Yanitskiy 9ae443d368 osmo-bts-virtual: remove unused 'codec_mode_request' argument
Change-Id: If5001d7b19820478d0e88fea3126e5dd4fbd2634
2022-04-13 15:03:20 +00:00
Vadim Yanitskiy 468c9e0a90 rsl: misc / cosmetic fixes for tx_ipac_XXcx_nack()
Change-Id: Ia7367cdfc6e1b1ebaabdf21e0a050fc1543968b2
2022-04-13 15:01:21 +00:00
Vadim Yanitskiy 128039a163 rsl: always check return value of rsl_tlv_parse()
Change-Id: I07cbd2849d83af28eb0458547f0eacc81347df23
2022-04-13 15:01:21 +00:00
Vadim Yanitskiy 851047b759 logging: use a different color tone for DLOOP
Normal blue (34) is really hard to read on terminals with dark
background.  Let's use light blue (94) instead.

Change-Id: Iadc9b8fb74ec17455435893a532c2f12e02cb804
2022-04-13 17:23:55 +03:00
Vadim Yanitskiy ab4ab48178 rsl: parse_multirate_config(): check if AMR codec is used
3GPP TS 48.058 defines the MultiRate configuration IE as optional,
and states that it's "included if the Channel Mode indicates that a
multi-rate codec is used".  If I understand this correctly, it may
be omitted even if a multi-rate codec is requested.  Otherwise it
would have been defined as a conditional IE.

For now let's print a warnig if this IE was expected, but missing.
We may need to apply some hard-coded defaults in this case.

If this IE is present, but the Channel Mode indicates a codec other
than AMR, let's send NACK with cause=RSL_ERR_OPT_IE_ERROR, assuming
that the CHAN ACT/MODIFY message is malformed.

Change-Id: I6ddc0b46a268ed56ac727cda57d0d68b2746fd59
Related: SYS#5917, OS#4984
2022-04-12 02:28:35 +03:00
Vadim Yanitskiy e3ff3bc4e0 rsl: rsl_rx_chan_{activ,modif}: do not sent an Error Report
Sending an Error Report along with a NACK makes no sense.

Change-Id: Idae55645c34970f839bb0eef61a7326a1026b20c
Related: SYS#5917, OS#4984
2022-04-12 01:12:28 +03:00
Vadim Yanitskiy 9b0c60ea63 rsl: de-duplicate parsing of MultiRate configuration IE
Change-Id: I98e10c3e947b9a4605e9db5bf7f499dc24bccad7
Related: SYS#5917, OS#4984
2022-04-12 00:49:18 +03:00
Vadim Yanitskiy 7bb3024764 osmo-bts-trx: amr_loop: remove unneeded #includes
Change-Id: I6d181f19711dc14695abd0f8e2586329e91aa68d
Related: SYS#5917, OS#4984
2022-04-11 23:42:29 +03:00
Vadim Yanitskiy 9ab2472851 osmo-bts-trx: use '#pragma once' in amr_loop.h
Change-Id: I98e42485955de4a261b6c8d865e84c313c1145d5
Related: SYS#5917, OS#4984
2022-04-11 23:39:58 +03:00
Vadim Yanitskiy 5cbd18cfce osmo-bts-trx: rename 'loops.[ch]' to 'amr_loop.[ch]'
There is nothing else except the AMR link adaptation loop in these files.

Change-Id: Iff2c0d32da5cd89824197d05f4732ce974c12f28
Related: SYS#5917, OS#4984
2022-04-11 20:06:51 +03:00
Vadim Yanitskiy 3ed84cc26b osmo-bts-{trx,virtual}: tx_tchh_fn(): remove FACCH/H alignment check
This check is redundant because it's guaranteed in rts_tchh_fn()
that FACCH/H is always scheduled at the correct frame offset.

Change-Id: I2f0c26f6007455aa1e3e8b27bc9d173f6b1f8c38
Related: SYS#5916, OS#5518
2022-04-10 19:07:16 +03:00
Vadim Yanitskiy 3ac0cf8c39 osmo-bts-trx: rx_tchh_fn(): use a lookup table for FACCH/H
Since change [1], in rts_tchh_fn() we're using a lookup table for
DL FACCH/H.  Let's do the same for UL FACCH/H in rx_tchh_fn().

Change-Id: I7c4e3befdd33bef4d89a04a4c7cb1a2d4078c156
Related: [1] I3dba243e5a1b7c8008ef0178ea18ed885256c50d
Related: SYS#5916, OS#5518
2022-04-10 19:04:29 +03:00
Vadim Yanitskiy 93e3a220b1 scheduler: rts_tchh_fn(): use a lookup table for FACCH/H
Unlike TCH/F, TCH/H imposes some additional requirements on the FACCH
transmission, so that a signalling block can be transmitted only at
specific TDMA frame numbers defined in 3GPP TS 45.002, table 1.

This is why in rts_tchh_fn() we need to check the given TDMA frame
number and tell rts_tch_common() whether FACCH/H is permitted or
not.  The check is based on a magic formula, which I find a bit
hard to read and understand.  Let's better use a lookup table.

Change-Id: I3dba243e5a1b7c8008ef0178ea18ed885256c50d
Related: SYS#5916, OS#5518
2022-04-10 18:25:53 +03:00
Vadim Yanitskiy 14b00bb8b2 scheduler: remove redundant OSMO_ASSERT() statements
It's guaranteed by the calling function bts_model_l1sap_down() that
the prim's operation is PRIM_OP_REQUEST and that the msg is present.

Change-Id: I6a01bba7b5eb337ae1552c442d74447565c52e25
2022-04-09 19:48:55 +03:00
Vadim Yanitskiy 94f7b4753a power_ctrl_params_def_reset(): set .ctrl_interval for both UL/DL
For the sake of consistency and code readability, initialize the
power loop control interval (P_Con_INTERVAL) for both Uplink and
Downlink directions in the same function.

Change-Id: If7c804e51eb104d9fe73294a3867ab3b551d83c3
2022-04-08 20:39:35 +00:00
Vadim Yanitskiy dd7bed3415 osmo-bts-trx: rx_tchf_fn(): clarify indexes in the AMR CMI lookup table
Change-Id: If81ff0bd449fe20da43cc3d96dadf38568507054
Related: SYS#5916
2022-04-08 19:05:45 +03:00
Vadim Yanitskiy 94806cee7b osmo-bts-trx: rx_tchh_fn(): fix indexes in the AMR CMI lookup table
In change [1] I didn't take into account that the TCH/H burst buffer
is 6 bursts wide, and that we're decoding 2 bursts late:

  +---+---+---+---+---+---+
  | a | b | c | d | e | f |  Burst 'a' received first, 'f' last
  +---+---+---+---+---+---+
   ^^^^^^^^^^^^^^^           Speech frame (bursts 'a' .. 'd')
   ^^^^^^^^^^^^^^^^^^^^^^^   FACCH frame  (bursts 'a' .. 'f')

The lookup table for TCH/H was calculated with the assumption that
in rx_tchh_fn() the 'bi->fn' indicates TDMA frame number for burst
'd', but in reality it holds the frame number of burst 'f'.

Change-Id: I4f22cf49fd52ed26f8017f76461059a701c181e1
Fixes: [1] I46def864729c8f9063af201750456771ea5558d5
Related: SYS#5916
2022-04-08 19:01:40 +03:00
Vadim Yanitskiy c4368ce3ab osmo-bts-trx: move AMR CMI lookup tables to the respective files
It makes no sense to have these tables in the header file, because
they're not used anywhere outside of the respective lchan handlers.

Change-Id: Ibdebfb9b1ef78c960b08240ebdb4c7af92cbed11
Related: SYS#5916
2022-04-08 18:37:08 +03:00
Vadim Yanitskiy f5b756e484 osmo-bts-trx: rx_tchh_fn(): fix meas reporting in signalling mode
In change [1] I broke measurement reporting for TCH/H in signalling
mode.  The problem is that in rx_tchh_fn() we started to invalidate
the Uplink RSSI for FACCH regardless of the channel mode: speech or
signalling.  In speech mode, the averaged measurements are carried
over by the two BFIs.  In signalling mode we send no BFIs, so:

* let's use the proper averaging mode S6N6 (not S6N4), and
* send the averaged measurements together with the FACCH.

This change fixes BTS_Tests.TC_meas_res_sign_tchh[_toa256].

Change-Id: If98aa1f0f7255f20344460bdd07e2c896dd6e56f
Fixes: [1] I7902b4709bc3f418174e8373f52e87bb31cdc826
Related: SYS#5853
2022-04-07 20:36:36 +03:00
Vadim Yanitskiy 5ce5c7db9b osmo-bts-trx: rx_{tchh,tchf}_fn(): use tch_mode directly
There is no reason not to use 'chan_state->tch_mode' directly in
the 'switch' statement.  If a logical channel is in signalling
mode, then both 'chan_state->{rsl,tch}_cmode' are set to
RSL_CMOD_SPD_SIGN and GSM48_CMODE_SIGN, respectively.

Change-Id: I9e5e2c891c80c32fc522b53c9371b71ea32dd54d
Related: SYS#5853
2022-04-07 20:27:46 +03:00
Vadim Yanitskiy 5a8413166f osmo-bts-trx: rx_{tchh,tchf}_fn(): use AMR CMI lookup tables
3GPP TS 45.009 defines that Codec Mode Indications shall be sent
with speech frames having specific TDMA frame numbers of their
*first* bursts, which are defined in tables 3.2.1.3-{1,2,3,4}.

Performance-wise it's batter to have these tables implemented as
arrays, rather then using the 'switch' statement.  We can simplify
things even further and have TDMA frame numbers corresponding to
the *last* bursts in them.  This eliminates the need of doing an
additional last-to-first mapping, so that bi->fn can be used.

Change-Id: I46def864729c8f9063af201750456771ea5558d5
2022-04-05 13:45:31 +00:00
Vadim Yanitskiy 12b3921a4a osmo-bts-trx: rx_{tchf,tchh}_fn(): get TDMA FN from meas history
Once we have an Uplink speech or FACCH frame decoded, we need to
hand it over to the upper layers indicating TDMA frame number of
the *first* burst corresponding to the beginning of a block.

Currently we use libosmogsm's gsm0502_fn_remap() API to calculate
the first TDMA frame number from the given last frame number.
This API involves iterating over the pre-calculated offset tables
for different channel and payload types, and thus imposes some
additional CPU cycles.  Another downside of the current approach
is that we have to perform such lookups several times for each
decoded L2 frame, e.g. for FACCH on TCH/AHS we do it three times!

In this patch I propose an alternative approach of storing TDMA
frame numbers in the measurement history, together with the
associated samples.  This way we can easily get N-th frame number
from there without performing any additional computations, other
than what we already do during the measurement processing.

Change-Id: Id9a2b7b0f1a1ad7cfbbab862faf521e135c90605
2022-04-05 13:45:31 +00:00
Vadim Yanitskiy 333e35439d osmo-bts-trx: rx_{tchf,tchh}_fn(): ensure complete set of bursts
The idea of this change is to avoid attempting to decode the burst
buffer unless it's filled up completely.  This eliminates expected
decoding errors in the beginning of lchan's lifetime.  Moreover
this allows us to be sure that the measurement history is complete,
so that we can abuse it to store TDMA frame numbers later.

Note that even in the absence of NOPE indications (TRXDv0 case)
we can still be sure that the burst mask has no gaps due to lost
bursts, because they are compensated by trx_sched_calc_frame_loss().

Change-Id: I56bebe1374eb803e3c1e9f08dda4da50a074ab0b
2022-04-05 13:45:31 +00:00
Vadim Yanitskiy 6d04bd95ee osmo-bts-trx: rx_{tchf,tchh}_fn(): shift Rx burst buffer on bid=0
For both TCH/F and TCH/H, the receive burst buffer needs to be
periodically shifted leftwards due to the nature of block-diagonal
interleaving.  Currently we do this on receipt of bid=3 for TCH/F
and bid=1 for TCH/H, right after attempting to decode the buffer.

If for some reason we return early before attempting to decode the
buffer, the content of that buffer might not be shifted and some
bursts might be overwritten.  This can be easily avoided by doing
the shifting on receipt of bid=0 for both TCH/H and TCH/F.

Change-Id: I0bd69f5a8f5c665fb5f00c127bc3fe1d91167abb
2022-04-05 13:45:31 +00:00
Vadim Yanitskiy b8b6066450 osmo-bts-trx: rx_{tchf,tchh}_fn(): also use meas_avg for BFI
In the current implementation of both TCH/F and TCH/H lchans, we
set the 'bfi_flag' to true only if decoding fails.  Perhaps this
was not the case when I wrote [1], so using meas_avg might result
in using uninitialized memory.  This is not the case anymore.

Pass the *averaged* measurememnts regardless of decoding result.

Change-Id: I23f767364a018d30d04885990adf69b50b2c9738
Related: [1] I2b02b51fea5664f161382a4ddc63dbf14ffc9ac5
2022-04-05 13:45:31 +00:00
Vadim Yanitskiy da433bba7b osmo-bts-trx: rx_tchh_fn(): get rid of chan_state->meas_avg_facch
FACCH/H takes out two speech frames, so we send two BFIs once we
have received it in rx_tchh_fn().  The upper layers responsible
for handling of the Uplink measurements expect a fixed amount of
measurement samples, so currently we do:

* send a FACCH frame with the associated measurememnts (S6N6),
* send the 1st BFI with invalidated measurements (RSSI=0),
* send the 2nd BFI with the stored measurememnts of FACCH.

This is achieved by preserving a copy of the FACCH measurememnts
in chan_state->meas_avg_facch and then using it two bursts later.

The same goal can be achieved a lot easier by sending the associated
measurements with both BFIs as if no FACCH was received:

* send a FACCH frame with invalidated measurememnts (RSSI=0),
* send the 1st BFI with the associated measurememnts (S6N4),
* send the 2nd BFI with the associated measurememnts (S6N4).

This eliminates the need to store anything outside of the existing
measurement history and simplifies the code a lot.  Also, this
eliminates the need for using a dedicated averaging mode S6N6.

Varified by running BTS_Tests.TC_meas_res_speech_tchh_facch.

Change-Id: I7902b4709bc3f418174e8373f52e87bb31cdc826
Related: I1ad9fa3815feb2b4da608ab7df716a87ba1f2f91
2022-04-05 13:45:31 +00:00
Vadim Yanitskiy bd7ef4101b osmo-bts-trx: rx_tchh_fn(): indicate BER10k=0 for FACCH BFIs
It makes no sense to store BER10k value of an Uplink FACCH frame
in order to indicate it in a BFI later on.  Given that these BFIs
are generated artificially, it's fine to indicate BER10k=0.

Change-Id: I24d12892760dca0ad0a5c2abca9fc66523d9e614
Related: I1ad9fa3815feb2b4da608ab7df716a87ba1f2f91
2022-04-05 13:45:31 +00:00
Pau Espin 7a2f307246 doc: rsl: Fix description of 'IP Connection Statistics' IE
Related: SYS#5915
Change-Id: Ic524d73a0c47fde528b78f9dfe7b72b7286550e1
2022-04-04 19:27:59 +02:00
Vadim Yanitskiy 5bb7031366 fix gsm_bts_get_cbch(): CBCH can be allocated on Cn
According to 3GPP TS 45.002, table 3, unlike the CCCH+SDCCH/4+CBCH
combination, which can only be allocated on C0/TS0, the SDCCH/8+CBCH
can be allocated on C0..n/TS0..3.  In other words, having CBCH on
e.g. C1/TS2 is perfectly legal.  This is why in gsm_bts_get_cbch()
we should check all transceivers, not just the C0.

Without this change osmo-bts does not send CBCH Load Indications
at all if the CBCH is allocated on C1..n.

Change-Id: Ib5976783b53521047fbdfc18e0e236e8bce8eaae
Related: osmo-bsc.git Ie79ccff4f8f0f1134757ec0c35e18b58081cc158
Related: SYS#5905
2022-03-31 19:57:10 +03:00
Vadim Yanitskiy b147878f9e trx_sched_ul_burst(): get rid of the 'switch' statement
Both TRXC_RACH and TRXC_PTCCH are handled in the rx_rach_fn(),
so we can eliminate the need of having a 'switch' statement in
the general (perfrmance critical) code path.

Change-Id: I66d8785a63215af37a77e258039549e4e6292e49
2022-03-22 18:28:15 +00:00
Vadim Yanitskiy 35e601a322 osmo-bts-trx: rx_tchh_fn(): use proper meas averaging mode
Compared to TCH/F, TCH/H is a bit special in a way that:

* speech frames are interleaved over 4 consecutive bursts,
* while FACCH frames are interleaved over 6 consecutive bursts.

This is why in rx_tchh_fn() we allocate a buffer large enough to
store up to 6 bursts.  Let's say we have that buffer filled up
completely with all 6 bursts (from 'a' to 'f').  Now attempting
to decode them may yield either a speech frame or a FACCH frame:

  +---+---+---+---+---+---+
  | a | b | c | d | e | f |  Burst 'a' received first, 'f' last
  +---+---+---+---+---+---+
   ^^^^^^^^^^^^^^^           Speech frame (bursts 'a' .. 'd')
   ^^^^^^^^^^^^^^^^^^^^^^^   FACCH frame  (bursts 'a' .. 'f')

For FACCH we use measurement averaging mode SCHED_MEAS_AVG_M_S6N6,
so that 6 last samples are averaged - so far so good.  For speech
we use SCHED_MEAS_AVG_M_S4N4, so that 4 last samples corresponding
to bursts 'c', 'd', 'e', 'f' are averaged - this is wrong.

We actually need to average the *first* 4 samples corresponding to
bursts 'a', 'b', 'c', 'd' in the case of speech.  Let's add and use
a new averaging mode SCHED_MEAS_AVG_M_S6N4 for that.

Change-Id: Iea6f4e5471550f4c2b57aaebeac83c80e879489d
2022-03-18 03:53:08 +03:00
Vadim Yanitskiy 523598e655 osmo-bts-trx: use a lookup table in trx_sched_meas_avg()
This should be better performance-wise and would also allow to avoid
having the same switch statement duplicated in functions added later.

Change-Id: If8124dcd38e7c8408a9f3b9a574d9e3181a2eb15
2022-03-18 03:53:06 +03:00
Vadim Yanitskiy 2de4d9baa8 osmo-bts-trx: use consistent naming for 'enum sched_meas_avg_mode'
This is a purely cosmetic change.  The new naming clearly indicates
how deep to go back in the measurement history (S) and how many
samples to average (N).  For example:

* SCHED_MEAS_AVG_M_S4N4 - go S=4 steps back and average N=4 samples;
* SCHED_MEAS_AVG_M_S6N2 - go S=6 steps back and average N=2 samples.

Change-Id: I96a8dd08084c7c179f879fc00e75c5edcfb11caa
2022-03-18 03:53:02 +03:00
Vadim Yanitskiy 4e9affee0b osmo-bts-trx: rx_tchh_fn(): mark valid SID frames as such
Set the FT (Frame Type) in the ToC (Type-of-Content) section as
defined in section 5.2 of RFC 5993.  Before this change SID frames
had FT = 000 (Good Speech frame), because gsm0503_tch_hr_decode()
does not distinguish between speech and SID frames internally.

Change-Id: I09cec984bb60c754908126acf0300a2cc602485c
Related: SYS#5853
2022-03-16 13:04:55 +03:00
Vadim Yanitskiy eb8059b615 osmo-bts-trx: rx_tchh_fn(): fix HR SID detection (wrong offset)
According to RFC5993, which is referenced by 3GPP TS 48.103, the
complete RTP HR payload consists of a Table-of-Contents (ToC) byte
followed by the 14 bytes of the HR codec frame.  See section 5.2.

gsm0503_tch_hr_decode() outputs frames in the RTP format with
length of 15 bytes (120 bits): 1 (ToC) + 14 (HR frame):

  +-------------+-------------------------
  | ToC section | HR codec frame ...
  +-------------+-------------------------

osmo_hr_check_sid() expects a HR codec frame of 14 bytes (112 bits)
as the input, so we should skip the ToC section when calling it.

Change-Id: Ie5fa776dcb2b2203a97aed56ecbf2450af7d87c1
Related: SYS#5853
2022-03-16 12:43:11 +03:00
Vadim Yanitskiy d32cf22fbc rsl: fix wrong IE being checked in rsl_rx_chan_activ()
According to 3GPP TS 48.058, section 4.1.4, BTS shall start transmission
on SACCH if both MS Power and *Timing Advance* IEs are present.  There
can be no Access Delay IE in the RSL CHANnel ACTIVation message.

Change-Id: Icd8ccfd6e37ded8966125a473b5003845ba87fec
Fixes: I170b63c9856230d5f1a10654a9d950ada8e730d7
Related: SYS#5838
2022-03-14 12:21:44 +00:00
Vadim Yanitskiy 79aaec8f01 osmo-bts-trx: rx_tchh_fn(): do not calculate BER10k for FACCH twice
We already have BER10k calculated in the generic code path, so do
not calculate it once again in the FACCH specific branch.

Change-Id: I5d3955d09990e280d11d687385eeaf5edf437395
2022-03-14 11:31:32 +00:00
Vadim Yanitskiy dc17d1036b osmo-bts-trx: do not run osmo_{fr,hr}_check_sid() on FACCH/U frames
It makes no sense to perform the SID codeword lookup in signalling
frames (FACCH), because it can be present only in speech frames.

Change-Id: I2f8137993acfe8a8add3fc2af276e5eb4da1605e
Related: SYS#5853
2022-03-10 17:23:27 +03:00
Vadim Yanitskiy 8ec3f28fad VTY: fix ambiguity in BTS specific command definitions
Most of the BTS specific VTY commands restrict BTS number to '<0-0>',
while bts_c0_power_red_cmd has '<0-255>'.  This confuses libosmovty:

  OsmoBTS# bts ?
    <0-0>    BTS number
    <0-255>  BTS Number

  OsmoBTS# bts 0 ?
  % Ambiguous command.

  OsmoBTS# bts 0 c0-power-red 0
  % Ambiguous command.

Let's stick to '<0-0>', we don't support multiple BTS anyway.

Change-Id: I937ac421143678b97627c1bc4fe573831ce097f6
2022-03-09 07:23:50 +00:00
Vadim Yanitskiy d84567779c osmo-bts-trx: new rate counter 'trx_sched:dl_fh_cache_miss'
This new rate counter allows to monitor the efficiency of the
radio carrier cache used for routing Downlink bursts when
baseband frequency hopping is in use.

Change-Id: Ie6da829e47298476267c8df2dcedafad564cbbb4
Related: SYS#5855
2022-03-09 07:22:27 +00:00
Vadim Yanitskiy ff30ca63a9 osmo-bts-trx: cosmetic: use rate_ctr_inc2() instead of rate_ctr_inc()
Change-Id: Id4c5999876ff284b80a021e075bf46eb9d4670a2
Related: SYS#5855
2022-03-09 07:22:27 +00:00
Vadim Yanitskiy 577de3a5a2 osmo-bts-trx: make use of OSMO_UNLIKELY() when handling TRXD PDUs
Given how often we send and receive TRXD PDUs, I believe it maks
sense to use OSMO_UNLIKELY() in the error checking conditions.
Theoretically this should improve performance.

Change-Id: I9266aaf2bbc0acfe21e9bfb12c9f38621d120553
2022-03-06 16:51:14 +03:00
Pau Espin ad8426e40c bts-trx: Log lchan if avaialble in Meas Avg
Change-Id: I1460715fa46c4195c5aaac91be776ad770d8099e
2022-03-03 19:03:07 +01:00
Pau Espin a3dca762dd rsl: Conditionally decrease log level if cause is normal event
This avoid a NOTICE log line like the following when gsm_lchan_release()
is called.
"""
rsl.c:2484 (bts=0,trx=0,ts=2,ss=0) Sending RTP delete indication: cause = Normal event, unspecified
"""
Change-Id: I0ce78c52644983220f5810bc5c661b07afd9e543
2022-03-02 19:07:01 +01:00
Pau Espin a6a0c6ad1e Change some log levels NOTICE->INFO
Change-Id: I65cccf2b48288353c2db2044ad1f3651ca9f68ec
2022-03-02 19:02:16 +01:00
Pau Espin bd02811e7e bts-trx: amr: Fix return code of osmo_amr_rtp_dec() checked too late
If len is < 0, it means osmo_amr_rtp_dec() failed and some of the out
variables there are not set. We should check the return code before
continuing and using potentially uninitialized values.

Change-Id: I76020c6b5dc8d3e52e8c5be8cdecdf8a0bb52ed9
2022-03-02 13:54:48 +01:00
Vadim Yanitskiy df505a503f logging: get rid of logging category DSUM
DSUM is somewhat similar to DMAIN, generic logging category used
in other Osmocom projects.  This category is rarely used in a few
places, where the other categories could fit better.  Remove it.

Change-Id: Ia9db783bc92b23ba87b4fdf1e4ed07d59ea6bbce
2022-02-08 14:31:58 +06:00
Vadim Yanitskiy 41d9e2c093 phy_instance_destroy(): fix NULL pointer dereference
It's possible that a PHY instance has no associated TRX instance.

Change-Id: Id028577ef92d1b3ce63ba62b63b8b29edb2ae5a4
Fixes: OS#5377
2021-12-28 22:01:35 +06:00
Oliver Smith d4ebb1f6c4 treewide: remove FSF address
Remove the paragraph about writing to the Free Software Foundation's
mailing address. The FSF has changed addresses in the past, and may do
so again. In 2021 this is not useful, let's rather have a bit less
boilerplate at the start of source files.

Change-Id: I12b250e16426b125124def49e124e40ae93d0d58
2021-12-14 12:11:11 +01:00
Vadim Yanitskiy 374939f8cc cbch: cosmetic: use talloc_zero() in bts_process_smscb_cmd()
Change-Id: Ibb5090b7cd53c1a485d0b9474c6470fa5831de67
2021-12-12 19:37:32 +03:00
Vadim Yanitskiy 7ce4fa4325 osmo-bts-trx: fix a memleak in trx_sched_set_lchan()
An additional burst buffer is allocated in rx_data_fn() for Uplink
SACCH repetition, but unlike the main buffer it never gets free()d.

Change-Id: I93310e7aed91a49c0511e2ed30e000440617f95a
Fixes: I7e4cc33cc010866e41e3b594351a7f7bf93e08ac
Related: OS#4795, SYS#5114
2021-12-12 19:03:05 +03:00
Vadim Yanitskiy 487feeb0ff osmo-bts-trx: use l1ts as talloc context for burst buffers
Before a massive refactoring of the scheduler structures [1] it was
impossible to have a clean hierarchy, in which the burst buffers
get allocated as children of their parent timeslot structures.

This change makes it easier to read talloc reports and simplifies
memory management, offloading free()ing of the burst bufferes to
talloc.

Change-Id: Idb1ceaf83c433d2d0eb84d77c2187a00a657905c
Related: [1] I7c4379e43a25e9d858d582a99bf6c4b65c9af481
2021-12-12 18:59:34 +03:00
Vadim Yanitskiy 4b3fe16200 oml: assign unique names to 'struct tlv_parsed' chunks
Change-Id: Ie248d2a65a11da914324a7e65b767b894ed8644a
2021-12-12 16:22:48 +03:00
Vadim Yanitskiy 1475a45492 oml: fix copy-pasted comments in oml_rx_set_*_attr()
Change-Id: Iaa0e630b28b2a86312c069e7e55dd8bc5743759a
2021-12-12 16:22:30 +03:00
Vadim Yanitskiy 1d9106d768 oml: use ts->trx as talloc-context in oml_rx_set_chan_attr()
Change-Id: I6dc3706a486726afa9eec5d2e5369bd62c511455
2021-12-12 16:14:36 +03:00
Vadim Yanitskiy 4275bf7232 oml: use proper talloc context in oml_rx_set_radio_attr()
Change-Id: I69b6c72d85f68e4225d7786646f24259a5964998
2021-12-12 16:07:41 +03:00
Oliver Smith a271ca7fc7 debian/control: add osmo-bts meta-package
Add an osmo-bts meta-package that depends on the subpackages
osmo-bts-trx and osmo-bts-virtual. This is important, because the
downstream packaging of debian does not split osmo-bts in subpackages,
it has only one osmo-bts package. So without this, when installing
"osmo-bts" in debian while having the Osmocom binary package repository
installed and expecting to get the newer version, the user will actually
get the older version from debian.

Closes: OS#5319
Related: https://salsa.debian.org/debian-mobcom-team/osmo-bts/-/blob/master/debian/control
Change-Id: I1a6edf2eb146616ac51b7957368a8d057caa685f
2021-11-30 09:03:12 +01:00
Harald Welte 127c419d08 [lc15,oc2g,octphy] Fix memory leak on write queue overflow
Callers of osmo_wqueue_enqueue must always check the return value
and free the message themselves in the error case.

Change-Id: Ic67fbef23e419c0c8a7bcfb16d134e1bf649de72
Related: OS#5329
2021-11-25 13:15:30 +00:00
Harald Welte cf12cee46c cbch: Fix dangling cur_msg leading to double-free in bts_cbch_reset()
If a new default message is installed via RSL, and the old default
message is currently being transmitted, we must set cur_msg to NULL.

The old default message must be talloc_free()d unconditionally whenever
a new default message is being set.

We can do that by using the TALLOC_FREE macro.

Change-Id: Id32c2074b61cd1f09957b9d1558ffb3a7691a8e0
Related: OS#5325
2021-11-24 20:02:42 +01:00
Harald Welte 79f21c4ed1 cbch: Fix bts_smscb_state_reset() to avoid double-free
If the currently transmitted message is the default message,
bts_ss->cur_msg == bts_ss->derfault_msg.  In this case we cannot
simply talloc_free() both of them, as it would result in a boudle-free.

Change-Id: I2d3645e34d31507b012a53ffe12d14223682f808
Closes: OS#5325
Fixes: Ib01d38c59ba9fa083fcc0682009c13d2db3664fe
2021-11-24 20:02:42 +01:00
Pau Espin 40e97f3d02 bts: Properly free bts->shutdown_fi when struct gsm_bts is freed
Change-Id: I8c59f030c39c83a91b8504d4c5ce3b2058206fcf
2021-11-23 14:42:09 +01:00
Pau Espin 02532bafb8 bts_shutdown_fsm.h: Remove wrong comment describing enum
Change-Id: I963234255ce5a648a842ae6dbfd9966a694d0c09
2021-11-23 14:32:26 +01:00
271 changed files with 20510 additions and 4835 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
open_collective: osmocom

6
.gitignore vendored
View File

@ -55,6 +55,7 @@ src/osmo-bts-oc2g/misc/.dirstamp
tests/atconfig
tests/package.m4
tests/amr/amr_test
tests/csd/csd_test
tests/agch/agch_test
tests/paging/paging_test
tests/cipher/cipher_test
@ -93,6 +94,7 @@ debian/tmp/
doc/manuals/*.html
doc/manuals/*.svg
doc/manuals/*.pdf
doc/manuals/vty/*.pdf
doc/manuals/*__*.png
doc/manuals/*.check
doc/manuals/generated/
@ -104,3 +106,7 @@ doc/manuals/common
doc/manuals/build
contrib/osmo-bts.spec
contrib/ber/rtp_ber
contrib/ber/rtp_gen_map
arm-poky-linux-gnueabi-libtool

View File

@ -27,16 +27,16 @@ Homepage
--------
The official homepage of the project is
https://osmocom.org/projects/osmobts/wiki
<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
git clone https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
There is a cgit interface at https://git.osmocom.org/osmo-bts/
There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-bts>
Documentation
-------------
@ -57,6 +57,13 @@ There also is an
[Abis reference Manual](https://ftp.osmocom.org/docs/latest/osmobts-abis.pdf)
describing the OsmoBTS specific A-bis dialect.
Forum
-----
We welcome any osmo-bts related discussions in the
[Cellular Network Infrastructure -> 2G RAN (GERAN)](https://discourse.osmocom.org/c/cni/geran)
section of the osmocom discourse (web based Forum).
Mailing List
------------
@ -69,6 +76,13 @@ Please observe the [Osmocom Mailing List
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
when posting.
Issue Tracker
-------------
We use the [issue tracker of the osmo-bts project on osmocom.org](https://osmocom.org/projects/osmobts/issues) for
tracking the state of bug reports and feature requests. Feel free to submit any issues you may find, or help
us out by resolving existing issues.
Contributing
------------

View File

@ -1,2 +1,12 @@
# When cleaning up this file: bump API version(s) in the following files:
# configure.ac, debian/control, and contrib/osmo-bts.spec.in.
# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install
# according to https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
# In short:
# LIBVERSION=c:r:a
# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a.
# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0.
# If any interfaces have been added since the last public release: c:r:a + 1.
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
libosmogsm >1.9.0 added new PRIM_INFO to include/osmocom/gsm/l1sap.h
libosmogsm >1.9.0 use of RLP code in libosmogsm
libosmoctrl >1.9.0 use ctrl_cmd_send2()

View File

@ -69,14 +69,15 @@ then
fi
dnl checks for libraries
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.6.0)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.6.0)
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.6.0)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.6.0)
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.6.0)
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.6.0)
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.2.0)
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.2.0)
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.5.0)
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.5.0)
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.4.0)
AC_MSG_CHECKING([whether to enable support for sysmobts calibration tool])
AC_ARG_ENABLE(sysmobts-calib,
@ -360,7 +361,7 @@ if test "x$enable_ext_tests" = "xyes" ; then
fi
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
AC_MSG_ERROR([Please install git://osmocom.org/python/osmo-python-tests to run the VTY/CTRL tests.])
AC_MSG_ERROR([Please install https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests to run the VTY/CTRL tests.])
fi
fi
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
@ -444,10 +445,12 @@ AC_OUTPUT(
tests/power/Makefile
tests/meas/Makefile
tests/amr/Makefile
tests/csd/Makefile
doc/Makefile
doc/examples/Makefile
doc/manuals/Makefile
contrib/Makefile
contrib/ber/Makefile
contrib/systemd/Makefile
contrib/osmo-bts.spec
Makefile)

View File

@ -1 +1 @@
SUBDIRS = systemd
SUBDIRS = systemd ber

28
contrib/ber/Makefile.am Normal file
View File

@ -0,0 +1,28 @@
AM_CPPFLAGS = \
$(all_includes) \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
-I$(builddir) \
$(NULL)
AM_CFLAGS = \
-Wall \
$(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMOCODEC_CFLAGS) \
$(NULL)
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOTRAU_LIBS) \
$(LIBOSMOCODEC_LIBS) \
$(NULL)
noinst_PROGRAMS = rtp_ber rtp_gen_map
rtp_ber_SOURCES = rtp_ber.c codec_bit_class.h
rtp_gen_map_SOURCES = rtp_gen_map.c
update_codec_bit_class_h: rtp_gen_map
$(AM_V_GEN)./$< > $(top_srcdir)/contrib/ber/codec_bit_class.h

26
contrib/ber/README Normal file
View File

@ -0,0 +1,26 @@
BER testing tool
----------------
* Check all configs (MSC/BSC/BTS) for proper codec support
- FR enabled
- EFR enabled
- AMR 12.2 enabled (and all other modes disabled !)
- Use `amr-payload octet-aligned` in BSC config
* Check BTS config
- Disable jitter buffer : `bts N / rtp jitter-buffer 0`
* Check BSC config
- Disable radio timeout : `network / bts n / radio-link-timeout infinite`
* Start BER testing tool
- `./rtp_ber 4000`
* On the MSC CLI, start a silent-call, then request GSM to test loop
- `subscriber imsi <XXX> silent-call start tch/f speech-amr`
- `subscriber imsi <XXX> ms-test close-loop b`
Don't forget to terminate the loop and terminate the silent call !
- `subscriber imsi <XXX> ms-test open-loop`
- `subscriber imsi <XXX> silent-call stop`

View File

@ -0,0 +1,59 @@
static const int gsm_fr_bitclass[] = {
-1, -1, -1, -1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 2, 2,
0, 0, 1, 2, 2, 0, 0, 1, 2, 2, 0, 1, 1, 2, 0, 1,
2, 2, 0, 1, 2, 1, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 0, 0, 0, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1,
1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1,
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2,
1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1,
1, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 0, 0, 0, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1,
1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1,
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2,
1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1,
2, 2, 1, 2, 2, 1, 2, 2,
};
static const int gsm_efr_bitclass[] = {
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
1, 1, 1, 1, 2, 2, 1, 2,
};
static const int gsm_amr_12_2_bitclass[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, -1, -1, -1, -1,
};

483
contrib/ber/rtp_ber.c Normal file
View File

@ -0,0 +1,483 @@
/* RTP based GSM BER testing for osmo-bts, implementing ideas described in
* https://osmocom.org/projects/osmobts/wiki/BER_Testing
*
* In short: The command transmits a PRBS sequence encapsulated in RTP frames, which are sent
* to the BTS, which transmits that data in the (unimpaired) downlink. The mobile station
* receives the data and is instructed to loop it back in the (possibly impaired) uplink.
* The BTS receives that uplink, puts in in RTP frames which end up being received back by this
* very tool. By correlating the received RTP with the PRBS sequence, this tool can compute
* the BER (Bit Error Rate) of the (possibly impaired) uplink. Doing this with different
* RF channel model simulators in the uplink allows to establish BER at different levels and
* channel conditions. */
/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <osmocom/codec/codec.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/prbs.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/utils.h>
#include <osmocom/trau/osmo_ortp.h>
#include <codec_bit_class.h>
struct app_state {
struct osmo_rtp_socket *rs;
enum {
WAIT_CONN = 0, /* Wait for incoming connection */
WAIT_LOOP, /* Wait for a somewhat valid packet to start measuring */
RUNNING, /* Main state */
} state;
int pt;
int ref_len;
uint8_t ref_bytes[GSM_FR_BYTES]; /* FR is the largest possible one */
ubit_t ref_bits[8*GSM_FR_BYTES];
struct osmo_timer_list rtp_timer;
uint16_t rx_last_seq;
uint32_t rx_last_ts;
uint32_t rx_idx;
uint32_t tx_idx;
const int *err_tbl; /* Classification table */
int err_frames; /* Number of accumulated frames */
int err_cnt[3]; /* Bit error counter */
int err_tot[3]; /* Total # bits in that class */
};
#define FLOW_REG_TX_MAX_ADVANCE 200
#define FLOW_REG_TX_MIN_ADVANCE 50
const struct log_info log_info;
static const uint8_t amr_size_by_ft[] = {
[0] = 12, /* 4.75 */
[1] = 13, /* 5.15 */
[2] = 15, /* 5.9 */
[3] = 17, /* 6.7 */
[4] = 19, /* 7.4 */
[5] = 20, /* 7.95 */
[6] = 26, /* 10.2 */
[7] = 31, /* 12.2 */
[8] = 5, /* SID */
};
static const char * const amr_rate_by_ft[] = {
[0] = "4.75",
[1] = "5.15",
[2] = "5.9",
[3] = "6.7",
[4] = "7.4",
[5] = "7.95",
[6] = "10.2",
[7] = "12.2",
[8] = "SID",
};
static void
_gsm_fr_gen_ref(struct app_state *as)
{
struct osmo_prbs_state pn9;
/* Length */
as->ref_len = GSM_FR_BYTES;
/* Marker */
as->ref_bits[0] = 1;
as->ref_bits[1] = 1;
as->ref_bits[2] = 0;
as->ref_bits[3] = 1;
/* PN */
osmo_prbs_state_init(&pn9, &osmo_prbs9);
pn9.state = 31;
osmo_prbs_get_ubits(&as->ref_bits[4], 260, &pn9);
/* Convert to bytes */
osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_FR_BYTES, 0);
/* Init error classes */
as->err_tot[0] = 50;
as->err_tot[1] = 132;
as->err_tot[2] = 78;
as->err_tbl = gsm_fr_bitclass;
}
static void
_gsm_efr_gen_ref(struct app_state *as)
{
struct osmo_prbs_state pn9;
/* Length */
as->ref_len = GSM_EFR_BYTES;
/* Marker */
as->ref_bits[0] = 1;
as->ref_bits[1] = 1;
as->ref_bits[2] = 0;
as->ref_bits[3] = 0;
/* PN */
osmo_prbs_state_init(&pn9, &osmo_prbs9);
pn9.state = 31;
osmo_prbs_get_ubits(&as->ref_bits[4], 244, &pn9);
/* Convert to bytes */
osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_EFR_BYTES, 0);
/* Init error classes */
as->err_tot[0] = 50;
as->err_tot[1] = 125;
as->err_tot[2] = 73;
as->err_tbl = gsm_efr_bitclass;
}
static void
_gsm_amr_gen_ref(struct app_state *as)
{
struct osmo_prbs_state pn9;
uint8_t hdr[2];
/* Length */
as->ref_len = 33;
/* Header */
hdr[0] = 0x70;
hdr[1] = 0x3c;
osmo_pbit2ubit_ext(as->ref_bits, 0, hdr, 0, 16, 0);
/* PN */
osmo_prbs_state_init(&pn9, &osmo_prbs9);
pn9.state = 31;
osmo_prbs_get_ubits(&as->ref_bits[16], 244, &pn9);
/* Unused bits */
as->ref_bits[260] = 0;
as->ref_bits[261] = 0;
as->ref_bits[262] = 0;
as->ref_bits[263] = 0;
/* Convert to bytes */
osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 264, 0);
/* Init error classes */
as->err_tot[0] = 81;
as->err_tot[1] = 163;
as->err_tot[2] = -1;
as->err_tbl = gsm_amr_12_2_bitclass;
}
static void
_gsm_gen_ref(struct app_state *as)
{
switch (as->pt) {
case RTP_PT_GSM_FULL:
_gsm_fr_gen_ref(as);
break;
case RTP_PT_GSM_EFR:
_gsm_efr_gen_ref(as);
break;
case RTP_PT_AMR:
_gsm_amr_gen_ref(as);
break;
default:
fprintf(stderr, "[!] Unsupported payload type for BER measurement\n");
}
}
static int
_gsm_ber(struct app_state *as, const uint8_t *payload, unsigned int payload_len)
{
ubit_t rx_bits[8*33];
int err[3]; /* Class 1a, 1b, 2 */
int ones;
int i, j;
if (payload) {
/* Process real-payload */
osmo_pbit2ubit_ext(rx_bits, 0, payload, 0, 8*payload_len, 0);
err[0] = err[1] = err[2] = 0;
ones = 0;
for (i = 0; i < 8 * payload_len; i++) {
j = as->err_tbl[i];
if (j >= 0) {
err[j] += rx_bits[i] ^ as->ref_bits[i];
ones += rx_bits[i];
}
}
if (ones < 32) { // This frames is probably us underrunning Tx, don't use it
fprintf(stderr, "[w] Frame ignored as probably TX underrun %d %d\n", as->tx_idx, as->rx_idx);
return 1;
}
} else {
/* No payload -> Lost frame completely */
err[0] = as->err_tot[0] / 2;
err[1] = as->err_tot[1] / 2;
err[2] = as->err_tot[2] / 2;
}
if (as->state == RUNNING) {
/* Update records */
if (err[0] != 0) {
/* Class 1a bits bad -> Frame error */
as->err_cnt[0]++;
}
as->err_cnt[1] += err[1]; /* Class 1b */
as->err_cnt[2] += err[2]; /* class 2 */
as->err_frames++;
/* Enough for a read-out ? */
if (as->err_frames == 200) {
printf("FBER: %4.2f C1b RBER: %5.3f C2 RBER: %5.3f\n",
100.0f * as->err_cnt[0] / as->err_frames,
100.0f * as->err_cnt[1] / (as->err_tot[1] * as->err_frames),
100.0f * as->err_cnt[2] / (as->err_tot[2] * as->err_frames)
);
memset(as->err_cnt, 0, sizeof(as->err_cnt));
as->err_frames = 0;
}
}
return err[0] != 0;
}
static int
_rtp_check_payload_type(const uint8_t *payload, unsigned int payload_len)
{
uint8_t ft;
int pt = -1;
switch (payload_len) {
case GSM_FR_BYTES: /* FR or AMR 12.2k */
/* Check for AMR */
ft = (payload[1] >> 3) & 0xf;
if (ft == 7)
pt = RTP_PT_AMR;
/* Check for FR */
else if ((payload[0] & 0xF0) == 0xD0)
pt = RTP_PT_GSM_FULL;
/* None of the above */
else
fprintf(stderr, "[!] FR without 0xD0 signature or AMR with unknwon Frame Type ?!?\n");
break;
case GSM_EFR_BYTES: /* EFR */
if ((payload[0] & 0xF0) != 0xC0)
fprintf(stderr, "[!] EFR without 0xC0 signature ?!?\n");
pt = RTP_PT_GSM_EFR;
break;
case GSM_HR_BYTES: /* HR */
pt = RTP_PT_GSM_HALF;
break;
default: /* AMR */
{
uint8_t cmr, cmi, sti;
cmr = payload[0] >> 4;
ft = (payload[1] >> 3) & 0xf;
if (payload_len != amr_size_by_ft[ft]+2)
fprintf(stderr, "AMR FT %u(%s) but size %u\n",
ft, amr_rate_by_ft[ft], payload_len);
switch (ft) {
case 0: case 1: case 2: case 3:
case 4: case 5: case 6: case 7:
cmi = ft;
printf("AMR SPEECH with FT/CMI %u(%s), "
"CMR %u\n",
cmi, amr_rate_by_ft[cmi],
cmr);
break;
case 8: /* SID */
cmi = (payload[2+4] >> 1) & 0x7;
sti = payload[2+4] & 0x10;
printf("AMR SID %s with CMI %u(%s), CMR %u(%s)\n",
sti ? "UPDATE" : "FIRST",
cmi, amr_rate_by_ft[cmi],
cmr, amr_rate_by_ft[cmr]);
break;
}
}
break;
}
return pt;
}
static void
rtp_timer_cb(void *priv)
{
struct app_state *as = (struct app_state *)priv;
/* Send at least one frame if we're not too far ahead */
if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MAX_ADVANCE)) {
osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION);
as->tx_idx++;
} else {
fprintf(stderr, "Skipped\n");
}
/* Then maybe a second one to try and catch up to RX */
if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MIN_ADVANCE)) {
osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION);
as->tx_idx++;
}
/* Re-schedule */
osmo_timer_schedule(&as->rtp_timer, 0, 20000);
}
static int
rtp_seq_num_diff(uint16_t new, uint16_t old)
{
int d = (int)new - (int)old;
while (d > 49152)
d -= 65536;
while (d < -49152)
d += 65536;
return d;
}
static void
rtp_rx_cb(struct osmo_rtp_socket *rs,
const uint8_t *payload, unsigned int payload_len,
uint16_t seq_number, uint32_t timestamp, bool marker)
{
struct app_state *as = (struct app_state *)rs->priv;
int pt, rc, d;
// printf("Rx(%u, %d, %d, %d): %s\n", payload_len, seq_number, timestamp, marker, osmo_hexdump(payload, payload_len));
/* Identify payload */
pt = _rtp_check_payload_type(payload, payload_len);
/* First packet ? */
if (as->state == WAIT_CONN) {
/* Setup for this payload type */
as->pt = pt;
osmo_rtp_socket_set_pt(as->rs, pt);
_gsm_gen_ref(as);
/* Timer every 20 ms */
osmo_timer_setup(&as->rtp_timer, rtp_timer_cb, as);
osmo_timer_add(&as->rtp_timer);
osmo_timer_schedule(&as->rtp_timer, 0, 20000);
/* Init our time tracking */
as->rx_last_seq = seq_number;
as->rx_last_ts = timestamp;
/* Now we wait for a loop */
as->state = WAIT_LOOP;
}
/* RX sequence & timstamp tracking */
if (rtp_seq_num_diff(seq_number, as->rx_last_seq) > 1)
fprintf(stderr, "[!] RTP sequence number discontinuity (%d -> %d)\n", as->rx_last_seq, seq_number);
d = (timestamp - as->rx_last_ts) / GSM_RTP_DURATION;
as->rx_idx += d;
as->rx_last_seq = seq_number;
as->rx_last_ts = timestamp;
/* Account for missing frames in BER tracking */
if (d > 1) {
fprintf(stderr, "[!] RTP %d missing frames assumed lost @%d\n", d-1, seq_number);
while (--d)
_gsm_ber(as, NULL, 0);
}
/* BER analysis */
rc = _gsm_ber(as, payload, payload_len);
if ((as->state == WAIT_LOOP) && (rc == 0))
as->state = RUNNING;
}
int main(int argc, char **argv)
{
struct app_state _as, *as = &_as;
int rc, port;
/* Args */
if (argc < 2)
return -1;
port = atoi(argv[1]);
/* App init */
memset(as, 0x00, sizeof(struct app_state));
log_init(&log_info, NULL);
osmo_rtp_init(NULL);
/* Start auto-connect RTP socket */
as->rs = osmo_rtp_socket_create(NULL, 0);
as->rs->priv = as;
as->rs->rx_cb = rtp_rx_cb;
/* Jitter buffer gets in the way, we want the raw traffic */
osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JIT_ADAP, 0);
osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JITBUF, 0);
/* Bind to requested port */
fprintf(stderr, "[+] Binding RTP socket on port %u...\n", port);
rc = osmo_rtp_socket_bind(as->rs, "0.0.0.0", port);
if (rc < 0) {
fprintf(stderr, "[!] error binding RTP socket: %d\n", rc);
return rc;
}
/* We 'connect' to the first source we hear from */
osmo_rtp_socket_autoconnect(as->rs);
/* Main loop */
while (1)
osmo_select_main(0);
return 0;
}

145
contrib/ber/rtp_gen_map.c Normal file
View File

@ -0,0 +1,145 @@
/* utility to generate codec_bit_class.h, a file with structures
* describing which [protection] class each bit of a given codec frame belongs to */
/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <osmocom/codec/codec.h>
static int
gen_table_fr(int *tbl)
{
int i, j;
tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1;
for (i = 0; i < 260; i++) {
j = 4 + gsm610_bitorder[i];
if (i < 50)
tbl[j] = 0; /* Class 1a */
else if (i < 182)
tbl[j] = 1; /* Class 1b */
else
tbl[j] = 2; /* Class 2 */
}
return GSM_FR_BYTES * 8;
}
static int
gen_table_efr(int *tbl)
{
int i, j, k;
tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1;
for (i = 0; i < 260; i++) {
j = gsm660_bitorder[i];
if (j < 71)
k = j;
else if (j < 73)
k = 71;
else if (j < 123)
k = j - 2;
else if (j < 125)
k = 119;
else if (j < 178)
k = j - 4;
else if (j < 180)
k = 172;
else if (j < 230)
k = j - 6;
else if (j < 232)
k = 222;
else if (j < 252)
k = j - 8;
else
continue;
if (i < 50)
tbl[k] = 0; /* Class 1a */
else if (i < 182)
tbl[k] = 1; /* Class 1b */
else
tbl[k] = 2; /* Class 2 */
}
return GSM_EFR_BYTES * 8;
}
static int
gen_table_amr_12_2(int *tbl)
{
int i;
for (i = 0; i < 16; i++)
tbl[i] = -1;
for (i = 0; i < 244; i++)
tbl[i+16] = i < 81 ? 0 : 1;
for (i = 0; i < 4; i++)
tbl[i+16+244] = -1;
return 8 * 33;
}
static void
print_table(const char *name, int *tbl, int len)
{
int i;
printf("static const int %s[] = {\n", name);
for (i = 0; i < len; i++) {
if ((i & 15) == 0)
printf("\t");
printf("%2d", tbl[i]);
if (((i & 15) == 15) || (i == len-1))
printf(",\n");
else
printf(", ");
}
printf("};\n\n");
}
int main(int argc, char *argv[])
{
int tbl[33*8];
int rv;
rv = gen_table_fr(tbl);
print_table("gsm_fr_bitclass", tbl, rv);
rv = gen_table_efr(tbl);
print_table("gsm_efr_bitclass", tbl, rv);
rv = gen_table_amr_12_2(tbl);
print_table("gsm_amr_12_2_bitclass", tbl, rv);
return 0;
}

View File

@ -9,7 +9,8 @@ export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmocore "" --disable-doxygen
osmo-build-dep.sh libosmo-abis
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
cd "$deps"

View File

@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmo-abis
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
cd "$deps"
osmo-layer1-headers.sh lc15 "$FIRMWARE_VERSION"

View File

@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmo-abis
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
cd "$deps"
osmo-layer1-headers.sh oc2g "$FIRMWARE_VERSION"

View File

@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmo-abis
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
cd "$deps"
osmo-layer1-headers.sh oct "$FIRMWARE_VERSION"

View File

@ -9,7 +9,8 @@ export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmocore "" --disable-doxygen
osmo-build-dep.sh libosmo-abis
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
cd "$deps"

View File

@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
osmo-build-dep.sh libosmo-abis
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
cd "$deps"
osmo-layer1-headers.sh sysmo "$FIRMWARE_VERSION"

View File

@ -27,16 +27,15 @@ BuildRequires: pkgconfig >= 0.20
%if 0%{?suse_version}
BuildRequires: systemd-rpm-macros
%endif
BuildRequires: pkgconfig(libosmocodec) >= 1.6.0
BuildRequires: pkgconfig(libosmocoding) >= 1.6.0
BuildRequires: pkgconfig(libosmocore) >= 1.6.0
BuildRequires: pkgconfig(libosmoctrl) >= 1.6.0
BuildRequires: pkgconfig(libosmogsm) >= 1.6.0
BuildRequires: pkgconfig(libosmovty) >= 1.6.0
BuildRequires: pkgconfig(libosmoabis) >= 1.2.0
BuildRequires: pkgconfig(libosmotrau) >= 1.2.0
### FIXME: DependencyHACK to include osmocom/gprs/protocol/gsm_04_60.h
BuildRequires: pkgconfig(libosmogb)
BuildRequires: pkgconfig(libosmocodec) >= 1.9.0
BuildRequires: pkgconfig(libosmocoding) >= 1.9.0
BuildRequires: pkgconfig(libosmocore) >= 1.9.0
BuildRequires: pkgconfig(libosmoctrl) >= 1.9.0
BuildRequires: pkgconfig(libosmogsm) >= 1.9.0
BuildRequires: pkgconfig(libosmovty) >= 1.9.0
BuildRequires: pkgconfig(libosmoabis) >= 1.5.0
BuildRequires: pkgconfig(libosmotrau) >= 1.5.0
BuildRequires: pkgconfig(libosmo-netif) >= 1.4.0
%{?systemd_requires}
%description

View File

@ -2,11 +2,15 @@
Description=osmo-bts manager for LC15 / sysmoBTS 2100
After=lc15-sysdev-remap.service
Wants=lc15-sysdev-remap.service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
NotifyAccess=all
WatchdogSec=21780s
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
Restart=always
RestartSec=2

View File

@ -2,11 +2,15 @@
Description=osmo-bts manager for OC-2G
After=oc2g-sysdev-remap.service
Wants=oc2g-sysdev-remap.service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
NotifyAccess=all
WatchdogSec=21780s
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
Restart=always
RestartSec=2

View File

@ -1,17 +1,22 @@
[Unit]
Description=osmo-bts for LC15 / sysmoBTS 2100
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/osmo-bts-lc15 -t 2 -s -c /etc/osmocom/osmo-bts-lc15.cfg -M
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
RuntimeDirectory=osmo-bts
Restart=always
RestartSec=2
RestartPreventExitStatus=1
# The msg queues must be read fast enough
# CPU scheduling policy:
CPUSchedulingPolicy=rr
CPUSchedulingPriority=1
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
CPUSchedulingPriority=11
# See sched(7) for further details on real-time policies and priorities
[Install]
WantedBy=multi-user.target

View File

@ -1,17 +1,22 @@
[Unit]
Description=osmo-bts for OC-2G
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/osmo-bts-oc2g -s -c /etc/osmocom/osmo-bts-oc2g.cfg -M
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
RuntimeDirectory=osmo-bts
Restart=always
RestartSec=2
RestartPreventExitStatus=1
# The msg queues must be read fast enough
# CPU scheduling policy:
CPUSchedulingPolicy=rr
CPUSchedulingPriority=1
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
CPUSchedulingPriority=11
# See sched(7) for further details on real-time policies and priorities
[Install]
WantedBy=multi-user.target

View File

@ -1,5 +1,7 @@
[Unit]
Description=osmo-bts for sysmocom sysmoBTS
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
@ -7,13 +9,16 @@ ExecStartPre=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness'
ExecStart=/usr/bin/osmo-bts-sysmo -s -c /etc/osmocom/osmo-bts-sysmo.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'
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
Restart=always
RestartSec=2
RestartPreventExitStatus=1
# The msg queues must be read fast enough
# CPU scheduling policy:
CPUSchedulingPolicy=rr
CPUSchedulingPriority=1
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
CPUSchedulingPriority=20
# See sched(7) for further details on real-time policies and priorities
[Install]
WantedBy=multi-user.target

View File

@ -1,15 +1,21 @@
[Unit]
Description=Osmocom osmo-bts for osmo-trx
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/osmo-bts-trx -s -c /etc/osmocom/osmo-bts-trx.cfg
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
Restart=always
RestartSec=2
# Let it process messages quickly enough
# CPU scheduling policy:
CPUSchedulingPolicy=rr
CPUSchedulingPriority=1
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
CPUSchedulingPriority=11
# See sched(7) for further details on real-time policies and priorities
[Install]
WantedBy=multi-user.target

View File

@ -1,15 +1,21 @@
[Unit]
Description=Osmocom GSM BTS for virtual Um layer based on GSMTAP/UDP
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/osmo-bts-virtual -s -c /etc/osmocom/osmo-bts-virtual.cfg
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
Restart=always
RestartSec=2
# Let it process messages quickly enough
# CPU scheduling policy:
CPUSchedulingPolicy=rr
CPUSchedulingPriority=1
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
CPUSchedulingPriority=11
# See sched(7) for further details on real-time policies and priorities
[Install]
WantedBy=multi-user.target

View File

@ -1,9 +1,13 @@
[Unit]
Description=osmo-bts manager for sysmoBTS
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/sysmobts-mgr -ns -c /etc/osmocom/sysmobts-mgr.cfg
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
Restart=always
RestartSec=2

441
debian/changelog vendored
View File

@ -1,3 +1,444 @@
osmo-bts (1.7.0) unstable; urgency=medium
[ arehbein ]
* common: Fix memleak in get_smscb_block()
* doc: Adapt to use of 'telnet_init_default'
* common: Remove redundant checks
* common: Remove unused function gsm_objclass2nmstate()
* gsm_objclass2mo(): Change signature/set NACK cause
* gsm_objclass2obj(): Change signature/set NACK cause
* PCU interface: Log version when starting listener
* common: Have PCU socket connection use osmo_wqueue
* common: Make socket queue max. length configurable
[ Max ]
* bts-virtual: fix segfault
* osmo-bts-trx: log TRXC/TRXD connection address
* osmo-bts-trx: use bool for true/false flags
* GSMTAP: allow configuring local address
* license: fix typos
[ Vadim Yanitskiy ]
* paging_add_imm_ass(): remove meaningless from_pcu argument
* osmo-bts-{trx,virtual}: clean up bts_model_l1sap_down()
* osmo-bts-{trx,virtual}: check lchan against NULL in bts_model_l1sap_down()
* osmo-bts-{trx,virtual}: set rc on error in bts_model_l1sap_down()
* GSMTAP: print 'gsmtap-local-host' if not NULL
* osmo-bts-virtual: indicate BTS_FEAT_[E]GPRS to the BSC
* rsl: remove redundant gsm_lchan_name() in rsl_tx_rf_rel_ack()
* rsl: reduce logging verbosity on some messages
* tests: use -no-install libtool flag to avoid ./lt-* scripts
* scheduler: log pchan value in trx_sched_set_pchan()
* osmo-bts-virtual: properly handle dynamic TS in vbts_set_ts()
* contrib/osmo-bts.spec.in: do not depend on libosmogb
* osmo-bts-trx: properly activate [CBCH/]BCCH/CCCH
* rsl: rsl_handle_chan_mod_ie(): add missing GSM48_CMODE_* values
* osmo-bts-{sysmo,lc15,oc2g}: fix segfault in ph_tch_req()
* tests: $(BUILT_SOURCES) is not defined, depend on osmo-bts-virtual
* osmo-bts-virtual: properly activate [CBCH/]BCCH/CCCH
* flags: add missing entries to bts_impl_flag_desc[]
* flags: group BTS_INTERNAL_FLAG_* into an enum
* flags: ensure completeness of bts_impl_flag_desc[]
* fixup: common: Remove unused function gsm_objclass2nmstate()
* oml: gsm_objclass2{mo,obj}(): cosmetic: return immediately
* oml: gsm_objclass2{mo,obj}(): set cause for unknown obj_class
* oml: reset BCCH carrier power reduction mode (if enabled)
* copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH
* osmo-bts-trx: alloc/free burst buffers in trx_sched_set_lchan()
* osmo-bts-trx: use direct pointer to chan_state->{ul,dl}_bursts
* osmo-bts-trx: tch_dl_dequeue(): do not drop CSD frames
* osmo-bts-trx: tx_pdtch_fn(): use msgb_l2len()
* osmo-bts-trx: fix recent regression in Tx lchan handlers
* osmo-bts-trx: remove redundant memset() on receipt of NOPE.ind
* l1sap: use gsm0502_fn2ccch_block() from libosmogsm
* scheduler: fix wrong union field in _sched_compose_tch_ind()
* scheduler: use msgb_hexdump_l2() in _sched_compose_tch_ind()
* scheduler: unify argument names/order for _sched_compose_*_ind()
* scheduler: constify *data pointer in _sched_compose_*_ind()
* scheduler: use size_t for data_len in _sched_compose_*_ind()
* fix bts_supports_cm(): properly check feature flags for VGCS/VBS
* measurement: suppress unsupported tch_mode warnings for CSD
* osmo-bts-trx: pull the AMR header in tch_dl_dequeue()
* osmo-bts-trx: implement CSD scheduling support
* osmo-bts-trx: implement FACCH/[FH] support for CSD
* osmo-bts-trx: implement TCH/F2.4 support for CSD
* osmo-bts-trx: visualize rx_tch[fh]_fn() functions
* osmo-bts-trx: unify and enrich 'Received bad data' logging
* osmo-bts-trx: rx_tchf_fn(): move compute_ber10k() above
* osmo-bts-trx: rx_tch[fh]_fn(): combine rc-checking ifs
* osmo-bts-trx: change 'Received bad data' back to LOGL_DEBUG
* osmo-bts-trx: tx_tch[fh]_fn(): fix NULL pointer dereference
* osmo-bts-trx: document/clarify the meaning of BUFMAX=24
* l1sap: proper rate adaptation for CSD (RFC4040 'clearmode')
* csd_v110_rtp_encode(): properly set E1/E2/E3 bits
* osmo-bts-trx: bts_supports_cm_data(): allow non-transparent modes
* rsl: rsl_handle_chan_mod_ie(): set lchan->csd_mode
* rsl: rsl_handle_chan_mod_ie(): do not use legacy defines
* csd_v110: fix comments in csd_v110_rtp_{en,de}code()
* csd_v110: properly set E1/E2/E3 for non-transparent data
* csd_v110: handle empty/incomplete Uplink frames gracefully
[ Philipp Maier ]
* pcu_sock: rename rc to fd
* pcu_sock: cosmetic: remove whitespace after type cast
* pcu_sock: cosmetic: remove unnecessary line breaks
* pcu_sock: do not mess with the osmo fd flags directly
* sched_lchan_tchx: use GSM_HR_BYTES_RTP_RFC5993 constant
* l1sap: fix wording in comment
* pcu_sock: don not continue when running out of TRX space
* paging: cosmetic: rename all IMM.ASS references to MAC block
* paging: parse PCUIF data indication outside of paging.c
* paging: do not confirm PAGING COMMAND messages
* pcu_sock: move variable declaration of imsi[4] into related scope
* l1sap: cosmetic: rename payload_len to rtp_pl_len
* pcu_sock: use PCUIF version 11 (direct TLLI)
* paging: also accept zero length IMSI strings 3
* pcuif_proto: rename tlli to msg_id
* pcu_sock: get rid of fn parameter in pcu_tx_pch_data_cnf
* pcuif_proto: remove unnecessary members from gsm_pcu_if_data_cnf_dt
* pcuif_proto: get rid of _DT, _dt (Direct TLLI)
* bts: make bts_agch_dequeue static
* pcuif_proto: use confirm flag in struct gsm_pcu_if_pch
* pcu_sock: use PCU_IF_SAPI_AGCH_2 instead PCU_IF_SAPI_AGCH
* pcu_sock: print SAPI and msg_id when sending confirmation
[ Pau Espin Pedrol ]
* bts-trx: Fix no NM Radio{Carrier,Channel} switching to Enabled if one TRX is rf_locked
* pcu_sock: Submit all DATA.ind regardless of link quality
* pcu_sock.c: Call osmo_fd_unregister() before closing and changing bfd->fd
* Rewrite pcu_sock_write()
* lchan: Improve error path logging in gsm_pchan2chan_nr()
* cosmetic: gsm_pchan2chan_nr(): Update spec documentation
* cosmetic: bts_trx.h: Fix whitespace
* Avoid tx RF Resource Ind for disabled TRX
* bts-trx: Avoid pushing interf_meas for disabled TRX
* contrib/ber: Avoid regenerating codec_bit_class.h every build
* bts-trx: Drop unused param to internal function
* Clarify configuration of TSC on each timeslot
* bts_model_apply_oml(): Drop unneded code
* oml.c: Remove dot character at the end of log lines
* nm: Apply BTS/TRX/TS OML Attributes through NM FSMs
* nm: Drop NM_EV_SETATTR_{ACK/NACK}
* oml: Get rid of unused tlv_parsed param in bts_model_apply_oml()
* bts_model_apply_oml(): Improve definition of parameter
* lc15,oc2g,sysmo: Update GPRS NM object state at the right time
* Simplify implementation of bts_model_opstart() in all bts types
* nm: Apply OPSTART through NM FSMs
* NM: NACK received OML OPSTART if no attributes were set beforehand
* Introduce NM FSM for GPRS NSE object
* Fix octet 2 of NM GPRS Cell
* Introduce NM FSM for GPRS Cell object
* Rearrange declaration of struct gsm_bts_gprs_nsvc
* Move NSVC structs to be part of NSE
* bts: Simplify lifecycle of BTS inside bts_list
* Introduce NM FSM for GPRS NSVC object
* nm: Dispatch NM_EV_SW_ACT in cascade to BTS SiteMgr children
* Merge gsm_network into gsm_bts_sm and place gsm_bts under it
* Move GPRS NSE under BTS SiteMgr
* Drop NM_EV_BBTRANSC_INSTALLED in favour of generic NM_EV_SW_ACT
* nm: Document current state of SW_ACT in TRX related objects
* Properly report all states through NM FSM upon OML link up
* Update g_bts_sm->num_bts when bts is added/removed from bts list
* Move pcu_sock_state to gprs section of bts_sm
* pcu_sock: Allocate pcu_sock_state using g_bts_sm talloc context
* pcu_sock: Drop bts_sm pointer
* oml: Fix potential null ptr access on trx object
* bts-sysmo: Fix pinst->version filled too early
* bts-sysmo: Delay marking phy_link as connected until L1 reset + got info
* vty.c: Use already available tpp pointer
* octphy: Fix clearly wrong noop assignment
* bbtransc/rcarrier: Fix statechg done twice upon NM_EV_RX_OPSTART
* Increase PCUIF wqueue size
* bts-trx: Fix CCCH not enabled if BS_AG_BLKS_RES!=1 is provided by BSC
* rsl: Improve logic reactivating CCCH upon SI3 BS_AG_BLKS_RES change
[ Oliver Smith ]
* gitignore: add vty pdf
* doc: rsl: add RSL_IE_IPAC_RTP_CSD_FORMAT
* rsl_rx_ipac_XXcx: parse csd_fmt_d/ir
* debian: set compat level to 10
* systemd: depend on networking-online.target
* gitignore: add arm-poky-linux-gnueabi-libtool
* osmo-bts-sysmo: trx_mute_on_init_cb: call bts_update_status
* osmo-bts-sysmo: activate_rf: no dispatch on fail
* osmo-bts-sysmo/l1_if: move mute_rf_compl_cb up
* osmo-bts-sysmo: mute PHY until OML is ready
[ Harald Welte ]
* DTX: bts-{sysmo,oc2g,lc15}: Print DEBUG messages about ONSET
* cosmetic: Replace %i with %d
* Introduce LOGPLCFN() for logging lchan-name + frame number
* bts-{sysmo,oc2g,lc15}: Fix RTP of AMR SID_FIRST_P1
* common/vty: Print AMR MultiRate Configuration in "show lchan"
* bts-{sysmo,oc2g,lc15}: Dump logical channel params during MPH-ACTIVATE.req
* cosmetic: use __func__ instead of __FUNCTION__
* lc15: fix compiler warning about wrong indent
* lc15: Remove unused warning
* lc15/oc2g: remove unused variables
* oc2g: Fix 'unused variable' compiler warning
* cosmetic: Remove "FIXME?" from Odd AMR CMI phase
* lc15: fix compiler warning about unused variable cell_size
* Replace explicit gsm_lchan_name() calls with LOGPLCHAN
* logging: Introduce LOGPLCGT()
* cosmetic: Change LOGPLCFN argument order
* paging: Add support for generating NLN/NLN-Status in P1 Rest Octets
* Add ASCI (advanced speech call items) log sub-system
* ASCI: NCH / NOTIFICATION support
* validate RSL "channel rate and type" against VGCS/VBS flags
* Store "Channel rate and type" from RSL Channel Mode IE in BTS
* ASCI: VGCS/VBS RACH -> RSL TALKER/LISTENER DETECT
* sysmo: Enable VGSCS + VBS feature flags
* omldummy: Claim to support VBS + VGCS towards BSC
[ Mychaela N. Falconia ]
* trx: detect UL SID in EFR just like in FR
* sysmo: fix handling of SID in EFR
* common: implement rtp continuous-streaming mode
* rtp continuous-streaming: fix BFI in the quality-suppressed case
* sysmo: emit empty RTP ticks during FACCH stealing on TCH/F
* bts-{lc15,oc2g,sysmo}: support EFR in repeat_last_sid()
* RTP input, FR & EFR: preen incoming payloads for SID errors
* lc15,oc2g: fix handling of SID in EFR
* all models, FR/EFR UL: change SID check to _is_any_sid()
* trx: remove model-specific BFI packet formats
* refactor: replace rtppayload_is_valid() with preening before enqueue
* all models, HR1 codec: accept both TS101318 and RFC5993 formats
* trx: fix HR1 codec breakage from format change
* trx, HR1 codec: change UL PHY output format to TS 101 318
* all models, HR1 codec: select RTP output format via vty option
* FR/HR/EFR TCH DL: implement DTX rules
* HR1 codec: validate ToC header in RFC5993 RTP input
* HR1 codec: act on SID indication in RFC5993 RTP input
* trx TCH DL: transmit invalid speech blocks instead of dummy FACCH
* ECU in UL path: make it optional per vty config
* ECU in UL path: move state alloc/free to l1sap
* ECU in UL path: move it from trx model to l1sap
[ Sylvain Munaut ]
* contrib: Add BER testing tool
[ Andreas Eversberg ]
* Change return value of bts_supports_cm() from int to bool
* ASCI: Add function to reactivate channel
* ASCI: Retrieve NCH position from System Information 1
* ASCI: Add Notification CHannel (NCH) support
* ASCI: Add support for rest octets in Paging request type 2 and 3
* ASCI: Send only NLN on Paging request type 1 rest octets
* ASCI: Add Notification/FACCH support
* ASCI: Repeat UPLINK FREE message until uplink becomes busy
* Add test cases for rest octets of Paging Requests
* ASCI: Enable UPLINK ACCESS on various BTS models
[ Keith ]
* Fix incorrect order of params passed to logging macro
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 16:05:30 +0200
osmo-bts (1.6.0) unstable; urgency=medium
[ Vadim Yanitskiy ]
* osmo-bts-trx: call osmo_timer_del() unconditionally
* osmo-bts-trx: amr_loop: trigger the loop unconditionally
* osmo-bts-trx: fix handling of ciphering params in PRIM_INFO_MODIFY
* osmo-bts-trx: rx_rach_fn(): properly detect handover RACH
* osmo-bts-trx: handle MTS 0b0110 indicating an Access Burst
* osmo-bts-trx: use lookup tables for checking AMR CMI/CMR on Downlink
* osmo-bts-trx: drop ul_amr_fn_is_cmi() / dl_amr_fn_is_cmi()
[ Pau Espin Pedrol ]
* rsl: rx ipac crcx/mdcx: Log payload_type2
* logging: Move category descriptions to be in order with enum
* Clean up osmo-bts-*/Makefile.am
* Split out lchan rtp socket creation from rsl handling code
* Avoid counting lchan->dl_tch_queue length every time a msg is enqueued
* Use libosmocore API msgb_queue_free() to free lists
* rsl: Reduce scope of variable
* Move lchan_dl_tch_queue_enqueue to lchan.c and make it public
* cosmetic: Fix formatting of if-else block brackets
* Depend on libosmo-netif
* Clarify RTP AMR header offset in TCH enc/dec
* tests/*/Makefile.am: Fix typo in LIBOSMONETIF_CFLAGS
* tests/*/Makefile.am: Add missing libosmo-netif cflags
* oc2g: Makefile.am Fix typo in LIBOSMONETIF_LIBS
* Introduce Osmux support
* abis: Avoid TCP/IPA RSL sockets continue conn establishment while shutting down
* osmux: Log sendto() error
* lchan: Reset Abis RTP/Osmux config during lchan release
* vty: Fix SPEECH_MODE printed with hex prefix but dec value
* vty: Print Osmux CID on lchans using Osmux
* Allocate struct osmux_in_handle through new libosmo-netif APIs
* osmux: Drop logging of osmux internal counters
* osmux: Match remote address in osmux_lchan_find()
* osmux: Log remote address upon rx of osmux pkt
* osmux: Lower log level when osmux batch received for unknown CID
* osmux: nullify osmux.rtpst after freeing it
* osmux: Skip lchans in lookup which still have no remote associated
* osmux: Close osmux socket when bts is freed
* osmux: Fix null ptr dereference sending UL data before the remote is configured
* osmux: Rotate over available Osmux CID when allocating a new one
* osmux: Use new osmux_xfrm_input API to set name on each link
* vty: Fix typo in write-config: osmux / local-port
* vty: Fix typo in symbol name
[ Max ]
* Set working directory in systemd service file
* Don't manually create pid file
* Document realtime options in .service units
* Update realtime scheduling priority in service file
* ctrl: take both address and port from vty config
* Add SI10 support
[ Philipp Maier ]
* pcu_sock: fix sourcecode formatting
* measurement: do not call msgb_l3len without checking
* l1sap: do not call msgb_l2hlen without checking
* rsl: use unsigned int
* pcuif_proto: cosmetic: add constant PCU_IF_NUM_NSVC and replace magic numbers
* sched_lchan_tchf: replace numeric constant with define constant
* l1sap: remove unused pointer variable
* pcuif_proto: use define constant to specify nax number of trx
* pcu_sock: use ARRAY_SIZE rather then magic number
[ Keith ]
* osmo-bts-trx: respond to tx-attenuation config in real time.
[ Harald Welte ]
* update outdated vty copyright statement
[ Daniel Willmann ]
* shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C
* shutdown_fsm: Add power_ramp_force() to jump straight to the tgt power
[ daniel ]
* Revert "shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C"
[ Alexander Couzens ]
* OML: NSVC[1] MO should have the same initial state as NVSC[0]
[ Oliver Smith ]
* oc2gbts_mgr_calib: fix build against gpsd >= 3.20
* contrib/jenkins: build libosmo-abis without dahdi
[ arehbein ]
* osmo-bts: Transition to use of 'telnet_init_default'
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 17:15:52 +0100
osmo-bts (1.5.0) unstable; urgency=medium
[ Pau Espin Pedrol ]
* bts_shutdown_fsm.h: Remove wrong comment describing enum
* bts: Properly free bts->shutdown_fi when struct gsm_bts is freed
* bts-trx: amr: Fix return code of osmo_amr_rtp_dec() checked too late
* Change some log levels NOTICE->INFO
* rsl: Conditionally decrease log level if cause is normal event
* bts-trx: Log lchan if avaialble in Meas Avg
* doc: rsl: Fix description of 'IP Connection Statistics' IE
* bts-trx: sched_lchan_tchh.c: Workaround gcc false positive error
* bts-sysmo: Replace use of deprecated ipa_client_conn_create API
[ Harald Welte ]
* cbch: Fix bts_smscb_state_reset() to avoid double-free
* cbch: Fix dangling cur_msg leading to double-free in bts_cbch_reset()
* [lc15,oc2g,octphy] Fix memory leak on write queue overflow
* update git URLs (git -> https; gitea)
[ Oliver Smith ]
* debian/control: add osmo-bts meta-package
* treewide: remove FSF address
* model_init: order features alphabetically
* model_init: set BTS_FEAT_PAGINATION_COORDINATION
* model_init: order features alphabetically, part 2
* src/common/bts.c: set BTS_FEAT_PAGING_COORDINATION
* src/common/bts.c: set BTS_FEAT_CCN
[ Vadim Yanitskiy ]
* oml: use proper talloc context in oml_rx_set_radio_attr()
* oml: use ts->trx as talloc-context in oml_rx_set_chan_attr()
* oml: fix copy-pasted comments in oml_rx_set_*_attr()
* oml: assign unique names to 'struct tlv_parsed' chunks
* osmo-bts-trx: use l1ts as talloc context for burst buffers
* osmo-bts-trx: fix a memleak in trx_sched_set_lchan()
* cbch: cosmetic: use talloc_zero() in bts_process_smscb_cmd()
* phy_instance_destroy(): fix NULL pointer dereference
* logging: get rid of logging category DSUM
* osmo-bts-trx: make use of OSMO_UNLIKELY() when handling TRXD PDUs
* osmo-bts-trx: cosmetic: use rate_ctr_inc2() instead of rate_ctr_inc()
* osmo-bts-trx: new rate counter 'trx_sched:dl_fh_cache_miss'
* VTY: fix ambiguity in BTS specific command definitions
* osmo-bts-trx: do not run osmo_{fr,hr}_check_sid() on FACCH/U frames
* osmo-bts-trx: rx_tchh_fn(): do not calculate BER10k for FACCH twice
* rsl: fix wrong IE being checked in rsl_rx_chan_activ()
* osmo-bts-trx: rx_tchh_fn(): fix HR SID detection (wrong offset)
* osmo-bts-trx: rx_tchh_fn(): mark valid SID frames as such
* osmo-bts-trx: use consistent naming for 'enum sched_meas_avg_mode'
* osmo-bts-trx: use a lookup table in trx_sched_meas_avg()
* osmo-bts-trx: rx_tchh_fn(): use proper meas averaging mode
* trx_sched_ul_burst(): get rid of the 'switch' statement
* fix gsm_bts_get_cbch(): CBCH can be allocated on Cn
* osmo-bts-trx: rx_tchh_fn(): indicate BER10k=0 for FACCH BFIs
* osmo-bts-trx: rx_tchh_fn(): get rid of chan_state->meas_avg_facch
* osmo-bts-trx: rx_{tchf,tchh}_fn(): also use meas_avg for BFI
* osmo-bts-trx: rx_{tchf,tchh}_fn(): shift Rx burst buffer on bid=0
* osmo-bts-trx: rx_{tchf,tchh}_fn(): ensure complete set of bursts
* osmo-bts-trx: rx_{tchf,tchh}_fn(): get TDMA FN from meas history
* osmo-bts-trx: rx_{tchh,tchf}_fn(): use AMR CMI lookup tables
* osmo-bts-trx: rx_{tchh,tchf}_fn(): use tch_mode directly
* osmo-bts-trx: rx_tchh_fn(): fix meas reporting in signalling mode
* osmo-bts-trx: move AMR CMI lookup tables to the respective files
* osmo-bts-trx: rx_tchh_fn(): fix indexes in the AMR CMI lookup table
* osmo-bts-trx: rx_tchf_fn(): clarify indexes in the AMR CMI lookup table
* power_ctrl_params_def_reset(): set .ctrl_interval for both UL/DL
* scheduler: remove redundant OSMO_ASSERT() statements
* scheduler: rts_tchh_fn(): use a lookup table for FACCH/H
* osmo-bts-trx: rx_tchh_fn(): use a lookup table for FACCH/H
* osmo-bts-{trx,virtual}: tx_tchh_fn(): remove FACCH/H alignment check
* osmo-bts-trx: rename 'loops.[ch]' to 'amr_loop.[ch]'
* osmo-bts-trx: use '#pragma once' in amr_loop.h
* osmo-bts-trx: amr_loop: remove unneeded #includes
* rsl: de-duplicate parsing of MultiRate configuration IE
* rsl: rsl_rx_chan_{activ,modif}: do not sent an Error Report
* rsl: parse_multirate_config(): check if AMR codec is used
* logging: use a different color tone for DLOOP
* rsl: always check return value of rsl_tlv_parse()
* rsl: misc / cosmetic fixes for tx_ipac_XXcx_nack()
* osmo-bts-virtual: remove unused 'codec_mode_request' argument
* l1sap: l1sap_chan_act(): alloc DTX FSM only for TCH
* l1sap: l1sap_chan_act(): remove unused *tp argument
* osmo-bts-trx: bts_report_interf_meas(): remove unused fn param
* rsl: use hard-coded defaults if the MultiRate conf IE is absent
* tests/amr/Makefile.am: use proper binary name prefix 'amr_test_'
* tests/amr: add a unit test for amr_parse_mr_conf()
* amr: fix parsing of threshold and hysteresis in amr_parse_mr_conf()
* tests: use 'check_PROGRAMS' instead of 'noinst_PROGRAMS'
* struct amr_multirate_conf: remove ms_mode[], raname bts_mode[]
* common: fix coding style: if is not a function
* osmo-bts-trx: amr_loop: simplify trx_loop_amr_set()
* osmo-bts-trx: use C/I in the AMR link adaptation loop
* osmo-bts-trx: amr_loop: improve logging in trx_loop_amr_input()
* osmo-bts-trx: amr_loop: allow upgrading codec mode > 0
* osmo-bts-trx: amr_loop: log if AMR mode remains unchanged
* osmo-bts-trx: amr_loop: do not miss C/I samples
* osmo-bts-trx: prioritize FACCH in s/tx_tch_common()/tch_dl_dequeue()/s
* osmo-bts-trx: tx_tchh_fn(): make handling of FACCH/H cleaner
* osmo-bts-trx: fix scheduling of dummy FACCH/H and FACCH/F
* VTY: fix NULL-pointer dereference in 'show transceiver'
* osmo-bts-trx: check if scheduling of [dummy] FACCH/H is allowed
* osmo-bts-trx: rx_{tchh,tchf}_fn(): improve logging of AMR DTX frames
* pcu_sock: comment out {dl,ul}_tbf_ext related warnings
* osmo-bts-trx: drop Uplink loss detection from Downlink path
* scheduler: trx_sched_is_sacch_fn(): make ts pointer const
* struct bts_ul_meas: reflect C/I units in field name s/c_i/ci_cb/
* tests/meas: improve logging in test_ts45008_83_is_sub_single()
* tests/meas: improve test_ts45008_83_is_sub_is_sub()
* measurement: log SUB/FULL as text in lchan_new_ul_meas()
* measurement: move SACCH detection to process_l1sap_meas_data()
* measurement: fix matching of SUB frames by TDMA FN
* osmo-bts-trx: rx_tchf_fn(): do not treat AFS_SID_UPDATE as SUB frame
* Revert "osmo-bts-trx: rx_tchf_fn(): do not treat AFS_SID_UPDATE as SUB frame"
-- Pau Espin Pedrol <pespin@sysmocom.de> Wed, 29 Jun 2022 09:41:38 +0200
osmo-bts (1.4.0) unstable; urgency=medium
[ Philipp Maier ]

2
debian/compat vendored
View File

@ -1 +1 @@
9
10

32
debian/control vendored
View File

@ -2,24 +2,41 @@ Source: osmo-bts
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
Section: net
Priority: optional
Build-Depends: debhelper (>= 9),
Build-Depends: debhelper (>= 10),
pkg-config,
dh-autoreconf,
autotools-dev,
pkg-config,
libosmocore-dev (>= 1.6.0),
libosmo-abis-dev (>= 1.2.0),
libosmocore-dev (>= 1.9.0),
libosmo-abis-dev (>= 1.5.0),
libosmo-netif-dev (>= 1.4.0),
libgps-dev,
txt2man,
osmo-gsm-manuals-dev (>= 1.2.0)
osmo-gsm-manuals-dev (>= 1.5.0)
Standards-Version: 3.9.8
Vcs-Browser: http://git.osmocom.org/osmo-bts/
Vcs-Git: git://git.osmocom.org/osmo-bts
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
Homepage: https://projects.osmocom.org/projects/osmobts
Package: osmo-bts
Architecture: any
Depends: osmo-bts-trx, osmo-bts-virtual, ${misc:Depends}
Description: Base Transceiver Station for GSM
OsmoBTS is a software implementation of Layer2/3 of a BTS. It implements the
following protocols/interfaces:
LAPDm (GSM 04.06)
RTP
A-bis/IP in IPA multiplex
OML (GSM TS 12.21)
RSL (GSM TS 08.58)
.
OsmoBTS is modular and has support for multiple back-ends. A back-end talks to
a specific L1/PHY implementation of the respective BTS hardware. Based on this
architecture, it should be relatively easy to add a new back-end to support
so-far unsupported GSM PHY/L1 and associated hardware.
Package: osmo-bts-trx
Architecture: any
Conflicts: osmo-bts
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
@ -34,7 +51,6 @@ Description: Debug symbols for the osmo-bts-trx
Package: osmo-bts-virtual
Architecture: any
Conflicts: osmo-bts
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Virtual Osmocom GSM BTS (no RF hardware; GSMTAP/UDP)
This version of OsmoBTS doesn't use actual GSM PHY/Hardware/RF, but

View File

@ -1,16 +1,29 @@
OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg
# all config examples must be listed here unconditionally, so that
# all of them end up in the release tarball (see OS#6349)
EXTRA_DIST = \
trx/osmo-bts-trx.cfg \
trx/osmo-bts-trx-calypso.cfg \
octphy/osmo-bts-trx2dsp1.cfg \
octphy/osmo-bts-octphy.cfg \
oc2g/osmo-bts-oc2g.cfg \
oc2g/oc2gbts-mgr.cfg \
sysmo/sysmobts-mgr.cfg \
sysmo/osmo-bts-sysmo.cfg \
litecell15/osmo-bts-lc15.cfg \
litecell15/lc15bts-mgr.cfg \
virtual/osmo-bts-virtual.cfg \
$(NULL)
doc_virtualdir = $(docdir)/examples/osmo-bts-virtual
doc_virtual_DATA = \
virtual/osmo-bts-virtual.cfg
EXTRA_DIST = $(doc_virtual_DATA)
OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg
if ENABLE_SYSMOBTS
doc_sysmodir = $(docdir)/examples/osmo-bts-sysmo
doc_sysmo_DATA = \
sysmo/osmo-bts-sysmo.cfg \
sysmo/sysmobts-mgr.cfg
EXTRA_DIST += $(doc_sysmo_DATA)
OSMOCONF_FILES += sysmo/osmo-bts-sysmo.cfg sysmo/sysmobts-mgr.cfg
endif
@ -19,7 +32,6 @@ doc_trxdir = $(docdir)/examples/osmo-bts-trx
doc_trx_DATA = \
trx/osmo-bts-trx.cfg \
trx/osmo-bts-trx-calypso.cfg
EXTRA_DIST += $(doc_trx_DATA)
OSMOCONF_FILES += trx/osmo-bts-trx.cfg
endif
@ -28,7 +40,6 @@ doc_octphydir = $(docdir)/examples/osmo-bts-octphy
doc_octphy_DATA = \
octphy/osmo-bts-trx2dsp1.cfg \
octphy/osmo-bts-octphy.cfg
EXTRA_DIST += $(doc_octphy_DATA)
OSMOCONF_FILES += octphy/osmo-bts-octphy.cfg
endif
@ -37,7 +48,6 @@ doc_lc15dir = $(docdir)/examples/osmo-bts-lc15
doc_lc15_DATA = \
litecell15/osmo-bts-lc15.cfg \
litecell15/lc15bts-mgr.cfg
EXTRA_DIST += $(doc_lc15_DATA)
OSMOCONF_FILES += litecell15/osmo-bts-lc15.cfg litecell15/lc15bts-mgr.cfg
endif
@ -46,7 +56,6 @@ doc_oc2gdir = $(docdir)/examples/osmo-bts-oc2g
doc_oc2g_DATA = \
oc2g/osmo-bts-oc2g.cfg \
oc2g/oc2gbts-mgr.cfg
EXTRA_DIST += $(doc_oc2g_DATA)
OSMOCONF_FILES += oc2g/osmo-bts-oc2g.cfg oc2g/oc2gbts-mgr.cfg
endif

View File

@ -3,10 +3,12 @@
!!
!
log stderr
logging filter all 1
logging color 1
logging print category 0
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level temp info
logging level fw info
logging level find info

View File

@ -4,7 +4,11 @@
!
log stderr
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level rsl info
logging level oml info
logging level rll notice

View File

@ -3,10 +3,12 @@
!!
!
log stderr
logging filter all 1
logging color 1
logging print category 0
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level temp info
logging level fw info
logging level find info

View File

@ -4,7 +4,11 @@
!
log stderr
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level rsl info
logging level oml info
logging level rll notice

View File

@ -4,7 +4,11 @@
!
log stderr
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level rsl info
logging level oml info
logging level rll notice

View File

@ -4,7 +4,11 @@
!
log stderr
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level rsl info
logging level oml info
logging level rll notice

View File

@ -4,7 +4,11 @@
!
log stderr
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level rsl info
logging level oml info
logging level rll notice

View File

@ -3,9 +3,12 @@
!!
!
log stderr
logging filter all 1
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level temp info
logging level fw info
logging level find info

View File

@ -5,7 +5,11 @@
!
log stderr
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level rsl notice
logging level oml notice
logging level rll notice

View File

@ -4,7 +4,11 @@
!
log stderr
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level rsl notice
logging level oml notice
logging level rll notice

View File

@ -3,10 +3,12 @@
!!
!
log stderr
logging filter all 1
logging color 0
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level rsl info
logging level oml info
logging level rll notice

View File

@ -192,6 +192,7 @@ Conforms to 3GPP TS 48.058 § 8.4.20, with these exceptions:
| 0x06 | RSL_SYSTEM_INFO_6
| 0x0d | RSL_SYSTEM_INFO_5bis
| 0x0e | RSL_SYSTEM_INFO_5ter
| 0x0f | RSL_SYSTEM_INFO_10
| 0x47 | RSL_EXT_MEAS_ORDER
| 0x48 | RSL_MEAS_INFO
|===
@ -516,6 +517,7 @@ number*.
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
|===
[[rsl_crcx_msg_ack]]
@ -576,6 +578,7 @@ properties of a user-plane RTP connection.
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
|===
[[rsl_mdcx_msg_ack]]
@ -864,6 +867,8 @@ addition to those indicated in 3GPP TS 48.058 Section 9.3:
| 0x01 | RSL_IE_CHAN_NR | <<RSL_IE_CHAN_NR>>
| 0x60 | RSL_IE_OSMO_REP_ACCH_CAP | <<RSL_IE_OSMO_REP_ACCH_CAP>>
| 0x61 | RSL_IE_OSMO_TRAINING_SEQUENCE | <<RSL_IE_OSMO_TRAINING_SEQUENCE>>
| 0x62 | RSL_IE_OSMO_TEMP_OVP_ACCH_CAP | <<RSL_IE_OSMO_TEMP_OVP_ACCH_CAP>>
| 0x63 | RSL_IE_OSMO_OSMUX_CID | <<RSL_IE_OSMO_OSMUX_CID>>
| 0xf0 | RSL_IE_IPAC_REMOTE_IP | <<RSL_IE_IPAC_REMOTE_IP>>
| 0xf1 | RSL_IE_IPAC_REMOTE_PORT | <<RSL_IE_IPAC_REMOTE_PORT>>
| 0xf3 | RSL_IE_IPAC_LOCAL_PORT | <<RSL_IE_IPAC_LOCAL_PORT>>
@ -871,6 +876,7 @@ addition to those indicated in 3GPP TS 48.058 Section 9.3:
| 0xf5 | RSL_IE_IPAC_LOCAL_IP | <<RSL_IE_IPAC_LOCAL_IP>>
| 0xf6 | RSL_IE_IPAC_CONN_STAT | <<RSL_IE_IPAC_CONN_STAT>>
| 0xf8 | RSL_IE_IPAC_CONN_ID | <<RSL_IE_IPAC_CONN_ID>>
| 0xf9 | RSL_IE_IPAC_RTP_CSD_FORMAT | <<RSL_IE_IPAC_RTP_CSD_FORMAT>>
| 0xfc | RSL_IE_IPAC_RTP_PAYLOAD2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>>
|===
@ -953,8 +959,8 @@ IEI followed by four bytes IPv4 address.
This information element contains statistics about the RTP connection.
It is encoded as 29 bytes, with the first byte as IEI and 28 bytes
fixed-length payload encoded as follows:
It is encoded as 30 bytes, with the first byte as IEI, the second byte as length
(=28), and 28 bytes fixed-length payload encoded as follows:
.A-bis/IP Connection Statistics
[options="header",width="60%",cols="15%,15%,70%"]
@ -1085,6 +1091,49 @@ for future use.
| 8..255 | reserved values
|===
[[RSL_IE_OSMO_TEMP_OVP_ACCH_CAP]]
==== RSL_IE_OSMO_TEMP_OVP_ACCH_CAP
FIXME: this IE has been defined, but remains to be documented.
[[RSL_IE_OSMO_OSMUX_CID]]
==== RSL_IE_OSMO_OSMUX_CID
FIXME: this IE has been defined, but remains to be documented.
[[RSL_IE_IPAC_RTP_CSD_FORMAT]]
==== RSL_IE_IPAC_RTP_CSD_FORMAT
This information element contains the RTP Circuit Switched Data format.
.A-bis/IP RTP CSD Format
[options="header",width="60%",cols="15%,15%,70%"]
|===
| Offset | Size | Description
| 0 | 4 | RTP CSD Format D
| 4 | 4 | RTP CSD Format IR
|===
.A-bis/IP RTP CSD Format D Values
[options="header",width="40%",cols="20%,80%"]
|===
| Value | Description
| 0 | External TRAU format
| 1 | Non-TRAU Packed format
| 2 | TRAU within the BTS
| 3 | IWF-Free BTS-BTS Data
|===
.A-bis/IP RTP CSD Format IR Values
[options="header",width="40%",cols="20%,80%"]
|===
| Value | Description
| 0 | 8 kb/s
| 1 | 16 kb/s
| 2 | 32 kb/s
| 3 | 48 kb/s
|===
=== A-bis RSL Initialization / BTS bring-up
Upon receiving the 'IPA RSL CONNECT' OML message by the respective

View File

@ -82,14 +82,13 @@ order to specify which PHY instance is allocated to this specific TRX.
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
| common | bts_controlif_setup() | Initialization of Control Interface
| bts-specific | bts_model_ctrl_cmds_install() | Install model-specific control interface commands
| common | telnet_init() | Initialization of telnet interface
| common | telnet_init_default() | Initialization of telnet interface
| common | pcu_sock_init() | Initialization of PCU socket
| common | main() | Installation of signal handlers
| common | abis_open() | Start of the A-bis connection to BSC
| 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
| bts-specific | bts_model_phy_link_close() | Close 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
|===

View File

@ -0,0 +1,39 @@
include::{commondir}/chapters/osmux/osmux.adoc[]
=== Osmux Support in {program-name}
Osmux usage in {program-name} in managed through the VTY commands in node
`osmux`. Command `use (on|off|only)` is used to configure use policy of Osmux
within {program-name}. Once enabled (`on` or `only`), {program-name} will
announce the _OSMUX_ BTS feature towards the BSC over OML. This way, the BSC
becomes aware that this BTS supports using Osmux to transfer voice call user
data when the AMR codec is selected.
It is then up to the BSC to decide whether to use Osmux or not when establishing
a new call. If the BSC decides to use Osmux for a given call, then the _IPACC
CRCX/MDCX_ messages sent by the BSC will contain an extra _Osmux CID_ IE
appended, which contains the Osmux CID to be used by the BTS to send Osmux
frames to the co-located BSC MGW (aka the BSC MGW' local CID, or {program-name}'
remote CID). The IP address and port provided in the same messages refer to the
address and port where Osmux frames with the provided CID are expected to be
received. Similarly, {program-name} appends an _Osmux CID_ IE to the _IPACC
CRCX/MDCX ACK_ message it generates, this time with its own local Osmux CID.
Same goes for the BTS' local IP address and port where Osmux frames are expected
to be received.
{program-name} will behave differently during call set up based on the VTY
command `use (on|off|only)` presented above:
* `off`: If _IPACC CRCX_ from BSC contains _Osmux CID_ IE, meaning
BSC wants to use Osmux for this call, then {program-name} will reject the
request and the call set up will fail.
* `on`: {program-name} will support and accept both Osmux and non-Osmux (RTP)
upon call set up. If _IPACC CRCX_ from BSC contains the _Osmux CID_ IE on a
AMR call (`Channel Mode GSM3`), it will set up an Osmux stream on its end and
provide the BSC with the BTS-local CID. If the BSC provides no _Osmux CID_ IE,
then {program-name} will set up a regular RTP based call.
* `only`: Same as per `on`, except that {program-name} will accept only Osmux
calls on the CN-side, this is, if _IPACC CRCX_ from BSC doesn't
contain an _Osmux CID_ IE, it will reject the assignment and the call set up
will fail. This means also that only AMR calls (`Channel Mode GSM3`) are
allowed.

View File

@ -1,4 +1,5 @@
:gfdl-enabled:
:program-name: OsmoBTS
OsmoBTS User Manual
===================
@ -30,6 +31,8 @@ include::{srcdir}/chapters/bts-models.adoc[]
include::{srcdir}/chapters/architecture.adoc[]
include::{srcdir}/chapters/osmux_bts.adoc[]
include::./common/chapters/qos-dscp-pcp.adoc[]
include::./common/chapters/vty_cpu_sched.adoc[]

View File

@ -21,13 +21,12 @@ The start-up procedure of OsmoBTS can be described as follows:
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
| common | bts_controlif_setup() | Initialization of Control Interface
| bts-specific | bts_model_ctrl_cmds_install()
| common | telnet_init() | Initialization of telnet interface
| common | telnet_init_default() | Initialization of telnet interface
| common | pcu_sock_init() | Initialization of PCU socket
| common | main() | Installation of signal handlers
| common | abis_open() | Start of the A-bis connection to BSC
| 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

98
doc/trx_sched_tch.txt Normal file
View File

@ -0,0 +1,98 @@
== rx_tchf_fn(): TCH/FS, TCH/EFS, TCH/AFS, TCH/F2.4, and FACCH/F
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 4
| | | | | | | | | | | | | | | | | | | | | a | b | c | d | Rx bid={0,1,2,3}, decode
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 4
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | g | h | Rx bid={0,1,2,3}, decode
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 4
|
|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame A
| |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame B
@ decoding from here
== rx_tchf_fn(): TCH/F14.4, TCH/F9.6, TCH/F4.8
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
| | | | | | | | | | | | | | | | | | | | | a | b | c | d | Rx bid={0,1,2,3}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | g | h | Rx bid={0,1,2,3}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
| | | | | | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | Rx bid={0,1,2,3}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
| | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | Rx bid={0,1,2,3}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
| | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | Rx bid={0,1,2,3}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | Rx bid={0,1,2,3}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
|
|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame A
| |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame B
@ decoding from here
== rx_tchh_fn(): TCH/HS, TCH/AHS
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | | | | | | | a | b | | | Rx bid={0,1}, decode
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | | | | | a | b | c | d | | | Rx bid={0,1}, decode
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | | | Rx bid={0,1}, decode
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
|<~~~~~~~~~~~~~>| frame A
| |<~~~~~~~~~~~~~>| frame B
@ decoding from here
== rx_tchh_fn(): FACCH/H
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | | | | | | | a | b | | | Rx bid={0,1}, decode
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | | | | | a | b | c | d | | | Rx bid={0,1}
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | | | Rx bid={0,1}, decode
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
|<~~~~~~~~~~~~~~~~~~~~~>| frame A
| |<~~~~~~~~~~~~~~~~~~~~~>| frame B
@ decoding from here
== rx_tchh_fn(): TCH/H4.8, TCH/H2.4
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | | | | | | | a | b | | | Rx bid={0,1}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | | | | | a | b | c | d | | | Rx bid={0,1}
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | | | Rx bid={0,1}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | | | a | b | c | d | e | f | g | h | | | Rx bid={0,1}
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | | | a | b | c | d | e | f | g | h | i | j | | | Rx bid={0,1}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | | | Rx bid={0,1}
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | | | Rx bid={0,1}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | | | Rx bid={0,1}
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | | | Rx bid={0,1}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | | | Rx bid={0,1}
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | | | Rx bid={0,1}, decode
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame A
| |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame B
@ decoding from here

View File

@ -1,9 +1,11 @@
noinst_HEADERS = \
abis.h \
abis_osmo.h \
asci.h \
bts.h \
bts_model.h \
bts_shutdown_fsm.h \
bts_sm.h \
bts_trx.h \
gsm_data.h \
logging.h \
@ -11,6 +13,7 @@ noinst_HEADERS = \
oml.h \
paging.h \
rsl.h \
rtp_input_preen.h \
signal.h \
vty.h \
amr.h \
@ -21,6 +24,7 @@ noinst_HEADERS = \
tx_power.h \
control_if.h \
cbch.h \
csd_v110.h \
l1sap.h \
lchan.h \
power_control.h \
@ -30,4 +34,6 @@ noinst_HEADERS = \
dtx_dl_amr_fsm.h \
ta_control.h \
nm_common_fsm.h \
notification.h \
osmux.h \
$(NULL)

View File

@ -14,5 +14,6 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
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);
void amr_init_mr_conf_def(struct gsm_lchan *lchan);
#endif /* _OSMO_BTS_AMR_H */

43
include/osmo-bts/asci.h Normal file
View File

@ -0,0 +1,43 @@
#pragma once
#include <stdint.h>
#include <osmo-bts/lchan.h>
enum {
VGCS_TALKER_NONE = 0,
VGCS_TALKER_WAIT_FRAME,
VGCS_TALKER_ACTIVE,
};
void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn);
void vgcs_lchan_activate(struct gsm_lchan *lchan);
void vgcs_lchan_react(struct gsm_lchan *lchan);
void vgcs_talker_frame(struct gsm_lchan *lchan);
void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access);
void vgcs_listener_reset(struct gsm_lchan *lchan);
static inline bool vgcs_is_uplink_free(struct gsm_lchan *lchan)
{
return lchan->asci.uplink_free;
}
static inline void vgcs_uplink_free_get(struct gsm_lchan *lchan, uint8_t *msg)
{
memcpy(msg, lchan->asci.uplink_free_msg, GSM_MACBLOCK_LEN);
}
static inline void vgcs_uplink_free_set(struct gsm_lchan *lchan, uint8_t *msg)
{
memcpy(lchan->asci.uplink_free_msg, msg, GSM_MACBLOCK_LEN);
lchan->asci.uplink_free = true;
}
static inline void vgcs_uplink_free_reset(struct gsm_lchan *lchan)
{
lchan->asci.uplink_free = false;
}

View File

@ -5,6 +5,7 @@
#include <osmocom/core/socket.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/bts_trx.h>
#include <osmo-bts/osmux.h>
struct gsm_bts_trx;
@ -24,11 +25,21 @@ enum {
BTS_CTR_RACH_RCVD,
BTS_CTR_RACH_DROP,
BTS_CTR_RACH_HO,
BTS_CTR_RACH_VGCS,
BTS_CTR_RACH_CS,
BTS_CTR_RACH_PS,
BTS_CTR_AGCH_RCVD,
BTS_CTR_AGCH_SENT,
BTS_CTR_AGCH_DELETED,
BTS_CTR_RTP_RX_TOTAL,
BTS_CTR_RTP_RX_MARKER,
BTS_CTR_RTP_RX_DROP_PREEN,
BTS_CTR_RTP_RX_DROP_LOOPBACK,
BTS_CTR_RTP_RX_DROP_OVERFLOW,
BTS_CTR_RTP_RX_DROP_V110_DEC,
BTS_CTR_RTP_TX_TOTAL,
BTS_CTR_RTP_TX_MARKER,
};
/* Used by OML layer for BTS Attribute reporting */
@ -52,36 +63,28 @@ enum gsm_bts_type_variant {
};
const char *btsvariant2str(enum gsm_bts_type_variant v);
/* TODO: add a brief description of this flag */
#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP (1 << 0)
/* When this flag is set then the measurement data is included in
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
* measurement data is passed using a separate MPH INFO MEAS IND.
* (See also ticket: OS#2977) */
#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB (1 << 1)
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
* (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
#define BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER (1 << 2)
/* Whether the BTS model reports interference measurements to L1SAP. */
#define BTS_INTERNAL_FLAG_INTERF_MEAS (1 << 3)
enum bts_impl_flag {
/* TODO: add a brief description of this flag */
BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP,
/* When this flag is set then the measurement data is included in
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
* measurement data is passed using a separate MPH INFO MEAS IND.
* (See also ticket: OS#2977) */
BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB,
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
* (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER,
/* Whether the BTS model reports interference measurements to L1SAP. */
BTS_INTERNAL_FLAG_INTERF_MEAS,
_BTS_INTERNAL_FLAG_NUM, /* must be at the end */
};
/* BTS implementation flags (internal use, not exposed via OML) */
#define bts_internal_flag_get(bts, flag) \
((bts->flags & (typeof(bts->flags)) flag) != 0)
((bts->flags & (typeof(bts->flags))(1 << flag)) != 0)
#define bts_internal_flag_set(bts, flag) \
bts->flags |= (typeof(bts->flags)) flag
struct gsm_bts_gprs_nsvc {
struct gsm_bts *bts;
/* data read via VTY config file, to configure the BTS
* via OML from BSC */
int id;
uint16_t nsvci;
struct osmo_sockaddr local; /* on the BTS */
struct osmo_sockaddr remote; /* on the SGSN */
struct gsm_abis_mo mo;
};
bts->flags |= (typeof(bts->flags))(1 << flag)
struct gprs_rlc_cfg {
uint16_t parameter[_NUM_RLC_PAR];
@ -130,9 +133,15 @@ struct bts_power_ctrl_params {
} pf;
};
/* BTS Site Manager */
struct gsm_bts_sm {
/* GPRS CELL; ip.access specific NM Object */
struct gsm_gprs_cell {
struct gsm_abis_mo mo;
uint16_t bvci;
uint8_t timer[11];
struct gprs_rlc_cfg rlc_cfg;
struct {
uint32_t gprs_codings; /* see NM_IPAC_F_GPRS_CODING_* flags */
} support;
};
/* Struct that holds one OML-Address (Address of the BSC) */
@ -141,9 +150,11 @@ struct bsc_oml_host {
char *addr;
};
#define BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT 100
/* One BTS */
struct gsm_bts {
/* list header in net->bts_list */
/* list header in g_bts_sm->bts_list */
struct llist_head list;
/* number of the BTS in network */
@ -157,6 +168,7 @@ struct gsm_bts {
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
* which is used as TSC for the CCCH */
uint8_t bsic;
bool bsic_configured;
/* type of BTS */
enum gsm_bts_type_variant variant;
enum gsm_band band;
@ -192,7 +204,7 @@ struct gsm_bts {
/* CCCH is on C0 */
struct gsm_bts_trx *c0;
struct gsm_bts_sm site_mgr;
struct gsm_bts_sm *site_mgr;
/* bitmask of all SI that are present/valid in si_buf */
uint32_t si_valid;
@ -222,18 +234,7 @@ struct gsm_bts {
/* Not entirely sure how ip.access specific this is */
struct {
struct {
struct gsm_abis_mo mo;
uint16_t nsei;
uint8_t timer[7];
} nse;
struct {
struct gsm_abis_mo mo;
uint16_t bvci;
uint8_t timer[11];
struct gprs_rlc_cfg rlc_cfg;
} cell;
struct gsm_bts_gprs_nsvc nsvc[2];
struct gsm_gprs_cell cell;
uint8_t rac;
} gprs;
@ -249,8 +250,9 @@ struct gsm_bts {
int16_t boundary[6];
uint8_t intave;
} interference;
unsigned int t200_ms[7];
uint32_t t200_fn[7];
unsigned int t3105_ms;
unsigned int t3115_ms; /* VGCS UPLINK GRANT repeat timer */
struct {
uint8_t overload_period;
struct {
@ -273,6 +275,7 @@ struct gsm_bts {
} rach;
} load;
uint8_t ny1;
uint8_t ny2; /* maximum number of repetitions for the VGCS UPLINK GRANT */
uint8_t max_ta;
/* AGCH queuing */
@ -302,6 +305,15 @@ struct gsm_bts {
bool pni; /* Primary Notification Identifier */
} etws;
/* Advanced Speech Call Items (VBS/VGCS) + NCH related bits */
struct {
int pos_nch; /* position of the NCH or < 0, if not available */
uint8_t nln, nln_status; /* current notification list number and status */
struct llist_head notifications;
int notification_entries; /* current number of entries in the list */
int notification_count; /* counter to count all entries */
} asci;
struct paging_state *paging_state;
struct llist_head bsc_oml_hosts;
unsigned int rtp_jitter_buf_ms;
@ -313,8 +325,13 @@ struct gsm_bts {
int rtp_ip_dscp;
int rtp_priority;
bool rtp_nogaps_mode; /* emit RTP stream without any gaps */
bool use_ul_ecu; /* "rtp internal-uplink-ecu" option */
bool emit_hr_rfc5993;
struct {
uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
uint8_t max_ta; /* maximum timing advance */
} support;
struct {
uint8_t tc4_ctr;
@ -359,18 +376,25 @@ struct gsm_bts {
struct {
char *sock_path;
unsigned int sock_wqueue_len_max;
} pcu;
/* GSMTAP Um logging (disabled by default) */
struct {
struct gsmtap_inst *inst;
char *remote_host;
char *local_host;
uint32_t sapi_mask;
uint8_t sapi_acch;
bool rlp;
bool rlp_skip_null;
} gsmtap;
struct osmux_state osmux;
struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */
bool shutdown_fi_exit_proc; /* exit process when shutdown_fsm is finished? */
bool shutdown_fi_skip_power_ramp; /* Skip power ramping and change power in one step? */
struct osmo_fsm_inst *abis_link_fi; /* FSM instance to manage abis connection during process startup and link failure */
struct osmo_tdef *T_defs; /* Timer defines */
@ -384,24 +408,30 @@ extern void *tall_bts_ctx;
#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
static inline struct gsm_bts *gsm_bts_sm_get_bts(struct gsm_bts_sm *site_mgr) {
return (struct gsm_bts *)container_of(site_mgr, struct gsm_bts, site_mgr);
static inline struct gsm_bts *gsm_gprs_cell_get_bts(struct gsm_gprs_cell *cell)
{
return (struct gsm_bts *)container_of(cell, struct gsm_bts, gprs.cell);
}
struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num);
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num);
struct gsm_bts *gsm_bts_alloc(struct gsm_bts_sm *bts_sm, uint8_t bts_num);
struct gsm_bts *gsm_bts_num(const struct gsm_bts_sm *bts_sm, int num);
int bts_init(struct gsm_bts *bts);
void bts_shutdown(struct gsm_bts *bts, const char *reason);
void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc);
void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc, bool skip_power_ramp);
int bts_link_estab(struct gsm_bts *bts);
int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg);
struct msgb *bts_agch_dequeue(struct gsm_bts *bts);
int bts_agch_max_queue_length(int T, int bcch_conf);
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
int is_ag_res);
enum ccch_msgt {
CCCH_MSGT_AGCH,
CCCH_MSGT_PCH,
CCCH_MSGT_NCH,
};
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, enum ccch_msgt ccch);
int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher);
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time);
void regenerate_si3_restoctets(struct gsm_bts *bts);
@ -417,8 +447,8 @@ struct gsm_time *get_time(struct gsm_bts *bts);
int bts_main(int argc, char **argv);
int bts_supports_cm(const struct gsm_bts *bts,
const struct rsl_ie_chan_mode *cm);
bool bts_supports_cm(const struct gsm_bts *bts,
const struct rsl_ie_chan_mode *cm);
int32_t bts_get_avg_fn_advance(const struct gsm_bts *bts);
@ -427,4 +457,11 @@ struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
int bts_set_c0_pwr_red(struct gsm_bts *bts, const uint8_t red);
/* Context information to be put in the control buffer (db) of the AGCH msg
* buffer */
struct bts_agch_msg_cb {
uint32_t msg_id;
bool confirm;
} __attribute__ ((packed));
#endif /* _BTS_H */

View File

@ -5,6 +5,7 @@
#include <osmocom/gsm/tlv.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmo-bts/gsm_data.h>
@ -20,8 +21,8 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type,
struct tlv_parsed *old_attr, struct tlv_parsed *new_attr,
void *obj);
int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
struct tlv_parsed *new_attr, int obj_kind, void *obj);
int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg,
struct gsm_abis_mo *mo, void *obj);
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
void *obj);

View File

@ -1,6 +1,6 @@
/* BTS shutdown FSM */
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* All Rights Reserved
@ -13,7 +13,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -24,7 +24,6 @@
#include <osmocom/core/fsm.h>
/* 3GPP TS 24.008 § 4.1.3.3 GMM mobility management states on the network side */
enum bts_shutdown_fsm_states {
BTS_SHUTDOWN_ST_NONE,
BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL,

48
include/osmo-bts/bts_sm.h Normal file
View File

@ -0,0 +1,48 @@
#pragma once
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/socket.h>
#include <osmocom/gsm/gsm23003.h>
#include <osmo-bts/oml.h>
struct pcu_sock_state;
/* GPRS NSVC; ip.access specific NM Object */
struct gsm_gprs_nse;
struct gsm_gprs_nsvc {
struct gsm_abis_mo mo;
struct gsm_gprs_nse *nse;
/* data read via VTY config file, to configure the BTS
* via OML from BSC */
int id;
uint16_t nsvci;
struct osmo_sockaddr local; /* on the BTS */
struct osmo_sockaddr remote; /* on the SGSN */
};
/* GPRS NSE; ip.access specific NM Object */
struct gsm_gprs_nse {
struct gsm_abis_mo mo;
uint16_t nsei;
uint8_t timer[7];
struct gsm_gprs_nsvc nsvc[2];
};
struct gsm_bts *gsm_gprs_nse_get_bts(const struct gsm_gprs_nse *nse);
/* BTS Site Manager */
struct gsm_bts_sm {
struct gsm_abis_mo mo;
struct llist_head bts_list;
unsigned int num_bts;
struct osmo_plmn_id plmn;
struct {
struct pcu_sock_state *pcu_state;
struct gsm_gprs_nse nse;
} gprs;
};
extern struct gsm_bts_sm *g_bts_sm;
struct gsm_bts_sm *gsm_bts_sm_alloc(void *talloc_ctx);

View File

@ -1,9 +1,16 @@
#pragma once
#include <osmocom/core/sockaddr_str.h>
#include <osmo-bts/gsm_data.h>
struct gsm_bts_bb_trx {
struct gsm_abis_mo mo;
/* how do we talk RSL with this TRX? */
struct {
struct osmo_sockaddr_str rem_addrstr;
uint8_t tei;
struct e1inp_sign_link *link;
} rsl;
};
/* One TRX in a BTS */
@ -16,9 +23,6 @@ struct gsm_bts_trx {
uint8_t nr;
/* human readable name / description */
char *description;
/* how do we talk RSL with this TRX? */
uint8_t rsl_tei;
struct e1inp_sign_link *rsl_link;
/* NM Radio Carrier and Baseband Transciever */
struct gsm_abis_mo mo;
@ -27,8 +31,8 @@ struct gsm_bts_trx {
uint16_t arfcn;
int nominal_power; /* in dBm */
unsigned int max_power_red; /* in actual dB */
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
uint8_t ta_ctrl_interval; /* 1 step is 2 SACCH periods */
@ -40,6 +44,12 @@ struct gsm_bts_trx {
/* The associated PHY instance */
struct phy_instance *pinst;
struct {
uint32_t freq_bands; /* see NM_IPAC_F_FREQ_BAND_* flags */
uint32_t chan_types; /* see NM_IPAC_F_CHANT_* flags */
uint32_t chan_modes; /* see NM_IPAC_F_CHANM_* flags */
} support;
struct gsm_bts_trx_ts ts[TRX_NR_TS];
};
@ -58,6 +68,7 @@ int trx_link_estab(struct gsm_bts_trx *trx);
void trx_operability_update(struct gsm_bts_trx *trx);
uint8_t num_agch(const struct gsm_bts_trx *trx, const char * arg);
int pos_nch(const struct gsm_bts_trx *trx, const char *arg);
bool trx_ms_pwr_ctrl_is_osmo(const struct gsm_bts_trx *trx);
#define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args)

View File

@ -1,5 +1,4 @@
#pragma once
int bts_ctrl_cmds_install(struct gsm_bts *bts);
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
const char *bind_addr, uint16_t port);
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port);

View File

@ -0,0 +1,23 @@
#pragma once
/* RFC4040 "clearmode" RTP payload length */
#define RFC4040_RTP_PLEN 160
struct gsm_lchan;
struct csd_v110_frame_desc {
uint16_t num_blocks;
uint16_t num_bits;
};
struct csd_v110_lchan_desc {
struct csd_v110_frame_desc fr;
struct csd_v110_frame_desc hr;
};
extern const struct csd_v110_lchan_desc csd_v110_lchan_desc[256];
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
const uint8_t *data, size_t data_len);
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
const uint8_t *rtp, size_t rtp_len);

View File

@ -41,12 +41,6 @@
#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41
#define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91
struct gsm_network {
struct llist_head bts_list;
unsigned int num_bts;
struct osmo_plmn_id plmn;
struct pcu_sock_state *pcu_state;
};
/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1:
4-bit index is used (2#1111 = 10#15) */
@ -58,12 +52,59 @@ struct gsm_network {
/* lchans 0..3 are SDCCH in combined channel configuration,
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
#define CCCH_LCHAN 4
#define CBCH_LCHAN 2
#define TRX_NR_TS 8
#define TS_MAX_LCHAN 8
#define MAX_VERSION_LENGTH 64
/* NM_IPAC_F_CHANT_* mask for NM_IPAC_EIE_CHAN_TYPES (common) */
#define NM_IPAC_MASK_CHANT_COMMON \
(NM_IPAC_F_CHANT_TCHF | \
NM_IPAC_F_CHANT_TCHH | \
NM_IPAC_F_CHANT_SDCCH8 | \
NM_IPAC_F_CHANT_BCCH | \
NM_IPAC_F_CHANT_BCCH_SDCCH4)
/* NM_IPAC_F_CHANM_SPEECH_* mask for NM_IPAC_EIE_CHAN_MODES */
#define NM_IPAC_MASK_CHANM_SPEECH \
(NM_IPAC_F_CHANM_SPEECH_FS | \
NM_IPAC_F_CHANM_SPEECH_EFS | \
NM_IPAC_F_CHANM_SPEECH_AFS | \
NM_IPAC_F_CHANM_SPEECH_HS | \
NM_IPAC_F_CHANM_SPEECH_AHS)
/* NM_IPAC_F_CHANM_CSD_NT_* mask for NM_IPAC_EIE_CHAN_MODES */
#define NM_IPAC_MASK_CHANM_CSD_NT \
(NM_IPAC_F_CHANM_CSD_NT_4k8 | \
NM_IPAC_F_CHANM_CSD_NT_9k6 | \
NM_IPAC_F_CHANM_CSD_NT_14k4)
/* NM_IPAC_F_CHANM_CSD_T_* mask for NM_IPAC_EIE_CHAN_MODES */
#define NM_IPAC_MASK_CHANM_CSD_T \
(NM_IPAC_F_CHANM_CSD_T_1200_75 | \
NM_IPAC_F_CHANM_CSD_T_600 | \
NM_IPAC_F_CHANM_CSD_T_1k2 | \
NM_IPAC_F_CHANM_CSD_T_2k4 | \
NM_IPAC_F_CHANM_CSD_T_4k8 | \
NM_IPAC_F_CHANM_CSD_T_9k6 | \
NM_IPAC_F_CHANM_CSD_T_14k4)
/* NM_IPAC_F_GPRS_CODING_CS[1-4] mask for NM_IPAC_EIE_GPRS_CODING */
#define NM_IPAC_MASK_GPRS_CODING_CS \
(NM_IPAC_F_GPRS_CODING_CS1 | \
NM_IPAC_F_GPRS_CODING_CS2 | \
NM_IPAC_F_GPRS_CODING_CS3 | \
NM_IPAC_F_GPRS_CODING_CS4)
/* NM_IPAC_F_GPRS_CODING_MCS[1-9] mask for NM_IPAC_EIE_GPRS_CODING */
#define NM_IPAC_MASK_GPRS_CODING_MCS \
(NM_IPAC_F_GPRS_CODING_MCS1 | \
NM_IPAC_F_GPRS_CODING_MCS2 | \
NM_IPAC_F_GPRS_CODING_MCS3 | \
NM_IPAC_F_GPRS_CODING_MCS4 | \
NM_IPAC_F_GPRS_CODING_MCS5 | \
NM_IPAC_F_GPRS_CODING_MCS6 | \
NM_IPAC_F_GPRS_CODING_MCS7 | \
NM_IPAC_F_GPRS_CODING_MCS8 | \
NM_IPAC_F_GPRS_CODING_MCS9)
enum gsm_bts_trx_ts_flags {
TS_F_PDCH_ACTIVE = 0x1000,
TS_F_PDCH_ACT_PENDING = 0x2000,
@ -90,7 +131,10 @@ struct gsm_bts_trx_ts {
/* Training Sequence Code (range 0..7) */
uint8_t tsc_oml; /* configured via OML */
uint8_t tsc; /* currently in use */
bool tsc_oml_configured;
uint8_t tsc_rsl; /* configured via RSL (Osmo extension) */
bool tsc_rsl_configured;
uint8_t tsc; /* TSC currently in use. Preference: RSL, OML, BTS-BSIC-OML */
/* Training Sequence Set (range 0..3) */
uint8_t tsc_set;
@ -193,6 +237,8 @@ int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts,
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);
void gsm_ts_apply_configured_tsc(struct gsm_bts_trx_ts *ts);
void gsm_ts_release(struct gsm_bts_trx_ts *ts);
#endif /* _GSM_DATA_H */

View File

@ -4,6 +4,8 @@
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/protocol/gsm_08_58.h>
#define L1SAP_MSGB_HEADROOM 128
/* lchan link ID */
#define LID_SACCH 0x40
#define LID_DEDIC 0x00
@ -96,10 +98,11 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
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_act(struct gsm_bts_trx *trx, uint8_t chan_nr);
int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr);
int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr);
int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr);
int l1sap_uplink_access(struct gsm_lchan *lchan, bool active);
enum l1sap_common_sapi {
L1SAP_COMMON_SAPI_UNKNOWN,
@ -139,9 +142,11 @@ int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg,
#define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h)
void radio_link_timeout_reset(struct gsm_lchan *lchan);
int bts_check_for_first_ciphrd(struct gsm_lchan *lchan,
uint8_t *data, int len);
int is_ccch_for_agch(struct gsm_bts_trx *trx, uint32_t fn);
enum ccch_msgt get_ccch_msgt(struct gsm_bts_trx *trx, uint32_t fn);
#endif /* L1SAP_H */

View File

@ -2,11 +2,13 @@
#include <stdbool.h>
#include <stdint.h>
#include <netinet/in.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/logging.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/codec/codec.h>
#include <osmocom/codec/ecu.h>
#include <osmocom/gsm/lapdm.h>
#include <osmocom/gsm/sysinfo.h>
@ -14,6 +16,7 @@
#include <osmocom/gsm/gsm48_rest_octets.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/meas_rep.h>
#include <osmocom/netif/osmux.h>
#include <osmo-bts/power_control.h>
@ -52,7 +55,7 @@ struct bts_ul_meas {
/* timing advance offset (in 1/256 bits) */
int16_t ta_offs_256bits;
/* C/I ratio in cB */
int16_t c_i;
int16_t ci_cb;
/* flags */
uint8_t is_sub:1;
/* RSSI in dBm * -1 */
@ -67,21 +70,22 @@ struct amr_mode {
struct amr_multirate_conf {
uint8_t gsm48_ie[2];
struct amr_mode ms_mode[4];
struct amr_mode bts_mode[4];
struct amr_mode mode[4];
uint8_t num_modes;
};
enum lchan_csd_mode {
LCHAN_CSD_M_NT,
LCHAN_CSD_M_NT = 0,
LCHAN_CSD_M_T_1200_75,
LCHAN_CSD_M_T_600,
LCHAN_CSD_M_T_1200,
LCHAN_CSD_M_T_2400,
LCHAN_CSD_M_T_4800,
LCHAN_CSD_M_T_9600,
LCHAN_CSD_M_T_14400,
LCHAN_CSD_M_T_29000,
LCHAN_CSD_M_T_32000,
_LCHAN_CSD_M_NUM,
};
/* State of the SAPIs in the lchan */
@ -139,6 +143,8 @@ struct gsm_lchan {
uint8_t nr;
/* The logical channel type */
enum gsm_chan_t type;
/* RSL channel rate and type */
enum rsl_cmod_crt rsl_chan_rt;
/* RSL channel mode */
enum rsl_cmod_spd rsl_cmode;
/* If TCH, traffic channel mode */
@ -163,6 +169,18 @@ struct gsm_lchan {
uint8_t rtp_payload;
uint8_t rtp_payload2;
uint8_t speech_mode;
struct {
bool use;
uint8_t local_cid;
uint8_t remote_cid;
/* Rx Osmux -> RTP, one allocated & owned per lchan */
struct osmux_out_handle *out;
/* Tx RTP -> Osmux, shared by all lchans sharing a
* remote endp (addr+port), see "struct osmux_handle" */
struct osmux_in_handle *in;
/* Used to build rtp messages we send to osmux */
struct osmo_rtp_handle *rtpst;
} osmux;
struct osmo_rtp_socket *rtp_socket;
} abis_ip;
@ -190,7 +208,10 @@ struct gsm_lchan {
uint8_t sapis_dl[23];
uint8_t sapis_ul[23];
struct lapdm_channel lapdm_ch;
/* It is required to have L3 info with DL establishment. */
bool l3_info_estab;
struct llist_head dl_tch_queue;
unsigned int dl_tch_queue_len;
struct {
/* bitmask of all SI that are present/valid in si_buf */
uint32_t valid;
@ -251,9 +272,26 @@ struct gsm_lchan {
/* last UL SPEECH resume flag */
bool is_speech_resume;
} dtx;
struct {
bool last_rtp_input_was_sid;
uint8_t last_sid[GSM_FR_BYTES];
uint8_t last_sid_len;
uint8_t last_sid_age;
/* A SID was transmitted on the DL in the period
* beginning with the last transmitted speech frame
* or the last mandatory-Tx position, whichever was
* more recent. */
bool dl_sid_transmitted;
/* The current frame in the DL is taken up by FACCH */
bool dl_facch_stealing;
} dtx_fr_hr_efr;
uint8_t last_cmr;
uint32_t last_fn;
struct {
/* buffers to re-combine RLP frame from multiple Um blocks */
uint8_t rlp_buf_ul[576/8]; /* maximum size of RLP frame */
uint8_t rlp_buf_dl[576/8]; /* maximum size of RLP frame */
} csd;
} tch;
/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
@ -273,6 +311,19 @@ struct gsm_lchan {
/* counts up to Ny1 */
unsigned int phys_info_count;
} ho;
struct {
bool listener_detected;
uint8_t talker_active;
uint8_t ref;
uint32_t fn;
/* T3115: VGCS UPLINK GRANT retransmission */
struct osmo_timer_list t3115;
/* counts up to Ny2 */
unsigned int vgcs_ul_grant_count;
/* uplink free message */
bool uplink_free;
uint8_t uplink_free_msg[GSM_MACBLOCK_LEN];
} asci;
/* S counter for link loss */
int s;
/* Kind of the release/activation. E.g. RSL or PCU */
@ -355,6 +406,12 @@ int lchan2ecu_codec(const struct gsm_lchan *lchan);
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state);
int lchan_rtp_socket_create(struct gsm_lchan *lchan, const char *bind_ip);
int lchan_rtp_socket_connect(struct gsm_lchan *lchan, const struct in_addr *ia, uint16_t connect_port);
void lchan_rtp_socket_free(struct gsm_lchan *lchan);
void lchan_dl_tch_queue_enqueue(struct gsm_lchan *lchan, struct msgb *msg, unsigned int limit);
static inline bool lchan_is_dcch(const struct gsm_lchan *lchan)
{
switch (lchan->type) {

View File

@ -20,7 +20,8 @@ enum {
DLOOP,
DABIS,
DRTP,
DSUM,
DOSMUX,
DASCI,
};
extern const struct log_info bts_log_info;
@ -37,4 +38,12 @@ extern const struct log_info bts_log_info;
#define DEBUGPFN(ss, fn, fmt, args...) \
LOGP(ss, LOGL_DEBUG, "%s " fmt, gsm_fn_as_gsmtime_str(fn), ## args)
/* LOGP with lchan + frame number prefix */
#define LOGPLCFN(lchan, fn, ss, lvl, fmt, args...) \
LOGP(ss, lvl, "%s %s " fmt, gsm_lchan_name(lchan), gsm_fn_as_gsmtime_str(fn), ## args)
/* LOGP with lchan + gsm_time prefix */
#define LOGPLCGT(lchan, gt, ss, lvl, fmt, args...) \
LOGP(ss, lvl, "%s %s " fmt, gsm_lchan_name(lchan), osmo_dump_gsmtime(gt), ## args)
#endif /* _LOGGING_H */

View File

@ -22,6 +22,9 @@ struct msgb;
/* Access 3rd part of msgb control buffer */
#define rtpmsg_ts(x) ((x)->cb[2])
/* Access 4th part of msgb control buffer */
#define rtpmsg_is_rfc5993_sid(x) ((x)->cb[3])
/**
* Classification of OML message. ETSI for plain GSM 12.21
* messages and IPA/Osmo for manufacturer messages.

View File

@ -1,7 +1,7 @@
/* Header for all NM FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21:
GSM 12.21 Objects' Operational state and availability status behaviour during initialization */
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* All Rights Reserved
@ -14,7 +14,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -30,18 +30,18 @@
/* Common */
enum nm_fsm_events {
NM_EV_SW_ACT,
NM_EV_SETATTR_ACK, /* data: struct nm_fsm_ev_setattr_data */
NM_EV_SETATTR_NACK, /* data: struct nm_fsm_ev_setattr_data */
NM_EV_RX_SETATTR, /* data: struct nm_fsm_ev_setattr_data */
NM_EV_RX_OPSTART,
NM_EV_OPSTART_ACK,
NM_EV_OPSTART_NACK,
NM_EV_SHUTDOWN_START,
NM_EV_SHUTDOWN_FINISH,
NM_EV_OML_UP,
NM_EV_RSL_UP, /* RadioCarrier and BaseBand Transceiver only */
NM_EV_RSL_DOWN, /* RadioCarrier and BaseBand Transceiver only */
NM_EV_PHYLINK_UP, /* RadioCarrier and BaseBand Transceiver only */
NM_EV_PHYLINK_DOWN, /* RadioCarrier and BaseBand Transceiver only */
NM_EV_DISABLE, /* RadioCarrier and BaseBand Transceiver only */
NM_EV_BBTRANSC_INSTALLED, /* Radio Channel only */
NM_EV_BBTRANSC_ENABLED, /* Radio Channel only */
NM_EV_BBTRANSC_DISABLED, /* Radio Channel only */
NM_EV_RCARRIER_ENABLED, /* Radio Channel only */
@ -50,8 +50,7 @@ enum nm_fsm_events {
extern const struct value_string nm_fsm_event_names[];
struct nm_fsm_ev_setattr_data {
struct msgb *msg; /* msgb ownership is transferred to FSM */
int cause;
const struct msgb *msg;
};
@ -95,3 +94,30 @@ enum nm_chan_op_fsm_states {
NM_CHAN_ST_OP_ENABLED,
};
extern struct osmo_fsm nm_chan_fsm;
/* GPRS NSE */
enum nm_gprs_nse_op_fsm_states {
NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED,
NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY,
NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE,
NM_GPRS_NSE_ST_OP_ENABLED,
};
extern struct osmo_fsm nm_gprs_nse_fsm;
/* GPRS NSVC */
enum nm_gprs_nsvc_op_fsm_states {
NM_GPRS_NSVC_ST_OP_DISABLED_NOTINSTALLED,
NM_GPRS_NSVC_ST_OP_DISABLED_DEPENDENCY,
NM_GPRS_NSVC_ST_OP_DISABLED_OFFLINE,
NM_GPRS_NSVC_ST_OP_ENABLED,
};
extern struct osmo_fsm nm_gprs_nsvc_fsm;
/* GPRS CELL */
enum nm_gprs_cell_op_fsm_states {
NM_GPRS_CELL_ST_OP_DISABLED_NOTINSTALLED,
NM_GPRS_CELL_ST_OP_DISABLED_DEPENDENCY,
NM_GPRS_CELL_ST_OP_DISABLED_OFFLINE,
NM_GPRS_CELL_ST_OP_ENABLED,
};
extern struct osmo_fsm nm_gprs_cell_fsm;

View File

@ -0,0 +1,61 @@
/* Maintain and generate ASCI notifications */
/*
* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
*
* Author: Harald Welte
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/* one [concurrent] ASCI (VBS/VGCS) notification */
struct asci_notification {
struct llist_head list; /* linked to bts->asci.notifications */
/* Group call reference (TS 24.008 10.5.1.9 "Descriptive group or broadcast call reference") */
uint8_t group_call_ref[5];
/* Group Channel Description (TS 44.018 10.5.2.14b) */
struct {
bool present;
uint8_t value[255];
uint8_t len;
} chan_desc;
/* NCH DRX Information (TS 48.058 9.3.47) */
struct {
bool present;
struct rsl_ie_nch_drx_info value;
} nch_drx_info;
};
int bts_asci_notification_add(struct gsm_bts *bts, const uint8_t *group_call_ref, const uint8_t *chan_desc,
uint8_t chan_desc_len, const struct rsl_ie_nch_drx_info *nch_drx_info);
int bts_asci_notification_del(struct gsm_bts *bts, const uint8_t *group_call_ref);
int bts_asci_notification_reset(struct gsm_bts *bts);
const struct asci_notification *bts_asci_notification_get_next(struct gsm_bts *bts);
void append_group_call_information(struct bitvec *bv, const uint8_t *gcr, const uint8_t *ch_desc, uint8_t ch_desc_len);
int bts_asci_notify_nch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf);
int bts_asci_notify_facch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf, const uint8_t *group_call_ref,
const uint8_t *chan_desc, uint8_t chan_desc_len);

View File

@ -63,11 +63,12 @@ int oml_tx_state_changed(const struct gsm_abis_mo *mo);
int oml_mo_tx_sw_act_rep(const struct gsm_abis_mo *mo);
int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause);
int oml_fom_ack_nack_copy_msg(const struct msgb *old_msg, uint8_t cause);
int oml_mo_fom_ack_nack(const struct gsm_abis_mo *mo, uint8_t orig_msg_type,
uint8_t cause);
extern const unsigned int oml_default_t200_ms[7];
extern const uint32_t oml_default_t200_fn[7];
/* Transmit failure event report */
int oml_tx_failure_event_rep(const struct gsm_abis_mo *mo, enum abis_nm_severity severity,
@ -77,11 +78,11 @@ void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3);
struct gsm_abis_mo *gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
const struct abis_om_obj_inst *obj_inst);
const struct abis_om_obj_inst *obj_inst,
enum abis_nm_nack_cause *c);
struct gsm_nm_state *gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
const struct abis_om_obj_inst *obj_inst);
void *gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
const struct abis_om_obj_inst *obj_inst);
const struct abis_om_obj_inst *obj_inst,
enum abis_nm_nack_cause *c);
#endif // _OML_H */

48
include/osmo-bts/osmux.h Normal file
View File

@ -0,0 +1,48 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <osmocom/core/select.h>
#include <osmocom/netif/osmux.h>
struct gsm_bts;
struct gsm_lchan;
enum osmux_usage {
OSMUX_USAGE_OFF = 0,
OSMUX_USAGE_ON = 1,
OSMUX_USAGE_ONLY = 2,
};
struct osmux_state {
enum osmux_usage use;
char *local_addr;
uint16_t local_port;
struct osmo_fd fd;
uint8_t batch_factor;
unsigned int batch_size;
bool dummy_padding;
struct llist_head osmux_handle_list;
};
/* Contains a "struct osmux_in_handle" towards a specific peer (remote IPaddr+port) */
struct osmux_handle {
struct llist_head head;
struct gsm_bts *bts;
struct osmux_in_handle *in;
struct osmo_sockaddr rem_addr;
int refcnt;
};
int bts_osmux_init(struct gsm_bts *bts);
void bts_osmux_release(struct gsm_bts *bts);
int bts_osmux_open(struct gsm_bts *bts);
int lchan_osmux_init(struct gsm_lchan *lchan, uint8_t rtp_payload);
void lchan_osmux_release(struct gsm_lchan *lchan);
int lchan_osmux_connect(struct gsm_lchan *lchan);
bool lchan_osmux_connected(const struct gsm_lchan *lchan);
int lchan_osmux_send_frame(struct gsm_lchan *lchan, const uint8_t *payload,
unsigned int payload_len, unsigned int duration, bool marker);
int lchan_osmux_skipped_frame(struct gsm_lchan *lchan, unsigned int duration);

View File

@ -7,6 +7,55 @@
struct paging_state;
struct gsm_bts;
struct asci_notification;
/* abstract representation of P1 rest octets; we only implement those parts we need for now */
struct p1_rest_octets {
struct {
bool present;
uint8_t nln;
uint8_t nln_status;
} nln_pch;
bool packet_page_ind[2];
bool r8_present;
struct {
bool prio_ul_access;
bool etws_present;
struct {
bool is_first;
uint8_t page_nr;
const uint8_t *page;
size_t page_bytes;
} etws;
} r8;
};
/* abstract representation of P2 rest octets; we only implement those parts we need for now */
struct p2_rest_octets {
struct {
bool present;
uint8_t cn3;
} cneed;
struct {
bool present;
uint8_t nln;
uint8_t nln_status;
} nln_pch;
};
/* abstract representation of P3 rest octets; we only implement those parts we need for now */
struct p3_rest_octets {
struct {
bool present;
uint8_t cn3;
uint8_t cn4;
} cneed;
struct {
bool present;
uint8_t nln;
uint8_t nln_status;
} nln_pch;
};
/* initialize paging code */
struct paging_state *paging_init(struct gsm_bts *bts,
@ -35,9 +84,15 @@ int paging_si_update(struct paging_state *ps, struct gsm48_control_channel_descr
int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
const uint8_t *identity_lv, uint8_t chan_needed);
/* Add an IMM.ASS message to the paging queue */
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
uint8_t len, bool from_pcu);
/* Add a ready formatted MAC block message to the paging queue, this can be an IMMEDIATE ASSIGNMENT, or a
* PAGING COMMAND (from the PCU) */
int paging_add_macblock(struct paging_state *ps, uint32_t msg_id, const char *imsi, bool confirm, const uint8_t *macblock);
/* Paging rest octests */
void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro,
const struct asci_notification *notif);
void append_p2_rest_octets(struct bitvec *bv, const struct p2_rest_octets *p2ro);
void append_p3_rest_octets(struct bitvec *bv, const struct p3_rest_octets *p3ro);
/* generate paging message for given gsm time */
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,

View File

@ -3,9 +3,11 @@
#include <osmo-bts/pcuif_proto.h>
struct gsm_bts_sm;
extern int pcu_direct;
#define PCUIF_HDR_SIZE ( sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u) )
#define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u))
int pcu_tx_info_ind(void);
int pcu_tx_si(const struct gsm_bts *bts, enum osmo_sysinfo_type si_type, bool enable);
@ -21,11 +23,11 @@ int pcu_tx_rach_ind(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
int pcu_tx_time_ind(uint32_t fn);
int pcu_tx_interf_ind(const struct gsm_bts_trx *trx, uint32_t fn);
int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed);
int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len);
int pcu_tx_data_cnf(uint32_t msg_id, uint8_t sapi);
int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id, uint8_t cause);
int pcu_sock_send(struct gsm_network *net, struct msgb *msg);
int pcu_sock_send(struct msgb *msg);
int pcu_sock_init(const char *path);
int pcu_sock_init(const char *path, int qlength_max);
void pcu_sock_exit(void);
bool pcu_connected(void);

View File

@ -3,20 +3,20 @@
#include <osmocom/gsm/l1sap.h>
#include <arpa/inet.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
#define PCU_IF_VERSION 0x0a
#define PCU_IF_VERSION 0x0c
#define TXT_MAX_LEN 128
/* msg_type */
#define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */
#define PCU_IF_MSG_DATA_CNF 0x01 /* confirm (e.g. transmission on PCH) */
#define PCU_IF_MSG_DATA_IND 0x02 /* receive data from given channel */
#define PCU_IF_MSG_SUSP_REQ 0x03 /* BTS forwards GPRS SUSP REQ to PCU */
#define PCU_IF_MSG_APP_INFO_REQ 0x04 /* BTS asks PCU to transmit APP INFO via PACCH */
#define PCU_IF_MSG_RTS_REQ 0x10 /* ready to send request */
#define PCU_IF_MSG_DATA_CNF_DT 0x11 /* confirm (with direct tlli) */
#define PCU_IF_MSG_DATA_CNF_2 0x11 /* confirm (using message id) */
#define PCU_IF_MSG_RACH_IND 0x22 /* receive RACH */
#define PCU_IF_MSG_INFO_IND 0x32 /* retrieve BTS info */
#define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */
@ -28,17 +28,16 @@
/* sapi */
#define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */
#define PCU_IF_SAPI_AGCH 0x02 /* assignment on AGCH */
#define PCU_IF_SAPI_PCH 0x03 /* paging/assignment on PCH */
#define PCU_IF_SAPI_BCCH 0x04 /* SI on BCCH */
#define PCU_IF_SAPI_PDTCH 0x05 /* packet data/control/ccch block */
#define PCU_IF_SAPI_PRACH 0x06 /* packet random access channel */
#define PCU_IF_SAPI_PTCCH 0x07 /* packet TA control channel */
#define PCU_IF_SAPI_AGCH_DT 0x08 /* assignment on AGCH but with additional TLLI */
#define PCU_IF_SAPI_PCH_2 0x08 /* assignment on PCH (confirmed using message id) */
#define PCU_IF_SAPI_AGCH_2 0x09 /* assignment on AGCH (confirmed using message id) */
/* flags */
#define PCU_IF_FLAG_ACTIVE (1 << 0)/* BTS is active */
#define PCU_IF_FLAG_SYSMO (1 << 1)/* access PDCH of sysmoBTS directly */
#define PCU_IF_FLAG_DIRECT_PHY (1 << 1)/* access PHY directly via dedicated hardware support */
#define PCU_IF_FLAG_CS1 (1 << 16)
#define PCU_IF_FLAG_CS2 (1 << 17)
#define PCU_IF_FLAG_CS3 (1 << 18)
@ -58,6 +57,20 @@
#define PCU_IF_ADDR_TYPE_IPV4 0x04 /* IPv4 address */
#define PCU_IF_ADDR_TYPE_IPV6 0x29 /* IPv6 address */
/* BTS model */
enum gsm_pcuif_bts_model {
PCU_IF_BTS_MODEL_UNSPEC,
PCU_IF_BTS_MODEL_LC15,
PCU_IF_BTS_MODEL_OC2G,
PCU_IF_BTS_MODEL_OCTPHY,
PCU_IF_BTS_MODEL_SYSMO,
PCU_IF_BTS_MODEL_TRX,
PCU_IF_BTS_MODEL_RBS,
};
#define PCU_IF_NUM_NSVC 2
#define PCU_IF_NUM_TRX 8
enum gsm_pcu_if_text_type {
PCU_VERSION,
PCU_OML_ALERT,
@ -83,19 +96,10 @@ struct gsm_pcu_if_data {
int16_t lqual_cb; /* !< \brief Link quality in centiBel */
} __attribute__ ((packed));
/* data confirmation with direct tlli (instead of raw mac block with tlli) */
struct gsm_pcu_if_data_cnf_dt {
/* data confirmation with message id (instead of raw mac block) */
struct gsm_pcu_if_data_cnf {
uint8_t sapi;
uint32_t tlli;
uint32_t fn;
uint16_t arfcn;
uint8_t trx_nr;
uint8_t ts_nr;
uint8_t block_nr;
int8_t rssi;
uint16_t ber10k; /* !< \brief BER in units of 0.01% */
int16_t ta_offs_qbits; /* !< \brief Burst TA Offset in quarter bits */
int16_t lqual_cb; /* !< \brief Link quality in centiBel */
uint32_t msg_id;
} __attribute__ ((packed));
struct gsm_pcu_if_rts_req {
@ -140,7 +144,7 @@ struct gsm_pcu_if_info_trx {
struct gsm_pcu_if_info_ind {
uint32_t version;
uint32_t flags;
struct gsm_pcu_if_info_trx trx[8]; /* TRX infos per BTS */
struct gsm_pcu_if_info_trx trx[PCU_IF_NUM_TRX]; /* TRX infos per BTS */
uint8_t bsic;
/* RAI */
uint16_t mcc, mnc;
@ -169,14 +173,15 @@ struct gsm_pcu_if_info_ind {
uint8_t initial_cs;
uint8_t initial_mcs;
/* NSVC */
uint16_t nsvci[2];
uint16_t local_port[2];
uint16_t remote_port[2];
uint8_t address_type[2];
uint16_t nsvci[PCU_IF_NUM_NSVC];
uint16_t local_port[PCU_IF_NUM_NSVC];
uint16_t remote_port[PCU_IF_NUM_NSVC];
uint8_t address_type[PCU_IF_NUM_NSVC];
union {
struct in_addr v4;
struct in6_addr v6;
} remote_ip[2];
} remote_ip[PCU_IF_NUM_NSVC];
uint8_t bts_model; /* enum gsm_pcuif_bts_model */
} __attribute__ ((packed));
struct gsm_pcu_if_act_req {
@ -226,6 +231,32 @@ struct gsm_pcu_if_container {
uint8_t data[0];
} __attribute__ ((packed));
/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via PCH. The struct is sent as a data request
* (data_req) under SAPI PCU_IF_SAPI_PCH_2. */
struct gsm_pcu_if_pch {
/* message id as reference for confirmation */
uint32_t msg_id;
/* IMSI (to derive paging group) */
char imsi[OSMO_IMSI_BUF_SIZE];
/* GSM mac-block (with immediate assignment message) */
uint8_t data[GSM_MACBLOCK_LEN];
/* Set to true in case the receiving end must send a confirmation
* when the MAC block (data) has been sent. */
bool confirm;
} __attribute__((packed));
/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via AGCH. The struct is sent as a data request
* (data_req) under SAPI PCU_IF_SAPI_AGCH_2. */
struct gsm_pcu_if_agch {
/* message id as reference for confirmation */
uint32_t msg_id;
/* GSM mac-block (with immediate assignment message) */
uint8_t data[GSM_MACBLOCK_LEN];
/* Set to true in case the receiving end must send a confirmation
* when the MAC block (data) has been sent. */
bool confirm;
} __attribute__((packed));
struct gsm_pcu_if {
/* context based information */
uint8_t msg_type; /* message type */
@ -234,8 +265,7 @@ struct gsm_pcu_if {
union {
struct gsm_pcu_if_data data_req;
struct gsm_pcu_if_data data_cnf;
struct gsm_pcu_if_data_cnf_dt data_cnf_dt;
struct gsm_pcu_if_data_cnf data_cnf2;
struct gsm_pcu_if_data data_ind;
struct gsm_pcu_if_susp_req susp_req;
struct gsm_pcu_if_rts_req rts_req;

View File

@ -4,7 +4,8 @@
#define LCHAN_FN_DUMMY 0xFFFFFFFF
#define LCHAN_FN_WAIT 0xFFFFFFFE
int msgb_queue_flush(struct llist_head *list);
bool rsl_chan_rt_is_asci(enum rsl_cmod_crt chan_rt);
bool rsl_chan_rt_is_vgcs(enum rsl_cmod_crt chan_rt);
int down_rsl(struct gsm_bts_trx *trx, struct msgb *msg);
int rsl_tx_rf_res(struct gsm_bts_trx *trx);
@ -16,6 +17,8 @@ int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause);
int rsl_tx_conn_fail(const struct gsm_lchan *lchan, uint8_t cause);
int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan);
int rsl_tx_hando_det(struct gsm_lchan *lchan, uint8_t *ho_delay);
int rsl_tx_listener_det(struct gsm_lchan *lchan, uint8_t *acc_delay);
int rsl_tx_talker_det(struct gsm_lchan *lchan, uint8_t *acc_delay);
/* call-back for LAPDm code, called when it wants to send msgs UP */
int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx);
@ -32,6 +35,6 @@ void ipacc_dyn_pdch_complete(struct gsm_bts_trx_ts *ts, int rc);
int rsl_tx_cbch_load_indication(struct gsm_bts *bts, bool ext_cbch, bool overflow, uint8_t amount);
int rsl_tx_meas_res(struct gsm_lchan *lchan, const uint8_t *l3, int l3_len, int timing_offset);
int rsl_tx_meas_res(struct gsm_lchan *lchan, const uint8_t *l3, unsigned int l3_len, int timing_offset);
#endif // _RSL_H */

View File

@ -0,0 +1,20 @@
/*
* RTP input validation function: makes the accept-or-drop decision,
* and for some codecs signals additional required actions such as
* dropping one header octet.
*/
#pragma once
#include <stdint.h>
#include <osmo-bts/lchan.h>
enum pl_input_decision {
PL_DECISION_DROP,
PL_DECISION_ACCEPT,
PL_DECISION_STRIP_HDR_OCTET,
};
enum pl_input_decision
rtp_payload_input_preen(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
unsigned rtp_pl_len, bool *rfc5993_sid_flag);

View File

@ -5,13 +5,6 @@
#include <osmo-bts/gsm_data.h>
/* Whether a logical channel must be activated automatically */
#define TRX_CHAN_FLAG_AUTO_ACTIVE (1 << 0)
/* FIXME: we should actually activate 'auto-active' channels */
#define TRX_CHAN_IS_ACTIVE(state, chan) \
(trx_chan_desc[chan].flags & TRX_CHAN_FLAG_AUTO_ACTIVE || (state)->active)
#define TRX_GMSK_NB_TSC(br) \
_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
@ -80,6 +73,7 @@ enum trx_mod_type {
/* A set of measurements belonging to one Uplink burst */
struct l1sched_meas_set {
uint32_t fn; /* TDMA frame number */
int16_t toa256; /* Timing of Arrival (1/256 of a symbol) */
int16_t ci_cb; /* Carrier-to-Interference (cB) */
float rssi; /* RSSI (dBm) */
@ -96,13 +90,12 @@ struct l1sched_chan_state {
bool active; /* Channel is active */
ubit_t *dl_bursts; /* burst buffer for TX */
enum trx_mod_type dl_mod_type; /* Downlink modulation type */
uint8_t dl_mask; /* mask of transmitted bursts */
sbit_t *ul_bursts; /* burst buffer for RX */
sbit_t *ul_bursts_prev;/* previous burst buffer for RX (repeated SACCH) */
uint32_t ul_first_fn; /* fn of first burst */
uint8_t ul_mask; /* mask of received bursts */
uint32_t ul_mask; /* mask of received bursts */
/* loss detection */
uint8_t lost_frames; /* how many L2 frames were lost */
uint32_t last_tdma_fn; /* last processed TDMA frame number */
uint32_t proc_tdma_fs; /* how many TDMA frames were processed */
uint32_t lost_tdma_fs; /* how many TDMA frames were lost */
@ -113,20 +106,17 @@ struct l1sched_chan_state {
/* 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 */
int lqual_cb_sum; /* sum of link quality samples (in cB) */
int lqual_cb_num; /* number of link quality samples */
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 */
uint8_t amr_last_dtx; /* last received dtx frame type */
/* TCH/H */
uint8_t dl_ongoing_facch; /* FACCH/H on downlink */
uint8_t ul_ongoing_facch; /* FACCH/H on uplink */
struct l1sched_meas_set meas_avg_facch; /* measurement results for last FACCH */
uint16_t ber10k_facch; /* bit error rate for last FACCH */
uint8_t dl_facch_bursts; /* number of remaining DL FACCH bursts */
@ -141,7 +131,7 @@ struct l1sched_chan_state {
/* Uplink measurements */
struct {
/* Active channel measurements (simple ring buffer) */
struct l1sched_meas_set buf[8]; /* up to 8 entries */
struct l1sched_meas_set buf[24]; /* up to 24 (BUFMAX) entries */
unsigned int current; /* current position */
/* Interference measurements */
@ -195,6 +185,12 @@ int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pch
/*! \brief set all matching logical channels active/inactive */
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active);
/*! \brief set uplink access on given logical channels active/inactive */
int trx_sched_set_ul_access(struct gsm_lchan *lchan, uint8_t chan_nr, bool active);
/*! \brief set all logical channels of BCCH/CCCH active/inactive */
int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool active);
/*! \brief set mode of all matching logical channels to given mode(s) */
int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
@ -233,7 +229,7 @@ struct trx_sched_multiframe {
int find_sched_mframe_idx(enum gsm_phys_chan_config pchan, uint8_t tn);
/*! Determine if given frame number contains SACCH (true) or other (false) burst */
bool trx_sched_is_sacch_fn(struct gsm_bts_trx_ts *ts, uint32_t fn, bool uplink);
bool trx_sched_is_sacch_fn(const struct gsm_bts_trx_ts *ts, uint32_t fn, bool uplink);
extern const struct trx_sched_multiframe trx_sched_multiframes[];
#define TRX_BI_F_NOPE_IND (1 << 0)
@ -243,6 +239,7 @@ extern const struct trx_sched_multiframe trx_sched_multiframes[];
#define TRX_BI_F_TRX_NUM (1 << 4)
#define TRX_BI_F_BATCH_IND (1 << 5)
#define TRX_BI_F_SHADOW_IND (1 << 6)
#define TRX_BI_F_ACCESS_BURST (1 << 7)
/*! UL burst indication with the corresponding meta info */
struct trx_ul_burst_ind {
@ -306,18 +303,24 @@ int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi);
/* Averaging mode for trx_sched_meas_avg() */
enum sched_meas_avg_mode {
/* last 4 bursts (default for xCCH, TCH/H, PTCCH and PDTCH) */
SCHED_MEAS_AVG_M_QUAD,
/* first 22 of last 24 bursts (for TCH/F14.4, TCH/F9.6, TCH/F4.8) */
SCHED_MEAS_AVG_M_S24N22,
/* last 22 bursts (for TCH/H4.8, TCH/H2.4) */
SCHED_MEAS_AVG_M_S22N22,
/* last 4 bursts (default for xCCH, PTCCH and PDTCH) */
SCHED_MEAS_AVG_M_S4N4,
/* last 8 bursts (default for TCH/F and FACCH/F) */
SCHED_MEAS_AVG_M_OCTO,
SCHED_MEAS_AVG_M_S8N8,
/* first 4 of last 6 bursts (default for TCH/H) */
SCHED_MEAS_AVG_M_S6N4,
/* last 6 bursts (default for FACCH/H) */
SCHED_MEAS_AVG_M_SIX,
SCHED_MEAS_AVG_M_S6N6,
/* first 4 of last 8 bursts */
SCHED_MEAS_AVG_M8_FIRST_QUAD,
SCHED_MEAS_AVG_M_S8N4,
/* first 2 of last 6 bursts */
SCHED_MEAS_AVG_M6_FIRST_TWO,
SCHED_MEAS_AVG_M_S6N2,
/* middle 2 of last 6 bursts */
SCHED_MEAS_AVG_M6_MIDDLE_TWO,
SCHED_MEAS_AVG_M_S4N2,
};
void trx_sched_meas_push(struct l1sched_chan_state *chan_state,
@ -325,3 +328,5 @@ void trx_sched_meas_push(struct l1sched_chan_state *chan_state,
void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state,
struct l1sched_meas_set *avg,
enum sched_meas_avg_mode mode);
uint32_t trx_sched_lookup_fn(const struct l1sched_chan_state *chan_state,
const unsigned int shift);

View File

@ -42,16 +42,18 @@ extern const ubit_t _sched_train_seq_gmsk_sb[64];
struct msgb *_sched_dequeue_prim(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);
int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn,
enum trx_chan_type chan, uint8_t *l2,
uint8_t l2_len, float rssi,
enum trx_chan_type chan,
const uint8_t *data, size_t data_len,
uint16_t ber10k, float rssi,
int16_t ta_offs_256bits, int16_t link_qual_cb,
uint16_t ber10k,
enum osmo_ph_pres_info_type presence_info);
int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn,
enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len,
int16_t ta_offs_256bits, uint16_t ber10k, float rssi,
int16_t link_qual_cb, uint8_t is_sub);
enum trx_chan_type chan,
const uint8_t *data, size_t data_len,
uint16_t ber10k, float rssi,
int16_t ta_offs_256bits, int16_t link_qual_cb,
uint8_t is_sub);
int tx_fcch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
int tx_sch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);

View File

@ -77,7 +77,12 @@ int get_p_trxout_target_mdBm_lchan(const struct gsm_lchan *lchan);
int get_p_trxout_actual_mdBm(const struct gsm_bts_trx *trx, uint8_t bs_power_red);
int get_p_trxout_actual_mdBm_lchan(const struct gsm_lchan *lchan);
int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass, ramp_compl_cb_t ramp_compl_cb);
int _power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass_max_power, ramp_compl_cb_t ramp_compl_cb, bool skip_ramping);
#define power_ramp_start(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb) \
_power_ramp_start(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb, false)
#define power_ramp_force(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb) \
_power_ramp_start(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb, true)
void power_ramp_abort(struct gsm_bts_trx *trx);
void power_trx_change_compl(struct gsm_bts_trx *trx, int p_trxout_cur_mdBm);

View File

@ -12,6 +12,7 @@ enum bts_vty_node {
PHY_INST_NODE,
BTS_NODE,
TRX_NODE,
OSMUX_NODE,
};
extern struct cmd_element cfg_bts_auto_band_cmd;
@ -20,12 +21,9 @@ extern struct cmd_element cfg_bts_no_auto_band_cmd;
struct phy_instance *vty_get_phy_instance(struct vty *vty, int phy_nr, int inst_nr);
int bts_vty_go_parent(struct vty *vty);
int bts_vty_is_config_node(struct vty *vty, int node);
int bts_vty_init(void *ctx);
struct gsm_network *gsmnet_from_vty(struct vty *v);
extern struct vty_app_info bts_vty_info;
extern struct gsm_bts *g_bts;

View File

@ -9,12 +9,14 @@ AM_CFLAGS = \
$(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMOCODEC_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOTRAU_LIBS) \
$(LIBOSMOCODEC_LIBS) \
$(LIBOSMONETIF_LIBS) \
$(NULL)
if ENABLE_LC15BTS
@ -29,13 +31,17 @@ libbts_a_SOURCES = \
abis.c \
abis_osmo.c \
oml.c \
osmux.c \
bts.c \
bts_sm.c \
bts_trx.c \
rsl.c \
rtp_input_preen.c \
vty.c \
paging.c \
measurement.c \
amr.c \
asci.c \
lchan.c \
load_indication.c \
pcu_sock.c \
@ -45,6 +51,7 @@ libbts_a_SOURCES = \
bts_ctrl_commands.c \
bts_ctrl_lookup.c \
bts_shutdown_fsm.c \
csd_v110.c \
l1sap.c \
cbch.c \
power_control.c \
@ -58,7 +65,11 @@ libbts_a_SOURCES = \
nm_bts_fsm.c \
nm_bb_transc_fsm.c \
nm_channel_fsm.c \
nm_gprs_cell_fsm.c \
nm_gprs_nse_fsm.c \
nm_gprs_nsvc_fsm.c \
nm_radio_carrier_fsm.c \
notification.c \
probes.d \
$(NULL)

View File

@ -13,7 +13,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -225,11 +225,19 @@ static void abis_link_connected(struct osmo_fsm_inst *fi, uint32_t event, void *
/* Then iterate over the RSL signalling links */
llist_for_each_entry(trx, &bts->trx_list, list) {
if (trx->rsl_link) {
e1inp_sign_link_destroy(trx->rsl_link);
trx->rsl_link = NULL;
if (trx->bb_transc.rsl.link) {
e1inp_sign_link_destroy(trx->bb_transc.rsl.link);
trx->bb_transc.rsl.link = NULL;
if (trx == trx->bts->c0)
load_timer_stop(trx->bts);
} else {
/* If we have no rsl_link yet it may mean that lower
* layers are still establishing the socket (TCP, IPA).
* Let's tell it to stop connection establishment since
* we are shutting down. */
struct e1inp_line *line = e1inp_line_find(0);
if (line)
e1inp_ipa_bts_rsl_close_n(line, trx->nr);
}
/* Note: Here we could send NM_EV_RSL_DOWN to each
* trx->(bb_transc.)mo.fi, but we are starting shutdown of the
@ -356,7 +364,7 @@ int abis_bts_rsl_sendmsg(struct msgb *msg)
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
* the signalling link at msg->dst */
msg->dst = msg->trx->rsl_link;
msg->dst = msg->trx->bb_transc.rsl.link;
return abis_sendmsg(msg);
}
@ -396,10 +404,10 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
break;
}
e1inp_ts_config_sign(sign_ts, line);
trx->rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
trx, trx->rsl_tei, 0);
trx->bb_transc.rsl.link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
trx, trx->bb_transc.rsl.tei, 0);
trx_link_estab(trx);
return trx->rsl_link;
return trx->bb_transc.rsl.link;
}
return NULL;
}

View File

@ -1,6 +1,6 @@
/* OSMO extenion link associated to same line as oml_link: */
/* (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* All Rights Reserved
@ -13,7 +13,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -30,8 +30,7 @@
#include <osmo-bts/logging.h>
#include <osmo-bts/pcu_if.h>
#include <osmo-bts/pcuif_proto.h>
extern struct gsm_network bts_gsmnet;
#include <osmo-bts/bts_sm.h>
#define OM_HEADROOM_SIZE 128
@ -106,7 +105,7 @@ static int rx_down_osmo_pcu(struct gsm_bts *bts, struct msgb *msg)
/* Trim Abis lower layers: */
msgb_pull_to_l2(msg);
/* we simply forward it to PCUIF: */
return pcu_sock_send(&bts_gsmnet, msg);
return pcu_sock_send(msg);
}
/* incoming IPA/OSMO extension Abis message from BSC */

View File

@ -6,6 +6,85 @@
#include <osmo-bts/logging.h>
#include <osmo-bts/amr.h>
/* Reasonable defaults for AMR-FR and AMR-HR rate configuration.
* The values are taken from 3GPP TS 51.010-1 (version 13.11.0).
* See 14.2.19.4.1 and 14.2.20.4.1 for AMR-FR and AMR-HR, respectively.
*
* ^ C/I (dB) | FR / HR |
* | |
* | |
* MODE4 | |
* = | ----+---- THR_MX_Up(3) | 20.5 / 18.0 |
* | | |
* | = ----+---- THR_MX_Dn(4) | 18.5 / 16.0 |
* MODE3 | |
* | = ----+---- THR_MX_Up(2) | 14.5 / 14.0 |
* | | |
* = | ----+---- THR_MX_Dn(3) | 12.5 / 12.0 |
* MODE2 | |
* = | ----+---- THR_MX_Up(1) | 8.5 / 10.0 |
* | | |
* | = ----+---- THR_MX_Dn(2) | 6.5 / 8.0 |
* MODE1 | |
* | |
* | |
*/
static const struct gsm48_multi_rate_conf amr_fr_mr_cfg_def = {
.m4_75 = 1,
.m5_90 = 1,
.m7_95 = 1,
.m12_2 = 1,
};
static const struct amr_mode amr_fr_bts_mode_def[] = {
{
.mode = 0, /* 4.75k */
.threshold = 13, /* THR_MX_Dn(2): 6.5 dB */
.hysteresis = 4, /* THR_MX_Up(1): 8.5 dB */
},
{
.mode = 2, /* 5.90k */
.threshold = 25, /* THR_MX_Dn(3): 12.5 dB */
.hysteresis = 4, /* THR_MX_Up(2): 14.5 dB */
},
{
.mode = 5, /* 7.95k */
.threshold = 37, /* THR_MX_Dn(4): 18.5 dB */
.hysteresis = 4, /* THR_MX_Up(3): 20.5 dB */
},
{
.mode = 7, /* 12.2k */
/* this is the last mode, so no threshold */
},
};
static const struct gsm48_multi_rate_conf amr_hr_mr_cfg_def = {
.m4_75 = 1,
.m5_90 = 1,
.m6_70 = 1,
.m7_95 = 1,
};
static const struct amr_mode amr_hr_bts_mode_def[] = {
{
.mode = 0, /* 4.75k */
.threshold = 16, /* THR_MX_Dn(2): 8.0 dB */
.hysteresis = 4, /* THR_MX_Up(1): 10.0 dB */
},
{
.mode = 2, /* 5.90k */
.threshold = 24, /* THR_MX_Dn(3): 12.0 dB */
.hysteresis = 4, /* THR_MX_Up(2): 14.0 dB */
},
{
.mode = 3, /* 6.70k */
.threshold = 32, /* THR_MX_Dn(4): 16.0 dB */
.hysteresis = 4, /* THR_MX_Up(3): 18.0 dB */
},
{
.mode = 5, /* 7.95k */
/* this is the last mode, so no threshold */
},
};
void amr_log_mr_conf(int ss, int logl, const char *pfx,
struct amr_multirate_conf *amr_mrc)
{
@ -16,9 +95,9 @@ void amr_log_mr_conf(int ss, int logl, const char *pfx,
for (i = 0; i < amr_mrc->num_modes; i++)
LOGPC(ss, logl, ", mode[%u] = %u/%u/%u",
i, amr_mrc->bts_mode[i].mode,
amr_mrc->bts_mode[i].threshold,
amr_mrc->bts_mode[i].hysteresis);
i, amr_mrc->mode[i].mode,
amr_mrc->mode[i].threshold,
amr_mrc->mode[i].hysteresis);
LOGPC(ss, logl, "\n");
}
@ -27,7 +106,7 @@ static inline int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc,
{
unsigned int i;
for (i = 0; i < amr_mrc->num_modes; i++) {
if (amr_mrc->bts_mode[i].mode == cmi)
if (amr_mrc->mode[i].mode == cmi)
return i;
}
return -EINVAL;
@ -117,23 +196,26 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
for (i = 0; i < 8; i++) {
if (mr_conf[1] & (1 << i)) {
amr_mrc->bts_mode[j++].mode = i;
amr_mrc->mode[j++].mode = i;
}
}
/* skip the first two octets of the IE */
mr_conf += 2;
if (num_codecs >= 2) {
amr_mrc->bts_mode[0].threshold = mr_conf[1] & 0x3F;
amr_mrc->bts_mode[0].hysteresis = mr_conf[2] >> 4;
amr_mrc->mode[0].threshold = mr_conf[0] & 0x3F;
amr_mrc->mode[0].hysteresis = mr_conf[1] >> 4;
}
if (num_codecs >= 3) {
amr_mrc->bts_mode[1].threshold =
((mr_conf[2] & 0xF) << 2) | (mr_conf[3] >> 6);
amr_mrc->bts_mode[1].hysteresis = (mr_conf[3] >> 2) & 0xF;
amr_mrc->mode[1].threshold =
((mr_conf[1] & 0xF) << 2) | (mr_conf[2] >> 6);
amr_mrc->mode[1].hysteresis = (mr_conf[2] >> 2) & 0xF;
}
if (num_codecs >= 4) {
amr_mrc->bts_mode[2].threshold =
((mr_conf[3] & 0x3) << 4) | (mr_conf[4] >> 4);
amr_mrc->bts_mode[2].hysteresis = mr_conf[4] & 0xF;
amr_mrc->mode[2].threshold =
((mr_conf[2] & 0x3) << 4) | (mr_conf[3] >> 4);
amr_mrc->mode[2].hysteresis = mr_conf[3] & 0xF;
}
return num_codecs;
@ -171,3 +253,26 @@ unsigned int amr_get_initial_mode(struct gsm_lchan *lchan)
}
}
}
void amr_init_mr_conf_def(struct gsm_lchan *lchan)
{
const struct gsm48_multi_rate_conf *mr_cfg;
const struct amr_mode *bts_mode;
unsigned int num_modes;
if (lchan->type == GSM_LCHAN_TCH_F) {
num_modes = ARRAY_SIZE(amr_fr_bts_mode_def);
bts_mode = &amr_fr_bts_mode_def[0];
mr_cfg = &amr_fr_mr_cfg_def;
} else {
num_modes = ARRAY_SIZE(amr_hr_bts_mode_def);
bts_mode = &amr_hr_bts_mode_def[0];
mr_cfg = &amr_hr_mr_cfg_def;
}
memcpy(lchan->tch.amr_mr.gsm48_ie, mr_cfg,
sizeof(lchan->tch.amr_mr.gsm48_ie));
memcpy(&lchan->tch.amr_mr.mode[0], &bts_mode[0],
sizeof(lchan->tch.amr_mr.mode));
lchan->tch.amr_mr.num_modes = num_modes;
}

211
src/common/asci.c Normal file
View File

@ -0,0 +1,211 @@
/* ASCI (VGCS/VBS) related common code */
/* (C) 2023 by Harald Welte <laforge@osmocom.org>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/rsl.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/rsl.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/l1sap.h>
#include <osmo-bts/asci.h>
static int tx_vgcs_ul_grant(struct gsm_lchan *lchan)
{
struct gsm0408_vgcs_ul_grant ul_grant;
struct gsm_time gt;
struct msgb *msg;
gsm_fn2gsmtime(&gt, lchan->asci.fn);
/* build the RR VGCS UPLINK GRANT message as per TS 44.018 Section 9.1.49 */
ul_grant = (struct gsm0408_vgcs_ul_grant) {
.hdr = {
.proto_discr = GSM48_PDISC_RR,
.msg_type = GSM48_MT_RR_VGCS_UPL_GRANT,
},
.req_ref = {
.ra = lchan->asci.ref,
.t1 = gt.t1,
.t2 = gt.t2,
.t3_low = gt.t3 & 7,
.t3_high = gt.t3 >> 3,
},
.ta = lchan->ta_ctrl.current,
};
/* Wrap it in a RSL UNITDATA REQUEST */
msg = rsl_rll_simple(RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan), 0x00, 0);
msg->l3h = msg->tail; /* emulate rsl_rx_rll() behaviour */
msgb_tl16v_put(msg, RSL_IE_L3_INFO, sizeof(ul_grant), (uint8_t *) &ul_grant);
/* send it towards MS, just like a RSL message from the BSC */
return lapdm_rslms_recvmsg(msg, &lchan->lapdm_ch);
}
/* timer call-back for T3115 (VGCS UPLINK GRANT re-transmit) */
static void vgcs_t3115_cb(void *data)
{
struct gsm_lchan *lchan = data;
struct gsm_bts *bts = lchan->ts->trx->bts;
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "T3115 timeout (%d resends left)\n",
bts->ny2 - lchan->asci.vgcs_ul_grant_count);
if (lchan->state != LCHAN_S_ACTIVE) {
LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "is not active. It is in state %s. Ignoring\n",
gsm_lchans_name(lchan->state));
return;
}
if (lchan->asci.vgcs_ul_grant_count >= bts->ny2) {
lchan->asci.vgcs_ul_grant_count = 0;
LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "NY2 reached, sending CONNection FAILure to BSC.\n");
rsl_tx_conn_fail(lchan, RSL_ERR_TALKER_ACC_FAIL);
lchan->asci.talker_active = VGCS_TALKER_NONE;
return;
}
tx_vgcs_ul_grant(lchan);
lchan->asci.vgcs_ul_grant_count++;
osmo_timer_schedule(&lchan->asci.t3115, 0, bts->t3115_ms * 1000);
}
/* Received random access on dedicated channel. */
void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn)
{
LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "VGCS RACH on dedicated channel type %s received with "
"TA=%u, ref=%u\n", gsm_lchant_name(lchan->type), acc_delay, ra);
if (ra == 0x25) { /* See TS 44.018 Table 9.1.45.1 */
/* Listener Detection (TS 48.058 Section 4.14) */
if (!lchan->asci.listener_detected) {
rsl_tx_listener_det(lchan, &acc_delay);
lchan->asci.listener_detected = true;
}
} else {
/* Talker Detection (TS 48.058 Section 4.13) */
struct gsm_bts *bts = lchan->ts->trx->bts;
/* Talker detection on group channels only */
if (!rsl_chan_rt_is_vgcs(lchan->rsl_chan_rt))
return;
if (lchan->asci.talker_active != VGCS_TALKER_NONE) {
LOGPLCHAN(lchan, DASCI, LOGL_DEBUG, "Ignoring RACH, there is an active talker already.\n");
return;
}
/* Set timing advance, power level and activate SACCH */
lchan->ta_ctrl.current = acc_delay;
lchan->ms_power_ctrl.current = lchan->ms_power_ctrl.max;
lchan->want_dl_sacch_active = true;
/* Stop RACH detection, wait for valid frame */
lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
if (l1sap_uplink_access(lchan, false) != 0) {
LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access after TALKER DET.\n");
rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
lchan->asci.talker_active = VGCS_TALKER_NONE;
return;
}
lchan->asci.ref = ra;
lchan->asci.fn = fn;
/* Send TALKER DETECT via RSL to BSC */
rsl_tx_talker_det(lchan, &acc_delay);
/* Send VGCS UPLINK GRANT */
lchan->asci.vgcs_ul_grant_count = 1;
tx_vgcs_ul_grant(lchan);
/* Start T3115 */
LOGPLCHAN(lchan, DASCI, LOGL_DEBUG, "Starting T3115 with %u ms\n", bts->t3115_ms);
lchan->asci.t3115.cb = vgcs_t3115_cb;
lchan->asci.t3115.data = lchan;
osmo_timer_schedule(&lchan->asci.t3115, 0, bts->t3115_ms * 1000);
}
}
/* Received channel activation. */
void vgcs_lchan_activate(struct gsm_lchan *lchan)
{
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated.\n");
if (l1sap_uplink_access(lchan, true) != 0) {
LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to activate uplink access after channel activation.\n");
rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
}
}
/* Received channel reactivation. (for assignment) */
void vgcs_lchan_react(struct gsm_lchan *lchan)
{
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated for assignment.\n");
lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
if (l1sap_uplink_access(lchan, false) != 0) {
LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access for assignment.\n");
rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
}
radio_link_timeout_reset(lchan);
}
/* Received first valid data frame on dedicated channel. */
void vgcs_talker_frame(struct gsm_lchan *lchan)
{
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "First valid frame detected, talker now active.\n");
osmo_timer_del(&lchan->asci.t3115);
lchan->asci.talker_active = VGCS_TALKER_ACTIVE;
radio_link_timeout_reset(lchan);
}
/* Release VGCS Talker state. */
void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access)
{
if (lchan->asci.talker_active == VGCS_TALKER_NONE)
return;
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Uplink released, no talker.\n");
/* Stop T3115 */
osmo_timer_del(&lchan->asci.t3115);
/* Talker released. */
lchan->asci.talker_active = VGCS_TALKER_NONE;
if (ul_access) {
if (l1sap_uplink_access(lchan, true) != 0) {
LOGPLCHAN(lchan, DASCI, LOGL_ERROR,
"Failed to activate uplink access after uplink became free.\n");
rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
}
}
}
/* Release VGCS Listener state. */
void vgcs_listener_reset(struct gsm_lchan *lchan)
{
lchan->asci.listener_detected = false;
}

View File

@ -13,7 +13,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -44,8 +44,10 @@
#include <osmo-bts/abis.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/bts_sm.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/pcuif_proto.h>
#include <osmo-bts/pcu_if.h>
#include <osmo-bts/rsl.h>
#include <osmo-bts/oml.h>
#include <osmo-bts/signal.h>
@ -54,17 +56,15 @@
#include <osmo-bts/bts_shutdown_fsm.h>
#include <osmo-bts/nm_common_fsm.h>
#include <osmo-bts/power_control.h>
#include <osmo-bts/osmux.h>
#include <osmo-bts/notification.h>
#define MAX_TA_DEF 63 /* default max Timing Advance value */
#define MIN_QUAL_RACH 50 /* minimum link quality (in centiBels) for Access Bursts */
#define MIN_QUAL_NORM -5 /* minimum link quality (in centiBels) for Normal Bursts */
static void bts_update_agch_max_queue_length(struct gsm_bts *bts);
struct gsm_network bts_gsmnet = {
.bts_list = { &bts_gsmnet.bts_list, &bts_gsmnet.bts_list },
.num_bts = 0,
};
void *tall_bts_ctx;
/* Table 3.1 TS 04.08: Values of parameter S */
@ -97,12 +97,22 @@ static const struct rate_ctr_desc bts_ctr_desc[] = {
[BTS_CTR_RACH_RCVD] = {"rach:rcvd", "Received RACH requests (Um)"},
[BTS_CTR_RACH_DROP] = {"rach:drop", "Dropped RACH requests (Um)"},
[BTS_CTR_RACH_HO] = {"rach:handover", "Received RACH requests (Handover)"},
[BTS_CTR_RACH_VGCS] = {"rach:vgcs", "Received RACH requests (VGCS)"},
[BTS_CTR_RACH_CS] = {"rach:cs", "Received RACH requests (CS/Abis)"},
[BTS_CTR_RACH_PS] = {"rach:ps", "Received RACH requests (PS/PCU)"},
[BTS_CTR_AGCH_RCVD] = {"agch:rcvd", "Received AGCH requests (Abis)"},
[BTS_CTR_AGCH_SENT] = {"agch:sent", "Sent AGCH requests (Abis)"},
[BTS_CTR_AGCH_DELETED] = {"agch:delete", "Sent AGCH DELETE IND (Abis)"},
[BTS_CTR_RTP_RX_TOTAL] = {"rtp:rx:total", "Total number of received RTP packets"},
[BTS_CTR_RTP_RX_MARKER] = {"rtp:rx:marker", "Number of received RTP packets with marker bit set"},
[BTS_CTR_RTP_RX_DROP_PREEN] = {"rtp:rx:drop:preen", "Total number of received RTP packets dropped during preening"},
[BTS_CTR_RTP_RX_DROP_LOOPBACK] = {"rtp:rx:drop:loopback", "Total number of received RTP packets dropped during loopback"},
[BTS_CTR_RTP_RX_DROP_OVERFLOW] = {"rtp:rx:drop:overflow", "Total number of received RTP packets dropped during DL queue overflow"},
[BTS_CTR_RTP_RX_DROP_V110_DEC] = {"rtp:rx:drop:v110_dec", "Total number of received RTP packets dropped during V.110 decode"},
[BTS_CTR_RTP_TX_TOTAL] = {"rtp:tx:total", "Total number of transmitted RTP packets"},
[BTS_CTR_RTP_TX_MARKER] = {"rtp:tx:marker", "Number of transmitted RTP packets with marker bit set"},
};
static const struct rate_ctr_group_desc bts_ctrg_desc = {
"bts",
@ -148,7 +158,6 @@ struct osmo_tdef abis_T_defs[] = {
{}
};
static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
static const uint8_t bts_cell_timer_default[] =
{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
static const struct gprs_rlc_cfg rlc_cfg_default = {
@ -206,32 +215,46 @@ const char *btsatttr2str(enum bts_attribute v)
const struct value_string bts_impl_flag_desc[] = {
{ BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP, "DSP/HW based MS Power Control Loop" },
{ BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB, "Measurement and Payload data combined" },
{ BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER, "OML RadioChannel MO depends on RadioCarrier MO" },
{ BTS_INTERNAL_FLAG_INTERF_MEAS, "Uplink interference measurements" },
{ 0, NULL }
};
/* Ensure that all BTS_INTERNAL_FLAG_* entries are present in bts_impl_flag_desc[] */
osmo_static_assert(ARRAY_SIZE(bts_impl_flag_desc) == _BTS_INTERNAL_FLAG_NUM + 1, _bts_impl_flag_desc);
static int gsm_bts_talloc_destructor(struct gsm_bts *bts)
{
if (bts->site_mgr.mo.fi) {
osmo_fsm_inst_free(bts->site_mgr.mo.fi);
bts->site_mgr.mo.fi = NULL;
}
if (bts->mo.fi) {
osmo_fsm_inst_free(bts->mo.fi);
bts->mo.fi = NULL;
}
if (bts->shutdown_fi) {
osmo_fsm_inst_free(bts->shutdown_fi);
bts->shutdown_fi = NULL;
}
bts_osmux_release(bts);
llist_del(&bts->list);
g_bts_sm->num_bts--;
return 0;
}
struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
struct gsm_bts *gsm_bts_alloc(struct gsm_bts_sm *bts_sm, uint8_t bts_num)
{
struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
int i;
struct gsm_bts *bts = talloc_zero(bts_sm, struct gsm_bts);
if (!bts)
return NULL;
talloc_set_destructor(bts, gsm_bts_talloc_destructor);
/* add to list of BTSs */
llist_add_tail(&bts->list, &bts_sm->bts_list);
g_bts_sm->num_bts++;
bts->site_mgr = bts_sm;
bts->nr = bts_num;
bts->num_trx = 0;
INIT_LLIST_HEAD(&bts->trx_list);
@ -244,32 +267,19 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
LOGL_INFO, NULL);
osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr);
bts->site_mgr.mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts, &bts->site_mgr,
LOGL_INFO, "bts_sm");
gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
0xff, 0xff, 0xff);
/* NM BTS */
bts->mo.fi = osmo_fsm_inst_alloc(&nm_bts_fsm, bts, bts,
LOGL_INFO, NULL);
osmo_fsm_inst_update_id_f(bts->mo.fi, "bts%d", bts->nr);
gsm_mo_init(&bts->mo, bts, NM_OC_BTS, bts->nr, 0xff, 0xff);
for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
bts->gprs.nsvc[i].bts = bts;
bts->gprs.nsvc[i].id = i;
gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
bts->nr, i, 0xff);
}
memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
sizeof(bts->gprs.nse.timer));
gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
bts->nr, 0xff, 0xff);
memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
sizeof(bts->gprs.cell.timer));
gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
bts->nr, 0xff, 0xff);
memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
sizeof(bts->gprs.cell.rlc_cfg));
/* NM GPRS CELL */
bts->gprs.cell.mo.fi = osmo_fsm_inst_alloc(&nm_gprs_cell_fsm, bts, &bts->gprs.cell,
LOGL_INFO, NULL);
osmo_fsm_inst_update_id_f(bts->gprs.cell.mo.fi, "gprs_cell%d-0", bts->nr);
gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL, bts->nr, 0, 0xff);
memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default, sizeof(bts->gprs.cell.rlc_cfg));
memcpy(&bts->gprs.cell.timer, bts_cell_timer_default, sizeof(bts->gprs.cell.timer));
/* create our primary TRX. It will be initialized during bts_init() */
bts->c0 = gsm_bts_trx_alloc(bts);
@ -285,14 +295,14 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
return bts;
}
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num)
struct gsm_bts *gsm_bts_num(const struct gsm_bts_sm *bts_sm, int num)
{
struct gsm_bts *bts;
if (num >= net->num_bts)
if (num >= bts_sm->num_bts)
return NULL;
llist_for_each_entry(bts, &net->bts_list, list) {
llist_for_each_entry(bts, &bts_sm->bts_list, list) {
if (bts->nr == num)
return bts;
}
@ -308,19 +318,14 @@ int bts_init(struct gsm_bts *bts)
static int initialized = 0;
void *tall_rtp_ctx;
/* add to list of BTSs */
llist_add_tail(&bts->list, &bts_gsmnet.bts_list);
bts->band = GSM_BAND_1800;
INIT_LLIST_HEAD(&bts->agch_queue.queue);
bts->agch_queue.length = 0;
bts->ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);
if (!bts->ctrs) {
llist_del(&bts->list);
if (!bts->ctrs)
return -1;
}
/* enable management with default levels,
* raise threshold to GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE to
@ -338,58 +343,66 @@ int bts_init(struct gsm_bts *bts)
bts->rtp_port_range_next = bts->rtp_port_range_start;
bts->rtp_ip_dscp = -1;
bts->rtp_priority = -1;
bts->emit_hr_rfc5993 = true;
/* Default (fall-back) MS/BS Power control parameters */
power_ctrl_params_def_reset(&bts->bs_dpc_params, true);
power_ctrl_params_def_reset(&bts->ms_dpc_params, false);
/* configurable via OML */
bts->bsic = 0xff; /* invalid value, guarded by bsc_configured=false */
bts->bsic_configured = false;
bts->load.ccch.load_ind_period = 112;
bts->rtp_jitter_buf_ms = 100;
bts->max_ta = 63;
bts->max_ta = MAX_TA_DEF;
bts->ny1 = 4;
bts->ny2 = 4;
bts->t3105_ms = 300;
bts->t3115_ms = 300;
bts->min_qual_rach = MIN_QUAL_RACH;
bts->min_qual_norm = MIN_QUAL_NORM;
bts->max_ber10k_rach = 1707; /* 7 of 41 bits is Eb/N0 of 0 dB = 0.1707 */
bts->pcu.sock_path = talloc_strdup(bts, PCU_SOCK_DEFAULT);
for (i = 0; i < ARRAY_SIZE(bts->t200_ms); i++)
bts->t200_ms[i] = oml_default_t200_ms[i];
bts->pcu.sock_wqueue_len_max = BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT;
for (i = 0; i < ARRAY_SIZE(bts->t200_fn); i++)
bts->t200_fn[i] = oml_default_t200_fn[i];
/* default RADIO_LINK_TIMEOUT */
bts->radio_link_timeout.oml = 32;
bts->radio_link_timeout.current = bts->radio_link_timeout.oml;
/* Start with the site manager */
oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
/* Start with the BTS */
oml_mo_state_init(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
/* set BTS attr to dependency */
oml_mo_state_init(&bts->gprs.nse.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
oml_mo_state_init(&bts->gprs.nsvc[0].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
oml_mo_state_init(&bts->gprs.nsvc[1].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
/* allocate a talloc pool for ORTP to ensure it doesn't have to go back
* to the libc malloc all the time */
tall_rtp_ctx = talloc_pool(tall_bts_ctx, 262144);
osmo_rtp_init(tall_rtp_ctx);
/* features implemented in 'common', available for all models */
/* Osmux */
rc = bts_osmux_init(bts);
if (rc < 0)
return rc;
/* features implemented in 'common', available for all models,
* order alphabetically */
osmo_bts_set_feature(bts->features, BTS_FEAT_ABIS_OSMO_PCU);
osmo_bts_set_feature(bts->features, BTS_FEAT_CCN);
osmo_bts_set_feature(bts->features, BTS_FEAT_DYN_TS_SDCCH8);
osmo_bts_set_feature(bts->features, BTS_FEAT_ETWS_PN);
osmo_bts_set_feature(bts->features, BTS_FEAT_IPV6_NSVC);
osmo_bts_set_feature(bts->features, BTS_FEAT_ABIS_OSMO_PCU);
osmo_bts_set_feature(bts->features, BTS_FEAT_DYN_TS_SDCCH8);
osmo_bts_set_feature(bts->features, BTS_FEAT_PAGING_COORDINATION);
/* Maximum TA supported by the PHY (can be overridden by PHY specific code) */
bts->support.max_ta = MAX_TA_DEF;
rc = bts_model_init(bts);
if (rc < 0) {
llist_del(&bts->list);
if (rc < 0)
return rc;
}
/* TRX0 was allocated early during gsm_bts_alloc, not later through VTY */
bts_model_trx_init(bts->c0);
bts_gsmnet.num_bts++;
if (!initialized) {
osmo_signal_register_handler(SS_GLOBAL, bts_signal_cbfn, NULL);
@ -406,6 +419,9 @@ int bts_init(struct gsm_bts *bts)
bts->smscb_queue_tgt_len = 2;
bts->smscb_queue_hyst = 2;
bts->asci.pos_nch = -ENOTSUP;
INIT_LLIST_HEAD(&bts->asci.notifications);
INIT_LLIST_HEAD(&bts->bsc_oml_hosts);
/* register DTX DL FSM */
@ -423,33 +439,13 @@ int bts_init(struct gsm_bts *bts)
/* main link is established, send status report */
int bts_link_estab(struct gsm_bts *bts)
{
int i, j;
LOGP(DOML, LOGL_INFO, "Main link established, sending NM Status\n");
LOGP(DSUM, LOGL_INFO, "Main link established, sending NM Status.\n");
/* BTS SITE MGR becomes Offline (tx SW ACT Report), BTS is DEPENDENCY */
osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SW_ACT, NULL);
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_SW_ACT, NULL);
/* those should all be in DEPENDENCY */
oml_tx_state_changed(&bts->gprs.nse.mo);
oml_tx_state_changed(&bts->gprs.cell.mo);
oml_tx_state_changed(&bts->gprs.nsvc[0].mo);
oml_tx_state_changed(&bts->gprs.nsvc[1].mo);
/* All other objects start off-line until the BTS Model code says otherwise */
for (i = 0; i < bts->num_trx; i++) {
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, i);
oml_tx_state_changed(&trx->mo);
oml_tx_state_changed(&trx->bb_transc.mo);
for (j = 0; j < ARRAY_SIZE(trx->ts); j++) {
struct gsm_bts_trx_ts *ts = &trx->ts[j];
oml_tx_state_changed(&ts->mo);
}
}
/* Signal OML UP to BTS SITE MGR. It will automatically SW_ACT repoort
* and become Disabled-Offline, then dispatch same event to its children
* objects.
*/
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OML_UP, NULL);
return bts_model_oml_estab(bts);
}
@ -648,7 +644,7 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg)
struct gsm48_imm_ass_rej *imm_ass_cmd = msgb_l3(msg);
if (bts->agch_queue.length > hard_limit) {
LOGP(DSUM, LOGL_ERROR,
LOGP(DRR, LOGL_ERROR,
"AGCH: too many messages in queue, "
"refusing message type %s, length = %d/%d\n",
gsm48_rr_msg_name(((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type),
@ -676,7 +672,7 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg)
return 0;
}
struct msgb *bts_agch_dequeue(struct gsm_bts *bts)
static struct msgb *bts_agch_dequeue(struct gsm_bts *bts)
{
struct msgb *msg = msgb_dequeue(&bts->agch_queue.queue);
if (!msg)
@ -742,12 +738,12 @@ static void compact_agch_queue(struct gsm_bts *bts)
return;
}
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
int is_ag_res)
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, enum ccch_msgt ccch)
{
struct msgb *msg = NULL;
int rc = 0;
int is_empty = 1;
const struct bts_agch_msg_cb *msg_cb;
/* Do queue house keeping.
* This needs to be done every time a CCCH message is requested, since
@ -756,26 +752,39 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt
*/
compact_agch_queue(bts);
/* Check for paging messages first if this is PCH */
if (!is_ag_res)
switch (ccch) {
case CCCH_MSGT_NCH:
/* Send NCH message, it has priority over AGCH and does not overlap with PCH. */
rc = bts_asci_notify_nch_gen_msg(bts, out_buf);
return rc;
case CCCH_MSGT_PCH:
/* Check whether the block may be overwritten by AGCH. */
rc = paging_gen_msg(bts->paging_state, out_buf, gt, &is_empty);
/* Check whether the block may be overwritten */
if (!is_empty)
return rc;
msg = bts_agch_dequeue(bts);
if (!msg)
return rc;
if (!is_empty)
return rc;
/* fall-through */
case CCCH_MSGT_AGCH:
/* If fallen here and the AGCH queue is empty, return empty PCH message. */
msg = bts_agch_dequeue(bts);
if (!msg)
return rc;
/* Continue to return AGCH message. */
break;
}
rate_ctr_inc2(bts->ctrs, BTS_CTR_AGCH_SENT);
/* Confirm sending of the AGCH message towards the PCU */
msg_cb = (struct bts_agch_msg_cb *) msg->cb;
if (msg_cb->confirm)
pcu_tx_data_cnf(msg_cb->msg_id, PCU_IF_SAPI_AGCH_2);
/* Copy AGCH message */
memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg));
rc = msgb_l3len(msg);
msgb_free(msg);
if (is_ag_res)
if (ccch == CCCH_MSGT_AGCH)
bts->agch_queue.agch_msgs++;
else
bts->agch_queue.pch_msgs++;
@ -803,30 +812,35 @@ struct gsm_time *get_time(struct gsm_bts *bts)
return &bts->gsm_time;
}
int bts_supports_cm(const struct gsm_bts *bts,
const struct rsl_ie_chan_mode *cm)
bool bts_supports_cm_speech(const struct gsm_bts *bts,
const struct rsl_ie_chan_mode *cm)
{
enum osmo_bts_features feature = _NUM_BTS_FEAT;
switch (cm->spd_ind) {
case RSL_CMOD_SPD_SIGN:
/* We assume that signalling support is mandatory,
* there is no BTS_FEAT_* definition to check that. */
return 1;
case RSL_CMOD_SPD_SPEECH:
/* Stage 1: check support for the requested channel type */
switch (cm->chan_rt) {
case RSL_CMOD_CRT_TCH_GROUP_Bm:
case RSL_CMOD_CRT_TCH_GROUP_Lm:
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VGCS))
return false;
break;
case RSL_CMOD_CRT_TCH_BCAST_Bm:
case RSL_CMOD_CRT_TCH_BCAST_Lm:
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VBS))
return false;
break;
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm:
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm:
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
return false;
break;
case RSL_CMOD_SPD_DATA:
default:
return 0;
}
/* Before the requested pchan/cm combination can be checked, we need to
* convert it to a feature identifier we can check */
/* Stage 2: check support for the requested codec */
switch (cm->chan_rt) {
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm:
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
return 0;
/* fall-through */
case RSL_CMOD_CRT_TCH_GROUP_Bm:
case RSL_CMOD_CRT_TCH_BCAST_Bm:
case RSL_CMOD_CRT_TCH_Bm:
switch (cm->chan_rate) {
case RSL_CMOD_SP_GSM1:
@ -840,14 +854,13 @@ int bts_supports_cm(const struct gsm_bts *bts,
break;
default:
/* Invalid speech codec type => Not supported! */
return 0;
return false;
}
break;
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm:
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
return 0;
/* fall-through */
case RSL_CMOD_CRT_TCH_GROUP_Lm:
case RSL_CMOD_CRT_TCH_BCAST_Lm:
case RSL_CMOD_CRT_TCH_Lm:
switch (cm->chan_rate) {
case RSL_CMOD_SP_GSM1:
@ -858,7 +871,7 @@ int bts_supports_cm(const struct gsm_bts *bts,
break;
default:
/* Invalid speech codec type => Not supported! */
return 0;
return false;
}
break;
@ -866,35 +879,81 @@ int bts_supports_cm(const struct gsm_bts *bts,
LOGP(DRSL, LOGL_ERROR,
"Unhandled RSL channel type=0x%02x/rate=0x%02x\n",
cm->chan_rt, cm->chan_rate);
return 0;
return false;
}
/* Check if the feature is supported by this BTS */
if (osmo_bts_has_feature(bts->features, feature))
return 1;
return true;
return 0;
return false;
}
static bool bts_supports_cm_data(const struct gsm_bts *bts,
const struct rsl_ie_chan_mode *cm)
{
switch (bts->variant) {
case BTS_OSMO_TRX:
switch (cm->chan_rate) {
/* TODO: RSL_CMOD_CSD_NT_14k5 */
/* TODO: RSL_CMOD_CSD_T_14k4 */
case RSL_CMOD_CSD_NT_12k0:
case RSL_CMOD_CSD_T_9k6:
if (cm->chan_rt != RSL_CMOD_CRT_TCH_Bm)
return false; /* invalid */
/* fall-through */
case RSL_CMOD_CSD_NT_6k0:
case RSL_CMOD_CSD_T_4k8:
case RSL_CMOD_CSD_T_2k4:
case RSL_CMOD_CSD_T_1k2:
case RSL_CMOD_CSD_T_600:
case RSL_CMOD_CSD_T_1200_75:
return true;
default:
return false;
}
default:
return 0;
}
}
bool bts_supports_cm(const struct gsm_bts *bts,
const struct rsl_ie_chan_mode *cm)
{
switch (cm->spd_ind) {
case RSL_CMOD_SPD_SIGN:
/* We assume that signalling support is mandatory,
* there is no BTS_FEAT_* definition to check that. */
return true;
case RSL_CMOD_SPD_SPEECH:
return bts_supports_cm_speech(bts, cm);
case RSL_CMOD_SPD_DATA:
return bts_supports_cm_data(bts, cm);
default:
return false;
}
}
/* return the gsm_lchan for the CBCH (if it exists at all) */
struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)
{
struct gsm_lchan *lchan = NULL;
struct gsm_bts_trx *trx = bts->c0;
/* According to 3GPP TS 45.002, table 3, CBCH can be allocated
* either on C0/TS0 (CCCH+SDCCH4) or on C0..n/TS0..3 (SDCCH/8). */
if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
lchan = &trx->ts[0].lchan[2];
else {
int i;
for (i = 0; i < 8; i++) {
if (trx->ts[i].pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
lchan = &trx->ts[i].lchan[2];
break;
}
return &trx->ts[0].lchan[2]; /* C0/TS0 */
llist_for_each_entry(trx, &bts->trx_list, list) { /* C0..n */
unsigned int tn;
for (tn = 0; tn <= 3; tn++) { /* TS0..3 */
struct gsm_bts_trx_ts *ts = &trx->ts[tn];
if (ts->pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH)
return &ts->lchan[2];
}
}
return lchan;
return NULL;
}
/* BCCH carrier power reduction (see 3GPP TS 45.008, section 7.1) */

View File

@ -12,7 +12,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -84,12 +84,45 @@ static int set_oml_alert(struct ctrl_cmd *cmd, void *data)
return CTRL_CMD_REPLY;
}
static int verify_max_ber10k_rach(struct ctrl_cmd *cmd, const char *value, void *_data)
{
int max_ber10k_rach = atoi(cmd->value);
if (max_ber10k_rach < 0 || max_ber10k_rach > 10000) {
cmd->reply = "Value is out of range";
return 1;
}
return 0;
}
static int get_max_ber10k_rach(struct ctrl_cmd *cmd, void *data)
{
cmd->reply = talloc_asprintf(cmd, "%u", g_bts->max_ber10k_rach);
if (!cmd->reply) {
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
return CTRL_CMD_REPLY;
}
static int set_max_ber10k_rach(struct ctrl_cmd *cmd, void *data)
{
g_bts->max_ber10k_rach = atoi(cmd->value);
cmd->reply = "OK";
return CTRL_CMD_REPLY;
}
CTRL_CMD_DEFINE(max_ber10k_rach, "max-ber10k-rach");
int bts_ctrl_cmds_install(struct gsm_bts *bts)
{
int rc = 0;
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_therm_att);
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_oml_alert);
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_max_ber10k_rach);
g_bts = bts;
return rc;

View File

@ -12,7 +12,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -88,14 +88,12 @@ err_index:
return -ERANGE;
}
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
const char *bind_addr, uint16_t port)
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port)
{
struct ctrl_handle *hdl;
int rc = 0;
hdl = ctrl_interface_setup_dynip(bts, bind_addr, port,
bts_ctrl_node_lookup);
hdl = ctrl_interface_setup(bts, port, bts_ctrl_node_lookup);
if (!hdl)
return NULL;

View File

@ -1,6 +1,6 @@
/* BTS shutdown FSM */
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* All Rights Reserved
@ -13,7 +13,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -29,6 +29,7 @@
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/bts_sm.h>
#include <osmo-bts/nm_common_fsm.h>
#define X(s) (1 << (s))
@ -60,7 +61,7 @@ static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data)
switch(event) {
case BTS_SHUTDOWN_EV_START:
/* Firt announce to NM objects that we are starting a shutdown procedure: */
osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SHUTDOWN_START, NULL);
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_START, NULL);
count = count_trx_operational(bts);
if (count) {
@ -89,7 +90,10 @@ static void st_wait_ramp_down_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t
llist_for_each_entry(trx, &bts->trx_list, list) {
if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED)
continue;
power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
if (bts->shutdown_fi_skip_power_ramp)
power_ramp_force(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
else
power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
}
}
@ -161,7 +165,7 @@ static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SHUTDOWN_FINISH, NULL);
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_FINISH, NULL);
if (bts->shutdown_fi_exit_proc) {
LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfully, exiting process\n");
@ -250,7 +254,7 @@ bool bts_shutdown_in_progress(const struct gsm_bts *bts)
return fi->state != BTS_SHUTDOWN_ST_NONE;
}
void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc)
void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc, bool skip_power_ramp)
{
struct osmo_fsm_inst *fi = bts->shutdown_fi;
if (bts_shutdown_in_progress(bts)) {
@ -260,6 +264,7 @@ void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc)
return;
}
bts->shutdown_fi_exit_proc = exit_proc;
bts->shutdown_fi_skip_power_ramp = skip_power_ramp;
LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, exit %u, reason: %s\n",
exit_proc, reason);
osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_START, NULL);
@ -267,7 +272,7 @@ void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc)
void bts_shutdown(struct gsm_bts *bts, const char *reason)
{
bts_shutdown_ext(bts, reason, true);
bts_shutdown_ext(bts, reason, true, true);
}
void bts_model_trx_close_cb(struct gsm_bts_trx *trx, int rc)

95
src/common/bts_sm.c Normal file
View File

@ -0,0 +1,95 @@
/* BTS support code common to all supported BTS models */
/* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <osmocom/core/talloc.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/fsm.h>
#include <osmo-bts/bts_sm.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/nm_common_fsm.h>
struct gsm_bts_sm *g_bts_sm;
static const uint8_t nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
struct gsm_bts *gsm_gprs_nse_get_bts(const struct gsm_gprs_nse *nse)
{
return gsm_bts_num(g_bts_sm, nse->mo.obj_inst.bts_nr);
}
static int gsm_bts_sm_talloc_destructor(struct gsm_bts_sm *bts_sm)
{
struct gsm_bts *bts;
while ((bts = llist_first_entry_or_null(&bts_sm->bts_list, struct gsm_bts, list)))
talloc_free(bts);
if (bts_sm->mo.fi) {
osmo_fsm_inst_free(bts_sm->mo.fi);
bts_sm->mo.fi = NULL;
}
return 0;
}
struct gsm_bts_sm *gsm_bts_sm_alloc(void *talloc_ctx)
{
struct gsm_bts_sm *bts_sm = talloc_zero(talloc_ctx, struct gsm_bts_sm);
struct gsm_gprs_nse *nse = &bts_sm->gprs.nse;
unsigned int i;
if (!bts_sm)
return NULL;
talloc_set_destructor(bts_sm, gsm_bts_sm_talloc_destructor);
INIT_LLIST_HEAD(&bts_sm->bts_list);
/* NM SITE_MGR */
bts_sm->mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts_sm, bts_sm,
LOGL_INFO, "bts_sm");
gsm_mo_init(&bts_sm->mo, NULL, NM_OC_SITE_MANAGER,
0xff, 0xff, 0xff);
oml_mo_state_init(&bts_sm->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
/* NM GPRS NSE */
nse->mo.fi = osmo_fsm_inst_alloc(&nm_gprs_nse_fsm, bts_sm, nse,
LOGL_INFO, "gprs_nse0");
gsm_mo_init(&nse->mo, NULL, NM_OC_GPRS_NSE, 0, 0xff, 0xff);
oml_mo_state_init(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
memcpy(&nse->timer, nse_timer_default, sizeof(nse->timer));
/* NM GPRS NSVCs */
for (i = 0; i < ARRAY_SIZE(nse->nsvc); i++) {
struct gsm_gprs_nsvc *nsvc = &nse->nsvc[i];
nsvc->nse = nse;
nsvc->id = i;
nsvc->mo.fi = osmo_fsm_inst_alloc(&nm_gprs_nsvc_fsm, bts_sm, nsvc,
LOGL_INFO, NULL);
osmo_fsm_inst_update_id_f(nsvc->mo.fi, "gprs_nsvc%d-%d",
nse->mo.obj_inst.bts_nr, i);
gsm_mo_init(&nsvc->mo, NULL, NM_OC_GPRS_NSVC, nse->mo.obj_inst.bts_nr, i, 0xff);
oml_mo_state_init(&nsvc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
}
return bts_sm;
}

View File

@ -74,12 +74,17 @@ static void gsm_bts_trx_init_ts(struct gsm_bts_trx *trx)
ts->trx = trx;
ts->nr = tn;
ts->tsc_oml_configured = false;
ts->tsc_rsl_configured = false;
ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff;
ts->mo.fi = osmo_fsm_inst_alloc(&nm_chan_fsm, trx, ts,
LOGL_INFO, NULL);
osmo_fsm_inst_update_id_f(ts->mo.fi, "%s-ts%u",
trx->bb_transc.mo.fi->id, ts->nr);
gsm_mo_init(&ts->mo, trx->bts, NM_OC_CHANNEL,
trx->bts->nr, trx->nr, ts->nr);
oml_mo_state_init(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
gsm_bts_trx_ts_init_lchan(ts);
}
@ -99,6 +104,10 @@ void gsm_bts_trx_init_shadow_ts(struct gsm_bts_trx *trx)
ts->trx = trx;
ts->nr = tn;
ts->tsc_oml_configured = false;
ts->tsc_rsl_configured = false;
ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff;
/* Link both primary and shadow */
trx->ts[tn].vamos.peer = ts;
ts->vamos.peer = &trx->ts[tn];
@ -148,14 +157,14 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
trx->mo.fi = osmo_fsm_inst_alloc(&nm_rcarrier_fsm, trx, trx,
LOGL_INFO, NULL);
osmo_fsm_inst_update_id_f(trx->mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER,
bts->nr, trx->nr, 0xff);
gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER, bts->nr, trx->nr, 0xff);
oml_mo_state_init(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
trx->bb_transc.mo.fi = osmo_fsm_inst_alloc(&nm_bb_transc_fsm, trx, &trx->bb_transc,
LOGL_INFO, NULL);
osmo_fsm_inst_update_id_f(trx->bb_transc.mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC,
bts->nr, trx->nr, 0xff);
gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC, bts->nr, trx->nr, 0xff);
oml_mo_state_init(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
gsm_bts_trx_init_ts(trx);
@ -222,15 +231,18 @@ int trx_link_estab(struct gsm_bts_trx *trx)
{
int rc;
LOGPTRX(trx, DSUM, LOGL_INFO, "RSL link up\n");
LOGPTRX(trx, DRSL, LOGL_INFO, "RSL link up\n");
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_RSL_UP, NULL);
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_RSL_UP, NULL);
if ((rc = rsl_tx_rf_res(trx)) < 0)
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
"Failed to establish RSL link (%d)", rc);
if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED ||
trx->bb_transc.mo.nm_state.operational == NM_OPSTATE_ENABLED) {
rc = rsl_tx_rf_res(trx);
if (rc < 0)
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
"Failed to establish RSL link (%d)", rc);
}
if (trx == trx->bts->c0)
load_timer_start(trx->bts);

View File

@ -12,7 +12,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -139,12 +139,8 @@ static int get_smscb_block(struct bts_smscb_state *bts_ss, uint8_t *out, uint8_t
block_type->seq_nr = block_nr;
/* determine if this is the last block */
if (block_nr + 1 == msg->num_segs)
block_type->lb = 1;
else
block_type->lb = 0;
if (block_nr == 4) {
block_type->lb = (block_nr + 1 == msg->num_segs);
if (block_type->lb) {
if (msg != bts_ss->default_msg) {
DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n",
chan_name, msg);
@ -198,7 +194,7 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ
return -EINVAL;
}
scm = talloc_zero_size(bts, sizeof(*scm));
scm = talloc_zero(bts, struct smscb_msg);
if (!scm)
return -1;
@ -233,10 +229,10 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ
rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_RCVD_QUEUED);
break;
case RSL_CB_CMD_TYPE_DEFAULT:
/* old default msg will be free'd in get_smscb_block() if it is currently in transit
* and we set a new default_msg here */
/* clear the cur_msg pointer if it is the old default message */
if (bts_ss->cur_msg && bts_ss->cur_msg == bts_ss->default_msg)
talloc_free(bts_ss->cur_msg);
bts_ss->cur_msg = NULL;
talloc_free(bts_ss->default_msg);
if (cmd_type.def_bcast == RSL_CB_CMD_DEFBCAST_NORMAL)
/* def_bcast == 0: normal message */
bts_ss->default_msg = scm;
@ -332,7 +328,10 @@ static void bts_smscb_state_reset(struct bts_smscb_state *bts_ss)
}
bts_ss->queue_len = 0;
rate_ctr_group_reset(bts_ss->ctrs);
TALLOC_FREE(bts_ss->cur_msg);
/* avoid double-free of default_msg in case cur_msg == default_msg */
if (bts_ss->cur_msg && bts_ss->cur_msg != bts_ss->default_msg)
talloc_free(bts_ss->cur_msg);
bts_ss->cur_msg = NULL;
TALLOC_FREE(bts_ss->default_msg);
}

188
src/common/csd_v110.c Normal file
View File

@ -0,0 +1,188 @@
/*
* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Vadim Yanitskiy <vyanitskiy@sysmocom.de>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdint.h>
#include <errno.h>
#include <osmocom/core/bits.h>
#include <osmocom/core/utils.h>
#include <osmocom/gsm/gsm44021.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/isdn/v110.h>
#include <osmo-bts/csd_v110.h>
#include <osmo-bts/lchan.h>
/* key is enum gsm48_chan_mode, so assuming a value in range 0..255 */
const struct csd_v110_lchan_desc csd_v110_lchan_desc[256] = {
#if 0
[GSM48_CMODE_DATA_14k5] = {
/* TCH/F14.4: 290 bits every 20 ms (14.5 kbit/s) */
.fr = { .num_blocks = 1, .num_bits = 290 },
},
#endif
[GSM48_CMODE_DATA_12k0] = {
/* TCH/F9.6: 4 * 60 bits every 20 ms (12.0 kbit/s) */
.fr = { .num_blocks = 4, .num_bits = 60 },
},
[GSM48_CMODE_DATA_6k0] = {
/* TCH/F4.8: 2 * 60 bits every 20 ms (6.0 kbit/s) */
.fr = { .num_blocks = 2, .num_bits = 60 },
/* TCH/H4.8: 4 * 60 bits every 40 ms (6.0 kbit/s) */
.hr = { .num_blocks = 4, .num_bits = 60 },
},
[GSM48_CMODE_DATA_3k6] = {
/* TCH/F2.4: 2 * 36 bits every 20 ms (3.6 kbit/s) */
.fr = { .num_blocks = 2, .num_bits = 36 },
/* TCH/H2.4: 4 * 36 bits every 40 ms (3.6 kbit/s) */
.hr = { .num_blocks = 4, .num_bits = 36 },
},
};
/* 3GPP TS 44.021, Figure 4: Coding of data rates (E1/E2/E3 bits) */
static const uint8_t e1e2e3_map[_LCHAN_CSD_M_NUM][3] = {
[LCHAN_CSD_M_T_600] = { 1, 0, 0 },
[LCHAN_CSD_M_T_1200] = { 0, 1, 0 },
[LCHAN_CSD_M_T_2400] = { 1, 1, 0 },
[LCHAN_CSD_M_T_4800] = { 0, 1, 1 },
[LCHAN_CSD_M_T_9600] = { 0, 1, 1 },
#if 0
[LCHAN_CSD_M_T_19200] = { 0, 1, 1 },
[LCHAN_CSD_M_T_38400] = { 0, 1, 1 },
[LCHAN_CSD_M_T_14400] = { 1, 0, 1 },
[LCHAN_CSD_M_T_28800] = { 1, 0, 1 },
#endif
};
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
const uint8_t *data, size_t data_len)
{
const struct csd_v110_frame_desc *desc;
ubit_t ra_bits[80 * 4];
OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
if (lchan->type == GSM_LCHAN_TCH_F)
desc = &csd_v110_lchan_desc[lchan->tch_mode].fr;
else
desc = &csd_v110_lchan_desc[lchan->tch_mode].hr;
if (OSMO_UNLIKELY(desc->num_blocks == 0))
return -ENOTSUP;
/* handle empty/incomplete Uplink frames gracefully */
if (OSMO_UNLIKELY(data_len < (desc->num_blocks * desc->num_bits))) {
/* encode N idle frames as per 3GPP TS 44.021, section 8.1.6 */
memset(&ra_bits[0], 0x01, sizeof(ra_bits));
for (unsigned int i = 0; i < desc->num_blocks; i++)
memset(&ra_bits[i * 80], 0x00, 8); /* alignment pattern */
goto ra1_ra2;
}
/* RA1'/RA1: convert from radio rate to an intermediate data rate */
for (unsigned int i = 0; i < desc->num_blocks; i++) {
struct osmo_v110_decoded_frame df;
/* convert a V.110 36-/60-bit frame to a V.110 80-bit frame */
if (desc->num_bits == 60)
osmo_csd_12k_6k_decode_frame(&df, &data[i * 60], 60);
else /* desc->num_bits == 36 */
osmo_csd_3k6_decode_frame(&df, &data[i * 36], 36);
/* E1 .. E3 must set by out-of-band knowledge */
if (lchan->csd_mode == LCHAN_CSD_M_NT) {
/* non-transparent: as per 3GPP TS 48.020, Table 7 */
df.e_bits[0] = 0; /* E1: as per 15.1.2, shall be set to 0 (for BSS-MSC) */
df.e_bits[1] = (i >> 1) & 0x01; /* E2: 0 for Q1/Q2, 1 for Q3/Q4 */
df.e_bits[2] = (i >> 0) & 0x01; /* E3: 0 for Q1/Q3, 1 for Q2/Q4 */
} else {
/* transparent: as per 3GPP TS 44.021, Figure 4 */
df.e_bits[0] = e1e2e3_map[lchan->csd_mode][0]; /* E1 */
df.e_bits[1] = e1e2e3_map[lchan->csd_mode][1]; /* E2 */
df.e_bits[2] = e1e2e3_map[lchan->csd_mode][2]; /* E3 */
}
osmo_v110_encode_frame(&ra_bits[i * 80], 80, &df);
}
ra1_ra2:
/* RA1/RA2: convert from an intermediate rate to 64 kbit/s */
if (desc->num_blocks == 4) {
/* 4 * 80 bits (16 kbit/s) => 2 bits per octet */
for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) {
rtp[i] = (0xff >> 2);
rtp[i] |= (ra_bits[j++] << 7);
rtp[i] |= (ra_bits[j++] << 6);
}
} else {
/* 2 * 80 bits (8 kbit/s) => 1 bit per octet */
for (unsigned int i = 0; i < RFC4040_RTP_PLEN; i++) {
rtp[i] = (0xff >> 1);
rtp[i] |= (ra_bits[i] << 7);
}
}
return RFC4040_RTP_PLEN;
}
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
const uint8_t *rtp, size_t rtp_len)
{
const struct csd_v110_frame_desc *desc;
ubit_t ra_bits[80 * 4];
OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
if (lchan->type == GSM_LCHAN_TCH_F)
desc = &csd_v110_lchan_desc[lchan->tch_mode].fr;
else
desc = &csd_v110_lchan_desc[lchan->tch_mode].hr;
if (OSMO_UNLIKELY(desc->num_blocks == 0))
return -ENOTSUP;
if (OSMO_UNLIKELY(rtp_len != RFC4040_RTP_PLEN))
return -EINVAL;
/* RA1/RA2: convert from 64 kbit/s to an intermediate rate */
if (desc->num_blocks == 4) {
/* 4 * 80 bits (16 kbit/s) => 2 bits per octet */
for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) {
ra_bits[j++] = (rtp[i] >> 7);
ra_bits[j++] = (rtp[i] >> 6) & 0x01;
}
} else {
/* 2 * 80 bits (8 kbit/s) => 1 bit per octet */
for (unsigned int i = 0; i < RFC4040_RTP_PLEN; i++)
ra_bits[i] = (rtp[i] >> 7);
}
/* RA1'/RA1: convert from an intermediate rate to radio rate */
for (unsigned int i = 0; i < desc->num_blocks; i++) {
struct osmo_v110_decoded_frame df;
/* convert a V.110 80-bit frame to a V.110 36-/60-bit frame */
osmo_v110_decode_frame(&df, &ra_bits[i * 80], 80);
if (desc->num_bits == 60)
osmo_csd_12k_6k_encode_frame(&data[i * 60], 60, &df);
else /* desc->num_bits == 36 */
osmo_csd_3k6_encode_frame(&data[i * 36], 36, &df);
}
return desc->num_blocks * desc->num_bits;
}

View File

@ -12,7 +12,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.

View File

@ -306,6 +306,29 @@ bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)
}
}
/* Apply ts->tsc based on what was configured coming from different sources.
* Priorities (preferred first, overrides ones afterward):
* 1- RSL OSMO_TSC IE
* 2- OML SetChannelAttr TSC IE
* 3- OML SetBtsAttr BSIC IE
*/
void gsm_ts_apply_configured_tsc(struct gsm_bts_trx_ts *ts)
{
if (ts->tsc_rsl_configured) {
ts->tsc = ts->tsc_rsl;
return;
}
if (ts->tsc_oml_configured) {
ts->tsc = ts->tsc_oml;
return;
}
if (ts->trx->bts->bsic_configured) {
ts->tsc = BTS_TSC(ts->trx->bts);
return;
}
ts->tsc = 0xff; /* invalid value */
}
void gsm_ts_release(struct gsm_bts_trx_ts *ts)
{
unsigned int ln;
@ -318,4 +341,8 @@ void gsm_ts_release(struct gsm_bts_trx_ts *ts)
/* Make sure pchan_is is reset, since PCU act_req to release it will be
* ignored as the lchan will already be released. */
ts->dyn.pchan_is = ts->dyn.pchan_want = GSM_PCHAN_NONE;
ts->tsc_oml_configured = false;
ts->tsc_rsl_configured = false;
ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff;
}

View File

@ -14,7 +14,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.

File diff suppressed because it is too large Load Diff

View File

@ -12,13 +12,15 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "btsconfig.h" /* for PACKAGE_VERSION */
#include <osmocom/core/logging.h>
#include <osmocom/trau/osmo_ortp.h>
@ -31,6 +33,7 @@
#include <osmo-bts/handover.h>
#include <osmo-bts/l1sap.h>
#include <osmo-bts/bts_model.h>
#include <osmo-bts/asci.h>
#include <errno.h>
static const struct value_string lchan_s_names[] = {
@ -54,41 +57,40 @@ const struct value_string lchan_ciph_state_names[] = {
};
/* prepare the per-SAPI T200 arrays for a given lchan */
static int t200_by_lchan(int *t200_ms_dcch, int *t200_ms_acch, struct gsm_lchan *lchan)
static int t200_by_lchan(uint32_t *t200_fn_dcch, uint32_t *t200_fn_acch, struct gsm_lchan *lchan)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
/* we have to compensate for the "RTS advance" due to the asynchronous interface between
* the BTS (LAPDm) and the PHY/L1 (OsmoTRX or DSP in case of osmo-bts-{sysmo,lc15,oc2g,octphy} */
int32_t fn_advance = bts_get_avg_fn_advance(bts);
int32_t fn_advance_us = fn_advance * 4615;
int fn_advance_ms = fn_advance_us / 1000;
t200_ms_acch[DL_SAPI0] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
t200_ms_acch[DL_SAPI3] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
if (lchan->rep_acch_cap.dl_facch_all && lchan_is_tch(lchan)) {
t200_ms_acch[DL_SAPI0] *= 2;
t200_ms_acch[DL_SAPI3] *= 2;
}
switch (lchan->type) {
case GSM_LCHAN_SDCCH:
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_SDCCH] + fn_advance_ms;
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_SDCCH_SAPI3] + fn_advance_ms;
t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_SDCCH];
t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_SDCCH_SAPI3];
t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_SDCCH];
t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_SDCCH];
break;
case GSM_LCHAN_TCH_F:
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_F];
t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_FACCH_F];
t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_TCH_SAPI0];
t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_TCH_SAPI3];
break;
case GSM_LCHAN_TCH_H:
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_H];
t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_FACCH_H];
t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_TCH_SAPI0];
t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_TCH_SAPI3];
break;
default:
/* Channels such as CCCH don't use lapdm DL, and hence no T200 is needed */
return -1;
}
/* Add time of two extra messages frames. */
if (lchan->rep_acch_cap.dl_facch_all && lchan_is_tch(lchan)) {
t200_fn_acch[DL_SAPI0] += 104 * 2;
t200_fn_acch[DL_SAPI3] += 104 * 2;
}
return 0;
}
@ -130,6 +132,7 @@ void gsm_lchan_init(struct gsm_lchan *lchan, struct gsm_bts_trx_ts *ts, unsigned
INIT_LLIST_HEAD(&lchan->sapi_cmds);
INIT_LLIST_HEAD(&lchan->dl_tch_queue);
lchan->dl_tch_queue_len = 0;
}
void gsm_lchan_name_update(struct gsm_lchan *lchan)
@ -148,17 +151,17 @@ void gsm_lchan_name_update(struct gsm_lchan *lchan)
int lchan_init_lapdm(struct gsm_lchan *lchan)
{
struct lapdm_channel *lc = &lchan->lapdm_ch;
int t200_ms_dcch[_NR_DL_SAPI], t200_ms_acch[_NR_DL_SAPI];
uint32_t t200_fn_dcch[_NR_DL_SAPI], t200_fn_acch[_NR_DL_SAPI];
if (t200_by_lchan(t200_ms_dcch, t200_ms_acch, lchan) == 0) {
if (t200_by_lchan(t200_fn_dcch, t200_fn_acch, lchan) == 0) {
LOGPLCHAN(lchan, DLLAPD, LOGL_DEBUG,
"Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in ms)\n",
t200_ms_dcch[DL_SAPI0], t200_ms_dcch[DL_SAPI3],
t200_ms_acch[DL_SAPI0], t200_ms_acch[DL_SAPI3]);
lapdm_channel_init3(lc, LAPDM_MODE_BTS, t200_ms_dcch, t200_ms_acch, lchan->type,
gsm_lchan_name(lchan));
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY);
"Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in frames)\n",
t200_fn_dcch[DL_SAPI0], t200_fn_dcch[DL_SAPI3],
t200_fn_acch[DL_SAPI0], t200_fn_acch[DL_SAPI3]);
lapdm_channel_init3(lc, LAPDM_MODE_BTS, NULL, NULL, lchan->type, gsm_lchan_name(lchan));
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY | LAPDM_ENT_F_RTS);
lapdm_channel_set_l1(lc, NULL, lchan);
lapdm_channel_set_t200_fn(lc, t200_fn_dcch, t200_fn_acch);
}
/* We still need to set Rx callback to receive RACH requests: */
lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan);
@ -200,10 +203,12 @@ void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind
rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC);
osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO,
"Closing RTP socket on Channel Release ");
osmo_rtp_socket_free(lchan->abis_ip.rtp_socket);
lchan->abis_ip.rtp_socket = NULL;
msgb_queue_flush(&lchan->dl_tch_queue);
lchan_rtp_socket_free(lchan);
} else if (lchan->abis_ip.osmux.use) {
lchan_osmux_release(lchan);
}
/* reset all Abis related config: */
memset(&lchan->abis_ip, 0, sizeof(lchan->abis_ip));
/* FIXME: right now we allow creating the rtp_socket even if chan is not
* activated... Once we check for that, we can move this check at the
@ -211,8 +216,11 @@ void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind
if (lchan->state == LCHAN_S_NONE)
return;
/* release handover state */
/* release handover, listener and talker states */
handover_reset(lchan);
vgcs_talker_reset(lchan, false);
vgcs_listener_reset(lchan);
vgcs_uplink_free_reset(lchan);
lchan->rel_act_kind = rel_kind;
@ -317,7 +325,7 @@ void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state)
}
}
/* See Table 10.5.25 of GSM04.08 */
/* See 3GPP TS 44.018 Table 10.5.2.5.1 "Channel Description information element" */
static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
uint8_t ts_nr, uint8_t lchan_nr)
{
@ -362,13 +370,13 @@ static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
break;
case GSM_PCHAN_NONE:
LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",
gsm_pchan_name(pchan));
cbits = 0x00;
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s not expected!\n",
ts_nr, lchan_nr, gsm_pchan_name(pchan));
cbits = 0x00; /* Reserved */
break;
default:
LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",
gsm_pchan_name(pchan), (int)pchan);
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s (0x%02x) not expected!\n",
ts_nr, lchan_nr, gsm_pchan_name(pchan), (int)pchan);
OSMO_ASSERT(0);
break;
}
@ -510,3 +518,148 @@ int lchan2ecu_codec(const struct gsm_lchan *lchan)
return -1;
}
}
static int bind_rtp(struct gsm_bts *bts, struct osmo_rtp_socket *rs, const char *ip)
{
int rc;
unsigned int i;
unsigned int tries;
tries = (bts->rtp_port_range_end - bts->rtp_port_range_start) / 2;
for (i = 0; i < tries; i++) {
if (bts->rtp_port_range_next >= bts->rtp_port_range_end)
bts->rtp_port_range_next = bts->rtp_port_range_start;
rc = osmo_rtp_socket_bind(rs, ip, bts->rtp_port_range_next);
bts->rtp_port_range_next += 2;
if (rc != 0)
continue;
if (bts->rtp_ip_dscp != -1) {
if (osmo_rtp_socket_set_dscp(rs, bts->rtp_ip_dscp))
LOGP(DRSL, LOGL_ERROR, "failed to set DSCP=%d: %s\n",
bts->rtp_ip_dscp, strerror(errno));
}
if (bts->rtp_priority != -1) {
if (osmo_rtp_socket_set_priority(rs, bts->rtp_priority))
LOGP(DRSL, LOGL_ERROR, "failed to set socket priority %d: %s\n",
bts->rtp_priority, strerror(errno));
}
return 0;
}
return -1;
}
int lchan_rtp_socket_create(struct gsm_lchan *lchan, const char *bind_ip)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
char cname[256+4];
int rc;
if (lchan->abis_ip.rtp_socket) {
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC CRCX, "
"but we already have socket!\n");
return -EALREADY;
}
/* FIXME: select default value depending on speech_mode */
//if (!payload_type)
lchan->tch.last_fn = LCHAN_FN_DUMMY;
lchan->abis_ip.rtp_socket = osmo_rtp_socket_create(lchan->ts->trx,
OSMO_RTP_F_POLL);
if (!lchan->abis_ip.rtp_socket) {
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to create RTP/RTCP sockets\n");
oml_tx_failure_event_rep(&lchan->ts->trx->mo,
NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT,
"%s IPAC Failed to create RTP/RTCP sockets",
gsm_lchan_name(lchan));
return -ENOTCONN;
}
rc = osmo_rtp_socket_set_param(lchan->abis_ip.rtp_socket,
bts->rtp_jitter_adaptive ?
OSMO_RTP_P_JIT_ADAP :
OSMO_RTP_P_JITBUF,
bts->rtp_jitter_buf_ms);
if (rc < 0)
LOGPLCHAN(lchan, DRTP, LOGL_ERROR,
"IPAC Failed to set RTP socket parameters: %s\n", strerror(-rc));
else
LOGPLCHAN(lchan, DRTP, LOGL_INFO, "IPAC set RTP socket parameters: %d\n", rc);
lchan->abis_ip.rtp_socket->priv = lchan;
lchan->abis_ip.rtp_socket->rx_cb = &l1sap_rtp_rx_cb;
rc = bind_rtp(bts, lchan->abis_ip.rtp_socket, bind_ip);
if (rc < 0) {
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to bind RTP/RTCP sockets\n");
oml_tx_failure_event_rep(&lchan->ts->trx->mo,
NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT,
"%s IPAC Failed to bind RTP/RTCP sockets",
gsm_lchan_name(lchan));
lchan_rtp_socket_free(lchan);
return -EBADFD;
}
/* Ensure RTCP SDES contains some useful information */
snprintf(cname, sizeof(cname), "bts@%s", bind_ip);
osmo_rtp_set_source_desc(lchan->abis_ip.rtp_socket, cname,
gsm_lchan_name(lchan), NULL, NULL,
gsm_trx_unit_id(lchan->ts->trx),
"OsmoBTS-" PACKAGE_VERSION, NULL);
/* FIXME: multiplex connection, BSC proxy */
return 0;
}
int lchan_rtp_socket_connect(struct gsm_lchan *lchan, const struct in_addr *ia, uint16_t connect_port)
{
int bound_port = 0;
int rc;
rc = osmo_rtp_socket_connect(lchan->abis_ip.rtp_socket,
inet_ntoa(*ia), connect_port);
if (rc < 0) {
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "Failed to connect RTP/RTCP sockets\n");
return -ECONNREFUSED;
}
/* save IP address and port number */
lchan->abis_ip.connect_ip = ntohl(ia->s_addr);
lchan->abis_ip.connect_port = connect_port;
rc = osmo_rtp_get_bound_ip_port(lchan->abis_ip.rtp_socket,
&lchan->abis_ip.bound_ip,
&bound_port);
if (rc < 0)
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC cannot obtain locally bound IP/port: %d\n", rc);
lchan->abis_ip.bound_port = bound_port;
return 0;
}
void lchan_rtp_socket_free(struct gsm_lchan *lchan)
{
osmo_rtp_socket_free(lchan->abis_ip.rtp_socket);
lchan->abis_ip.rtp_socket = NULL;
msgb_queue_free(&lchan->dl_tch_queue);
lchan->dl_tch_queue_len = 0;
}
/*! limit number of queue entries to %u; drops any surplus messages */
void lchan_dl_tch_queue_enqueue(struct gsm_lchan *lchan, struct msgb *msg, unsigned int limit)
{
if (lchan->dl_tch_queue_len > limit) {
unsigned int excess = lchan->dl_tch_queue_len - limit;
LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "freeing %d queued frames\n", excess);
rate_ctr_add2(lchan->ts->trx->bts->ctrs, BTS_CTR_RTP_RX_DROP_OVERFLOW, excess);
}
while (lchan->dl_tch_queue_len > limit) {
struct msgb *tmp = msgb_dequeue_count(&lchan->dl_tch_queue, &lchan->dl_tch_queue_len);
msgb_free(tmp);
}
msgb_enqueue_count(&lchan->dl_tch_queue, msg, &lchan->dl_tch_queue_len);
}

View File

@ -12,7 +12,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.

View File

@ -13,7 +13,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -84,17 +84,6 @@ static struct log_info_cat bts_log_info_cat[] = {
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
[DABIS] = {
.name = "DABIS",
.description = "A-bis Intput Subsystem",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
[DRTP] = {
.name = "DRTP",
.description = "Realtime Transfer Protocol",
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
[DPCU] = {
.name = "DPCU",
.description = "PCU interface",
@ -116,15 +105,33 @@ static struct log_info_cat bts_log_info_cat[] = {
[DLOOP] = {
.name = "DLOOP",
.description = "Control loops",
.color = "\033[0;34m",
.color = "\033[0;94m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
[DSUM] = {
.name = "DSUM",
.description = "DSUM",
[DABIS] = {
.name = "DABIS",
.description = "A-bis Intput Subsystem",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
[DRTP] = {
.name = "DRTP",
.description = "Realtime Transfer Protocol",
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
[DOSMUX] = {
.name = "DOSMUX",
.description = "Osmux (Osmocom RTP multiplexing)",
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
[DASCI] = {
.name = "DASCI",
.description = "ASCI (Advanced Speech Call Items: VGCS/VBS)",
.loglevel = LOGL_NOTICE,
.enabled = 1,
},
};
static int osmo_bts_filter_fn(const struct log_context *ctx, struct log_target *tgt)

View File

@ -12,7 +12,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -49,6 +49,7 @@
#include <osmo-bts/logging.h>
#include <osmo-bts/abis.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/bts_sm.h>
#include <osmo-bts/vty.h>
#include <osmo-bts/l1sap.h>
#include <osmo-bts/bts_model.h>
@ -233,7 +234,7 @@ static void signal_handler(int signum)
oml_tx_failure_event_rep(&g_bts->mo,
NM_SEVER_CRITICAL, OSMO_EVT_CRIT_PROC_STOP,
"BTS: SIGINT received -> shutdown");
bts_shutdown(g_bts, "SIGINT");
bts_shutdown_ext(g_bts, "SIGINT", true, false);
}
quit++;
break;
@ -257,25 +258,6 @@ static void signal_handler(int signum)
}
}
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_trx *trx;
@ -303,13 +285,21 @@ int bts_main(int argc, char **argv)
bts_vty_init(tall_bts_ctx);
e1inp_vty_init();
logging_vty_add_deprecated_subsys(tall_bts_ctx, "sum");
handle_options(argc, argv);
fprintf(stderr, "((*))\n |\n / \\ OsmoBTS\n");
if (vty_test_mode)
fprintf(stderr, "--- VTY test mode: not connecting to BSC, not exiting ---\n");
g_bts = gsm_bts_alloc(tall_bts_ctx, 0);
g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx);
if (!g_bts_sm) {
fprintf(stderr, "Failed to create BTS Site Manager structure\n");
exit(1);
}
g_bts = gsm_bts_alloc(g_bts_sm, 0);
if (!g_bts) {
fprintf(stderr, "Failed to create BTS structure\n");
exit(1);
@ -356,8 +346,6 @@ int bts_main(int argc, char **argv)
}
}
write_pid_file("osmo-bts");
/* Accept a GSMTAP host from VTY config, but a commandline option overrides that. */
if (gsmtap_ip != NULL) {
if (g_bts->gsmtap.remote_host != NULL) {
@ -373,27 +361,26 @@ int bts_main(int argc, char **argv)
/* TODO: move this to gsm_bts_alloc() */
if (g_bts->gsmtap.remote_host != NULL) {
LOGP(DLGLOBAL, LOGL_NOTICE,
"Setting up GSMTAP Um forwarding to '%s:%u'\n",
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
g_bts->gsmtap.inst = gsmtap_source_init(g_bts->gsmtap.remote_host,
GSMTAP_UDP_PORT, 1);
"Setting up GSMTAP Um forwarding '%s->'%s:%u'\n",
g_bts->gsmtap.local_host, g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
g_bts->gsmtap.inst = gsmtap_source_init2(g_bts->gsmtap.local_host, 0,
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT, 1);
if (g_bts->gsmtap.inst == NULL) {
fprintf(stderr, "Failed during gsmtap_source_init()\n");
fprintf(stderr, "Failed during gsmtap_source_init2()\n");
exit(1);
}
gsmtap_source_add_sink(g_bts->gsmtap.inst);
}
bts_controlif_setup(g_bts, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BTS);
bts_controlif_setup(g_bts, OSMO_CTRL_PORT_BTS);
rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(),
g_vty_port_num);
rc = telnet_init_default(tall_bts_ctx, NULL, g_vty_port_num);
if (rc < 0) {
fprintf(stderr, "Error initializing telnet\n");
exit(1);
}
if (pcu_sock_init(g_bts->pcu.sock_path)) {
if (pcu_sock_init(g_bts->pcu.sock_path, g_bts->pcu.sock_wqueue_len_max)) {
fprintf(stderr, "PCU L1 socket failed\n");
exit(1);
}
@ -405,6 +392,11 @@ int bts_main(int argc, char **argv)
signal(SIGUSR2, &signal_handler);
osmo_init_ignore_signals();
if (bts_osmux_open(g_bts) < 0) {
fprintf(stderr, "Osmux setup failed\n");
exit(1);
}
if (vty_test_mode) {
/* Just select-loop without connecting to the BSC, don't exit. This allows running tests on the VTY
* telnet port. */

View File

@ -16,10 +16,26 @@
#include <osmo-bts/power_control.h>
#include <osmo-bts/ta_control.h>
/* Tables as per TS 45.008 Section 8.3 */
static const uint8_t ts45008_83_tch_f[] = { 52, 53, 54, 55, 56, 57, 58, 59 };
static const uint8_t ts45008_83_tch_hs0[] = { 0, 2, 4, 6, 52, 54, 56, 58 };
static const uint8_t ts45008_83_tch_hs1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };
/* Active TDMA frame subset for TCH/H in DTX mode (see 3GPP TS 45.008 Section 8.3).
* This mapping is used to determine if a L2 block starting at the given TDMA FN
* belongs to the SUB set and thus shall always be transmitted in DTX mode. */
static const uint8_t ts45008_dtx_tchh_speech_fn_map[104] = {
/* TCH/H(0): 0, 2, 4, 6, 52, 54, 56, 58 */
[0] = 1, /* block { 0, 2, 4, 6} */
[52] = 1, /* block {52, 54, 56, 58} */
/* TCH/H(1): 14, 16, 18, 20, 66, 68, 70, 72 */
[14] = 1, /* block {14, 16, 18, 20} */
[66] = 1, /* block {66, 68, 70, 72} */
};
static const uint8_t ts45008_dtx_tchh_data_fn_map[104] = {
/* UL TCH/H(0): 52, 54, 56, 58, 60, 62, 65, 67, 69, 71 */
[52] = 1, /* block {52, 54, 56, 58, 60, 62} */
[60] = 1, /* block {60, 62, 65, 67, 69, 71} */
/* UL TCH/H(1): 70, 72, 74, 76, 79, 81, 83, 85, 87, 89 */
[70] = 1, /* block {70, 72, 74, 76, 79, 81} */
[79] = 1, /* block {79, 81, 83, 85, 87, 89} */
};
/* In cases where we less measurements than we expect we must assume that we
* just did not receive the block because it was lost due to bad channel
@ -31,22 +47,11 @@ static const uint8_t ts45008_83_tch_hs1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };
static const struct bts_ul_meas measurement_dummy = {
.ber10k = MEASUREMENT_DUMMY_BER,
.ta_offs_256bits = 0,
.c_i = 0,
.ci_cb = 0,
.is_sub = 0,
.inv_rssi = MEASUREMENT_DUMMY_IRSSI
};
/* find out if an array contains a given key as element */
#define ARRAY_CONTAINS(arr, val) array_contains(arr, ARRAY_SIZE(arr), val)
static bool array_contains(const uint8_t *arr, unsigned int len, uint8_t val) {
int i;
for (i = 0; i < len; i++) {
if (arr[i] == val)
return true;
}
return false;
}
/* Decide if a given frame number is part of the "-SUB" measurements (true) or not (false)
* (this function is only used internally, it is public to call it from unit-tests) */
bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
@ -54,61 +59,59 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
uint32_t fn104 = fn % 104;
/* See TS 45.008 Sections 8.3 and 8.4 for a detailed descriptions of the rules
* implemented here. We only implement the logic for Voice, not CSD */
* implemented here. We implement the logic for both speech and data (CSD). */
/* AMR is special, SID frames may be scheduled dynamically at any time */
if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
return false;
switch (lchan->type) {
case GSM_LCHAN_TCH_F:
switch (lchan->tch_mode) {
case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
case GSM48_CMODE_SPEECH_V1:
case GSM48_CMODE_SPEECH_V1_VAMOS:
case GSM48_CMODE_SPEECH_EFR:
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
return true;
if (ARRAY_CONTAINS(ts45008_83_tch_f, fn104))
case GSM48_CMODE_SPEECH_V2_VAMOS:
/* Active TDMA frame subset for TCH/F: 52, 53, 54, 55, 56, 57, 58, 59.
* There is only one *complete* block in this subset starting at FN=52.
* Incomplete blocks {... 52, 53, 54, 55} and {56, 57, 58, 59 ...}
* contain only 50% of the useful bits (partial SID) and thus ~50% BER. */
if (fn104 == 52)
return true;
break;
case GSM48_CMODE_SPEECH_AMR:
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
return true;
break;
case GSM48_CMODE_SIGN:
/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
* SUB */
return true;
case GSM48_CMODE_DATA_12k0: /* TCH/F9.6 */
case GSM48_CMODE_DATA_6k0: /* TCH/F4.8 */
/* FIXME: The RXQUAL_SUB (not RXLEV!) report shall include measurements on
* the TDMA frames given in the table of subclause 8.3 only if L2 fill frames
* have been received as FACCH/F frames at the corresponding frame positions. */
default:
LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n",
gsm_lchan_name(lchan), lchan->tch_mode);
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
return fn104 == 52;
LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode);
break;
}
break;
case GSM_LCHAN_TCH_H:
switch (lchan->tch_mode) {
case GSM48_CMODE_SPEECH_V1:
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
return true;
switch (lchan->nr) {
case 0:
if (ARRAY_CONTAINS(ts45008_83_tch_hs0, fn104))
return true;
break;
case 1:
if (ARRAY_CONTAINS(ts45008_83_tch_hs1, fn104))
return true;
break;
default:
OSMO_ASSERT(0);
}
break;
case GSM48_CMODE_SPEECH_AMR:
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
case GSM48_CMODE_SPEECH_V1_VAMOS:
if (ts45008_dtx_tchh_speech_fn_map[fn104])
return true;
break;
case GSM48_CMODE_SIGN:
/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
* SUB */
return true;
case GSM48_CMODE_DATA_6k0: /* TCH/H4.8 */
case GSM48_CMODE_DATA_3k6: /* TCH/H2.4 */
/* FIXME: The RXQUAL_SUB (not RXLEV!) report shall include measurements on
* the TDMA frames given in the table of subclause 8.3 only if L2 fill frames
* have been received as FACCH/H frames at the corresponding frame positions. */
default:
LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n",
gsm_lchan_name(lchan), lchan->tch_mode);
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
return ts45008_dtx_tchh_data_fn_map[fn104] == 1;
LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode);
break;
}
break;
@ -287,9 +290,8 @@ int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn)
}
if (rc == 1) {
DEBUGP(DMEAS,
"%s meas period end fn:%u, fn_mod:%i, status:%d, pchan:%s\n",
gsm_lchan_name(lchan), fn, fn_mod, rc, gsm_pchan_name(pchan));
LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG, "meas period end fn_mod:%d, status:%d, pchan:%s\n", fn_mod,
rc, gsm_pchan_name(pchan));
}
return rc;
@ -325,16 +327,15 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan,
struct bts_ul_meas *dest;
if (lchan->state != LCHAN_S_ACTIVE) {
LOGPFN(DMEAS, LOGL_NOTICE, fn,
"%s measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n",
gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
lchan->meas.num_ul_meas, fn_mod);
LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE,
"measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n",
gsm_lchans_name(lchan->state), lchan->meas.num_ul_meas, fn_mod);
}
if (lchan->meas.num_ul_meas >= ARRAY_SIZE(lchan->meas.uplink)) {
LOGPFN(DMEAS, LOGL_NOTICE, fn,
"%s no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n",
gsm_lchan_name(lchan), lchan->meas.num_ul_meas, fn_mod);
LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE,
"no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n", lchan->meas.num_ul_meas,
fn_mod);
return -ENOSPC;
}
@ -346,10 +347,10 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan,
if (!ulm->is_sub)
dest->is_sub = ts45008_83_is_sub(lchan, fn);
DEBUGPFN(DMEAS, fn, "%s adding measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, is_sub=%u, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
gsm_lchan_name(lchan), ulm->ber10k, ulm->ta_offs_256bits,
ulm->c_i, dest->is_sub, ulm->inv_rssi, lchan->meas.num_ul_meas,
fn_mod);
LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG,
"adding a %s measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
dest->is_sub ? "SUB" : "FULL", ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi,
lchan->meas.num_ul_meas, fn_mod);
lchan->meas.last_fn = fn;
@ -423,32 +424,50 @@ static unsigned int lchan_meas_num_expected(const struct gsm_lchan *lchan)
}
/* In DTX a subset of blocks must always be transmitted
* See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX) */
static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
* See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX)
* Return value N: (N < 0) -- at least N SUB frames expected;
* (N > 0) -- exactly N SUB frames expected;
* (N == 0) - unknown channel type/mode? */
static int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
{
enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
/* AMR is using a more elaborated model with a dymanic amount of
* DTX blocks so this function is not applicable to determine the
* amount of expected SUB Measurements when AMR is used */
OSMO_ASSERT(lchan->tch_mode != GSM48_CMODE_SPEECH_AMR);
switch (pchan) {
case GSM_PCHAN_TCH_F:
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
/* 1 block SACCH, 24 blocks TCH (see note 1) */
return 25;
} else {
/* 1 block SACCH, 2 blocks TCH */
return 3;
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
return 1 + 1; /* 1 x SACCH + 1 x FACCH */
/* else: signalling or speech */
switch (lchan->tch_mode) {
case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
case GSM48_CMODE_SPEECH_V1: /* TCH/FS */
case GSM48_CMODE_SPEECH_V1_VAMOS:
case GSM48_CMODE_SPEECH_EFR: /* TCH/EFS */
case GSM48_CMODE_SPEECH_V2_VAMOS:
return 1 + 1; /* 1 x SACCH + 1 x TCH */
case GSM48_CMODE_SPEECH_AMR: /* TCH/AFS */
case GSM48_CMODE_SPEECH_V3_VAMOS:
case GSM48_CMODE_SPEECH_V4: /* O-TCH/WFS */
case GSM48_CMODE_SPEECH_V5: /* TCH/WFS */
case GSM48_CMODE_SPEECH_V5_VAMOS:
default:
return -1; /* at least 1 x SACCH + M x TCH (variable) */
}
case GSM_PCHAN_TCH_H:
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
/* 1 block SACCH, 12 blocks TCH (see ynote 1) */
return 13;
} else {
/* 1 block SACCH, 4 blocks TCH */
return 5;
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
return 1 + 2; /* 1 x SACCH + 2 x FACCH */
/* else: signalling or speech */
switch (lchan->tch_mode) {
case GSM48_CMODE_SIGN: /* TCH/H sign: DTX *is not* permitted */
return 1 + 12; /* 1 x SACCH + 12 x TCH */
case GSM48_CMODE_SPEECH_V1:
case GSM48_CMODE_SPEECH_V1_VAMOS:
return 1 + 2; /* 1 x SACCH + 2 x TCH */
case GSM48_CMODE_SPEECH_AMR: /* TCH/AHS */
case GSM48_CMODE_SPEECH_V3_VAMOS:
case GSM48_CMODE_SPEECH_V4: /* O-TCH/WHS */
case GSM48_CMODE_SPEECH_V6: /* O-TCH/AHS */
default:
return -1; /* at least 1 x SACCH + M x TCH (variable) */
}
case GSM_PCHAN_SDCCH8_SACCH8C:
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
@ -461,8 +480,6 @@ static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
default:
return 0;
}
/* Note 1: In signalling mode all blocks count as SUB blocks. */
}
/* if we clip the TOA value to 12 bits, i.e. toa256=3200,
@ -568,7 +585,7 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
unsigned int num_meas_sub = 0;
unsigned int num_meas_sub_actual = 0;
unsigned int num_meas_sub_subst = 0;
unsigned int num_meas_sub_expect;
int num_meas_sub_expect;
unsigned int num_ul_meas;
unsigned int num_ul_meas_actual = 0;
unsigned int num_ul_meas_subst = 0;
@ -588,16 +605,7 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
* intentionally to save energy. It is not necessarly an error
* when we get less measurements as we expect. */
num_ul_meas_expect = lchan_meas_num_expected(lchan);
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR)
num_meas_sub_expect = lchan_meas_sub_num_expected(lchan);
else {
/* When AMR is used, we expect at least one SUB frame, since
* the SACCH will always be SUB frame. There may occur more
* SUB frames but since DTX periods in AMR are dynamic, we
* can not know how many exactly. */
num_meas_sub_expect = 1;
}
num_meas_sub_expect = lchan_meas_sub_num_expected(lchan);
if (lchan->meas.num_ul_meas > num_ul_meas_expect)
num_ul_meas_excess = lchan->meas.num_ul_meas - num_ul_meas_expect;
@ -631,24 +639,21 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
m = &lchan->meas.uplink[i + num_ul_meas_excess];
if (m->is_sub) {
irssi_sub_sum += m->inv_rssi;
ci_sub_sum += m->c_i;
ci_sub_sum += m->ci_cb;
num_meas_sub_actual++;
is_sub = true;
}
irssi_full_sum += m->inv_rssi;
ta256b_sum += m->ta_offs_256bits;
ci_full_sum += m->c_i;
ci_full_sum += m->ci_cb;
num_ul_meas_actual++;
} else {
m = &measurement_dummy;
/* For AMR the amount of SUB frames is defined by the
* the occurrence of DTX periods, which are dynamically
* negotiated in AMR, so we can not know if and how many
* SUB frames are missing. */
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
if (num_meas_sub <= i) {
/* only if we know the exact number of SUB measurements */
if (num_meas_sub_expect >= 0) {
if (num_meas_sub < num_meas_sub_expect) {
num_meas_sub_subst++;
is_sub = true;
}
@ -664,16 +669,6 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
}
}
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
"Received UL measurements contain %u SUB measurements, expected %u\n",
num_meas_sub_actual, num_meas_sub_expect);
} else {
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
"Received UL measurements contain %u SUB measurements, expected at least %u\n",
num_meas_sub_actual, num_meas_sub_expect);
}
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, "Replaced %u measurements with dummy values, "
"from which %u were SUB measurements\n", num_ul_meas_subst, num_meas_sub_subst);
@ -684,17 +679,24 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
* above only adds missing measurements during the calculation
* it can not remove excess SUB measurements or add missing SUB
* measurements when there is no more room in the interval. */
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
if (num_meas_sub != num_meas_sub_expect) {
if (num_meas_sub_expect < 0) {
num_meas_sub_expect = -num_meas_sub_expect;
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
"Received UL measurements contain %u SUB measurements, expected at least %d\n",
num_meas_sub_actual, num_meas_sub_expect);
if (OSMO_UNLIKELY(num_meas_sub < num_meas_sub_expect)) {
LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
"Incorrect number of SUB measurements detected! "
"(%u vs exp %u)\n", num_meas_sub, num_meas_sub_expect);
"(%u vs exp >=%d)\n", num_meas_sub, num_meas_sub_expect);
}
} else {
if (num_meas_sub < num_meas_sub_expect) {
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
"Received UL measurements contain %u SUB measurements, expected %d\n",
num_meas_sub_actual, num_meas_sub_expect);
if (OSMO_UNLIKELY(num_meas_sub != num_meas_sub_expect)) {
LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
"Incorrect number of SUB measurements detected! "
"(%u vs exp >=%u)\n", num_meas_sub, num_meas_sub_expect);
"(%u vs exp %d)\n", num_meas_sub, num_meas_sub_expect);
}
}
@ -933,6 +935,8 @@ void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg)
uint8_t ms_ta;
int8_t ul_rssi;
int16_t ul_ci_cb;
uint8_t *l3;
unsigned int l3_len;
if (msgb_l2len(msg) == GSM_MACBLOCK_LEN) {
/* Some brilliant engineer decided that the ordering of
@ -962,7 +966,9 @@ void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg)
}
timing_offset = ms_to_valid(lchan) ? ms_to2rsl(lchan, ms_ta) : -1;
rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), timing_offset);
l3 = msgb_l3(msg);
l3_len = l3 ? msgb_l3len(msg) : 0;
rc = rsl_tx_meas_res(lchan, l3, l3_len, timing_offset);
if (rc == 0) /* Count successful transmissions */
lchan->meas.res_nr++;

View File

@ -10,7 +10,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -321,17 +321,17 @@ static inline bool dtx_amr_sid_optional(struct gsm_lchan *lchan, uint32_t fn)
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->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) {
} 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) {
} 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);
@ -380,15 +380,19 @@ static inline bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn)
static const uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 },
h0[] = { 0, 2, 4, 6, 52, 54, 56, 58 },
h1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };
if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1) {
switch (lchan->tch_mode) {
case GSM48_CMODE_SPEECH_V1:
if (lchan->type == GSM_LCHAN_TCH_F)
return fn_chk(f, fn, ARRAY_SIZE(f));
else
return fn_chk(lchan->nr ? h1 : h0, fn,
lchan->nr ? ARRAY_SIZE(h1) :
ARRAY_SIZE(h0));
case GSM48_CMODE_SPEECH_EFR:
return fn_chk(f, fn, ARRAY_SIZE(f));
default:
return false;
}
return false;
}
/*! \brief Check if DTX DL AMR is enabled for a given lchan (it have proper type,
@ -466,10 +470,6 @@ void dtx_int_signal(struct gsm_lchan *lchan)
*/
uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn)
{
/* FIXME: add EFR support */
if (lchan->tch_mode == GSM48_CMODE_SPEECH_EFR)
return 0;
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
if (dtx_sched_optional(lchan, fn))
return 0;

View File

@ -1,6 +1,6 @@
/* NM Radio Carrier FSM */
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* All Rights Reserved
@ -13,7 +13,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -70,17 +70,17 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint3
static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
int i;
switch (event) {
case NM_EV_SW_ACT:
oml_mo_tx_sw_act_rep(&bb_transc->mo);
nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE);
for (i = 0; i < TRX_NR_TS; i++) {
struct gsm_bts_trx_ts *ts = &trx->ts[i];
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_BBTRANSC_INSTALLED, NULL);
}
ev_dispatch_children(bb_transc, event);
return;
case NM_EV_OML_UP:
/* Report current state: */
oml_tx_state_changed(&bb_transc->mo);
ev_dispatch_children(bb_transc, event);
return;
case NM_EV_RSL_UP:
return;
@ -119,17 +119,48 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
{
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
struct gsm_bts *bts = trx->bts;
struct nm_fsm_ev_setattr_data *setattr_data;
bool phy_state_connected;
bool rsl_link_connected;
int rc;
switch (event) {
case NM_EV_SETATTR_ACK:
case NM_EV_SETATTR_NACK:
case NM_EV_OML_UP:
/* Report current state: */
oml_tx_state_changed(&bb_transc->mo);
ev_dispatch_children(bb_transc, event);
return;
case NM_EV_RX_SETATTR:
setattr_data = (struct nm_fsm_ev_setattr_data *)data;
bb_transc->mo.setattr_success = setattr_data->cause == 0;
oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
break;
rc = bts_model_apply_oml(trx->bts, setattr_data->msg,
&bb_transc->mo, bb_transc);
bb_transc->mo.setattr_success = rc == 0;
oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
return;
case NM_EV_RX_OPSTART:
#if 0
/* Disabled because osmo-bsc doesn't send SetAttr on BB_TRANSC object */
if (!bb_transc->mo.setattr_success) {
oml_mo_opstart_nack(&bb_transc->mo, NM_NACK_CANT_PERFORM);
return;
}
#endif
/* Connect RSL link: */
if (bts->variant == BTS_OSMO_OMLDUMMY) {
LOGPFSML(fi, LOGL_NOTICE, "Not connecting RSL in OML-DUMMY!\n");
} else {
rc = e1inp_ipa_bts_rsl_connect_n(bts->oml_link->ts->line,
bb_transc->rsl.rem_addrstr.ip,
bb_transc->rsl.rem_addrstr.port, trx->nr);
if (rc < 0) {
LOGPFSML(fi, LOGL_NOTICE, "Error connecting IPA RSL: %d\n", rc);
oml_mo_opstart_nack(&bb_transc->mo, NM_NACK_CANT_PERFORM);
return;
}
}
bts_model_opstart(trx->bts, &bb_transc->mo, bb_transc);
return;
case NM_EV_OPSTART_ACK:
bb_transc->mo.opstart_success = true;
oml_mo_opstart_ack(&bb_transc->mo);
@ -153,10 +184,10 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
}
if (trx->bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */
if (bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */
struct phy_instance *pinst = trx_phy_instance(trx);
phy_state_connected = phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED;
rsl_link_connected = !!trx->rsl_link;
rsl_link_connected = !!trx->bb_transc.rsl.link;
} else {
phy_state_connected = true;
rsl_link_connected = true;
@ -231,6 +262,7 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = {
[NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED] = {
.in_event_mask =
X(NM_EV_SW_ACT) |
X(NM_EV_OML_UP) |
X(NM_EV_RSL_UP) |
X(NM_EV_RSL_DOWN) |
X(NM_EV_PHYLINK_UP) |
@ -245,8 +277,9 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = {
},
[NM_BBTRANSC_ST_OP_DISABLED_OFFLINE] = {
.in_event_mask =
X(NM_EV_SETATTR_ACK) |
X(NM_EV_SETATTR_NACK) |
X(NM_EV_OML_UP) |
X(NM_EV_RX_SETATTR) |
X(NM_EV_RX_OPSTART) |
X(NM_EV_OPSTART_ACK) |
X(NM_EV_OPSTART_NACK) |
X(NM_EV_RSL_UP) |

View File

@ -1,6 +1,6 @@
/* NM BTS FSM */
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* All Rights Reserved
@ -13,7 +13,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -36,6 +36,7 @@
#include <osmo-bts/nm_common_fsm.h>
#include <osmo-bts/phy_link.h>
#include <osmo-bts/cbch.h>
#include <osmo-bts/notification.h>
#define X(s) (1 << (s))
@ -60,8 +61,13 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint3
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
/* Reset state: */
bts->si_valid = 0;
bts->bsic_configured = false;
bts->bsic = 0xff; /* invalid value */
TALLOC_FREE(bts->mo.nm_attr);
bts_cbch_reset(bts);
bts_asci_notification_reset(bts);
if (bts->c0_power_red_db > 0)
bts_set_c0_pwr_red(bts, 0);
bts->mo.setattr_success = false;
bts->mo.opstart_success = false;
@ -74,7 +80,8 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
struct gsm_bts_trx *trx;
switch (event) {
case NM_EV_SW_ACT:
case NM_EV_OML_UP:
/* automatic SW_ACT upon OML link establishment: */
oml_mo_tx_sw_act_rep(&bts->mo);
llist_for_each_entry(trx, &bts->trx_list, list) {
@ -91,6 +98,7 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
}
nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_DISABLED_OFFLINE);
ev_dispatch_children(bts, event);
return;
default:
OSMO_ASSERT(0);
@ -109,13 +117,21 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
{
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
struct nm_fsm_ev_setattr_data *setattr_data;
int rc;
switch (event) {
case NM_EV_SETATTR_ACK:
case NM_EV_SETATTR_NACK:
case NM_EV_RX_SETATTR:
setattr_data = (struct nm_fsm_ev_setattr_data *)data;
bts->mo.setattr_success = setattr_data->cause == 0;
oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
rc = bts_model_apply_oml(bts, setattr_data->msg, &bts->mo, bts);
bts->mo.setattr_success = rc == 0;
oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
break;
case NM_EV_RX_OPSTART:
if (!bts->mo.setattr_success) {
oml_mo_opstart_nack(&bts->mo, NM_NACK_CANT_PERFORM);
return;
}
bts_model_opstart(bts, &bts->mo, bts);
break;
case NM_EV_OPSTART_ACK:
bts->mo.opstart_success = true;
@ -166,7 +182,7 @@ static void nm_bts_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data
static struct osmo_fsm_state nm_bts_fsm_states[] = {
[NM_BTS_ST_OP_DISABLED_NOTINSTALLED] = {
.in_event_mask =
X(NM_EV_SW_ACT),
X(NM_EV_OML_UP),
.out_state_mask =
X(NM_BTS_ST_OP_DISABLED_NOTINSTALLED) |
X(NM_BTS_ST_OP_DISABLED_OFFLINE),
@ -176,8 +192,8 @@ static struct osmo_fsm_state nm_bts_fsm_states[] = {
},
[NM_BTS_ST_OP_DISABLED_OFFLINE] = {
.in_event_mask =
X(NM_EV_SETATTR_ACK) |
X(NM_EV_SETATTR_NACK) |
X(NM_EV_RX_SETATTR) |
X(NM_EV_RX_OPSTART) |
X(NM_EV_OPSTART_ACK) |
X(NM_EV_OPSTART_NACK),
.out_state_mask =

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