Compare commits

...

64 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
189 changed files with 10163 additions and 791 deletions

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

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

View File

@ -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

@ -7,3 +7,6 @@
# 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

@ -11,7 +11,6 @@ WorkingDirectory=%S/osmocom
RuntimeDirectory=osmo-bts
Restart=always
RestartSec=2
RestartPreventExitStatus=1
# CPU scheduling policy:
CPUSchedulingPolicy=rr

View File

@ -11,7 +11,6 @@ WorkingDirectory=%S/osmocom
RuntimeDirectory=osmo-bts
Restart=always
RestartSec=2
RestartPreventExitStatus=1
# CPU scheduling policy:
CPUSchedulingPolicy=rr

View File

@ -13,12 +13,11 @@ StateDirectory=osmocom
WorkingDirectory=%S/osmocom
Restart=always
RestartSec=2
RestartPreventExitStatus=1
# CPU scheduling policy:
CPUSchedulingPolicy=rr
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
CPUSchedulingPriority=11
CPUSchedulingPriority=20
# See sched(7) for further details on real-time policies and priorities
[Install]

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

@ -867,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>>
@ -1089,6 +1091,16 @@ 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

View File

@ -11,11 +11,13 @@ enum {
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);
void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access);
void vgcs_listener_reset(struct gsm_lchan *lchan);

View File

@ -31,6 +31,15 @@ enum {
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 */
@ -130,6 +139,9 @@ struct gsm_gprs_cell {
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) */
@ -238,7 +250,7 @@ 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 {
@ -319,6 +331,7 @@ struct gsm_bts {
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;
@ -373,6 +386,8 @@ struct gsm_bts {
char *local_host;
uint32_t sapi_mask;
uint8_t sapi_acch;
bool rlp;
bool rlp_skip_null;
} gsmtap;
struct osmux_state osmux;

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/>.

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

View File

@ -59,6 +59,52 @@
#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,

View File

@ -102,6 +102,7 @@ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr);
int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr);
int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr);
int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr);
int l1sap_uplink_access(struct gsm_lchan *lchan, bool active);
enum l1sap_common_sapi {
L1SAP_COMMON_SAPI_UNKNOWN,

View File

@ -208,6 +208,8 @@ struct gsm_lchan {
uint8_t sapis_dl[23];
uint8_t sapis_ul[23];
struct lapdm_channel lapdm_ch;
/* It is required to have L3 info with DL establishment. */
bool l3_info_estab;
struct llist_head dl_tch_queue;
unsigned int dl_tch_queue_len;
struct {
@ -285,7 +287,11 @@ struct gsm_lchan {
} 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*/

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/>.

View File

@ -68,7 +68,7 @@ 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,

View File

@ -7,12 +7,11 @@
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
#define PCU_IF_VERSION 0x0b
#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 */
@ -29,8 +28,6 @@
/* 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 */
@ -40,7 +37,7 @@
/* 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)
@ -60,6 +57,17 @@
#define PCU_IF_ADDR_TYPE_IPV4 0x04 /* IPv4 address */
#define PCU_IF_ADDR_TYPE_IPV6 0x29 /* IPv6 address */
/* BTS model */
enum gsm_pcuif_bts_model {
PCU_IF_BTS_MODEL_UNSPEC,
PCU_IF_BTS_MODEL_LC15,
PCU_IF_BTS_MODEL_OC2G,
PCU_IF_BTS_MODEL_OCTPHY,
PCU_IF_BTS_MODEL_SYSMO,
PCU_IF_BTS_MODEL_TRX,
PCU_IF_BTS_MODEL_RBS,
};
#define PCU_IF_NUM_NSVC 2
#define PCU_IF_NUM_TRX 8
@ -173,6 +181,7 @@ struct gsm_pcu_if_info_ind {
struct in_addr v4;
struct in6_addr v6;
} remote_ip[PCU_IF_NUM_NSVC];
uint8_t bts_model; /* enum gsm_pcuif_bts_model */
} __attribute__ ((packed));
struct gsm_pcu_if_act_req {
@ -256,7 +265,6 @@ 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 data_cnf2;
struct gsm_pcu_if_data data_ind;
struct gsm_pcu_if_susp_req susp_req;

View File

@ -92,7 +92,6 @@ struct l1sched_chan_state {
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 */
uint32_t ul_mask; /* mask of received bursts */
@ -186,6 +185,9 @@ 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);

View File

@ -21,7 +21,6 @@ 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);

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,9 +225,9 @@ 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 {
@ -364,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);
}
@ -404,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

@ -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/>.

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/>.
@ -126,9 +126,9 @@ void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t
/* Stop RACH detection, wait for valid frame */
lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
if (l1sap_chan_modify(lchan->ts->trx, gsm_lchan2chan_nr(lchan)) != 0) {
LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "failed to modify channel after TALKER DET\n");
rsl_tx_conn_fail(lchan, RSL_ERR_TALKER_ACC_FAIL);
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;
}
@ -151,11 +151,25 @@ void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t
}
}
/* 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);
}
@ -169,7 +183,7 @@ void vgcs_talker_frame(struct gsm_lchan *lchan)
}
/* Release VGCS Talker state. */
void vgcs_talker_reset(struct gsm_lchan *lchan)
void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access)
{
if (lchan->asci.talker_active == VGCS_TALKER_NONE)
return;
@ -179,8 +193,15 @@ void vgcs_talker_reset(struct gsm_lchan *lchan)
/* Stop T3115 */
osmo_timer_del(&lchan->asci.t3115);
/* Talker detection done */
/* 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. */

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/>.
@ -59,6 +59,7 @@
#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 */
@ -103,6 +104,15 @@ static const struct rate_ctr_desc bts_ctr_desc[] = {
[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",
@ -344,7 +354,7 @@ int bts_init(struct gsm_bts *bts)
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;
@ -354,8 +364,8 @@ int bts_init(struct gsm_bts *bts)
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);
bts->pcu.sock_wqueue_len_max = BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT;
for (i = 0; i < ARRAY_SIZE(bts->t200_ms); i++)
bts->t200_ms[i] = oml_default_t200_ms[i];
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;
@ -384,6 +394,9 @@ int bts_init(struct gsm_bts *bts)
osmo_bts_set_feature(bts->features, BTS_FEAT_IPV6_NSVC);
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)
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/>.
@ -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/>.

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/>.

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

@ -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

@ -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

@ -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

@ -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/>.

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/>.
@ -33,6 +33,7 @@
#include <osmocom/gsm/l1sap.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/rsl.h>
#include <osmocom/gsm/rlp.h>
#include <osmocom/core/gsmtap.h>
#include <osmocom/core/gsmtap_util.h>
#include <osmocom/core/utils.h>
@ -957,10 +958,10 @@ static void l1sap_update_fnstats(struct gsm_bts *bts, uint32_t rts_fn)
}
/* Common dequeueing function */
static inline struct msgb *lapdm_phsap_dequeue_msg(struct lapdm_entity *le)
static inline struct msgb *lapdm_phsap_dequeue_msg(struct lapdm_entity *le, uint32_t fn)
{
struct osmo_phsap_prim pp;
if (lapdm_phsap_dequeue_prim(le, &pp) < 0)
if (lapdm_phsap_dequeue_prim_fn(le, &pp, fn) < 0)
return NULL;
return pp.oph.msg;
}
@ -983,7 +984,7 @@ static inline struct msgb *lapdm_phsap_dequeue_msg_facch(struct gsm_lchan *lchan
lchan->rep_acch.dl_facch[1].msg = NULL;
} else {
/* Fetch new FACCH from queue ... */
if (lapdm_phsap_dequeue_prim(le, &pp) < 0)
if (lapdm_phsap_dequeue_prim_fn(le, &pp, fn) < 0)
return NULL;
msg = pp.oph.msg;
@ -1013,7 +1014,7 @@ static inline struct msgb *lapdm_phsap_dequeue_msg_facch(struct gsm_lchan *lchan
}
/* Special dequeueing function with SACCH repetition (3GPP TS 44.006, section 11) */
static inline struct msgb *lapdm_phsap_dequeue_msg_sacch(struct gsm_lchan *lchan, struct lapdm_entity *le)
static inline struct msgb *lapdm_phsap_dequeue_msg_sacch(struct gsm_lchan *lchan, struct lapdm_entity *le, uint32_t fn)
{
struct osmo_phsap_prim pp;
struct msgb *msg;
@ -1037,7 +1038,7 @@ static inline struct msgb *lapdm_phsap_dequeue_msg_sacch(struct gsm_lchan *lchan
}
/* Fetch new repetition candidate from queue */
if (lapdm_phsap_dequeue_prim(le, &pp) < 0)
if (lapdm_phsap_dequeue_prim_fn(le, &pp, fn) < 0)
return NULL;
msg = pp.oph.msg;
sapi = (msg->data[0] >> 2) & 0x07;
@ -1148,9 +1149,9 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx,
LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-SACCH repetition: active => inactive\n");
lchan->rep_acch.dl_sacch_active = false;
}
pp_msg = lapdm_phsap_dequeue_msg_sacch(lchan, le);
pp_msg = lapdm_phsap_dequeue_msg_sacch(lchan, le, fn);
} else {
pp_msg = lapdm_phsap_dequeue_msg(le);
pp_msg = lapdm_phsap_dequeue_msg(le, fn);
}
} else {
if (lchan->ts->trx->bts->dtxd)
@ -1159,7 +1160,7 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx,
if (lchan->rep_acch.dl_facch_active && lchan->rsl_cmode != RSL_CMOD_SPD_SIGN)
pp_msg = lapdm_phsap_dequeue_msg_facch(lchan, le, fn);
else
pp_msg = lapdm_phsap_dequeue_msg(le);
pp_msg = lapdm_phsap_dequeue_msg(le, fn);
lchan->tch.dtx_fr_hr_efr.dl_facch_stealing = (pp_msg != NULL);
}
if (!pp_msg) {
@ -1802,22 +1803,37 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
lchan_meas_handle_sacch(lchan, msg);
}
if (L1SAP_IS_LINK_SACCH(link_id))
le = &lchan->lapdm_ch.lapdm_acch;
else
le = &lchan->lapdm_ch.lapdm_dcch;
/* bad frame */
if (len == 0)
if (len == 0) {
/* Notify current receive FN to lapdm. */
lapdm_t200_fn(le, fn);
return -EINVAL;
}
/* report first valid received frame to handover process */
if (lchan->ho.active == HANDOVER_WAIT_FRAME)
handover_frame(lchan);
/* report first valid received frame to VGCS talker process */
if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt) && lchan->asci.talker_active == VGCS_TALKER_WAIT_FRAME)
vgcs_talker_frame(lchan);
if (L1SAP_IS_LINK_SACCH(link_id))
le = &lchan->lapdm_ch.lapdm_acch;
else
le = &lchan->lapdm_ch.lapdm_dcch;
if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) {
/* report first valid received frame to VGCS talker process */
if (lchan->asci.talker_active == VGCS_TALKER_WAIT_FRAME)
vgcs_talker_frame(lchan);
/* 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.
*/
if (lchan->asci.talker_active != VGCS_TALKER_ACTIVE)
return 0;
}
if (check_for_first_ciphrd(lchan, data, len))
l1sap_tx_ciph_req(lchan->ts->trx, chan_nr, 1, 0);
@ -1826,23 +1842,111 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
msgb_pull_to_l2(msg);
lapdm_phsap_up(&l1sap->oph, le);
/* Notify current receive FN to lapdm. */
lapdm_t200_fn(le, fn);
/* don't free, because we forwarded data */
return 1;
}
static void send_ul_rtp_packet_data(struct gsm_lchan *lchan, uint32_t fn,
/* process one MAC block of unpacked bits of a non-transparent CSD channel */
static void gsmtap_csd_rlp_process(struct gsm_lchan *lchan, bool is_uplink,
const struct ph_tch_param *tch_ind,
const uint8_t *data, unsigned int data_len)
{
struct gsm_bts_trx *trx = lchan->ts->trx;
struct gsmtap_inst *inst = trx->bts->gsmtap.inst;
struct osmo_rlp_frame_decoded rlpf;
pbit_t *rlp_buf;
uint16_t arfcn;
int byte_len;
if (!inst || !trx->bts->gsmtap.rlp)
return;
if (lchan->csd_mode != LCHAN_CSD_M_NT)
return;
if (is_uplink)
rlp_buf = lchan->tch.csd.rlp_buf_ul;
else
rlp_buf = lchan->tch.csd.rlp_buf_dl;
/* TCH/F 9.6: 4x60bit block => 240bit RLP frame
* TCH/F 4.8: 2x 2x60bit blocks starting at B0/B2/B4 => 240bit RLP frame
* TCH/H 4.8: 4x60bit block => 240bit RLP frame
* TCH/F 2.4: 2x36bit blocks => transparent only
* TCH/H 2.4: 4x36bit blocks => transparent only
* TCH/F 14.4: 2x 290 bit block (starting with M1=0) => 576-bit RLP frame
*/
if (lchan->type == GSM_LCHAN_TCH_F && lchan->tch_mode == GSM48_CMODE_DATA_6k0) {
/* in this mode we have 120bit MAC blocks; two of them need to be concatenated
* to render a 240-bit RLP frame. The fist block is present in B0/B2/B4.
* The E7 bit is used to indicate the Frame MF0a */
OSMO_ASSERT(data_len == 120);
ubit_t e7 = data[4*7+3];
if (e7 == 0) {
osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1);
return;
} else {
osmo_ubit2pbit_ext(rlp_buf, 120, data, 0, data_len, 1);
byte_len = 240/8;
}
} else if (lchan->type == GSM_LCHAN_TCH_F && lchan->tch_mode == GSM48_CMODE_DATA_14k5) {
/* in this mode we have 290bit MAC blocks containing M1, M2 and 288 data bits;
* two of them need to be concatenated to render a
* 576-bit RLP frame. The start of a RLP frame is
* denoted by a block with M1-bit set to 0. */
OSMO_ASSERT(data_len == 290);
ubit_t m1 = data[0];
if (m1 == 0) {
osmo_ubit2pbit_ext(rlp_buf, 0, data, 2, data_len, 1);
return;
} else {
osmo_ubit2pbit_ext(rlp_buf, 288, data, 2, data_len, 1);
byte_len = 576/8;
}
} else {
byte_len = osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1);
}
if (trx->bts->gsmtap.rlp_skip_null) {
int rc = osmo_rlp_decode(&rlpf, 0, rlp_buf, byte_len);
if (rc == 0 && rlpf.ftype == OSMO_RLP_FT_U && rlpf.u_ftype == OSMO_RLP_U_FT_NULL)
return;
}
arfcn = trx->arfcn;
if (is_uplink)
arfcn |= GSMTAP_ARFCN_F_UPLINK;
gsmtap_send_ex(inst, GSMTAP_TYPE_GSM_RLP, arfcn, lchan->ts->nr,
lchan->type == GSM_LCHAN_TCH_H ? GSMTAP_CHANNEL_VOICE_H : GSMTAP_CHANNEL_VOICE_F,
lchan->nr, tch_ind->fn, tch_ind->rssi, 0, rlp_buf, byte_len);
}
static void send_ul_rtp_packet_data(struct gsm_lchan *lchan, const struct ph_tch_param *tch_ind,
const uint8_t *data, uint16_t data_len)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
uint8_t rtp_pl[RFC4040_RTP_PLEN];
int rc;
gsmtap_csd_rlp_process(lchan, true, tch_ind, data, data_len);
rc = csd_v110_rtp_encode(lchan, &rtp_pl[0], data, data_len);
if (rc < 0)
return;
rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_TX_TOTAL);
if (lchan->rtp_tx_marker)
rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_TX_MARKER);
osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket,
&rtp_pl[0], sizeof(rtp_pl),
fn_ms_adj(fn, lchan),
fn_ms_adj(tch_ind->fn, lchan),
lchan->rtp_tx_marker);
/* Only clear the marker bit once we have sent a RTP packet with it */
lchan->rtp_tx_marker = false;
@ -1852,12 +1956,17 @@ static void send_ul_rtp_packet_data(struct gsm_lchan *lchan, uint32_t fn,
static void send_ul_rtp_packet_speech(struct gsm_lchan *lchan, uint32_t fn,
const uint8_t *rtp_pl, uint16_t rtp_pl_len)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
if (lchan->abis_ip.osmux.use) {
lchan_osmux_send_frame(lchan, rtp_pl, rtp_pl_len,
fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
} else if (lchan->abis_ip.rtp_socket) {
osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket,
rtp_pl, rtp_pl_len, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_TX_TOTAL);
if (lchan->rtp_tx_marker)
rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_TX_MARKER);
}
/* Only clear the marker bit once we have sent a RTP packet with it */
lchan->rtp_tx_marker = false;
@ -1950,6 +2059,12 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap,
LOGPLCGT(lchan, &g_time, DL1P, LOGL_DEBUG, "Rx TCH.ind\n");
}
/* Notify current receive FN to lapdm.
* TCH frames may be indicated before FACCH frames are indicated. To prevent T200 timeout before FACCH is
* received, subtract one frame number, so that timeout is processed next time after FACCH is received.
*/
lapdm_t200_fn(&lchan->lapdm_ch.lapdm_dcch, GSM_TDMA_FN_SUB(fn, 1));
/* The ph_tch_param contained in the l1sap primitive may contain
* measurement data. If this data is present, forward it for
* processing */
@ -1976,9 +2091,10 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap,
send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len);
break;
case RSL_CMOD_SPD_DATA:
send_ul_rtp_packet_data(lchan, fn, msg->data, msg->len);
send_ul_rtp_packet_data(lchan, tch_ind, msg->data, msg->len);
break;
case RSL_CMOD_SPD_SIGN:
return 0; /* drop stale TCH.ind */
default: /* shall not happen */
OSMO_ASSERT(0);
}
@ -2254,17 +2370,25 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
uint32_t timestamp, bool marker)
{
struct gsm_lchan *lchan = rs->priv;
struct gsm_bts *bts = lchan->ts->trx->bts;
struct msgb *msg;
bool rfc5993_sid = false;
rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_TOTAL);
if (marker)
rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_MARKER);
/* if we're in loopback mode, we don't accept frames from the
* RTP socket anymore */
if (lchan->loopback)
if (lchan->loopback) {
rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_DROP_LOOPBACK);
return;
}
/* initial preen */
switch (rtp_payload_input_preen(lchan, rtp_pl, rtp_pl_len, &rfc5993_sid)) {
case PL_DECISION_DROP:
rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_DROP_PREEN);
return;
case PL_DECISION_ACCEPT:
break;
@ -2284,8 +2408,13 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
int rc = csd_v110_rtp_decode(lchan, msg->tail,
rtp_pl, rtp_pl_len);
if (rc > 0) {
/* 'fake' tch_ind containing all-zero so gsmtap code can be shared
* between UL and DL */
static const struct ph_tch_param fake_tch_ind = {};
gsmtap_csd_rlp_process(lchan, false, &fake_tch_ind, msg->tail, rc);
msgb_put(msg, rc);
} else {
rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_DROP_V110_DEC);
msgb_free(msg);
return;
}
@ -2395,6 +2524,10 @@ int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr)
lchan->ecu_state = NULL;
}
/* reset CSD RLP buffers to avoid any user plane data leaking from
* one previous lchan into a later one */
memset(&lchan->tch.csd, 0, sizeof(lchan->tch.csd));
return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_DEACTIVATE,
0);
}
@ -2432,3 +2565,26 @@ int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr)
return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_MODIFY, 0);
}
int l1sap_uplink_access(struct gsm_lchan *lchan, bool active)
{
uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
struct osmo_phsap_prim l1sap;
if (lchan->state != LCHAN_S_ACTIVE && !rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) {
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Channel %s is not an active ASCI type channel.\n",
rsl_chan_nr_str(chan_nr));
return -EINVAL;
}
LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s uplink access detection on channel %s\n",
(active) ? "Activating" : "Deactivating", rsl_chan_nr_str(chan_nr));
memset(&l1sap, 0, sizeof(l1sap));
osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, PRIM_OP_REQUEST, NULL);
l1sap.u.info.type = (active) ? PRIM_INFO_ACT_UL_ACC : PRIM_INFO_DEACT_UL_ACC;
l1sap.u.info.u.ulacc_req.chan_nr = chan_nr;
return l1sap_down(lchan->ts->trx, &l1sap);
}

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/>.
@ -57,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;
}
@ -152,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);
@ -219,7 +218,7 @@ void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind
/* release handover, listener and talker states */
handover_reset(lchan);
vgcs_talker_reset(lchan);
vgcs_talker_reset(lchan, false);
vgcs_listener_reset(lchan);
vgcs_uplink_free_reset(lchan);
@ -653,9 +652,11 @@ void lchan_rtp_socket_free(struct gsm_lchan *lchan)
/*! limit number of queue entries to %u; drops any surplus messages */
void lchan_dl_tch_queue_enqueue(struct gsm_lchan *lchan, struct msgb *msg, unsigned int limit)
{
if (lchan->dl_tch_queue_len > limit)
LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "freeing %d queued frames\n",
lchan->dl_tch_queue_len - limit);
if (lchan->dl_tch_queue_len > limit) {
unsigned int excess = lchan->dl_tch_queue_len - limit;
LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "freeing %d queued frames\n", excess);
rate_ctr_add2(lchan->ts->trx->bts->ctrs, BTS_CTR_RTP_RX_DROP_OVERFLOW, excess);
}
while (lchan->dl_tch_queue_len > limit) {
struct msgb *tmp = msgb_dequeue_count(&lchan->dl_tch_queue, &lchan->dl_tch_queue_len);
msgb_free(tmp);

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/>.

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

@ -19,7 +19,7 @@
/* Active TDMA frame subset for TCH/H in DTX mode (see 3GPP TS 45.008 Section 8.3).
* This mapping is used to determine if a L2 block starting at the given TDMA FN
* belongs to the SUB set and thus shall always be transmitted in DTX mode. */
static const uint8_t ts45008_dtx_tchh_fn_map[104] = {
static const uint8_t ts45008_dtx_tchh_speech_fn_map[104] = {
/* TCH/H(0): 0, 2, 4, 6, 52, 54, 56, 58 */
[0] = 1, /* block { 0, 2, 4, 6} */
[52] = 1, /* block {52, 54, 56, 58} */
@ -28,6 +28,15 @@ static const uint8_t ts45008_dtx_tchh_fn_map[104] = {
[66] = 1, /* block {66, 68, 70, 72} */
};
static const uint8_t ts45008_dtx_tchh_data_fn_map[104] = {
/* UL TCH/H(0): 52, 54, 56, 58, 60, 62, 65, 67, 69, 71 */
[52] = 1, /* block {52, 54, 56, 58, 60, 62} */
[60] = 1, /* block {60, 62, 65, 67, 69, 71} */
/* UL TCH/H(1): 70, 72, 74, 76, 79, 81, 83, 85, 87, 89 */
[70] = 1, /* block {70, 72, 74, 76, 79, 81} */
[79] = 1, /* block {79, 81, 83, 85, 87, 89} */
};
/* In cases where we less measurements than we expect we must assume that we
* just did not receive the block because it was lost due to bad channel
* conditions. We set up a dummy measurement result here that reflects the
@ -50,7 +59,7 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
uint32_t fn104 = fn % 104;
/* See TS 45.008 Sections 8.3 and 8.4 for a detailed descriptions of the rules
* implemented here. We only implement the logic for Voice, not CSD */
* implemented here. We implement the logic for both speech and data (CSD). */
/* AMR is special, SID frames may be scheduled dynamically at any time */
if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
@ -59,8 +68,11 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
switch (lchan->type) {
case GSM_LCHAN_TCH_F:
switch (lchan->tch_mode) {
case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
case GSM48_CMODE_SPEECH_V1:
case GSM48_CMODE_SPEECH_V1_VAMOS:
case GSM48_CMODE_SPEECH_EFR:
case GSM48_CMODE_SPEECH_V2_VAMOS:
/* Active TDMA frame subset for TCH/F: 52, 53, 54, 55, 56, 57, 58, 59.
* There is only one *complete* block in this subset starting at FN=52.
* Incomplete blocks {... 52, 53, 54, 55} and {56, 57, 58, 59 ...}
@ -68,19 +80,14 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
if (fn104 == 52)
return true;
break;
case GSM48_CMODE_SIGN:
/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
* SUB */
return true;
case GSM48_CMODE_DATA_12k0: /* TCH/F9.6 */
case GSM48_CMODE_DATA_6k0: /* TCH/F4.8 */
/* FIXME: In case of data traffic channels TCH/F9.6 and TCH/F4.8 the
* RXQUAL_SUB 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. */
/* 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:
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
return false;
return fn104 == 52;
LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode);
break;
}
@ -88,7 +95,8 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
case GSM_LCHAN_TCH_H:
switch (lchan->tch_mode) {
case GSM48_CMODE_SPEECH_V1:
if (ts45008_dtx_tchh_fn_map[fn104])
case GSM48_CMODE_SPEECH_V1_VAMOS:
if (ts45008_dtx_tchh_speech_fn_map[fn104])
return true;
break;
case GSM48_CMODE_SIGN:
@ -97,13 +105,12 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
return true;
case GSM48_CMODE_DATA_6k0: /* TCH/H4.8 */
case GSM48_CMODE_DATA_3k6: /* TCH/H2.4 */
/* FIXME: In case of data traffic channels TCH/H4.8 and TCH/H2.4 the
* RXQUAL_SUB 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. */
/* 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:
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
return false;
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;
}
@ -417,32 +424,50 @@ static unsigned int lchan_meas_num_expected(const struct gsm_lchan *lchan)
}
/* In DTX a subset of blocks must always be transmitted
* See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX) */
static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
* See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX)
* Return value N: (N < 0) -- at least N SUB frames expected;
* (N > 0) -- exactly N SUB frames expected;
* (N == 0) - unknown channel type/mode? */
static int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
{
enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
/* AMR is using a more elaborated model with a dymanic amount of
* DTX blocks so this function is not applicable to determine the
* amount of expected SUB Measurements when AMR is used */
OSMO_ASSERT(lchan->tch_mode != GSM48_CMODE_SPEECH_AMR);
switch (pchan) {
case GSM_PCHAN_TCH_F:
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
/* 1 block SACCH, 24 blocks TCH (see note 1) */
return 25;
} else {
/* 1 block SACCH, 1 block TCH */
return 2;
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
return 1 + 1; /* 1 x SACCH + 1 x FACCH */
/* else: signalling or speech */
switch (lchan->tch_mode) {
case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
case GSM48_CMODE_SPEECH_V1: /* TCH/FS */
case GSM48_CMODE_SPEECH_V1_VAMOS:
case GSM48_CMODE_SPEECH_EFR: /* TCH/EFS */
case GSM48_CMODE_SPEECH_V2_VAMOS:
return 1 + 1; /* 1 x SACCH + 1 x TCH */
case GSM48_CMODE_SPEECH_AMR: /* TCH/AFS */
case GSM48_CMODE_SPEECH_V3_VAMOS:
case GSM48_CMODE_SPEECH_V4: /* O-TCH/WFS */
case GSM48_CMODE_SPEECH_V5: /* TCH/WFS */
case GSM48_CMODE_SPEECH_V5_VAMOS:
default:
return -1; /* at least 1 x SACCH + M x TCH (variable) */
}
case GSM_PCHAN_TCH_H:
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
/* 1 block SACCH, 12 blocks TCH (see ynote 1) */
return 13;
} else {
/* 1 block SACCH, 2 blocks TCH */
return 3;
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
return 1 + 2; /* 1 x SACCH + 2 x FACCH */
/* else: signalling or speech */
switch (lchan->tch_mode) {
case GSM48_CMODE_SIGN: /* TCH/H sign: DTX *is not* permitted */
return 1 + 12; /* 1 x SACCH + 12 x TCH */
case GSM48_CMODE_SPEECH_V1:
case GSM48_CMODE_SPEECH_V1_VAMOS:
return 1 + 2; /* 1 x SACCH + 2 x TCH */
case GSM48_CMODE_SPEECH_AMR: /* TCH/AHS */
case GSM48_CMODE_SPEECH_V3_VAMOS:
case GSM48_CMODE_SPEECH_V4: /* O-TCH/WHS */
case GSM48_CMODE_SPEECH_V6: /* O-TCH/AHS */
default:
return -1; /* at least 1 x SACCH + M x TCH (variable) */
}
case GSM_PCHAN_SDCCH8_SACCH8C:
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
@ -455,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,
@ -562,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;
@ -582,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;
@ -637,12 +651,9 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
} else {
m = &measurement_dummy;
/* For AMR the amount of SUB frames is defined by the
* the occurrence of DTX periods, which are dynamically
* negotiated in AMR, so we can not know if and how many
* SUB frames are missing. */
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
if (num_meas_sub <= i) {
/* only if we know the exact number of SUB measurements */
if (num_meas_sub_expect >= 0) {
if (num_meas_sub < num_meas_sub_expect) {
num_meas_sub_subst++;
is_sub = true;
}
@ -658,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);
@ -678,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);
}
}

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/>.

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/>.
@ -119,6 +119,7 @@ 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;
@ -145,6 +146,19 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
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:
@ -170,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;

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/>.

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/>.

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/>.

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/>.

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/>.

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/>.

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/>.

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/>.
@ -153,7 +153,7 @@ 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 */
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;

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/>.
@ -164,9 +164,9 @@ int oml_mo_send_msg(const struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_
return oml_send_msg(msg, 0);
}
static inline void add_bts_attrs(struct msgb *msg, const struct gsm_bts *bts)
/* Put NM_ATT_SW_CONFIG as per 9.4.61 "SW Configuration" */
static int add_att_sw_config(struct msgb *msg, const struct gsm_abis_mo *mo)
{
uint16_t total_len = 0;
uint8_t *len;
/* Put NM_ATT_SW_CONFIG as per 9.4.61 "SW Configuration". */
@ -175,17 +175,39 @@ static inline void add_bts_attrs(struct msgb *msg, const struct gsm_bts *bts)
/* We don't know the length yet, so we update it later. */
len = msgb_put(msg, 2);
total_len += abis_nm_put_sw_file(msg, "osmobts", PACKAGE_VERSION, true);
total_len += abis_nm_put_sw_file(msg, btsatttr2str(BTS_TYPE_VARIANT),
btsvariant2str(bts->variant), true);
switch (mo->obj_class) {
case NM_OC_BTS:
{
const struct gsm_bts *bts = mo->bts;
if (strlen(bts->sub_model)) {
total_len += abis_nm_put_sw_file(msg, btsatttr2str(BTS_SUB_MODEL),
bts->sub_model, true);
abis_nm_put_sw_file(msg, "osmobts", PACKAGE_VERSION, true);
abis_nm_put_sw_file(msg, btsatttr2str(BTS_TYPE_VARIANT),
btsvariant2str(bts->variant), true);
if (strlen(bts->sub_model)) {
abis_nm_put_sw_file(msg, btsatttr2str(BTS_SUB_MODEL),
bts->sub_model, true);
}
break;
}
case NM_OC_BASEB_TRANSC:
{
const struct gsm_bts_trx *trx = container_of(mo, struct gsm_bts_trx, bb_transc.mo);
const struct phy_instance *pinst = trx->pinst;
const char *phy_version;
phy_version = pinst && strlen(pinst->version) ? pinst->version : "Unknown";
abis_nm_put_sw_file(msg, btsatttr2str(TRX_PHY_VERSION), phy_version, true);
break;
}
default:
msgb_get(msg, 1 + 2); /* TL16 */
return -ENOTSUP;
}
/* Finally, update the length */
osmo_store16be(total_len, len);
osmo_store16be((uint16_t)(msg->tail - (len + 2)), len);
return 0;
}
/* Add BTS features as 3GPP TS 52.021 §9.4.30 Manufacturer Id */
@ -195,98 +217,249 @@ static inline void add_bts_feat(struct msgb *msg, const struct gsm_bts *bts)
msgb_tl16v_put(msg, NM_ATT_MANUF_ID, len, bts->features->data);
}
static inline void add_trx_attr(struct msgb *msg, const struct gsm_bts_trx *trx)
/* Add ip.access feature flags for the given MO */
static int add_att_ipacc_features(struct msgb *msg, const struct gsm_abis_mo *mo)
{
const struct phy_instance *pinst = trx_phy_instance(trx);
const char *phy_version;
uint16_t total_len;
const struct gsm_bts *bts = mo->bts;
const struct gsm_bts_trx *trx;
uint32_t val;
uint8_t *len;
/* Put NM_ATT_SW_CONFIG as per 9.4.61 "SW Configuration". */
msgb_v_put(msg, NM_ATT_SW_CONFIG);
msgb_v_put(msg, NM_ATT_IPACC_SUPP_FEATURES);
/* We don't know the length yet, so we update it later. */
len = msgb_put(msg, 2);
phy_version = pinst && strlen(pinst->version) ? pinst->version : "Unknown";
total_len = abis_nm_put_sw_file(msg, btsatttr2str(TRX_PHY_VERSION), phy_version, true);
switch (mo->obj_class) {
case NM_OC_BTS:
msgb_tv16_put(msg, NM_IPAC_EIE_MAX_TA, 1); /* TL16 */
msgb_put_u8(msg, (bts->support.max_ta >> 0) & 0xff);
break;
case NM_OC_RADIO_CARRIER:
trx = container_of(mo, struct gsm_bts_trx, mo);
msgb_tv16_put(msg, NM_IPAC_EIE_FREQ_BANDS, 1); /* TL16 */
msgb_put_u8(msg, (trx->support.freq_bands >> 0) & 0xff);
break;
case NM_OC_BASEB_TRANSC:
trx = container_of(mo, struct gsm_bts_trx, bb_transc.mo);
msgb_tv16_put(msg, NM_IPAC_EIE_CIPH_ALGOS, 1); /* TL16 */
msgb_put_u8(msg, bts->support.ciphers); /* LSB is A5/1 */
msgb_tv16_put(msg, NM_IPAC_EIE_CHAN_TYPES, 2); /* TL16 */
msgb_put_u8(msg, (trx->support.chan_types >> 0) & 0xff);
msgb_put_u8(msg, (trx->support.chan_types >> 8) & 0xff);
msgb_tv16_put(msg, NM_IPAC_EIE_CHAN_MODES, 3); /* TL16 */
msgb_put_u8(msg, (trx->support.chan_modes >> 0) & 0xff);
msgb_put_u8(msg, (trx->support.chan_modes >> 8) & 0xff);
msgb_put_u8(msg, (trx->support.chan_modes >> 16) & 0xff);
msgb_tv16_put(msg, NM_IPAC_EIE_RTP_FEATURES, 1); /* TL16 */
val = NM_IPAC_F_RTP_FEAT_IR_64k;
msgb_put_u8(msg, (val >> 0) & 0xff);
msgb_tv16_put(msg, NM_IPAC_EIE_RSL_FEATURES, 1); /* TL16 */
val = NM_IPAC_F_RSL_FEAT_DYN_PDCH_ACT
| NM_IPAC_F_RSL_FEAT_RTP_PT2;
msgb_put_u8(msg, (val >> 0) & 0xff);
break;
case NM_OC_GPRS_CELL:
msgb_tv16_put(msg, NM_IPAC_EIE_GPRS_CODING, 2); /* TL16 */
msgb_put_u8(msg, (bts->gprs.cell.support.gprs_codings >> 0) & 0xff);
msgb_put_u8(msg, (bts->gprs.cell.support.gprs_codings >> 8) & 0xff);
break;
default:
msgb_get(msg, 1 + 2); /* TL16 */
return -ENOTSUP;
}
/* Finally, update the length */
osmo_store16be(total_len, len);
}
/* Handle a list of attributes requested by the BSC, compose
* TRX-specific Get Attribute Response IE as per 9.4.64. */
static inline int handle_attrs_trx(struct msgb *out_msg, const struct gsm_bts_trx *trx,
const uint8_t *attr, uint16_t attr_len)
{
uint8_t num_unsupported = 0;
uint8_t *buf;
int i;
if (!trx) {
LOGP(DOML, LOGL_ERROR, "%s: O&M Get Attributes for unknown TRX\n", gsm_trx_name(trx));
return -NM_NACK_TRXNR_UNKN;
}
for (i = 0; i < attr_len; i++) {
switch (attr[i]) {
case NM_ATT_SW_CONFIG:
add_trx_attr(out_msg, trx);
break;
default:
LOGP(DOML, LOGL_ERROR, "%s: O&M Get Attributes [%u], %s is unsupported by TRX\n",
gsm_trx_name(trx), i, get_value_string(abis_nm_att_names, attr[i]));
/* Push this tag to the list of unsupported attributes */
buf = msgb_push(out_msg, 1);
*buf = attr[i];
num_unsupported++;
}
}
/* Push the amount of unsupported attributes */
buf = msgb_push(out_msg, 1);
*buf = num_unsupported;
osmo_store16be((uint16_t)(msg->tail - (len + 2)), len);
return 0;
}
/* Handle a list of attributes requested by the BSC, compose
* BTS-specific Get Attribute Response IE as per 9.4.64. */
static inline int handle_attrs_bts(struct msgb *out_msg, const struct gsm_bts *bts,
const uint8_t *attr, uint16_t attr_len)
/* Add attribute 9.4.8 BCCH ARFCN for BTS class */
static inline void add_att_bcch_arfcn(struct msgb *msg, const struct gsm_bts *bts)
{
uint8_t num_unsupported = 0;
uint8_t *buf;
int i;
/* type + 16 bit value */
msgb_tv16_put(msg, NM_ATT_BCCH_ARFCN, bts->c0->arfcn);
}
if (!bts) {
LOGP(DOML, LOGL_ERROR, "O&M Get Attributes for unknown BTS\n");
return -NM_NACK_BTSNR_UNKN;
/* Add attribute 9.4.25 Interference Level Boundaries for BTS class */
static inline void add_att_interf_bound(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 8 bit values */
msgb_put_u8(msg, NM_ATT_INTERF_BOUND);
for (int j = 0; j < ARRAY_SIZE(bts->interference.boundary); j++)
msgb_put_u8(msg, abs(bts->interference.boundary[j]));
}
/* Add attribute 9.4.24 Intave Parameter for BTS class */
static inline void add_att_intave_param(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_INTAVE_PARAM, bts->interference.intave);
}
/* Add attribute 9.4.14 Connection Failure Criterion for BTS class */
static inline void add_att_conn_fail_crit(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + length + values */
msgb_tv16_put(msg, NM_ATT_CONN_FAIL_CRIT, 2);
msgb_put_u8(msg, 0x01);
msgb_put_u8(msg, bts->radio_link_timeout.current);
}
/* Add attribute 9.4.31 Maximum Timing Advance for BTS class */
static inline void add_att_max_ta(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_MAX_TA, bts->max_ta);
}
/* Add attribute 9.4.39 Overload Period for BTS class */
static inline void add_att_overl_period(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + length + value */
msgb_tv16_put(msg, NM_ATT_OVERL_PERIOD, 1);
msgb_put_u8(msg, bts->load.overload_period);
}
/* Add attribute 9.4.12 CCCH Load Threshold for BTS class */
static inline void add_att_ccch_l_t(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_CCCH_L_T, bts->load.ccch.load_ind_thresh);
}
/* Add attribute 9.4.11 CCCH Load Indication Period for BTS class */
static inline void add_att_ccch_l_i_p(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_CCCH_L_I_P, bts->load.ccch.load_ind_period);
}
/* Add attribute 9.4.44 RACH Busy Threshold for BTS class */
static inline void add_att_rach_b_thresh(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_RACH_B_THRESH, abs(bts->load.rach.busy_thresh));
}
/* Add attribute 9.4.45 RACH Load Averaging Slots for BTS class */
static inline void add_att_ldavg_slots(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 16 bit value */
msgb_tv16_put(msg, NM_ATT_LDAVG_SLOTS, bts->load.rach.averaging_slots);
}
/* Add attribute 9.4.10 BTS Air Timer for BTS class */
static inline void add_att_bts_air_timer(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_BTS_AIR_TIMER, bts->t3105_ms / 10);
}
/* Add attribute 9.4.37 NY1 for BTS class */
static inline void add_att_ny1(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_NY1, bts->ny1);
}
/* Add attribute 9.4.9 BSIC for BTS class */
static inline int add_att_bsic(struct msgb *msg, const struct gsm_bts *bts)
{
/* BSIC must be configured. */
if (!bts->bsic_configured)
return -EINVAL;
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_BSIC, bts->bsic);
return 0;
}
/* Add attribute 9.4.20 GSM Time for BTS class */
static inline void add_att_gsm_time(struct msgb *msg, const struct gsm_bts *bts)
{
/* type + 16 bit value */
msgb_tv16_put(msg, NM_ATT_GSM_TIME, bts->gsm_time.fn % GSM_RFN_MODULUS);
}
/* Add attribute 9.4.47 RF Max Power Reduction for radio carrier class */
static inline void add_att_rf_maxpowr_r(struct msgb *msg, const struct gsm_bts_trx *trx)
{
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_RF_MAXPOWR_R, trx->max_power_red / 2);
}
/* Add attribute 9.4.5 ARFCN List for radio carrier class */
static inline void add_att_arfcn_list(struct msgb *msg, const struct gsm_bts_trx *trx)
{
#if 0
/* type + length + values */
msgb_tv16_put(msg, NM_ATT_ARFCN_LIST, trx->arfcn_num * 2);
for (int j = 0; j < trx->arfcn_num; j++)
msgb_put_u16(msg, trx->arfcn_list[j]);
#else
/* type + length + values */
msgb_tv16_put(msg, NM_ATT_ARFCN_LIST, 2);
msgb_put_u16(msg, trx->arfcn);
#endif
}
/* Add attribute 9.4.5 ARFCN List for channel class */
static inline void add_att_arfcn_list_ts(struct msgb *msg, const struct gsm_bts_trx_ts *ts)
{
if (ts->hopping.enabled) {
/* type + length + values */
msgb_tv16_put(msg, NM_ATT_ARFCN_LIST, ts->hopping.arfcn_num * 2);
for (int j = 0; j < ts->hopping.arfcn_num; j++)
msgb_put_u16(msg, ts->hopping.arfcn_list[j]);
} else {
/* type + length + values */
msgb_tv16_put(msg, NM_ATT_ARFCN_LIST, 2);
msgb_put_u16(msg, ts->trx->arfcn);
}
}
for (i = 0; i < attr_len; i++) {
switch (attr[i]) {
case NM_ATT_SW_CONFIG:
add_bts_attrs(out_msg, bts);
break;
case NM_ATT_MANUF_ID:
add_bts_feat(out_msg, bts);
break;
default:
LOGP(DOML, LOGL_ERROR, "O&M Get Attributes [%u], %s is unsupported by BTS\n", i,
get_value_string(abis_nm_att_names, attr[i]));
/* Push this tag to the list of unsupported attributes */
buf = msgb_push(out_msg, 1);
*buf = attr[i];
num_unsupported++;
}
}
/* Add attribute 9.4.13 Channel Combination for channel class */
static inline int add_att_chan_comb(struct msgb *msg, const struct gsm_bts_trx_ts *ts)
{
int comb = abis_nm_chcomb4pchan(ts->pchan);
/* Push the amount of unsupported attributes */
buf = msgb_push(out_msg, 1);
*buf = num_unsupported;
/* If current channel combination is not yet set, 0xff is returned. */
if (comb < 0 || comb == 0xff)
return -EINVAL;
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_CHAN_COMB, comb);
return 0;
}
/* Add attribute 9.4.60 TSC for channel class */
static inline void add_att_tsc(struct msgb *msg, const struct gsm_bts_trx_ts *ts)
{
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_TSC, ts->tsc);
}
/* Add attribute 9.4.60 HSN for channel class */
static inline int add_att_hsn(struct msgb *msg, const struct gsm_bts_trx_ts *ts)
{
if (!ts->hopping.enabled)
return -EINVAL;
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_HSN, ts->hopping.hsn);
return 0;
}
/* Add attribute 9.4.21 MAIO for channel class */
static inline int add_att_maio(struct msgb *msg, const struct gsm_bts_trx_ts *ts)
{
if (!ts->hopping.enabled)
return -EINVAL;
/* type + 8 bit value */
msgb_tv_put(msg, NM_ATT_MAIO, ts->hopping.maio);
return 0;
}
@ -295,32 +468,177 @@ static int oml_tx_attr_resp(const struct gsm_abis_mo *mo,
const uint8_t *attr, uint16_t attr_len)
{
struct msgb *nmsg = oml_msgb_alloc();
const char *mo_name = gsm_abis_mo_name(mo);
unsigned int num_unsupported = 0;
struct gsm_bts_trx *trx = NULL;
struct gsm_bts_trx_ts *ts = NULL;
int rc;
if (!nmsg)
return -NM_NACK_CANT_PERFORM;
/* Set TRX, if object class is Radio Carrier, Baseband Transceiver or Channel. */
switch (mo->obj_class) {
case NM_OC_BTS:
rc = handle_attrs_bts(nmsg, mo->bts, attr, attr_len);
break;
case NM_OC_RADIO_CARRIER:
case NM_OC_BASEB_TRANSC:
rc = handle_attrs_trx(nmsg, gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr), attr, attr_len);
case NM_OC_CHANNEL:
trx = gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr);
break;
default:
LOGP(DOML, LOGL_ERROR, "%s: Unsupported MO class in Get Attribute Response\n",
mo_name);
rc = -NM_NACK_OBJCLASS_NOTSUPP;
}
if (rc < 0) {
LOGP(DOML, LOGL_ERROR, "%s: Tx Get Attribute Response FAILED with rc=%d\n",
mo_name, rc);
msgb_free(nmsg);
return rc;
/* Set TS, if object class is Channel. */
if (mo->obj_class == NM_OC_CHANNEL && trx)
ts = &trx->ts[mo->obj_inst.ts_nr];
for (unsigned int i = 0; i < attr_len; i++) {
switch (attr[i]) {
case NM_ATT_OPER_STATE:
msgb_tv16_put(nmsg, attr[i], 1);
msgb_put_u8(nmsg, mo->nm_state.operational);
break;
case NM_ATT_ADM_STATE:
msgb_tv16_put(nmsg, attr[i], 1);
msgb_put_u8(nmsg, mo->nm_state.administrative);
break;
case NM_ATT_AVAIL_STATUS:
msgb_tv16_put(nmsg, attr[i], 1);
msgb_put_u8(nmsg, mo->nm_state.availability);
break;
case NM_ATT_SW_CONFIG:
if (add_att_sw_config(nmsg, mo) != 0)
goto unsupported;
break;
case NM_ATT_MANUF_ID:
if (mo->obj_class == NM_OC_BTS)
add_bts_feat(nmsg, mo->bts);
else
goto unsupported;
break;
case NM_ATT_IPACC_SUPP_FEATURES:
if (add_att_ipacc_features(nmsg, mo) != 0)
goto unsupported;
break;
case NM_ATT_BCCH_ARFCN:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_bcch_arfcn(nmsg, mo->bts);
break;
case NM_ATT_INTERF_BOUND:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_interf_bound(nmsg, mo->bts);
break;
case NM_ATT_INTAVE_PARAM:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_intave_param(nmsg, mo->bts);
break;
case NM_ATT_CONN_FAIL_CRIT:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_conn_fail_crit(nmsg, mo->bts);
break;
case NM_ATT_MAX_TA:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_max_ta(nmsg, mo->bts);
break;
case NM_ATT_OVERL_PERIOD:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_overl_period(nmsg, mo->bts);
break;
case NM_ATT_CCCH_L_T:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_ccch_l_t(nmsg, mo->bts);
break;
case NM_ATT_CCCH_L_I_P:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_ccch_l_i_p(nmsg, mo->bts);
break;
case NM_ATT_RACH_B_THRESH:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_rach_b_thresh(nmsg, mo->bts);
break;
case NM_ATT_LDAVG_SLOTS:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_ldavg_slots(nmsg, mo->bts);
break;
case NM_ATT_BTS_AIR_TIMER:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_bts_air_timer(nmsg, mo->bts);
break;
case NM_ATT_NY1:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_ny1(nmsg, mo->bts);
break;
case NM_ATT_BSIC:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
if (add_att_bsic(nmsg, mo->bts) != 0)
goto unsupported;
break;
case NM_ATT_GSM_TIME:
if (mo->obj_class != NM_OC_BTS)
goto unsupported;
add_att_gsm_time(nmsg, mo->bts);
break;
case NM_ATT_RF_MAXPOWR_R:
if (mo->obj_class != NM_OC_RADIO_CARRIER || !trx)
goto unsupported;
add_att_rf_maxpowr_r(nmsg, trx);
break;
case NM_ATT_ARFCN_LIST:
if (mo->obj_class == NM_OC_RADIO_CARRIER && trx) {
add_att_arfcn_list(nmsg, trx);
break;
}
if (mo->obj_class == NM_OC_CHANNEL && ts) {
add_att_arfcn_list_ts(nmsg, ts);
break;
}
goto unsupported;
case NM_ATT_CHAN_COMB:
if (mo->obj_class != NM_OC_CHANNEL || !ts)
goto unsupported;
if (add_att_chan_comb(nmsg, ts) != 0)
goto unsupported;
break;
case NM_ATT_TSC:
if (mo->obj_class != NM_OC_CHANNEL || !ts)
goto unsupported;
add_att_tsc(nmsg, ts);
break;
case NM_ATT_HSN:
if (mo->obj_class != NM_OC_CHANNEL || !ts)
goto unsupported;
if (add_att_hsn(nmsg, ts) != 0)
goto unsupported;
break;
case NM_ATT_MAIO:
if (mo->obj_class != NM_OC_CHANNEL || !ts)
goto unsupported;
if (add_att_maio(nmsg, ts) != 0)
goto unsupported;
break;
default:
unsupported:
LOGP(DOML, LOGL_ERROR, "%s: O&M Get Attributes [%u], %s is unsupported\n",
gsm_abis_mo_name(mo), i, get_value_string(abis_nm_att_names, attr[i]));
/* Push this tag to the list of unsupported attributes */
msgb_push_u8(nmsg, attr[i]);
num_unsupported++;
}
}
/* Push the amount of unsupported attributes */
msgb_push_u8(nmsg, num_unsupported);
/* Push Get Attribute Response Info TL (actually TV where V is L) */
msgb_tv16_push(nmsg, NM_ATT_GET_ARI, msgb_length(nmsg));
@ -515,16 +833,21 @@ int oml_mo_tx_sw_act_rep(const struct gsm_abis_mo *mo)
return oml_mo_send_msg(mo, nmsg, NM_MT_SW_ACTIVATED_REP);
}
/* The defaults below correspond to various sources/recommendations that could be found online.
* The BSC should override this via OML anyway. */
const unsigned int oml_default_t200_ms[7] = {
[T200_SDCCH] = 1000,
[T200_FACCH_F] = 1000,
[T200_FACCH_H] = 1000,
[T200_SACCH_TCH_SAPI0] = 2000,
[T200_SACCH_SDCCH] = 2000,
[T200_SDCCH_SAPI3] = 1000,
[T200_SACCH_TCH_SAPI3] = 2000,
/* The defaults below correspond to the number of frames until a response from the MS is expected.
* It defines the FN distance between the frame number when a message is sent (first frame) and when the response is
* received (first frame). On SACCH the duration is two frames, because SAPI0 and SAPI3 are are transmitted in
* alternating order. On DCCH with SAPI3 the duration is two seconds, because SAPI0 has priority over SAPI3.
*
* See Table 8 if 3GPP TS 44.006. Note that the table only shows the FN distance between frames.
*/
const uint32_t oml_default_t200_fn[7] = {
[T200_SDCCH] = 4+32,
[T200_FACCH_F] = 8+9,
[T200_FACCH_H] = 6+10,
[T200_SACCH_TCH_SAPI0] = 79+25+104,
[T200_SACCH_SDCCH] = 4+32+51,
[T200_SDCCH_SAPI3] = 4+32+408, /* two seconds */
[T200_SACCH_TCH_SAPI3] = 79+25+104,
};
/* 3GPP TS 52.021 §8.11.1 Get Attributes has been received */
@ -667,25 +990,26 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
}
/* 9.4.53 T200 */
if (TLVP_PRES_LEN(&tp, NM_ATT_T200, ARRAY_SIZE(bts->t200_ms))) {
payload = TLVP_VAL(&tp, NM_ATT_T200);
for (i = 0; i < ARRAY_SIZE(bts->t200_ms); i++) {
uint32_t t200_ms = payload[i] * abis_nm_t200_ms[i];
if (TLVP_PRES_LEN(&tp, NM_ATT_T200, ARRAY_SIZE(bts->t200_fn))) {
/* 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. */
DEBUGPFOH(DOML, foh, "Ignoring T200 BTS attribute.\n");
#if 0
bts->t200_ms[i] = t200_ms;
DEBUGPFOH(DOML, foh, "T200[%u]: OML=%u, mult=%u => %u ms\n",
payload = TLVP_VAL(&tp, NM_ATT_T200);
for (i = 0; i < ARRAY_SIZE(bts->t200_fn); i++) {
uint32_t t200_ms = payload[i] * abis_nm_t200_ms[i];
uint32_t t200_fn = t200_ms * 1000 + (GSM_TDMA_FN_DURATION_uS - 1) / GSM_TDMA_FN_DURATION_uS;
/* Values must not be less than absolute minimum. */
if (oml_default_t200_fn[i] <= t200_fn)
bts->t200_fn[i] = t200_fn;
else
bts->t200_fn[i] = oml_default_t200_fn[i];
DEBUGPFOH(DOML, foh, "T200[%u]: OML=%u, mult=%u => %u ms -> %u fn\n",
i, payload[i], abis_nm_t200_ms[i],
bts->t200_ms[i]);
#else
/* we'd rather use the 1s/2s (long) defaults by
* libosmocore, as we appear to have some bug(s)
* related to handling T200 expiration in
* libosmogsm lapd(m) code? */
LOGPFOH(DOML, LOGL_NOTICE, foh, "Ignoring T200[%u] (%u ms) "
"as sent by BSC due to suspected LAPDm bug!\n",
i, t200_ms);
#endif
t200_ms, bts->t200_fn[i]);
}
#endif
}
/* 9.4.31 Maximum Timing Advance */
@ -1534,6 +1858,7 @@ static int rx_oml_ipa_rsl_connect(struct gsm_bts *bts, struct msgb *msg,
struct e1inp_sign_link *oml_link = bts->oml_link;
const struct abis_om_fom_hdr *foh = msgb_l3(msg);
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
struct gsm_bts_bb_trx *bb_transc;
const char *trx_name;
struct in_addr in;
uint16_t port = IPA_TCP_PORT_RSL;
@ -1547,6 +1872,7 @@ static int rx_oml_ipa_rsl_connect(struct gsm_bts *bts, struct msgb *msg,
if (TLVP_PRESENT(tp, NM_ATT_IPACC_DST_IP_PORT))
port = ntohs(tlvp_val16_unal(tp, NM_ATT_IPACC_DST_IP_PORT));
if (TLVP_PRESENT(tp, NM_ATT_IPACC_STREAM_ID))
stream_id = *TLVP_VAL(tp, NM_ATT_IPACC_STREAM_ID);
@ -1557,22 +1883,16 @@ static int rx_oml_ipa_rsl_connect(struct gsm_bts *bts, struct msgb *msg,
goto tx_ack_nack;
}
bb_transc = &trx->bb_transc;
osmo_sockaddr_str_from_in_addr(&bb_transc->rsl.rem_addrstr, &in, port);
bb_transc->rsl.tei = stream_id;
trx_name = gsm_trx_name(trx);
LOGP(DOML, LOGL_INFO, "%s: Rx IPA RSL CONNECT IP=%s PORT=%u STREAM=0x%02x\n",
trx_name, inet_ntoa(in), port, stream_id);
trx_name, bb_transc->rsl.rem_addrstr.ip, bb_transc->rsl.rem_addrstr.port,
bb_transc->rsl.tei);
if (bts->variant == BTS_OSMO_OMLDUMMY) {
rc = 0;
LOGP(DOML, LOGL_NOTICE, "%s: Not connecting RSL in OML-DUMMY!\n", trx_name);
} else {
trx->rsl_tei = stream_id;
rc = e1inp_ipa_bts_rsl_connect_n(oml_link->ts->line, inet_ntoa(in), port, trx->nr);
if (rc < 0) {
LOGP(DOML, LOGL_NOTICE, "%s: Error connecting IPA RSL: %d\n", trx_name, rc);
rc = NM_NACK_CANT_PERFORM;
}
}
rc = 0;
tx_ack_nack:
/* The ACK/NACK is expected to contain all IEs */

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

@ -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

@ -53,8 +53,6 @@ static int avail_lai = 0, avail_nse = 0, avail_cell = 0, avail_nsvc[2] = {0, 0};
static const char *sapi_string[] = {
[PCU_IF_SAPI_RACH] = "RACH",
[PCU_IF_SAPI_AGCH] = "AGCH",
[PCU_IF_SAPI_PCH] = "PCH",
[PCU_IF_SAPI_BCCH] = "BCCH",
[PCU_IF_SAPI_PDTCH] = "PDTCH",
[PCU_IF_SAPI_PRACH] = "PRACH",
@ -232,6 +230,25 @@ static void info_ind_fill_trx(struct gsm_pcu_if_info_trx *trx_info,
}
}
static enum gsm_pcuif_bts_model bts_model_from_variant(enum gsm_bts_type_variant variant)
{
switch (variant) {
case BTS_OSMO_LITECELL15:
return PCU_IF_BTS_MODEL_LC15;
case BTS_OSMO_OC2G:
return PCU_IF_BTS_MODEL_OC2G;
case BTS_OSMO_OCTPHY:
return PCU_IF_BTS_MODEL_OCTPHY;
case BTS_OSMO_SYSMO:
return PCU_IF_BTS_MODEL_SYSMO;
case BTS_OSMO_TRX:
case BTS_OSMO_VIRTUAL:
return PCU_IF_BTS_MODEL_TRX;
default:
return PCU_IF_BTS_MODEL_UNSPEC;
}
}
int pcu_tx_info_ind(void)
{
struct msgb *msg;
@ -264,7 +281,7 @@ int pcu_tx_info_ind(void)
LOGP(DPCU, LOGL_INFO, "BTS is down\n");
if (pcu_direct)
info_ind->flags |= PCU_IF_FLAG_SYSMO;
info_ind->flags |= PCU_IF_FLAG_DIRECT_PHY;
info_ind->bsic = bts->bsic;
/* RAI */
@ -360,6 +377,8 @@ int pcu_tx_info_ind(void)
info_ind_fill_trx(&info_ind->trx[trx->nr], trx);
}
info_ind->bts_model = bts_model_from_variant(bts->variant);
return pcu_sock_send(msg);
}

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/>.

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/>.
@ -371,6 +371,16 @@ static bool chan_nr_is_dchan(uint8_t chan_nr)
return true;
}
static struct gsm_bts_trx *trx_lookup_by_arfcn(struct llist_head *trx_list, uint16_t arfcn)
{
struct gsm_bts_trx *trx;
llist_for_each_entry(trx, trx_list, list) {
if (trx->arfcn == arfcn)
return trx;
}
return NULL;
}
static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
const char *log_name)
{
@ -993,6 +1003,15 @@ static int rsl_rx_osmo_etws_cmd(struct gsm_bts_trx *trx, struct msgb *msg)
* \param[in] len length of \a current in octets */
static inline void lapdm_ui_prefix(uint8_t *buf, uint32_t *valid, const uint8_t *current, uint8_t osmo_si, uint16_t len)
{
/* Special case for short header SI. Do not pre-fix the two-byte UI header. */
switch (osmo_si) {
case SYSINFO_TYPE_10:
(*valid) |= (1 << osmo_si);
memset(buf, GSM_MACBLOCK_PADDING, sizeof(sysinfo_buf_t));
memcpy(buf, current, len);
return;
}
/* We have to pre-fix with the two-byte LAPDM UI header */
if (len > sizeof(sysinfo_buf_t) - 2) {
LOGP(DRSL, LOGL_ERROR, "Truncating received SI%s (%u -> %zu) to prepend LAPDM UI header (2 bytes)\n",
@ -1374,18 +1393,33 @@ static int rsl_rx_imm_ass(struct gsm_bts_trx *trx, struct msgb *msg)
* the channel is active. Hence we still wait for the activation, but don't need the Abis roundtrip of Activ ACK
* -> Immediate Assignment via the BSC.
* If anything is wrong with the sizes or the lchan lookup, behave normally, i.e. do not do the RR IA caching,
* but just send the RR message to the MS as-is. */
* but just send the RR message to the MS as-is.
* 'trx' here is the TRX of the BCCH channel. To find the correct TRX for the IMM ASS target, we need to look up
* the ARFCN that is contained in the IMM ASS message. When frequency hopping is enabled, there will not be an
* ARFCN, so we cannot support early-IA with frequency hopping enabled. */
if (msg->len >= sizeof(struct gsm48_imm_ass)) {
struct gsm48_imm_ass *rr_ia = (void*)msg->data;
struct gsm_lchan *ia_target_lchan = lchan_lookup(trx, rr_ia->chan_desc.chan_nr, "Early IA check: ");
if (ia_target_lchan && ia_target_lchan->state != LCHAN_S_ACTIVE) {
/* Target lchan is not yet active. Cache the IA.
* If a previous IA is still lingering, free it. */
msgb_free(ia_target_lchan->early_rr_ia);
ia_target_lchan->early_rr_ia = msg;
if (rr_ia->chan_desc.h0.h == 0) {
/* hopping is disabled. */
struct gsm_bts_trx *ia_target_trx;
uint16_t arfcn;
arfcn = (rr_ia->chan_desc.h0.arfcn_high << 8) + rr_ia->chan_desc.h0.arfcn_low;
/* return 1 means: don't msgb_free() the msg */
return 1;
ia_target_trx = trx_lookup_by_arfcn(&trx->bts->trx_list, arfcn);
if (ia_target_trx) {
/* found the ARFCN's trx */
struct gsm_lchan *ia_target_lchan;
ia_target_lchan = lchan_lookup(ia_target_trx, rr_ia->chan_desc.chan_nr, "Early IA check: ");
if (ia_target_lchan && ia_target_lchan->state != LCHAN_S_ACTIVE) {
/* Target lchan is not yet active. Cache the IA.
* If a previous IA is still lingering, free it. */
msgb_free(ia_target_lchan->early_rr_ia);
ia_target_lchan->early_rr_ia = msg;
/* return 1 means: don't msgb_free() the msg */
return 1;
}
}
}
}
@ -1898,6 +1932,9 @@ static int rsl_rx_chan_activ(struct msgb *msg)
reactivation = true;
}
/* If Activation Type is IMMEDIATE ASSIGNMENT, we expect L3 info with establishment. */
lchan->l3_info_estab = (type == RSL_ACT_INTRA_IMM_ASS);
if (!reactivation && lchan->state != LCHAN_S_NONE) {
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "error: lchan is not available, but in state: %s.\n",
gsm_lchans_name(lchan->state));
@ -2198,8 +2235,12 @@ static int rsl_rx_chan_activ(struct msgb *msg)
lchan->top_acch_active = false;
/* set ASCI channel into right state */
if (reactivation && rsl_chan_rt_is_asci(lchan->rsl_chan_rt))
vgcs_lchan_react(lchan);
if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) {
if (reactivation)
vgcs_lchan_react(lchan);
else
vgcs_lchan_activate(lchan);
}
/* on reactivation, the channel is already activated */
if (reactivation) {
@ -2911,7 +2952,7 @@ static int tx_ipac_XXcx_nack(struct gsm_lchan *lchan, uint8_t cause,
static char *get_rsl_local_ip(struct gsm_bts_trx *trx)
{
struct e1inp_ts *ts = trx->rsl_link->ts;
struct e1inp_ts *ts = trx->bb_transc.rsl.link->ts;
struct sockaddr_storage ss;
socklen_t sa_len = sizeof(ss);
static char hostbuf[256];
@ -3054,7 +3095,7 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg)
* address */
if (connect_ip == 0) {
struct e1inp_sign_link *sign_link =
lchan->ts->trx->rsl_link;
lchan->ts->trx->bb_transc.rsl.link;
ia.s_addr = htonl(get_signlink_remote_ip(sign_link));
} else
@ -3609,7 +3650,7 @@ static int rsl_rx_rll(struct gsm_bts_trx *trx, struct msgb *msg)
/* VGCS Uplink is released by MSC using REL-REQ. */
if (rh->c.msg_type == RSL_MT_REL_REQ)
vgcs_talker_reset(lchan);
vgcs_talker_reset(lchan, true);
LOGPLCHAN(lchan, DRLL, LOGL_DEBUG, "Rx RLL %s Abis -> LAPDm\n", rsl_msg_name(rh->c.msg_type));
@ -3818,6 +3859,23 @@ int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx)
msg->trx = lchan->ts->trx;
msg->lchan = lchan;
/* If DL estabishment on main signaling link and SAPI 0 with L3 info is expected. */
if (lchan->l3_info_estab && rh->msg_type == RSL_MT_EST_IND) {
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
if ((rllh->link_id & 0xc7) == 0) {
/* Reject initial establishment without L3 info. */
if (msgb_l2len(msg) == sizeof(struct abis_rsl_rll_hdr)) {
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "RLL EST IND without contention resolution.\n");
/* Release normally, re-use the msgb. */
rh->msg_type = RSL_MT_REL_REQ;
msgb_tv_put(msg, RSL_IE_RELEASE_MODE, RSL_REL_NORMAL);
return rsl_rx_rll(lchan->ts->trx, msg);
}
/* Re-estabishment without contention resoltuion is allowed. */
lchan->l3_info_estab = false;
}
}
/* If this is a Measurement Report, then we simply ignore it,
* because it has already been processed in l1sap_ph_data_ind(). */
if (rslms_is_meas_rep(msg)) {
@ -3831,7 +3889,7 @@ int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx)
/* REL_IND handling */
if (rh->msg_type == RSL_MT_REL_IND && lchan_is_tch(lchan)) {
vgcs_talker_reset(lchan);
vgcs_talker_reset(lchan, true);
LOGPLCHAN(lchan, DRSL, LOGL_INFO,
"Scheduling %s to L3 in next associated TCH-RTS.ind\n",
rsl_msg_name(rh->msg_type));

View File

@ -16,7 +16,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

@ -15,7 +15,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/>.
@ -1084,11 +1084,8 @@ static void _trx_sched_set_lchan(struct gsm_lchan *lchan,
const size_t buf_size = 24 * GSM_NBITS_NB_GMSK_PAYLOAD;
if (trx_chan_desc[chan].dl_fn != NULL)
chan_state->dl_bursts = talloc_zero_size(l1ts, buf_size);
if (trx_chan_desc[chan].ul_fn != NULL) {
if (trx_chan_desc[chan].ul_fn != NULL)
chan_state->ul_bursts = talloc_zero_size(l1ts, buf_size);
if (L1SAP_IS_LINK_SACCH(trx_chan_desc[chan].link_id))
chan_state->ul_bursts_prev = talloc_zero_size(l1ts, buf_size);
}
} else {
chan_state->ho_rach_detect = 0;
@ -1100,7 +1097,6 @@ static void _trx_sched_set_lchan(struct gsm_lchan *lchan,
/* Release memory used by Rx/Tx burst buffers */
TALLOC_FREE(chan_state->dl_bursts);
TALLOC_FREE(chan_state->ul_bursts);
TALLOC_FREE(chan_state->ul_bursts_prev);
}
chan_state->active = active;
@ -1144,6 +1140,33 @@ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_i
return found ? 0 : -EINVAL;
}
int trx_sched_set_ul_access(struct gsm_lchan *lchan, uint8_t chan_nr, bool active)
{
struct l1sched_ts *l1ts = lchan->ts->priv;
uint8_t tn = L1SAP_CHAN2TS(chan_nr);
uint8_t ss = l1sap_chan2ss(chan_nr);
int i;
if (!l1ts) {
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "%s UL access on lchan with uninitialized scheduler structure.\n",
(active) ? "Activating" : "Deactivating");
return -EINVAL;
}
/* look for all matching chan_nr */
for (i = 0; i < _TRX_CHAN_MAX; i++) {
if (trx_chan_desc[i].chan_nr == (chan_nr & RSL_CHAN_NR_MASK)) {
struct l1sched_chan_state *l1cs = &l1ts->chan_state[i];
l1cs->ho_rach_detect = active;
}
}
_sched_act_rach_det(lchan->ts->trx, tn, ss, active);
return 0;
}
int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool active)
{
struct l1sched_ts *l1ts = lchan->ts->priv;

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/>.

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/>.

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/>.

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

@ -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/>.
@ -140,20 +140,6 @@ int bts_vty_go_parent(struct vty *vty)
return vty->node;
}
int bts_vty_is_config_node(struct vty *vty, int node)
{
switch (node) {
case TRX_NODE:
case BTS_NODE:
case PHY_NODE:
case PHY_INST_NODE:
case OSMUX_NODE:
return 1;
default:
return 0;
}
}
static const char osmobts_copyright[] =
"Copyright (C) 2010-2011 by Harald Welte, Andreas Eversberg and On-Waves\r\n"
"Copyright (C) 2011-2022 by sysmocom - s.f.m.c. GmbH\r\n"
@ -166,7 +152,6 @@ struct vty_app_info bts_vty_info = {
.version = PACKAGE_VERSION,
.copyright = osmobts_copyright,
.go_parent_cb = bts_vty_go_parent,
.is_config_node = bts_vty_is_config_node,
.usr_attr_desc = {
[BTS_VTY_ATTR_NEW_LCHAN] = \
"This command applies for newly created lchans",
@ -462,6 +447,12 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts)
sapi_buf = osmo_str_tolower(get_value_string(gsmtap_sapi_names, GSMTAP_CHANNEL_ACCH));
vty_out(vty, " gsmtap-sapi %s%s", sapi_buf, VTY_NEWLINE);
}
if (bts->gsmtap.rlp) {
if (bts->gsmtap.rlp_skip_null)
vty_out(vty, " gsmtap-rlp skip-null%s", VTY_NEWLINE);
else
vty_out(vty, " gsmtap-rlp%s", VTY_NEWLINE);
}
vty_out(vty, " min-qual-rach %d%s", bts->min_qual_rach,
VTY_NEWLINE);
vty_out(vty, " min-qual-norm %d%s", bts->min_qual_norm,
@ -1659,10 +1650,10 @@ static void trx_dump_vty(struct vty *vty, const struct gsm_bts_trx *trx)
vty_out(vty, " NM State: ");
net_dump_nmstate(vty, &trx->mo.nm_state);
vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
vty_out(vty, " RSL State: %s%s", trx->bb_transc.rsl.link ? "connected" : "disconnected", VTY_NEWLINE);
vty_out(vty, " Baseband Transceiver NM State: ");
net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
vty_out(vty, " IPA stream ID: 0x%02x%s", trx->rsl_tei, VTY_NEWLINE);
vty_out(vty, " IPA stream ID: 0x%02x%s", trx->bb_transc.rsl.tei, VTY_NEWLINE);
}
static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts)
@ -1876,10 +1867,10 @@ static void lchan_ms_power_ctrl_state_dump(struct vty *vty, unsigned int indent,
int current_dbm = ms_pwr_dbm(trx->bts->band, st->current);
int max_dbm = ms_pwr_dbm(trx->bts->band, st->max);
cfg_out(vty, "Current power level: %u, -%d dBm",
cfg_out(vty, "Current power level: %u, %d dBm",
st->current, current_dbm);
if (st->dpc_params != NULL)
vty_out(vty, " (max %u, -%d dBm)", st->max, max_dbm);
vty_out(vty, " (max %u, %d dBm)", st->max, max_dbm);
vty_out(vty, "%s", VTY_NEWLINE);
if (st->dpc_params == NULL)
@ -2401,6 +2392,29 @@ DEFUN(cfg_bts_no_gsmtap_sapi, cfg_bts_no_gsmtap_sapi_cmd,
return CMD_SUCCESS;
}
DEFUN(cfg_bts_gsmtap_rlp, cfg_bts_gsmtap_rlp_cmd,
"gsmtap-rlp [skip-null]",
"Enable generation of GSMTAP frames for RLP (non-transparent CSD)\n"
"Skip the generation of GSMTAP for RLP NULL frames\n")
{
struct gsm_bts *bts = vty->index;
bts->gsmtap.rlp = true;
if (argc >= 1 && !strcmp(argv[0], "skip-null"))
bts->gsmtap.rlp_skip_null = true;
else
bts->gsmtap.rlp_skip_null = false;
return CMD_SUCCESS;
}
DEFUN(cfg_bts_no_gsmtap_rlp, cfg_bts_no_gsmtap_rlp_cmd,
"no gsmtap-rlp",
NO_STR "Disable generation of GSMTAP frames for RLP (non-transparent CSD)\n")
{
struct gsm_bts *bts = vty->index;
bts->gsmtap.rlp = false;
return CMD_SUCCESS;
}
static struct cmd_node phy_node = {
PHY_NODE,
"%s(phy)# ",
@ -2772,6 +2786,8 @@ int bts_vty_init(void *ctx)
install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_all_cmd);
install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_cmd);
install_element(BTS_NODE, &cfg_bts_no_gsmtap_sapi_cmd);
install_element(BTS_NODE, &cfg_bts_gsmtap_rlp_cmd);
install_element(BTS_NODE, &cfg_bts_no_gsmtap_rlp_cmd);
/* Osmux Node */
install_element(BTS_NODE, &cfg_bts_osmux_cmd);

View File

@ -16,7 +16,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

@ -15,7 +15,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

@ -17,7 +17,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/>.
@ -347,7 +347,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg,
abort();
}
len = msgb_l2len(msg);
len = (msg->l2h) ? msgb_l2len(msg) : 0;
chan_nr = l1sap->u.data.chan_nr;
link_id = l1sap->u.data.link_id;
@ -1426,6 +1426,30 @@ static int info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
LOGP(DL1C, LOGL_FATAL, "BTS band %s not supported by hw\n",
gsm_band_name(trx->bts->band));
/* Frequency bands indicated to the BSC */
switch (fl1h->hw_info.band_support) {
case GSM_BAND_450:
trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_450;
break;
case GSM_BAND_480:
trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_480;
break;
case GSM_BAND_850:
trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_850;
break;
case GSM_BAND_900:
trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_PGSM;
/* XXX: does GSM_BAND_900 include NM_IPAC_F_FREQ_BAND_EGSM? */
/* XXX: does GSM_BAND_900 include NM_IPAC_F_FREQ_BAND_RGSM? */
break;
case GSM_BAND_1800:
trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_DCS;
break;
case GSM_BAND_1900:
trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_PCS;
break;
}
/* Request the activation */
l1if_activate_rf(fl1h, 1);

View File

@ -15,7 +15,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

@ -15,7 +15,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

@ -16,7 +16,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/>.
@ -89,6 +89,8 @@ int bts_model_init(struct gsm_bts *bts)
bts->model_priv = bts_lc15;
bts->variant = BTS_OSMO_LITECELL15;
bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3);
bts->gprs.cell.support.gprs_codings = NM_IPAC_MASK_GPRS_CODING_CS
| NM_IPAC_MASK_GPRS_CODING_MCS;
/* specific default values for LC15 platform */
bts_lc15->led_ctrl_mode = LC15_BTS_LED_CTRL_MODE_DEFAULT;
@ -102,6 +104,7 @@ int bts_model_init(struct gsm_bts *bts)
/* order alphabetically */
osmo_bts_set_feature(bts->features, BTS_FEAT_AGCH_PCH_PROP);
osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH);
osmo_bts_set_feature(bts->features, BTS_FEAT_EGPRS);
osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS);
osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS);
@ -125,6 +128,17 @@ int bts_model_init(struct gsm_bts *bts)
int bts_model_trx_init(struct gsm_bts_trx *trx)
{
/* Frequency bands indicated to the BSC */
trx->support.freq_bands = 0x00; /* updated in info_compl_cb() */
/* Channel types and modes indicated to the BSC */
trx->support.chan_types = NM_IPAC_MASK_CHANT_COMMON
| NM_IPAC_F_CHANT_BCCH_SDCCH4_CBCH
| NM_IPAC_F_CHANT_SDCCH8_CBCH
| NM_IPAC_F_CHANT_PDCHF
| NM_IPAC_F_CHANT_TCHF_PDCHF;
trx->support.chan_modes = NM_IPAC_MASK_CHANM_SPEECH;
trx->nominal_power = 40;
trx->power_params.trx_p_max_out_mdBm = to_mdB(trx->bts->c0->nominal_power);
return 0;

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/>.

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/>.

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/>.

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/>.

View File

@ -17,7 +17,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

@ -17,7 +17,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

@ -16,7 +16,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

@ -16,7 +16,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

@ -16,7 +16,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/>.
@ -89,39 +89,10 @@ static int go_to_parent(struct vty *vty)
return vty->node;
}
static int is_config_node(struct vty *vty, int node)
{
switch (node) {
case MGR_NODE:
case ACT_NORM_NODE:
case ACT_WARN_NODE:
case ACT_CRIT_NODE:
case LIMIT_SUPPLY_TEMP_NODE:
case LIMIT_SOC_NODE:
case LIMIT_FPGA_NODE:
case LIMIT_RMSDET_NODE:
case LIMIT_OCXO_NODE:
case LIMIT_TX0_TEMP_NODE:
case LIMIT_TX1_TEMP_NODE:
case LIMIT_PA0_TEMP_NODE:
case LIMIT_PA1_TEMP_NODE:
case LIMIT_SUPPLY_VOLT_NODE:
case LIMIT_TX0_VSWR_NODE:
case LIMIT_TX1_VSWR_NODE:
case LIMIT_SUPPLY_PWR_NODE:
case LIMIT_PA0_PWR_NODE:
case LIMIT_PA1_PWR_NODE:
return 1;
default:
return 0;
}
}
static struct vty_app_info vty_info = {
.name = "lc15bts-mgr",
.version = PACKAGE_VERSION,
.go_parent_cb = go_to_parent,
.is_config_node = is_config_node,
.copyright = copyright,
};

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/>.

View File

@ -16,7 +16,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

@ -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/>.

View File

@ -16,7 +16,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

@ -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/>.

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/>.

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/>.

View File

@ -16,7 +16,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

@ -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/>.

View File

@ -15,7 +15,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

@ -16,7 +16,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

@ -16,7 +16,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

@ -15,7 +15,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/>.

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