Compare commits

...

324 Commits

Author SHA1 Message Date
Oliver Smith 3b5e7b554e debian/postinst: add checks, be verbose
Do not attempt to change permissions/ownership if the package gets
upgraded from a version higher than the next release.

Do not fail if the user deleted the config file.

Be verbose when changing permissions.

Related: OS#4107
Change-Id: I853097a13e27b2ebd0b940117c8f5f4b3ea49b9a
2024-05-14 15:20:34 +02:00
Oliver Smith 99ad68f299 contrib: remove rpm spec file
Related: https://osmocom.org/news/255
Related: OS#6446
Change-Id: Ic79cde09bf7d5e96e439b1883d3a3fe5568bdbf1
2024-05-08 14:40:56 +02:00
Oliver Smith 6c66f59314 .deb/.rpm: various fixes related to non-root
* Explicitly chown /var/lib/osmocom to osmocom:osmocom, instead of
  relying on systemd to do it when the service starts up. This does not
  work with the systemd versions in debian 10 and almalinux 8.
* deb: Use "useradd" instead of the interactive "adduser" perl script
  from Debian. This makes it consistent with how we do it in rpm, and
  avoids the dependency on "adduser".
* deb: Consistently use tabs through the file, instead of mixing tabs
  and spaces.
* deb: Remove support for the "dpkg-statoverride --list" logic. This
  seems to be a rather obscure feature to override permissions for
  certain files or directories, for which it does not seem to be a good
  idea to make the postinst script less maintainable. Something similar
  can be achieved by using your own Osmocom config file in a different
  path with different permissions.

Related: OS#4107
Change-Id: Ie34e7aa65e576cf1742a33530a6f44d2344c39d0
2024-04-26 15:08:44 +02:00
Max 1bca191188 .deb/.rpm: add osmocom user during package install
Create osmocom user & group during package installation.
Fix the configuration dir/files permission to match.

Related: OS#4107
Tweaked-By: Oliver Smith <osmith@sysmocom.de>
Change-Id: Ic64bcd8a8124fcc8c6d7ffe31d32f51b288afdcb
2024-04-24 11:51:26 +02:00
Pau Espin 9fb31c13df cbsp_link.c: Update somo_stream read_cb2 functions to accommodate for new API param
libosmo-netif (not yet released) stream_{cli,srv} osmo_io read_cb API was
updated to provide read result status. Hence, now API users
can account for lower layer errors and act properly, like it used to
do with the previous ofd backend.

This commit partially reverts some error code paths removed in
85687bf176 when converting code to use
osmo_io osmo_stream backend.

Change-Id: I4cce5cb6ca98bc28a67dd6e927e9cdfd2312851a
Depends: libosmo-netif.git Change-Id I395c75ff1e9904757ce1d767a9ac2f779593c4c8
2024-04-17 16:13:39 +02:00
Pau Espin d7afb4341e lb: Log name of unhandled sigtran primitive
Change-Id: I2d71fd347af404c025fc6b13e96f1964e685db05
2024-04-16 21:32:05 +02:00
Harald Welte 829986e06a README.md Add Forum + Issue Tracker sections
Change-Id: I0e9fc221fdf78ad94de7713b62473680ee7d58c2
2024-03-23 16:47:20 +01:00
Harald Welte 8c8e920eb7 README.md: Overhaul (more links, fix markdown formatting)
Change-Id: Id1e320439c052797cb9c6cda51b65cd2b9e9a3c4
2024-03-23 16:47:20 +01:00
Harald Welte bd3583ffbd 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: I754edea2ed122b6056e0fc94056ec6d509299067
2024-03-23 16:47:20 +01:00
Harald Welte 85687bf176 CBSP: Port over to use osmo_io via libosmo-netif
Change-Id: Icce412e6ee69366c7b131c9bc1d51e8d44204917
Depends: libosmocore.git Change-Id I5e922c54b3431d759b38e81e55076125c5a34008
Related: OS#5755
2024-03-04 19:16:14 +00:00
Matan Perelman cc1ac21671 ctrl: Add lchan show to all ctrl levels
This new commands show information about logical channels:
    net.btsN.trxM.tsI.show-lchan.full
    net.btsN.trxM.show-lchan.full
    net.btsN.show-lchan.full
    net.show-lchan.full

Change-Id: I23c1a7e6f6679e3964e359fb202ffe6781a07e8a
2024-02-24 16:44:30 +02:00
Matan Perelman a5249dd96c ctrl: Add lchan show
This new command shows information about a logical channel using
net.btsN.trxM.tsI.lchanL.show.full

Change-Id: I5432800eae452b6df71a151a7649f228704ed0da
2024-02-20 12:41:07 +02:00
Harald Welte ea42371454 bsc_ctrl_lookup.c: Use AGPLv3, not GPLv2
I guess it must have been a mistake when introducing this file.
The entire project is under AGPLv3, it doesn't make sense to have
one single file under GPLv2.

As th entire git commit history only contains sysmocom employees,
I have the authority to re-license it even if GPLv2 was done
intentionally at the time. Let's change it.

Change-Id: I5e5385f7630b41f1c4ad9534dbb4551e597ad596
2024-02-19 20:47:27 +00:00
Harald Welte 3f1b81bcf4 Fix license header in various source code files.
IF we say "... under the terms of the GNU Affero General Public License"
then we cannot say "see the GNU General Public license" later on, that's
misleading and likely a copy+paste error somewhere.

The project license has always been AGPLv3-or-later.

Change-Id: I6b8ad5147ca76052213809e67856dcb80bff2b93
2024-02-19 20:47:27 +00:00
Matan Perelman d399e0c927 ctrl: Add ms power
This new command allows to control MS power level for a specific
logical channel using net.btsN.trxM.tsI.lchanL.ms-power

This patch also adds a lchan node to the ctrl interface.

Depends: libosmocore.git Ibf2786f668ee7e4f5b6a9ef43f2141cd2d79b4e2
Change-Id: I6f556b66011be6126d6bac31a14101ba37f81cc4
2024-02-17 11:07:46 +02:00
Matan Perelman 6b6714ba13 ctrl: Split bts_trx_ts_ctrl from bts_trx_ctrl
Besides from making the ts ctrl interface follow the convention
of being in its own file, it will be used in the next patch to add
a ctrl interface for lchan.

Change-Id: I9840bddd4eae409bc8373912d54b6bbfc9fc1c1a
2024-02-08 20:30:51 +00:00
Matan Perelman 88c051447a ctrl: Remove unused vty includes
Change-Id: Ib464d0be9df839740a648ff6747130c18d33455d
2024-02-07 15:28:45 +00:00
Vadim Yanitskiy a14b4a7379 abis_nm: fix -Wunused-but-set-variable (bug)
clang warns us about 'len' being set, but not used:  And this is

  abis_nm.c:2172:10: warning: variable 'len' set but not used [-Wunused-but-set-variable]
        uint8_t len = attr_len;
                ^

This is actually a bug, because in the case of NACK we append 2 more
bytes {NM_ATT_NACK_CAUSES, NM_NACK_OBJCLASS_NOTSUPP}, and we need to
pass the final length to fill_om_fom_hdr(), including those optional
two bytes.  Passing 'attr_len' (length of 'attr') is wrong.

Change-Id: I3ca8e761fdf99dd498a979ccc9d53c6c3e03e2cc
2024-02-05 14:45:09 +01:00
Pau Espin 0368a9e815 abis_nm_sw_act_req_ack: attr_len should be unsigned
Change-Id: I5c0ba76b5cc2464c7e362a850325c94770f38397
2024-02-05 14:45:04 +01:00
Vadim Yanitskiy 11d7ed2d9f abis_nm: misc/cosmetic changes to abis_nm_sw_act_req_ack()
Change-Id: I2849a22647805e7477d66055c18614a3a9f80748
2024-02-03 06:38:45 +07:00
Vadim Yanitskiy a885a77a1e lchan_fsm: fix -Wgnu-designator warnings printed by clang
Change-Id: I48baef2e2b31f639281a455b2c3b07fd4f7af591
2024-02-03 04:20:15 +07:00
Vadim Yanitskiy 08042c3b8a bsc_ctrl: do not overwrite rc in bsc_base_ctrl_cmds_install()
Change-Id: Ie4242be1d3e58d7e37938d9ccbeffcb2b442632f
2024-02-03 04:20:15 +07:00
Vadim Yanitskiy 3c92391c9d build: include README.md into the release tarball
Change-Id: I1dc8e6c4faca2761ae8caf73b1ee83233ed2c1e1
2024-01-26 23:30:27 +07:00
Andreas Eversberg 0c1ab7d82f Add vty commands "no gprs nsvc ..."
A switch (bool) is used to enable or disable NSVC 0 or 1. It is enabled
via any "gprs nsvc 0|1" command and disabled via "no gprs nsvc 0|1"
command. If it is disabled, it is treated as unconfigured, similar when
no remote IP or port has been defined.

Related: OS#6006
Change-Id: Ia112e86aa35f6a245d98ef1b3720c18835faeda6
2024-01-24 08:52:55 +00:00
Andreas Eversberg 9a730ee2d4 VTY: Add command `show bts brief`
This line shows all BTS an their OML states in a single line.
Additionally the uptime or downtime is displayed, if there was a connect
or disconnect of the OML link.

Related: OS#6018
Change-Id: I003fd32e589ddf53b7dd42089f904cfb598e3625
2024-01-24 08:52:55 +00:00
Andreas Eversberg f405db793e Also track downtime when OML link is lost
This will be used in a later patch to dertemine when a BTS became
offline.

Related: OS#6018
Change-Id: I1776099cbfef51af1d5a3a056fb0654abd7366a9
2024-01-24 08:52:55 +00:00
Vadim Yanitskiy b2f11dbcae Remove unused OpenBSC leftover 'openbscdefines.h'
Change-Id: Iafc9f387a07f1eba66d291a84017e7dee56c4cb7
2024-01-22 19:52:27 +07:00
Oliver Smith dea9921e28 vty: show mscs: add BSSMAP state
New output:
  OsmoBSC> show mscs
  MSC 0: RI=SSN_PC,PC=0.23.3,SSN=BSSAP <-> RI=SSN_PC,PC=0.23.1,SSN=BSSAP
         ASP protocol: m3ua
         BSSMAP state: CONNECTED

Closes: OS#6741
Change-Id: I23ddba7d935e5cc5dae041458207c674ccb9d013
2024-01-16 19:01:54 +01:00
Oliver Smith fb23879651 vty: show mscs: tweak output
Make the output more readable and split it over two lines, in
preparation to add more information in the next patch.

Before:

  OsmoBSC> show mscs
  0 m3ua RI=SSN_PC,PC=0.23.3,SSN=BSSAP RI=SSN_PC,PC=0.23.1,SSN=BSSAP

After:

  OsmoBSC> show mscs
  MSC 0: RI=SSN_PC,PC=0.23.3,SSN=BSSAP <-> RI=SSN_PC,PC=0.23.1,SSN=BSSAP
         ASP protocol: m3ua

Related: OS#6741
Change-Id: I70ad1b0f44f2a923248f4e3259747cb3fec98fd2
2024-01-16 18:25:17 +01:00
Matan Perelman 1cfec9d2c9 ctrl: Add ms max power
Change-Id: I703057b0ad15ca56abf2b6223d5a5f4b33d944d8
2024-01-14 08:32:07 +02:00
Matan Perelman 5e28334fa9 ctrl: Add rach max transmission
Change-Id: I34c92cbbcaa46235481a491f4c6ff723b671fff1
2024-01-14 08:11:17 +02:00
Neels Hofmeyr 2323e577d9 vty: disallow combination of early-IA and frequency hopping
Related: osmo-bts Id9a930e5c67122812b229dc27ea2bfe246b67611
Related: SYS#6655
Change-Id: I8d375e5155be7b53034d5c0be5566d2f33af5db0
2024-01-10 07:59:51 +00:00
Harald Welte f53c5588d2 fix spelling s/omso/osmo/ in bts_variant_names
Change-Id: I37949c286498d99ecfdd3c36961226fefdc000ec
2024-01-08 11:48:19 +01:00
Matan Perelman 126952e203 ctrl: Fix missing reply in set_bts_cell_reselection_offset
Change-Id: Iacdb192dc15ab7e10e06c0dfe0984fc8a5727ecc
2024-01-06 13:04:56 +02:00
Matan Perelman c37fcff9c5 vty: Ensure radio-link-timeout is a multiple of 4
According to Table 10.5.2.3.1 in TS 144.018, radio-link-timeout
values are between 4 to 64 in steps of 4.

Change-Id: I733591d5f72f2e4f822761ca9eda85de7a4c6c81
2024-01-04 18:14:33 +02:00
Matan Perelman 29389bd44a ctrl: Add radio link timeout
Change-Id: Ic9532d4b051d34e71c91aaff545fb3dfa7d7c8b2
2024-01-04 13:56:00 +02:00
Matan Perelman 6f1991fd82 ctrl: Add rach expiry timeout
Change-Id: I74a402a3800d245e4bc3052ccb53d8d2660e9f52
2024-01-02 13:44:28 +02:00
Matan Perelman 40ecc7d538 abis_rsl: Add rach expiry timeout
This allows controlling the RACH DoS attack protection without
increasing call drops rate.

Change-Id: Iff7266672dd8bc9ce2b34b0478d98fb70691f425
2024-01-02 09:14:16 +02:00
Keith Whyte f033c82f54 VTY: fix config indentation for pcu-socket params
osmo-bsc would not start with a config written from the vty due
to incorrect identation on the pcu-socket parameters.

Change-Id: I36a66794e654989b4b8bf54bb3727ccbfc2131fa
2023-12-27 17:26:31 +00:00
Matan Perelman 9579e8337b ctrl: Add rxlev access min control
Change-Id: I25bf4bb11bf8e34e80f740fb89a467fc6e491962
2023-12-27 08:40:13 +02:00
Vadim Yanitskiy 9da6536312 vgcs_fsm: fix NULL pointer dereference in vgcs_call_fsm_busy()
Change-Id: I14ad41bfa1ab3455a6a175cfb05341ca12c8d73e
Fixes: CID#322299
2023-12-12 22:42:18 +07:00
Andreas Eversberg 5dee672e96 Only check for intersecting AMR codec support on matching TS rate
Only check for intersecting full rate AMR codec, if the BTS has at least
one full rate or dynamic time slot configured.

Only check for intersecting half rate AMR codec, if the BTS has at least
one half rate or dynamic time slot configured.

Related: OS#5926
Change-Id: Ia4a8e7f22dc652655ee7c5458624df8ae136dd95
2023-12-11 08:59:46 +00:00
Vadim Yanitskiy 510a868168 gsm_data: use ABIS_RSL_CHAN_NR_CBITS_* in gsm_pchan2chan_nr()
Change-Id: Ic9370d8d7f13cce0f9c6e60a920d04161a7d6844
2023-12-09 01:47:13 +07:00
Vadim Yanitskiy 2376b52da2 gsm_data: fix wrong variable set in gsm_pchan2chan_nr()
I believe the actual intention was to reset the 'lchan_nr' variable,
and not the 'chan_nr'.  The 'lchan_nr' is used to compose the 'cbits':

  cbits = 0x04;
  cbits += lchan_nr;

If the value is 4, then the result is:

  cbits = 0x04 + 4 = 0x08

which corresponds to SDCCH8 (not SDCCH4), and is clearly wrong.

Change-Id: Ic9c7c2e46e24dab0b721221e9adcbbae2ca56d23
Fixes: ec1b5a0e9 "gsm_ts2chan_nr(): add assertions for lchan_nr"
Fixes: CID#336586
2023-12-09 01:47:13 +07:00
Andreas Eversberg 71f96f1b57 Use uniform log format for default config files
Related: OS#6272
Change-Id: I992ff466db768f625dd722d40829aa0301cc1705
2023-12-01 12:33:42 +01:00
Neels Hofmeyr 65e257effb systemd,manual: set LimitNOFILE=65536
A typical OS imposed limit is 1024 open FD, which is too low when there
are hundreds of BTS.

In systemd service file, set a super high limit of 65536.

In osmo-bsc's user manual, add section 'Configure limits' describing
this in detail.

Related: OS#6256
Change-Id: I26c4058484b11ff1d035a919bf88824c3af14e71
2023-11-30 18:03:31 +01:00
Oliver Smith 6766608231 recover BORKEN lchans for missing ACK scenarios
We already recover broken lchans where an ACTIV ACK or REL ACK arrives
late. Now add a recovery path for lchans that are broken because no
ACTIV ACK or REL ACK arrives at all.

Add a timeout of X28 = 30s to the lchan BORKEN state.
On timeout, attempt both a Channel Activation and a Channel Release. If
any of them is ACKed, we have successfully synced BTS and BSC's state.

After successful recovery, place the lchan back in the UNUSED state,
available for servicing subscribers.

If recovery is unsuccessful, just continue to attempt recovery every
further X28 seconds.

Patch-by: osmith, nhofmeyr
Related: osmo-ttcn3-hacks I9b4ddfc4a337808d9d5ec538c25fd390b1b2530f
Related: OS#5106
Related: SYS#6655
Change-Id: Ic4728b3efe843ea63e2a0b54b1ea8a925347484a
2023-11-27 16:33:25 +00:00
Andreas Eversberg a4fc35c3b2 ASCI: Repeat notification after assigning MS to VGCS/VBS channel
The assignment is repeated because the calling subscriber may not
receive the notification on the DCCH, during handover process. After the
assignment is complete, the calling subscriber will receive
notification.

This cannot be done automatically by the BTS, because the BTS has no
relation between the notifications and the channels.

The notification is required, so that the MS knows the channel to listen
to when leaving the uplink the first time. If no notification is
received, the MS will abort the call.

Change-Id: Ife568b8c2756be332c0b8de21111f66f6e537c4d
2023-11-27 15:51:40 +01:00
arehbein 252e7f3e91 bsc: Make socket queue max. length configurable
Title refers to the maximum length of the osmo_wqueue used for
the PCU socket connection.

Related: OS#5774
Change-Id: Ic5f19f4613bccaf582997a4d02b689adee083a0b
2023-11-24 10:46:08 +00:00
Neels Hofmeyr e24e8a3389 use X6 timer for REL ACK, not T3111
The lchan FSM timers were originally implemented to model earlier code
as closely as possible. Now it has come up that T3111 is used in the
wrong place:

3GPP TS 44.018 says:

 T3111:
 This timer is used to delay the channel deactivation after
 disconnection of the main signalling link.
 Its purpose is to let some time for possible repetition of the disconnection.
 Its value is equal to the value of T3110.

Before this patch, we use it also to time the RF REL ACK message. That
is pretty bad, because T3111 is only 2 seconds by default, making RF
CHAN REL vulnerable for timeout. When a user increased T3111 to
alleviate the problem, the result is that each lchan also delays its
normal channel release procedure by the configured amount of time. Very
inelegant.

Instead, use the X6 timer for REL ACK, because X6 already times the CHAN
ACTIV ACK, which is semantically identical.

Compatibility / user impact: No negative impact expected.
We can assume that every user out there has X6 configured to work for
CHAN ACTIV ACK. From that logic, switching channel release ACK to the
same timer is guaranteed to be what the user intends. We could instruct
users in the release notes that they may now choose T3111 freely (as
short as 2 seconds) without jeopardising channel release anymore.

Related: SYS#6655
Change-Id: Ibd118fa23e5deb4381bc31b11a7b495f57901d6c
2023-11-22 00:48:10 +01:00
Philipp Maier 647bc1e698 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: I4b58912ad7be3070829614853901aa19108ba2c0
2023-11-21 09:16:46 +00:00
Matan Perelman 54cc907c97 ctrl: Add cell barred
Change-Id: I6dc45fa1d76707be0d9f9d4391550be598ed0a6d
2023-11-07 19:27:47 +00:00
Andreas Eversberg 9baa065c8d SI10: Fix uninitialized last_i index
Not only l_bts must be declared outside the for-loop, but also last_i.

This is a fixup of I9dbbd066075f9ccb331616a2b59b46b1b44c8b4c.

Related: CID#330311
Change-Id: Ia10c5e68cb2940d9360d78f606af25bb207ee55f
2023-11-06 11:19:07 +01:00
Andreas Eversberg 9b81ef5db8 SI10: Fix uninitialized l_bts pointer
l_bts must be declared outside the for-loop. If the loop is passed with
n_bts set the first time, l_bts is set. If the loop is passed with
n_bts set next time(s), l_bts is used to encode additional neighbor
cell infos.

Related: CID#330310 and CID#330311
Change-Id: I9dbbd066075f9ccb331616a2b59b46b1b44c8b4c
2023-11-01 10:04:11 +01:00
arehbein 50cb01c29f osmo-bsc: Have PCU socket connection use osmo_wqueue
Close PCU socket on write queue overflow.

Related: OS#5774
Change-Id: Ifd9741045a87338e17eec3492590a5de9c308cb5
2023-10-24 19:30:25 +00:00
Philipp Maier 801b55ee4a 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: Iebb3a634fee680bdc3636a61f3ccaa1e97e54a64
2023-10-24 15:10:28 +00:00
Andreas Eversberg d4625a20a5 ASCI: Add System Information 10 support
For each BTS, an SI 10 is generated with the informations about all
neighbor BTS that have the same group/broadcast call.

The SI 10 will only define neighbor cells within the same BSC, because
it does not know about neighbor cells within other BSCs.

When multiple channels are used for a group/broadcast call, the SI 10
is generated after all channels have been activated. Subsequent channel
activations result in an update of SI 10 on all channels.

Change-Id: Icd3101e6dd935a57f003253aaef400c2cf95a0c3
2023-10-23 11:31:26 +02:00
Andreas Eversberg fec682b45b ASCI: Make neigh_list_get_arfcn() available to other users
The error logging message within this function is moved to the user
neigh_list_get_arfcn().

In case of an error, which results in measurement report with cell
index that does not exist in the list of neigbor cells, the measurement
report is truncated to 0 neighbor cell measurements.

Change-Id: Ia8a1dca4837536129d17e7784b892bcb75b9ca4b
2023-10-09 12:47:04 +02:00
Andreas Eversberg d561e2dcba Select correct neighbor list for measurement report decoding
System Information 2 (bis/ter) uses BA_IND of 0. This refers to
"neigh_list". System information 5 (bis/ter) uses BA_IND of 1. This may
refer to "neigh_list" or optionally "si5_neigh_list", depending on the
VTY settings.

If BA_IND of 1 is received in measurement report and if the optional
"si5_neigh_list" is used, this list is chosen to decode the measurement
report.

Change-Id: Ie9123928fb3ae6f10921ecf01d1b50330661da38
2023-10-09 09:50:10 +02:00
Andreas Eversberg 82f10a6358 Do not generate 'bit map 0' neighbor lists with R-GSM ARFCN
Before this patch, neighbor cells with ARFCN 955 to 974 were ignored in
the GSM 900 band. This resulted an empty 'bit map 0' list in SI2/SI5
messages.

This patch includes R-GSM ARFCN in range 955 to 974. A different encoding
is chosen, if neigboring cells fall within this range.

Change-Id: I40d024290fa4be2ba8d3149ec841b182d0cc8c1f
2023-10-09 09:50:07 +02:00
Philipp Maier a3a225a16b 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: I23df067df99b76048667131905c4448d32d80640
2023-10-04 14:46:21 +00:00
arehbein ea388e1db1 meas_feed: Use osmo_io instead of write queue
Related: OS#6170
Change-Id: Ib0570a3242e2846062e24c93cbbbbd31137acdee
2023-10-04 08:38:12 +00:00
Pau Espin 9bb4b22152 Drop unused local var
Change-Id: I6da89b8861c0bd17fc011b55d5f4979ad6787f80
2023-10-03 14:12:09 +02:00
Oliver Smith dea8aa8e61 vty: make NCC Permitted (SI2) configurable
Related: SYS#6579
Change-Id: I71bb855c35378f8f0598bc11a42bd274b7232a5e
2023-09-28 17:04:23 +00:00
Pau Espin eb5ac9dca4 sccplite: Support multiple MGW in MGW pool
Before this patch, the MGW was selected at startup, and the MGCP data
was always forwarded to that same MGW.
If several MGW were configured in the MGW pool, then osmo-bsc would
select any of those from the pool, and start configured the BTS-side
connection on an endpoint in that MGW. However, when the MSC submitted
the MGCP encapsulated in IPA to the BSC, the BSC would always forward
the MGCP message to that same MGW selected at startup.
As a result, multiple MGWs configured with osmo-bsc using SCCPlite was
broken.

This commit fixes support for multiple MGWs by looking up the already
selected MGW (to setup the BTS-side conn on the endpoint), based on the
CIC (MGCP Endpoint) which was provided by the MSC upon AssignReq.

Related: OS#6189
Depends: libosmocore.git Change-Id Iee361d740845257fa62c9093e30e8079fa933827
Depends: osmo-mgw.git Change-Id I18d7bdf650c0ec87ae16ed4944aed9f495400137
Change-Id: Ia106a21b7692eb5b2ac3b5ac2b358bedbc3b9da6
2023-09-27 18:28:16 +02:00
Matan Perelman eff19b55b0 si2quater: Invalidate thresh_lo, prio and qrxlm when needed
Change-Id: I5910ce8db2d085295b327b12096ba129369eb532
2023-09-24 16:05:29 +00:00
Vadim Yanitskiy 8fcd6ab174 abis_nm: send Get Attributes to GPRS Cell MO(s)
Change-Id: Ib6d87da49217f1c8d76445ce623a511a07daedbf
Related: OS#4505
2023-09-23 17:56:49 +07:00
Vadim Yanitskiy a84f30d7c5 abis_nm: send Get Attributes to Rado Carrier MO(s)
Change-Id: If7b75689c12a253377f2747babd4d7ebd1db5f87
Related: OS#4505
2023-09-23 17:56:49 +07:00
Vadim Yanitskiy 029ab2326a oml: ipacc: fix sending hard-coded GPRS Cell attributes
Change-Id: I7d90ca3d6a660af8e953e890c7919194f5d297d2
Related: OS#4505
2023-09-23 17:56:47 +07:00
Vadim Yanitskiy daf7b28387 oml: ipacc: send GPRS Cell attributes based on IPA Object Version
Change-Id: Ie0fb3eaf76e1f70e5a19bb088e1674b7e553d32a
Related: OS#4505
2023-09-23 17:54:05 +07:00
Harald Welte c992bda3cd oml: ipacc: print all supported versions of MOs
The first byte is the default version, the other bytes describe the
optional other versions supported by the MO.  Print them all.

Change-Id: I01da4883cf59101ddaef575979519ac48fcf54b0
2023-09-23 17:45:24 +07:00
Vadim Yanitskiy 392cfc6a2a abis_nm: delay configure_loop() until NM_MT_SW_ACTIVATED_REP
Even though the Abis/OML message flow looks the way it should look
on the wire, it does not actually reflect the sequence/flow of events
and actions in the NM FSMs.  For example (extracted from a PCAP):

    GPRS Cell(00,00,ff) State Changed Event Report
    GPRS Cell(00,00,ff) Software Activate Request
    GPRS Cell(00,00,ff) Software Activate Request ACK
    GPRS Cell(00,00,ff) Activate Software
    GPRS Cell(00,00,ff) Activate Software ACK
[a] GPRS Cell(00,00,ff) State Changed Event Report
[b] GPRS Cell(00,00,ff) Software Activated Report
[c] GPRS Cell(00,00,ff) Get Attributes
    GPRS Cell(00,00,ff) Get Attributes Response
[d] GPRS Cell(00,00,ff) IPA Set Attributes
    GPRS Cell(00,00,ff) IPA Set Attributes ACK
    GPRS Cell(00,00,ff) Change Administrative State
    GPRS Cell(00,00,ff) Change Administrative State ACK
    GPRS Cell(00,00,ff) State Changed Event Report
    GPRS Cell(00,00,ff) Opstart
    GPRS Cell(00,00,ff) Opstart ACK

A follow-up patch [1] changes the logic generating message [d],
so that the IPA Object Version of the GPRS Cell MO is taken into
account when adding the attributes.

The problem is that both messages [c] and [d] are generated and
queued for transmission on the receipt of message [a], but *before*
message [b] has been processed.  So the IPA Object Version is not
known and assumed to be 0 at that point in time.

This patch delays configure_loop() until message [b] is received.
So far only for nanoBTS and only for those MOs, for which Figure 2
in 3GPP TS 52.021 explicitly mentions that the SW downloading and
activation procedures may be required, plus for the ip.access
specific MOs which all seem to support the SW activation.

osmo-bts does send SW Activated Report only for a subset of MOs,
which does not include Baseband Transceiver, Radio Carrier, and
Radio Channel.  3GPP TS 52.021 is not clear on whether this
message shall be sent by all MOs either, so we consider it
optional and delay configure_loop() only for nanoBTS.

Change-Id: I3953a5e41eb27165f9ff203cac7447ee9d311abf
Related: [1] Ie0fb3eaf76e1f70e5a19bb088e1674b7e553d32a
2023-09-23 17:04:41 +07:00
Vadim Yanitskiy a1745e3bdd abis_nm: handle NM_EV_SW_ACT_REP in ST_OP_DISABLED_{DEPENDENCY,OFFLINE}
3GPP TS 52.021 does not strictly mandate that the SW Activated Report
can only be received in state DISABLED/OFFLINE.  The only requirement
is that the software load procedure (if needed) and activation is to
be performed in this state.

The successful outcome of software activation procedure is indicated
by the BTS using the above-mentioned SW Activated Report message,
which may be received in ST_OP_DISABLED_{DEPENDENCY,OFFLINE} too.

The MO state changes are triggered by the State Changed Event Report
messages, and happen asynchronously with the software activation.

This patch fixes the following warnings seen with a nanoBTS:

NM_BTS_OP(bts2){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_GPRS_NSE_OP(nse2){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_GPRS_CELL_OP(gprs-cell2){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_GPRS_NSVC_OP(nsvc0){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_GPRS_NSVC_OP(nsvc1){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_BB_TRANSC_OP(bts2-trx0){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_CHAN_OP(bts2-trx0-ts0){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_CHAN_OP(bts2-trx0-ts1){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_CHAN_OP(bts2-trx0-ts2){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_CHAN_OP(bts2-trx0-ts3){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_CHAN_OP(bts2-trx0-ts4){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_CHAN_OP(bts2-trx0-ts5){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_CHAN_OP(bts2-trx0-ts6){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_CHAN_OP(bts2-trx0-ts7){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted
NM_RCARRIER_OP(bts2-trx0){DISABLED_OFFLINE}: Event SW_ACT_REP not permitted

The following warning is still expected to show up though:

NM_BTS_SM_OP(bts_sm){ENABLED}: Event SW_ACT_REP not permitted

but is caused by a different problem, which is to be fixed later.

Change-Id: I00a423adcde5c34977f4c4dad920874687fa493c
2023-09-21 01:48:38 +07:00
Vadim Yanitskiy faf7592bf5 oml: ipacc: add missing is_ipa_abisip_bts() checks
These functions are called from a signal handler (SS_NM), and the
signal itself is sent from the generic OML logic whenever the
Software Activated Report is received from some BTS, which is not
necessarily a nanoBTS or osmo-bts.

It would be nice if we could check the BTS type once in the signal
handler, but the signal data is not always the same and depends on
the signal type, so unfortunately it's not possible.

Change-Id: I088ff75f2048e54e4bfd926a79c1dcf27b4fb3a4
2023-09-19 21:09:25 +07:00
Vadim Yanitskiy fc2fb0d1a4 abis_nm: fix bts->nr vs bts->bts_nr
Using bts->nr on the wire is wrong because:

* bts->nr is a BTS number in the BSC's config file,
* bts->bts_nr is a BTS number within the SITE-MANAGER MO.

The problem does not show up if there exists only one BTS node
in osmo-bsc.cfg.  Otherwise, the Software Load and BTS Restart
procedures are broken for nanoBTS.

Change-Id: I99d9c72752e55c4553e2e9c60df5caa8343b7be0
2023-09-16 22:56:40 +07:00
Vadim Yanitskiy bf7b457f1c oml: ipacc: fix copy-pasted talloc chunk names
Change-Id: Ib0858c0d84b9bd2d3a4d732cfedb045862d2efed
Related: OS#4505
2023-09-15 19:21:22 +07:00
Vadim Yanitskiy 362c040e16 oml: ipacc: log supported features using LOGL_INFO
Change-Id: Ie0b05bc9e3739b5a38b32a676641e64f2cf698ac
Related: OS#4505
2023-09-15 19:21:22 +07:00
Vadim Yanitskiy 4454350b42 oml: ipacc: parse Object Version from SW Activated Report
Change-Id: I39105096a6b29bd7e4fb15287653074527c3e024
Related: OS#4505
2023-09-15 05:29:05 +07:00
Vadim Yanitskiy 5bdf6432f9 bts_ipaccess_nanobts: clean up, use gsm_objclass2mo()
Change-Id: Ic6c0dfe950459d07a8f506b5007a65fea1950c18
2023-09-15 05:29:05 +07:00
Vadim Yanitskiy ebffc84bf9 gsm_data: refactor/simplify and expose gsm_objclass2mo()
Change-Id: Ic03fdfabf84a1b5cd8046101c1575296914c6332
2023-09-14 16:26:19 +07:00
Vadim Yanitskiy c3446ef49e abis_nm: get rid of MAX_BTS_ATTR
This is a partial revert of commit [1], which defined a limit on the
number of attributes and SW Description IEs as a constant and added
a spec. reference.  The problem is that there is no such limit in the
referenced 3GPP TS 52.021.  The attributes and SW Description IEs are
using TL16V encoding, so there can be as many as the Length part can
represent.  It's actually the limitation of our side, since we
allocate a buffer of fixed size on the stack for parsing.

* Remove the MAX_BTS_ATTR and confusing spec. reference.
* For the SW Description IEs, define SW_DESCR_MAX locally.
* For the attributes, define the buffer size in place.

Change-Id: Idd8b971d32cf0f7a910a664d921e644b7c32d831
Related: [1] 1ebf23b7fe "Prepare for BTS attribute reporting via OML"
Related: OS#4505
2023-09-13 10:40:45 +00:00
Vadim Yanitskiy 9e1b54254c nm_{bb_transc,bts}_fsm: rework sending of Get Attributes
* Make it easier to append the attributes conditionally.
* Remove irrelevant comments about the order of attributes.
* Request NM_ATT_IPACC_SUPP_FEATURES from Abis/IP models only.

Change-Id: Ice5bddd51481a3ef9fcffd77a4c292ea211bf179
Related: OS#4505
2023-09-13 10:40:45 +00:00
Vadim Yanitskiy 9ac3459a00 abis_nm: parse feature flags in NM_ATT_IPACC_SUPP_FEATURES
Since change [1], among with the other attributes we started requesting
NM_ATT_IPACC_SUPP_FEATURES from the BTS.  This patch adds the logic for
parsing the response (so far only printing supported features).

Change-Id: I64cffa0bdead3617cc169c83b0f6ddf74f0866a7
Related: [1] 43440e1fc5
Depends: libosmocore.git Ia4208e10d61843dd6ae77398f6624c918dc81ea4
Related: OS#4505
2023-09-13 10:40:45 +00:00
Vadim Yanitskiy c8c4ac5659 abis_nm: separate parsing of osmo-bts features into a function
This commit prepares for adding handling of additional attributes.
The parse_attr_resp_info_attr() is already quite complex, so take
a chance to simplify it a bit.

Change-Id: Ia5919a8311cd6a7fc16d02d2196276881e96f4c5
Related: OS#4505
2023-09-13 10:40:45 +00:00
Vadim Yanitskiy 0ac03bd525 bts_siemens_bs11: remove ip.access nanoBTS specific code
This code is unreachable, because this file is all about Siemens BS11.
Take a chance to remove redundant BTS type check in nm_reconfig_bts().

Change-Id: I2db92fe448b1f4cd25c1e5c6e1bb9593795c9cb2
Related: OS#4505
2023-09-13 10:40:45 +00:00
Vadim Yanitskiy c4b330ba4c struct gsm_bts_trx[_ts], gsm_abis_mo: drop unused nm_attr
Change-Id: I36c3aaefa0bd9ee946a53ed537cf5c3bd7e9761e
2023-09-12 22:04:16 +00:00
Pau Espin b2b5ca0613 Bump version: 1.10.0.237-94878-dirty → 1.11.0
Change-Id: I25bfb1ecb202dc43928ee92a303bc1c6159d1626
2023-09-12 16:40:04 +02:00
Pau Espin 94878456e2 oml: ipacc: Use new packed struct abis_nm_ipacc_att_rlc_cfg from libosmcore
This way it becomes a lot clearer what kind of content is expected to be
transmitted over the wire.

It is expected that in the future the nowadays hardcoded values will be fed
into struct abis_nm_ipacc_att_ns_cfg come from osmo_tdef, etc.

Change-Id: I4b4dfac9fd36378b20889fb90135be74f8968d5f
Depends: libosmocore.git Change-Id I60e17dedd1fadce0f705616e3ed96cabb318bcec
Related: OS#5335
2023-09-01 20:45:13 +02:00
Pau Espin a473c260ff oml: ipacc: Use new packed struct abis_nm_ipacc_att_ns_cfg from libosmcore
This way it becomes a lot clearer what kind of content is expected to be
transmitted over the wire.

It is expected that in the future the bts_sm->gprs.nse.timer will
disappear and the values fed into struct abis_nm_ipacc_att_ns_cfg
come from osmo_tdef, etc.

Change-Id: I610ca34babc0b0ac9477622aa7b8360be8f3f59f
Depends: libosmocore.git Change-Id Ie477b0e6d79e6d408e0004fd60307afc5feaa3b6
Related: OS#5335
2023-09-01 20:45:13 +02:00
Pau Espin 9e5b3ad687 oml: ipacc: Use new packed struct abis_nm_ipacc_att_bssgp_cfg from libosmcore
This way it becomes a lot clearer what kind of content is expected to be
transmitted over the wire.

It is expected that in the future the bts->gprs.cell.timer will
disappear and the values fed into struct abis_nm_ipacc_att_bssgp_cfg
come from osmo_tdef, etc.

Depends: libosmocore.git Change-Id Ibfd759cb8a252f801bb3a758ea7960072c96f254
Related: OS#5335
Change-Id: Ie659879c548b29a08eeb8bf3fc023bf3d7d52aa1
2023-09-01 20:44:50 +02:00
Pau Espin 6d4c1d84e5 oml: ipacc: Remove BSSGP value assignment being overwritten afterwards
bts->gprs.cell.timer is initialized during BTS allocation from
bts_cell_timer_default.

Later on, during nanobts_gen_set_nse_attr(), the same default values are
applied to an internal buffer and immedately later overwritten by the
content of bts->gprs.cell.timer.

Hence, drop the temporary assignment since it gets overwritten and is
basically a NO-OP.

This is only an intermediate one-step-at-a-time commit, since anyway
that arrive has to be convertd to osmocom tdef, etc.

Change-Id: I2a170093e62f726e594d3b9c456087f47d2b4198
2023-09-01 20:14:55 +02:00
Philipp Maier e55a114e8a pcu_sock: use PCU_IF_SAPI_AGCH_2 instead PCU_IF_SAPI_AGCH
In PCUIF v.11 we use PCU_IF_SAPI_AGCH_2 exclusively. We use this SAPI
to transfer IMMEDIATE ASSIGNMENT messages for uplink and downlink. One
new feature of PCU_IF_SAPI_AGCH_2 is that the PCU may ask to send a
confirmation when the MAC block is sent.

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

Related: OS#5927
Depends: osmo-pcu.git I9effdcec1da91a6e2e7a7c41f95d3300ad1bb292
Change-Id: I709c27adaf09a6766cfde4d76d878626d30ebb3c
2023-08-31 11:03:20 +02:00
Philipp Maier 33a2a2fed5 pcuif_proto: check confirm flag in struct gsm_pcu_if_pch
Since osmo-bsc uses RSL (with a propritary Ericsson RBS specific
extension) to send a confirmed IMMEDIATE ASSIGNMENT messages via
PCH, we can not just forward the MAC blocks into the paging queue
without determining whether the MAC block is a PAGING message or an
IMMEDIATE ASSIGNMENT message. the reason for this is that RSL uses
two different message types (IMMEDIATE ASSIGNMENT COMMAND and PAGING
COMMAND) to process IMMEDIATE ASSIGNMENT and PAGING messages.

This means we have to look into the MAC block to make sure whether
the message is a PAGING message or an IMMEDIATE ASSIGNMENT message.

We also need to make sure that the confirm flag is properly executed.
In the case of the IMMEDIATE ASSIGNMENT this means we have to include
(confirm=true) or not include (confirm=false) the RSL_IE_ERIC_MOBILE_ID
into the IMMEDIATE ASSIGNMENT COMMAND message.

In the case of PAGING we directly echo a confirmation after sending
the PAGING COMMAND via RSL when a confirmation is requested.

Related: OS#5927
Depends: osmo-pcu.git Ia202862aafc1f0cb6601574ef61eb9155de11f04
Change-Id: I3d2842626b7e8325860ea3160c7d900d39e953a0
2023-08-31 08:29:58 +00:00
Pau Espin c1d7bb6908 meas_feed: Increase wqueue max_len to 100 and make it vty-configurable
The previous amount of 10 messages may be small if the BSC is processing
lots of measurements from lots of BTS connected to it.
Increase it to 100 by default, and allow changing the write_queue length
through the VTY.

Related: SYS#6550
Change-Id: Ib2e3591498c038b8e59f3ad447ac1f65928d6da8
2023-08-30 11:27:24 +02:00
Pau Espin 94426aae61 meas_feed: Refactor fd/wqueue lifecycle
The previous checks had several rough edges which may end up in
unexpected behaviors, specially with fd=0 vs fd=-1.
The new code is much more robust.

Change-Id: I96b0b5c4654970ba1c3e2aecfa896e310063ab6f
2023-08-29 17:39:57 +02:00
Andreas Eversberg 2ab39f7fa0 ASCI: Fix uninitialized values in vgcs_fsm.c, found by gcc 13.1.1.20230714
Change-Id: Iee4cc0fbf03e7ca4b53424f7f52ed9d599f96e49
2023-08-29 11:28:39 +00:00
Philipp Maier 5c9162980d pcuif_proto: get rid of _DT, _dt (Direct TLLI)
Since we now no longer refer to TLLI when we mean "message ID" (msg_id),
we should also remove the "_DT" / "_dt" suffix from structs and define
constants and replace it with "_2" if required.

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

Let's remove all those unused members.

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

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

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

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

Related: OS#5927
Depends: osmo-pcu.git I4a25039dfe329e68879bc68936e49c4b190625e6
Change-Id: Ifb3f257099b52c50e525768484f9e93282089d0f
2023-08-08 17:40:22 +02:00
Vadim Yanitskiy b74b3ae38f fix send_assignment_complete(): proper SCE encoding for CSD
As stated in 3GPP TS 48.008, section 3.2.2.103, coding of the Speech
Codec Element for the CSData Codec Type differs from coding for the
actual speech codecs like FR/HR/AMR/etc.  However, osmo-bsc currently
encodes the "Speech Codec (Choosen)" IE regardless of the channel
mode, be it GSM0808_CHAN_SPEECH or GSM0808_CHAN_DATA.  This causes
failures at the establishment stage of modem-to-modem data calls.

Change-Id: I8b94c0292964f6d5f5ffa98ad8da03728f8bf6a0
Related: OS#6110, OS#4393
2023-07-26 11:15:17 +00:00
Andreas Eversberg 7200b01577 Select channel type by enum instead of three boolean
struct lchan_activate_info and struct lchan_modify_info use an enum to
define, if the channel type is for a normal channel, a VAMOS channel or
a VGCS/VBS channel.

Change-Id: I21167eb4192c02cd7b5e1574cddb382a3feaebe0
2023-07-21 13:33:55 +02:00
Andreas Eversberg 2d93d61fe3 ASCI: Add assignment to a VGCS/VBS channel
The assignment is triggered by the MSC by sending an ASSIGNMENT REQUEST
with a group call reference. The reference is used to find the VGCS/VBS
channel that belogs to the referenced call.

The existing VGCS/VBS channel is reactivated. This will put the channel
into a state where the MS can establish the link on it, to complete the
assignment. The old connection is released by the MSC and assignment
completion is handled by the VGCS FSM.

Change-Id: Idaa864cd5ce4df6c3193494ce12d91523c104d89
Related: OS#4852
2023-07-21 13:33:51 +02:00
Andreas Eversberg b0712a9f22 ASCI: Send release on VGCS/VBS channel via unit data
Channel release is sent to MS that is in dedicated mode on the main
DCCH. Additionally it is sent as unit data on a VGCS/VBS to notify all
listeners that the channel has been released. All listeners return to
IDLE mode.

Change-Id: Ib777fe98c8ce2342082d88d227b796167d92cfe1
Related: OS#4852
2023-07-21 13:33:46 +02:00
Andreas Eversberg b620a1d994 ASCI: Add support for reception of TALKER/LISTENER DETECTION
TALKER DETECTION and LISTENER DETECTION is used when the uplink is
accessed on the VGCS channel by a talker or listener.

Change-Id: I166d6d42c04337e669307943ecbb8eea6906b385
Related: OS#4852
2023-07-21 13:33:44 +02:00
Andreas Eversberg ded74dc220 ASCI: Indicate release of subscriber connection to VGCS FSM
If an SCCP connection or channel is released or fails, send indications
towards VGCS FSM, so that it can terminate the state machines belonging
to these connections.

Change-Id: Ia74db9ba47fea11b359ac01269f714482485d464
Related: OS#4852
2023-07-21 13:33:41 +02:00
Andreas Eversberg 55860eed89 ASCI: Forward lchan activation states to VGCS FSM
Change-Id: I757b562e02480c1a68446d91217910069f17d060
Related: OS#4852
2023-07-21 13:33:39 +02:00
Andreas Eversberg a0230990df ASCI: Forward RLL to VGCS FSM
RLL events are forwarded to VGCS FSM. Included L3 information are not
forwarded to gsm0408_rcvmsg(), but forwarded to VGCS FSM only.

Change-Id: I5e098a20225ba11206f43281f4da519a4086bae5
Related: OS#4852
2023-07-21 13:33:36 +02:00
Andreas Eversberg 62b9c83721 ASCI: Add decoding of VGCS/VBS A-interface messages
Change-Id: I77b4d072d76039b1889ae4bba4a602e956405eb8
Related: OS#4852
2023-07-21 13:33:34 +02:00
Andreas Eversberg 1f05282243 ASCI: Add processing and FSMs for VGCS/VBS
Change-Id: Id9e94fb4f27bb438b7093c031344a3400bfa34f1
Related: OS#4852
2023-07-21 13:33:31 +02:00
Andreas Eversberg 8ebf52ac76 ASCI: Add encoding of VGCS/VBS A-interface messages
Change-Id: Ic2203a5119a226ac859a91dc42d81cbd71027ec8
Related: OS#4852
2023-07-21 13:33:28 +02:00
Andreas Eversberg 1ad32f7430 ASCI: Forward UPLINK RELEASE on dedicated channel to MSC
If the phone is (still) on a dedicated channel, it may release the
uplink in case of a voice group call. It depends on the MSC how to
handle the situation. Currently it releases the call.

Generally the phone is assigned to the VGCS/VBS channel before it
releases the uplink.

Change-Id: Ib91c282ed36e82b38c0e738533e3a421de81a9a8
Related: OS#4852
2023-07-21 13:33:25 +02:00
Andreas Eversberg 1349c9c217 ASCI: Add TX support for UPLINK FREE/BUSY messages
Change-Id: Ia27e0ebb5bf7edb1b9f84999cafc028231b9489f
Related: OS#4852
2023-07-21 13:33:22 +02:00
Andreas Eversberg 353fa5a14d ASCI: Add support for sending RSL UNIT-DATA towards BTS
This is required to send UPLINK FREE and UPLINK BUSY messages to the
BTS.

Change-Id: I25e80f079989a4c7dede58c327c22b958784f3ff
Related: OS#4852
2023-07-21 11:15:27 +00:00
Andreas Eversberg d8a6a533a1 ASCI: Do not wait for RLL establishment
A VGCS channel is established, even if there is no RLL establishmnt.
RLL connection can be established or released by the talker, while
the channel is kept in established state all the time.

Change-Id: I96390924736029b92e54590157e38093be749dd9
Related: OS#4852
2023-07-21 11:15:27 +00:00
Andreas Eversberg fd35bc917a ASCI: Do not release channel, if SAPI 0 is released
A VGCS channel must not release, if all SAPIs (including 0) are
released. lchan FSM will ignore this.

Change-Id: Ief1e1894362c4917f6e0092268690f68c8193750
Related: OS#4852
2023-07-21 11:15:27 +00:00
Andreas Eversberg 0a2e79e946 ASCI: Add new debug category "ASCI" for VGCS/VBS state machines
Change-Id: I4714fa4ff2b1327183a365223a3e3d89ae0357f7
Related: OS#4852
2023-07-21 11:15:27 +00:00
Andreas Eversberg 87a6e6b651 ASCI: Prepare bssmap_handle_ass_req_ct_speech() for VGCS/VBS
bssmap_handle_ass_req_ct_speech() calls select_codecs(), which requires
a bts pointer.

An extra bts pointer is added to both function and used instead of
deiving it from the conn->lchan pointer. This funcion can then be called
if no channel is assigned (yet). (conn->lchan is NULL)

This function will be used by the VGCS/VBS call control also.
(Chg-Id: Id9e94fb4f27bb438b7093c031344a3400bfa34f1)

Change-Id: Ifc1e315d5282f01f8d1bd600d62476c2ae74eca9
Related: OS#4852
2023-07-21 11:15:27 +00:00
Andreas Eversberg b18cae1952 ASCI: Make function to add OSMUX IE public
Rename _gsm0808_ass_compl_extend_osmux() to gsm0808_extend_osmux().

This IE is also used for VGCS/VBS assignment command that is located in
a different file.

Change-Id: I1452cabb142f9e7a169f4ddfeac85908abaf8dfc
Related: OS#4852
2023-07-21 11:15:27 +00:00
Andreas Eversberg 2193f98f3e ASCI: Add TX support for UPLINK RELEASE message
Change-Id: Ie3d8ad1ea8325c13759838d8083c6e47a0f54497
Related: OS#4852
2023-07-21 11:14:44 +00:00
Andreas Eversberg 2436f40b4c ASCI: Add selection reason for VGCS/VBS channels
"enum lchan_select_reason" gets a new selection reason: "SELECT_FOR_VGCS"

The selection "direction" can also be changed via VTY.

Change-Id: I6b96d0a1df68efa5858b98297ebe0944b1473aaf
Related: OS#4852
2023-07-21 11:14:44 +00:00
Andreas Eversberg 4827437a26 ASCI: Add support for Group/Broadcast channel activation
"struct lchan_activate_info" is expanded to support flags for VGCS and
VBS. These are used to send the correct Channel Mode to the BTS.

"enum lchan_activate_for" is expanded to indicate and activation of
VGCS/VBS calls.

Change-Id: Ic0c0597d149d0758d6766937d99660fa02e0e139
Related: OS#4852
2023-07-21 11:14:44 +00:00
Andreas Eversberg bcb7b32f5a ASCI: Add support for NOTIFICATION COMMAND (RSL) message
This message will be sent to each BTS with a VGCS/VBS channel to notify
the served MSs about ongoing group/broadcast calls. It is also used to
remove the notification, if the call is terminated.

Change-Id: I96ec0ee5d1a772a45f1ebfd64210718c8bf5aa58
Related: OS#4852
2023-07-21 11:14:44 +00:00
Andreas Eversberg a7e3e0064d Cleanup code style of rate counters in osmo_bsc_msc.c
Change-Id: I7cfd4f20ebfee0c8df9305372977d6628d6337c5
2023-07-21 11:14:44 +00:00
Andreas Eversberg e45fdd42d7 Fix typo in rate counters ASSIGMENT->ASSIGNMENT
Change-Id: I73079948afbdde35594660959b5335118a810d7b
2023-07-21 11:14:44 +00:00
Andreas Eversberg aee1db9dc1 ASCI: Add new rate counters to support VGCS/VBS messages
Change-Id: I18e4ca3599e480de2d0f64cc1b6f4bb6ce8020d4
Related: OS#4852
2023-07-21 11:14:44 +00:00
Matan Perelman 1c7eb78896 control.adoc: Update with recent changes
Change-Id: Iea1a416b958e28b95bc881b4ebf0568b43447fec
2023-07-21 11:03:53 +00:00
Matan Perelman 24e01a8225 control.adoc: Remove short-name and long-name
Those options don't actually exist in the CTRL interface!

Change-Id: Ic30807fc9ef6b586d040b81c88e4a8d2a76aa0a6
2023-07-21 11:03:37 +00:00
Vadim Yanitskiy 121461669e lchan_select: fix lchan selection for GSM48_CMODE_DATA_{14k5,12k0}
Change-Id: I271ebf7e64e3d0861586e9bc63bec113cb5fb410
Fixes: d5eb0f1b5 "lchan_select: chan_mode_to_chan_type: support CSD"
Related: OS#4393
2023-07-20 08:01:17 +00:00
Oliver Smith e6337315d0 configure: add --enable-meas-udp2db/pcap2db/vis
Do not build these utils implicitly if libsqlite3/libpcap/libcdk are
installed. Add configure flags for explicit building and fail if
dependencies are missing.

Keep behavior in deb and rpm packaging:
* deb: build meas_vis
* rpm: build none of these (libcdk dependency for meas_vis is not
  available in most rpm-based distributions we build for)

Fixes: OS#5173
Depends: docker-playground I015b6d7cb834e99ea5d04206ba5f8c519c4e6af1
Change-Id: I8b3d5efb769437a5d3036e1e627b8d477275d93e
2023-07-20 07:20:05 +00:00
Matan Perelman 241e594f7a ctrl: Support adding si2quater earfcn neighbor
Change-Id: Ifd2740ee54db66742785437a278cb9244e1f76d0
2023-07-17 09:00:49 +00:00
Matan Perelman 1bae98e2d6 ctrl: Add getting si2quater earfcn neighbor list
Change-Id: Ib942bfa95aca2b514ac68f602545b9e7cbed097a
2023-07-17 09:00:49 +00:00
Matan Perelman 8b64e032e2 ctrl: Support adding si2quater uarfcn neighbor
Change-Id: I8116175b5dff1ee4bbff0dc3b4f93890ce4c975b
2023-07-17 09:00:49 +00:00
Matan Perelman 4e13aab269 ctrl: Add getting si2quater uarfcn neighbor list
Change-Id: Iab1d2e264c0deb75f03aec6ae38ac406bc7b58cb
2023-07-17 09:00:49 +00:00
Pau Espin bc8b61139d cosmetic: Document DRX_TIMER_MAX upper limit on BCCH smaller than possible range
Related: OS#6097
Change-Id: I5c8699bb5357a74805c25e8d02e982b25b47555d
2023-07-14 19:02:11 +02:00
Pau Espin 74b34b4395 SI13: Set DRX_TIMER_MAX value actually transmitted
The set of values in seconds which can be expressed in the 3-bit field
DRX_TIMER_MAX (0s, 1s, 2s, 4s,...64s) don't include the "3s" that where
being specified. Instead, libosmocore's encode_drx_timer() was
taking both upper boundary "4s" and encoding it "0b011".
Hence, better write the value actually being transmitted to MS, to avoid
users/readers confusion.

More related info can be found on TS 44.060 Table 12.24.2 and TS 45.002
6.5.6.

Related: OS#6097
Change-Id: Ibf01a50b258e197ba5e3173492513349ddffdb38
2023-07-14 19:01:44 +02:00
Oliver Smith 681f965710 contrib/jenkins.sh: deduplicate configure flags
Prepare to add meas-related flags to CONFIG in future patches.

Related: OS#5173
Change-Id: I5685aa0bcb77286d1cd89cc9c8fee58991597446
2023-07-11 14:52:07 +02:00
Oliver Smith 3dc3ca5bab Cosmetic: debian/rules: remove boilerplate
Change-Id: I4582c711abc914736322ec2cffcd7b849507534c
2023-07-11 12:48:28 +02:00
Oliver Smith 79b683ec24 configure: ipa utils: add default=yes to arg help
Change-Id: Ie8c22f5103857b317add5f7d9d9f951665a6103a
2023-07-11 12:48:28 +02:00
Oliver Smith 162d8d79d4 Cosmetic: configure: move if … then to same line
Make it consistent throughout the file.

Change-Id: I13b98ef63c6fcbb98fb32311404fa5821f7bce58
2023-07-11 12:48:27 +02:00
Oliver Smith 40f5b3ff97 Fix various typos
Change-Id: I2726f18156f96999159f7b5f7c6c5a2d93667131
2023-07-11 12:48:27 +02:00
Matan Perelman 08b7b008c2 ctrl: Add rach max delay
Change-Id: I113211cc7e7ef20fac7e9d30e156522406ad62f7
2023-06-30 17:59:12 +03:00
Matan Perelman 1dd9afe582 ctrl: Add bsic
Change-Id: I5c941770924e5373733c3a3939671fab518f7a58
2023-06-25 06:26:22 +00:00
Matan Perelman 03b7b76a9f ctrl: Add setting SI5 neighbor list
Change-Id: I1bab242cdbd0d7b39636d69027bf75794a5d5ba7
2023-06-25 06:26:22 +00:00
Pau Espin caad230e99 Use new libosmo-sccp APIs osmo_ss7_asp_get_{name,proto}()
Depends: libosmo-sccp.git Change-Id If9acfca1abc9ab7eb6d2388f548d7ee577b9c5ac
Change-Id: I0479f7bfb8337a6a955ba66c7b403db3565659d6
2023-06-21 11:01:35 +00:00
Harald Welte 6153c619fc prevent bogus NCH related error message if no NCH is configured
Back in Change-Id  Iefde0af44a663f22462a54d68a58caa560eceb2f I
introduced indication of the NCH position in the SI1 rest octets.

However, a related ERROR messages is accidentially also printed in
case no NCH is configured at all.

Let's split the already overly-complex if clause into a separate
function which then also handles the "bts->nch.num_blocks == 0"
case as permitted.

Change-Id: Iab2120a343cb0f6553f13a821b44b3c312587579
Related: OS#5781
2023-06-21 11:48:45 +02:00
Philipp Maier faff9f8fdc pcu_sock: use correct SAPI in message PCUIF PCU_IF_MSG_DATA_CNF_DT
The message PCU_IF_MSG_DATA_CNF_DT uses SAPI PCU_IF_SAPI_PCH, which is
formally not correct. It should use SAPI PCU_IF_SAPI_PCH_DT

Depends: osmo-pcu.git I0883b51fc232ec0267f1511c3a37c0bcd0967a08
Change-Id: Id5c799e625c56e57f7b51cd4fb57f5bea9c973d2
2023-06-16 15:20:48 +02:00
Daniel Willmann ee8205b46b cosmetic: Fix type in VTY description
Change-Id: I3301d1c84b3386e0a4e9c3f18f89aee62e9097d5
2023-06-15 18:42:16 +02:00
Pau Espin ea9a6a1aea Use new mgcp_client_conf_alloc() API to alloc mgcp_client_conf
Depends: osmo-mgw.git Change-Id Iba0853ed099a32cf1dde78c17e1b34343db41cfc
Change-Id: I9d342d2eff7b57b0c542ff0c1c579f708451637c
2023-06-13 19:53:30 +02:00
Harald Welte 43440e1fc5 nanobts: Request "supported features" attribute from BTS and BB_TRANSC
The nanoBTS feature reporting works significantly different from what
osmo-bts implements.  They have a "Supported Features" IE in potentially
each of their MOs, and within this have nested IEs expressing respective
feature sets.

Let's start by requesting those for at least those MOs where we already
implement a GET ATTRIBUTES call in the FSM.

Change-Id: I15116044fb354ec0a0682c62078fbfa907b318f3
2023-06-11 19:32:33 +00:00
Matan Perelman 633b7a9caf ctrl: Add getting SI5 neighbor list
Change-Id: I71f5f23473b94059ac64770ceb256b4df36c0ef7
2023-06-11 19:26:34 +00:00
Matan Perelman d76bc795f7 ctrl: Add getting neighbor list
Change-Id: Icba0b7d92f4c67e617d707ca651d674f0d1ba8a7
2023-06-11 19:26:34 +00:00
Vadim Yanitskiy 50387d52f5 contrib/jenkins.sh: remove unrecognized --enable-vty-tests
There is no such option in the configure.ac:

configure: WARNING: unrecognized options: --enable-vty-tests

Change-Id: I04421af0b250651a598a7aeb5bed55dbacec2f7c
2023-06-11 19:25:49 +00:00
Pau Espin 9dc7211880 Write explicit role & sctp-role fields in ASP configurations
Change-Id: I9015c49cc52c75c6db986de2e3ac68529e5e4f9c
2023-06-08 19:37:13 +02:00
Vadim Yanitskiy 2a6954b3ae tests/{ctrl,vty}_test_runner.py: raise an exception if proc's rc != 0
Change-Id: I5fa3477979d41aef7b22464a925941ed0f115193
Depends: osmo-python-tests.git I1e11fcb6c5a587c27fc00920b6e157862d972fd9
Related: OS#5665
2023-06-01 20:10:10 +07:00
Harald Welte 8798689f3b Support (optional) indication of NCH position in SI1 rest octets
This adds the vty commands and respective logic to allow the user to
specify the NCH (notification channel) position in the SI1 rests octets.

Change-Id: Iefde0af44a663f22462a54d68a58caa560eceb2f
Related: OS#5781
Requires: libosmocore.git I24a0095ac6eee0197f9d9ef9895c7795df6cdc49
2023-05-31 09:19:53 +00:00
Vadim Yanitskiy ff3540cb2c fixup: contrib/jenkins: create workspace.tar.xz on error
cat-testlogs.sh does "exit 1", so no workspace.tar.xz is created.
Call this script after archiving the workspace.

Change-Id: Ibcb842f32418e66a186d6b21bb5861cf4a0b7c4a
Fixes: d33a66b779 "contrib/jenkins: create workspace.tar.xz on error"
Related: OS#5665
2023-05-28 03:04:56 +07:00
Oliver Smith fc914e9eb8 systemd: depend on networking-online.target
Related: SYS#6400
Change-Id: I9c0cc0779f9ddb7520a565668b7cde07c6ad55d8
2023-05-26 15:31:01 +00:00
Pau Espin 5b60a0c8b5 UserManual: Include sigtran*.adoc from osmo-gsm-manuals.git
They were only included in osmo-stp so far.

Change-Id: I004ca2ef70e7f32c83d14d90849cf13f3d1a2cdd
2023-05-26 14:09:23 +02:00
Philipp Maier a1ff30920d pcu_sock: fix PCUIF interface (PCH)
The PCUIF interface implementation in osmo-bsc provides two ways to
access the paging channel (PCH).

1) Under the SAPI PCU_IF_SAPI_PCH PAGING COMMAND messages are accepted
as whole MAC block but the format is in the style that we are going
to deprecate with PCUIF v.11. Also at the moment those PAGING COMMANDs
are not confirmed towards the PCU. This is also not necessary since
osmo-pcu would silently drop such confirmations. (see pcu_rx_data_cnf
in pcu_l1_if.cpp)

2) Under the SAPI PCU_IF_SAPI_PCH_DT messages are also accepded as
MAC blocks but the SAPI will only accept IMMEDIATE ASSIGNMENT messages.
The messages are encapsulated in a struct that holds IMSI (paging group)
and TLLI (used for confirmation) as separate struct members. The
messages are also confirmed towards the PCU as it should be.

Since we want to depreacete the older V.10 version of PCUIF and there is
not much benefit in maintaining two interfaces we should use
SAPI PCU_IF_SAPI_PCH_DT for both message types. This also requires small
adjustments to osmo-pcu (see Depends).

Depends: osmo-pcu.git I99cfe373fa157cfb32b74c113ad9935347653a71
Related: OS#5927
Change-Id: I82443f2b402aa2416469c8c50b1c050323ef3b8f
2023-05-24 12:29:00 +02:00
Oliver Smith d33a66b779 contrib/jenkins: create workspace.tar.xz on error
In order to figure out why we sometimes get a coredump in the jenkins
master jobs, add a quick hack to get all relevant binaries on libraries
on error.

Related: OS#5665
Change-Id: I1439c06316edbe11f162c14774c2d507152b97a7
2023-05-23 16:18:11 +02:00
Vadim Yanitskiy 1f3bfff668 copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH
Change-Id: I849a18a3bfd15aad00de3e103339540a7548e097
2023-05-18 17:22:26 +07:00
Max c1e2888050 pcu_connected(): constify parameter
Change-Id: I6d18ec0ad2bd6f71e0187ed70b03c3a2d0447f21
2023-05-11 18:19:23 +00:00
Harald Welte ef4ce1f3f1 test case fixup: Add missing (void) empty argument list specification
Change-Id: Idf7b044424f59f3069adda90ed336d01dac0118b
2023-05-08 06:31:11 +02:00
Harald Welte ea7b53850b cosmetic: Clarify language ip.access nanoBTS vs. all IPA Abis/IP
Don't explicitly mention ip.access/nanoBTS if we actually want to refer
to all BTSs implementing an IPA-style Abis/IP interface.

Also, remove some bogus "is_ipa_abisip_bts(bts) || is_osmobts(bts)".
is_ipa_abisip_bts includes osmobts.

Change-Id: I31696d9a21a799511741a561085686cfa0728f93
2023-05-08 06:28:52 +02:00
Harald Welte ceccba70a9 cosmetic: Rename is_ipaccess_bts() to is_ipa_abisip_bts()
This function is used to check if the BTS is using the IPA Abis-IP
transport, and not whether its manufacturer/vendor is ip.access.

Let's use a less confusing name.

Change-Id: I202c58341c1536489064d2671c0842c6f70b5429
2023-05-08 06:28:51 +02:00
Harald Welte 5d8ab13b34 abis_nm: Only osmo-bts re-purposes the MANUF_ID for BTS feature flags
The Manufacturer ID IE is normally used to indicate the [name of] the
manufacturer.  In case of ip.access nanoBTS it is, for example, "com.ipaccess".

Osmocom decided to re-pupose this IE to indicate bts-specific feature
flags.  Stop interpreting the string "com.ipaccess" as feature bitmap.

In fact, nanoBTS doesn't support runtime reporting of features (at
least not in this way), so let's mark features_get_reported = false,
resulting in the copy of bts_model->features to bts->features at the
time a BTS is initialized.

Change-Id: I76cee190dc1f074464df570cdfc3d38559f04846
Closes: OS#5959
2023-05-04 05:23:42 +00:00
Matan Perelman ba3fe2c908 ctrl: Add setting access control class
Change-Id: I7abbf0adc3798e9224834a68d7cdce4bbe03c9a3
2023-05-01 22:16:30 +03:00
Matan Perelman a8fcc1bb73 ctrl: Add getting access control class
Change-Id: I279249f9047f5edacc9edf3d231e3e74023fc84e
2023-05-01 22:16:30 +03:00
Matan Perelman f4d9dfe6bd ctrl: Add cell reselection hysteresis control
Change-Id: Ia96f6656d99381c039a4b3fd02674215fbbaec91
2023-05-01 22:15:33 +03:00
Matan Perelman 639cd00a22 ctrl: Add penalty time control
The penalty time gives the duration for which the temporary
offset is applied.

Change-Id: Idfdd54dec72fb5f52eee22df018161d75b8c48c8
2023-05-01 19:13:49 +00:00
Neels Hofmeyr 5d8d6d2079 fix mscpool for large msc NRs
Use the proper type that can handle the entire range of MSC numbers we
allow on the VTY, we have:
 #define MSC_NR_RANGE "<0-1000>"

Before this patch, MSC pool round robin would glitch around for any
'msc' numbers 'msc 256' thru 'msc 1000'.

Change-Id: I98bee022c1a78508554d2ff4a10fbce3c53f1128
2023-05-01 00:11:48 +00:00
Neels Hofmeyr a70d6b25c4 fix length check in abis_rsl_rx_rll()
In abis_rsl_rx_rll(), we do the following header length check -- quick
challenge, can you spot the two bugs hidden here?

  struct abis_rsl_rll_hdr *rllh;
  if (msgb_l2len(msg) >
      sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh))
           msg->l3h = &rllh->data[3];

Fix these bugs:

- struct abis_rsl_common_hdr is already included as the first member of
  abis_rsl_rll_hdr, no need to add that.
- We are going to be accessing rrlh->data[3], so we must check for at
  least sizeof(*rllh) + 4.

Change-Id: Ie4aee615c8c904ae8308ec0074d8bc5208137061
2023-05-01 00:11:48 +00:00
Vadim Yanitskiy ea3e3c258d gsm_bts_send_c0_power_red(): check if BTS is online first
... and print a proper error message instead of "not supported".  We
don't know for sure whether it's supported before the BTS is connected.

Change-Id: I080aa7ef331b76918ae48d555eea6e4290c57120
Related: SYS#6435
2023-04-28 18:05:37 +07:00
Vadim Yanitskiy 16922c5017 bts: st_op_enabled_on_enter(): resume C0 power reduction
If power saving is enabled for a BTS, it should remain enabled even
if the BTS is restarted for whatever reason.  This persistence can be
achieved by re-sending the configured power reduction value whenever
the BTS NM FSM enters the ENABLED state again (i.e. reconnects).

Separate gsm_bts_send_c0_power_red() from gsm_bts_set_c0_power_red()
and call the former from st_op_enabled_on_enter().  All we need to do
is to send the value that was configured before, per-timeslot power
reduction limits remain and need not to be updated.

Take a chance to move logging from BTS specific to the generic code.

Change-Id: Ic3f8a2ab0ffd049a8ed84361a3a588c1e1b23ac6
Related: SYS#6435
2023-04-28 18:05:37 +07:00
Vadim Yanitskiy 05e2deb49c bootstrap_rsl(): cosmetic: cache trx->bts and use it directly
Change-Id: I736ebf185028976dad5ff6f61386b6d2eeab8fbd
Related: SYS#6435
2023-04-28 02:21:20 +07:00
Vadim Yanitskiy 253f67f625 struct gsm_bts_model: rename power_ctrl_{set->send}_c0_power_red
Change-Id: I13d9e6ea2a2b7b11f92532d377e71f0e83974622
Related: SYS#6435
2023-04-28 02:19:44 +07:00
Vadim Yanitskiy 856c6dc2f5 bts_is_online(): make the BTS pointer const, return bool
Change-Id: Idb4f9f8862041c5902df0e6e8d1ac2a60ada95df
2023-04-28 02:19:44 +07:00
Oliver Smith 758634eadf debian: set compat level to 10
Related: OS#5958
Change-Id: Id0f168a7d3c2ae6869121397e65ca1d0cfea30d3
2023-04-27 12:28:23 +00:00
Matan Perelman 1619a82825 ctrl: Remove dots from OOM
Change-Id: Ic2c6a052a9f9dcdca225225b38eb0ebdd05ac959
2023-04-25 15:52:09 +03:00
Matan Perelman 41e464e272 ctrl: Add cell reselection offset control
Change-Id: I159bbe14e71dbf1e1add60b57b0b2e03d3146682
2023-04-25 14:58:18 +03:00
Oliver Smith 712343c321 CSD: support non-transparent data rates
Implement gsm0808_data_rate_non_transp_to_gsm0408.

Related: OS#4393
Change-Id: Ib5f4bdf17a9833f65a0b623a033da838a2594d68
2023-04-20 11:02:31 +02:00
Oliver Smith d128791919 abis_rsl: fix encoding RSL_IE_IPAC_RTP_CSD_FORMAT
The A-bis/IP RTP CSD Format IR Values need to be shifted by 4 bits
instead of 5. See OsmoBTS Abis Protocol Specification § 5.8.14
RSL_IE_IPAC_RTP_CSD_FORMAT.

Related: https://ftp.osmocom.org/docs/osmo-bts/master/osmobts-abis.pdf
Related: OS#4393
Change-Id: I9ce0b2d9b77eef61a6d4dce417efe4e853217dc5
2023-04-19 11:16:02 +02:00
Neels Hofmeyr a4cc4ef8ea fix comment typo
Change-Id: I5c38f47cdf21d4e787341bf68e1e63c713003bbd
2023-04-15 00:07:05 +02:00
Neels Hofmeyr 2dfffad7e3 log: N-PCSTATE: use new value_strings
Related: SYS#6319
Depends: I873ea30e8f64280487769668c748c67ce4ff4023 (libosmo-sccp)
Change-Id: I7a13fcf2bfee232c6cebc3c1180b956a73abc24e
2023-04-14 14:33:07 +00:00
Neels Hofmeyr 8f8af40974 SCCP N-PCSTATE: trigger MSC status on PC availability
Related: SYS#6319
Related: Ia1aea4e33230d6a685b72ea5ba20dd9c7d265d44 osmo-ttcn3-hacks
Related: Ib4a5330df30a73e744c316898817b2fa3271d75e osmo-ttcn3-hacks
Change-Id: I3a0869598b8395601a16d78dbc46eec400c0ea84
2023-04-14 14:32:44 +00:00
Vadim Yanitskiy ba6fd4f8e4 si2quater: check return value of osmo_earfcn_del()
Change-Id: I227dad57737721c40a508f67616d9f5003bb1a3e
Fixes: CID#313584
2023-04-07 18:24:35 +07:00
Vadim Yanitskiy f2f0ab209d si2quater: add CTRL commands for deleting neighbor [EU]ARFCNs
EUTRAN neighbors can be deleted using the following command:

  $ osmo_ctrl.py \
	-d 127.0.0.1 -p 4249 \
	-s "bts.0.si2quater-neighbor-list.del.earfcn" EARFCN

UTRAN neighbors can be deleted using the following command:

  $ osmo_ctrl.py \
	-d 127.0.0.1 -p 4249 \
	-s "bts.0.si2quater-neighbor-list.del.uarfcn" UARFCN,SCRAMBLE

This commit implements only deletion, implementing the add command
would require slightly more effort (lots of manual string parsing),
so it's left as a TODO for later.

Change-Id: I890bffb003f2a0ee9438f6ea6e8067c092504f08
Related: SYS#6401
2023-04-06 22:34:46 +07:00
Pau Espin 58db3305d7 ipaccess nm: Handle TS_EV_OML_DOWN through NM FSM
This way we have much more control on where the events are expected to
happen.

Related: OS#5973
Change-Id: I314b8bbd8721b0420aa4a2a4da9e911834853324
2023-04-05 19:06:32 +00:00
Pau Espin 90b83f9195 ipaccess nm: Delay marking TS as usable until OML reports Enabled state
The BTS can immediatelly ACK the OPSTART, but that doesn't mean the TS
is already usable. It should only be used when the BTS reports it is in
Enabled state.

Related: OS#5973
Change-Id: I712aa22252d29ceea152c25a5da75542e1691faf
2023-04-05 19:06:32 +00:00
Vadim Yanitskiy 143dc67c99 si2quater: bts_earfcn_add(): do not add duplicate EARFCNs
We don't want to have duplicate EARFCNs in the config file.
The desired behavior is modifying existing EARFCNs.

Change-Id: Ia2fd8bd86d9f093967c1b0b0135151d2d5386dc1
Related: SYS#6401
2023-04-05 19:05:56 +00:00
Vadim Yanitskiy 117c699107 si2quater: bts_uarfcn_add(): modify existsing UARFCNs
Do not print an error, modify the existsing UARFCNs instead.

Change-Id: Iadc884aa8968e2dc01adf26ba68ba9597fa05d94
Related: SYS#6401
2023-04-05 19:05:56 +00:00
Vadim Yanitskiy a60d74ba9c si2quater: bts_uarfcn_add(): check if already added first
This way we print the proper message if the given UARFCN is already
added, no matter if the UTRAN neighbour list is full or not.

Change-Id: Ife83023f6a9e28d77e44e4757457d4d1c879e78f
Related: SYS#6401
2023-04-05 19:05:56 +00:00
Vadim Yanitskiy b8e115c646 cosmetic: bts_vty: switch is not a function, add a space
Change-Id: I3e21d8f31c8ca7359e4ed4e1c978984b7b776a82
Related: SYS#6401
2023-04-05 19:04:05 +00:00
Vadim Yanitskiy b96af7d7ec cosmetic: bts_uarfcn_add(): pass diversity directly to encode_fdd()
Change-Id: I274e5b7cf43b710a58b3c370334c5639c9f5e249
Related: SYS#6401
2023-04-05 19:04:05 +00:00
Oliver Smith 377c1e3fd7 bsc_mgw_setup: use mgcp_client_pool_empty()
Don't fall back to the legacy config if the pool is configured but no
connection to any pool member can be established.

Depends: osmo-mgw I009483ac9dfd6627e414f14d43b89f40ea4644db
Related: OS#5993
Change-Id: I3a8418fb5841c71049ec91439143e1fe5553ed40
2023-04-04 16:32:27 +02:00
Vadim Yanitskiy eb1de89024 gprs: fix has_valid_nsvc(): permit local udp port 0
NSVC local port 0 is actually a valid value, which tells the PCU to
pick a random port for bind()ing.  It was supported before 315af2f9e,
but now osmo-bsc would simply ignore NSVCs with 'local udp port 0'
and leave the respective MOs unconfigured in the BTS.

Change-Id: I0afd83e77f3daeeb082e7db911610428b5bc587c
Fixes: 315af2f9e "bts: ipa/osmo-bts/sysmobts: MO: add support for the second NSVC"
Related: OS#5979
2023-03-31 15:46:29 +00:00
Vadim Yanitskiy a9b4849e49 tests: add more tests for GPRS NSVC parameters
Change-Id: I13d6ac887ddb1c9bc5d1e4122f20405a28f135d4
Related: OS#5979
2023-03-31 15:46:29 +00:00
Vadim Yanitskiy ed5080adb3 tests: rename and extend gprs_{bvci_default->params}.vty
Match default values for all GPRS related params, not only the BVCI.

Change-Id: Ia02e9a97137eb7724f22526fc3768331b35ac55d
Related: OS#5979
2023-03-31 15:46:29 +00:00
Vadim Yanitskiy c8994ea6f7 doc/{examples,manuals}: remove dummy 'gprs nsvc 1'
Change-Id: I976471ad15dbb7be832dc1a87ca794009ee1aa7c
Related: OS#5979
2023-03-31 14:02:15 +00:00
arehbein fffd1b599c PCU interface: Log version when starting listener
Change-Id: Ie3d8ebcb3175412313dfae3b7d560202a98ff8ab
2023-03-31 13:46:23 +00:00
Vadim Yanitskiy 6d369665dd tests: demonstrate the problems of 'si2quater neighbor-list'
* osmo-bsc currently does not support adding multile EARFCNs
  with different thresh/prio/qrxlv parameter values;
* adding an EARFCN which already exists creates a duplicate;
* adding an UARFCN which already exists fails;
* adding UARFCN=0 fails.

Change-Id: Iece6b9058f4eb06f8f2c19311de4f2eea01cfe82
Related: SYS#6401
2023-03-31 10:48:50 +00:00
Vadim Yanitskiy bd6f8887e6 tests: add VTY transcript tests for 'si2quater neighbor-list'
Change-Id: I1209cca6a4ba0b9658a98f1782a9575c01263832
Related: SYS#6401
2023-03-31 10:48:50 +00:00
Vadim Yanitskiy ed8098ab2e osmoappdesc.py: add more config files for testing
Change-Id: I9199f3e39c677dfd6e3936b9cf4897a070156b03
2023-03-31 10:46:04 +00:00
Vadim Yanitskiy f80361d167 tests: $(BUILT_SOURCES) is not defined, depend on osmo-bsc
Change-Id: I640dd2cd599707ad6bc661e7bea08372d85b47df
2023-03-31 10:46:04 +00:00
Pau Espin 27195c50a0 bts-rbs2k: Simplify osmo_fsm_inst_alloc_child_id()
Change-Id: I5344161e5a65ae9959684f0fda7f8b06cbb447f3
2023-03-31 12:13:43 +02:00
Pau Espin d38ccedad7 Move paging queue specific handling to signal callback outside RSL code
The signal is already there but not being used.
Let's further split generic paging code from RSL specificites.

Change-Id: Iabc1c29908a5136501d6dc6e60f8777dab511b86
2023-03-31 12:12:21 +02:00
Pau Espin 4de0769720 abis_rsl: Document spec ref of CCCH Load Ind
Change-Id: Iada13bb29688249eecbd492388a6d4b0cc95575d
2023-03-30 15:51:02 +02:00
arehbein 097925b626 main: Give specific error message
vty_read_config() returns an errno number or zero; add the appropriate error string in case of error

Change-Id: I0015824a29ebf8aaeaa996ab4d2cb2769ea48864
2023-03-25 08:04:25 +00:00
Pau Espin ad253850d8 Use new GSM0408 defines for half-octet tags
The old ones have been deprecated and shall not be used anymore·

Depends: libosmocore.git Change-Id I799e35dc8d4d153fa63bf50563a5482cdf4de2d7
Change-Id: Id3be8e38ec87ae39c4e1b4fab163563b24fb2cee
2023-03-25 01:12:25 +00:00
Philipp Maier 2365db4856 doc: bts-examples: discuss Ericsson RBS EGPRS configuration
Add a configuration file example to illustrate how exactly EGPRS is
configured on ericsson RBS BTSs.

Related: OS#5198
Change-Id: I2fb5b4d9300b16b0fac48f33b5db81442ab25031
2023-03-24 14:20:42 +01:00
Philipp Maier f99952c2b0 examples: update erissson GPRS config files
The example config files that illustrate how to set up GPRS/EGPRS using
a BSC co-located PCU do not have any of the general GPRS parameters set.
Lets add a gprs prameter block to both of them.

Related: OS#5198
Change-Id: Ifc538940fadca08d03a36bf6a28392f22640493d
2023-03-24 14:20:42 +01:00
Philipp Maier ccd69e9b2f doc: running: Describe how to configure a co-located PCU
The manual does not yet mention the possibility to configure a BSC
co-located PCU. Lets add a short description to the chapter
Running OsmoBSC, Configure primary Links that enables users to get an
idea where exactly the BSC co-located PCU has its place in the RAN
infrastructure and which links it is connected with. Also give a short
example how to setup the unix domain socket path.

A more detailed description, especially about the timeslot configuration
will be added with a follow up patch for bts.adoc

Related: OS#5198
Change-Id: I3af3cd8ef7099bb94f4cb25513e9dfdc5fcc1b5a
2023-03-24 14:20:42 +01:00
Philipp Maier 4743ea578c bts: bts: Explain Ericsson's interface switch (IS)
The built in interface switch in ericsson RBS base stations no where
explained. From the example configuration files alone it is not possible
to understand how the IS configuration works. Let's add a chapter that
explains how the IS configuration works.

Related: OS#5198
Change-Id: Ib6ebd7fdfe9063c0d8cacf53ffd27f6099d9038a
2023-03-24 14:20:42 +01:00
Neels Hofmeyr 25bbe8895c add location_services_fsm_bsc.dot
Change-Id: I3bdcc90c59459473a5f2e06d9018a2a98147a6b9
2023-03-22 09:58:47 +00:00
Neels Hofmeyr 7a0bef1ae4 segfault: verify lchan presence on Assignment Complete
User reports a SEGV:

 Program terminated with signal SIGSEGV, Segmentation fault.
 #0  send_assignment_complete (conn=conn@entry=0x557dbabb75a0) at assignment_fsm.c:188
 #1  0x0000557db66aa6b0 in assignment_success (conn=0x557dbabb75a0) at assignment_fsm.c:277
 #2  0x00007f6007afee82 in _osmo_fsm_inst_dispatch (fi=0x557db9615b80, event=4, data=0x0, file=0x7f6007a7dc21 "mgcp_client_endpoint_fsm.c", line=513) at fsm.c:875
 #3  0x00007f6007a78c12 in ?? () from /lib/x86_64-linux-gnu/libosmo-mgcp-client.so.9

 version: osmo-bsc 1.9.0.111.fc339.202212220009

The situation apparently is conn->lchan == NULL (primary lchan is gone),
but Assignment has just concluded. Apparently an unexpected / orthogonal
event has interrupted operations.

During assignment_success(), do not assume that conn->lchan is still
present. This should normally be true, but if not, fail the assignment
procedure instead of crashing osmo-bsc.

Related: SYS#6382
Change-Id: I4db25d0458f620954a1ca345282f5d8316341919
2023-03-22 09:22:58 +00:00
arehbein d7b277ff01 gsm_bts_check_ny1: Prevent possible division by zero
Do this by setting the minimal value for T3105 to 1 in its timer definition.

Fixes: Coverity scan CID#307389
Change-Id: I1fd0b92ab507a58fed6e9649eaa4770f1ad1cbad
2023-03-21 20:16:15 +00:00
Philipp Maier 64c0e6e11c doc: overview: replace section TRAU mapper / E1 sub-channel muxer
The manual contains a section about a TRAU mapper / E1 sub-channel
muxer. This section seems to be copied from the OsmoNITB manual. In
OsmoNITB everything was integrated in one binary, now dealing with TRAU
frames is the task of the MGW. Let's remove the section but still leave
a word about how Speech traffic is handled/relayed by OsmoBSC.

Change-Id: If33589feb80e1b29b4f841b678fe5329b8c06a76
2023-03-21 15:09:38 +01:00
Philipp Maier 563652890c doc: add sample configuration for GPRS with ericsson RBS
This patch contains a sample configuration for the 64K and the 16K CCU
mode.

Change-Id: I923608d4edc28b02e882c5f04851a29fc11bad4e
Related: OS#5198
2023-03-20 10:44:22 +01:00
Philipp Maier a288c9f420 pcuif_proto: increment version number
The co-located PCU support for Ericsson RBS E1 CCU made it necessary to
add new features to the PCU socket interface, so let's increase the
version number.

Change-Id: I8315bd67c7f3eb0d7ee71b64cd4dff889a84fcf1
Depends: osmo-pcu.git I2a78651593323e8b9627c39918d949a33497b70f
Related: OS#5198
2023-03-20 10:44:22 +01:00
Philipp Maier 0625172265 pcu_sock: handle multiple BTSs with one BSC co-located PCU (in theory)
The current PCU implementation has never been tested with multiple BTS
attached to it. This is due to the fact that it has been used
exclusively in an BTS co-located setup where naturally only one BTS is
present. The PCU sock protocol supports multiple BTSs in theory and we
should handle this correctly.

Related: OS#5198
Change-Id: I0b42c2c130106f6ffca2dd08d079e1a7bda41f0b
2023-03-20 10:44:22 +01:00
Philipp Maier 10ae64a777 pcu_sock.c: Call osmo_fd_unregister() before closing and changing listen_bfd->fd
Change-Id: I48e0411c4cba9897bc04865d22d8f68ed4fe87a2
2023-03-20 10:44:22 +01:00
Philipp Maier 2af29ae92d pcu_sock: drop usage of PCUIF flag PCU_IF_FLAG_DT
The flag PCU_IF_FLAG_DT is no longer needed. The PCU implementation will
distinguish by the version number instead.

Change-Id: I0dc20e351deb14906b2edffc39499bad9659cc35
Related: OS#5198
2023-03-20 10:44:22 +01:00
Philipp Maier ec7842f816 pcu_sock: check BTS type properly in pcu_info_update()
When updating the BTS information in the bsc co-located PCU, first check
if the BTS has a BSC co-located PCU at all. Also check if the BTS is E1
based since those type of BTS require extra information about the E1
connection.

Related: OS#5198
Change-Id: I8da26debc0e27f24fae4ee88f22f8875de13bc84
2023-03-20 09:42:05 +00:00
Philipp Maier c4ab940544 pcu_sock: use is_ericsson_bts() to check for ericsson BTS
Do not access bts->type directly, we have is_ericsson_bts() to do that

Related: OS#5198
Change-Id: I274a9f0f1208dc17713ba2e1c7a1110eeb133cca
2023-03-20 09:41:00 +00:00
Philipp Maier 4af073c109 bts: add function to check if a BTS has a BSC co located PCU
At the momemnt we use is_ericsson_bts() to check if the BTS uses a BSC
co-located PCU, this is a bit ambiguous, lets have a function that
explicitly checks for a BSC co-located PCU and nothing else.

Change-Id: I23ed4219e5ebd188867c17f387ca877efa9bc3b0
Related: OS#5198
2023-03-20 10:30:47 +01:00
Philipp Maier a10a34cf6a bts: is_xyz_bts check functions should return bool
The check functions that we use to distinguish between the various types
of BTSs return an integer that can be 0 or 1. Let's change the return
type to bool

Change-Id: I3de957f228452c9d3aa4fed342f73bfb17363b40
2023-03-20 09:29:31 +00:00
Neels Hofmeyr f2768d39c1 fix coverity (false) warning in codec-list vty
Since there were complaints about this old parsing code during recent
code review in Ifdc9e04bf1d623da65bfb8a2fddea765601f6d9b, and now also
coverity finds something odd in it, just rewrite this.

Related: CID#310912
Change-Id: I96cd5d88ec6808a2915c6bccd0c0140216f328f2
2023-03-18 02:08:03 +00:00
Neels Hofmeyr 2fda8dba70 vty: codec-list: fix error message
Change-Id: I89460229f894bfa67c6939dc3825f1865378d918
2023-03-18 02:08:03 +00:00
Pau Espin 9f7611a32f Fix Lb/A SCCP conn lookup after recent regression in optimization patch
In osmo-bsc, there's currently 0..1 Lb links and 0..N A links, where N
is the number of MSC, but links can be shared in the underlaying stack
(struct osmo_sccp_instance), hence range 0..N of different
osmo_sccp_instance (identified by PC).
Even more, the Lb and A link can share the same underlaying stack, so
osmo-bsc can end up with only 1 struct osmo_sccp_instance shared by all
the above mentioned links in case all are configured under the same PC.
Total range A+Lb is 0..(1+N).

A struct gsm_subscriber_conn stores 2 struct sccp_instance*, one for
Lb (conn->lcs.lb.*)and one for A (conn->sccp.*).
They can actually point to the same sccp_instance or to different ones,
as explained above, depending on the configured setup. In any case, a
gsm_subscriber_conn needs 2 rb_nodes since it can hold
any of the 2 conn_ids independently (A or Lb).

The previous patch forgot to add that 2nd rb_node as well as some
initialization and release code for the Lb conn. This patch addresses
that.

When the 2nd rb_node, a problem when iterating the rbtree appears: how to
find out the "conn" pointer from the rb_node pointer, since the rb_node pointer
can be any of the 2 rb_nodes inside the struct at a different offsets.

In order to solve that problem, a new struct bscp_sccp_conn_node is
added, which holds all the relevant information used by the rbtree lookup code
in a generic way (rb_node and conn_id), plus a backpointer to the struct
bsc_gsm_subcriber it relates too.

Fixes: 85062ccad3
Change-Id: If42d93adee71d646766929a09bc01ae92b734ef3
2023-03-17 18:08:26 +00:00
Vadim Yanitskiy cbf3e5d850 fix ipacc_rtp_csd_fmt_non_transp(): add missing breaks
Change-Id: I13adcabd26c5f6543681e418b87c70b2822e7dcf
Fixes: CID#310964, CID#310965, CID#310967
2023-03-17 16:42:34 +07:00
Vadim Yanitskiy f18397aac9 fix bs11_read_swl_file(): properly clean up stale file list
Calling talloc_free() on struct llist_head is wrong and will lead
to unexpected behavior.  Call it on the containing struct instead.

Change-Id: Ib5eaa328aaf6881ae9621ca14859e4e255af2b00
2023-03-16 06:17:08 +07:00
Pau Espin a4fd6d9371 bsc_subscriber: Optimize lookup of bsub by TMSI
It was found that on a busy osmo-bsc process (>1000 concurrent calls
spead over different BTSs), a good amount of time is spent iterating the
subscribers list trying to find a subscriber based on a TMSI (1.60% of
total CPU time used by osmo-bsc).

This patch introduces a new rbtree under struct bsc_subscr_store which
allows storing all the busbs ordered by TMSI.
This way, lookup time changes O(N) -> O(log(N)), at the expense of
increased insert/deletion time O(1) -> O(log(N)).

Related: SYS#6200
Change-Id: If27429e715ef4b327177e427249e68321a6e83cc
2023-03-15 10:45:13 +01:00
Pau Espin 08a7db6cd3 bsc_subscriber: Introduce bsc_subscriber_store object
This allows keeping the bsc_subscriber storage internals outside of main
gsm_network code, while easily allowing making the internal
implementation more complex (in order to optimize it in a follow-up
commit).
It is also nice since we get rid of uncommon procedures being used in
this code, like allocating an llist directly as a talloc context, etc.

Change-Id: I616e8872af4ac63a6985f8900909e324ba889192
2023-03-15 09:44:22 +00:00
Pau Espin 0c87d39faf bsc_subscriber: Mark functions used only internally as static
Change-Id: I846af993905aee0be75aa3021460b130362c6d3d
2023-03-15 09:44:22 +00:00
Pau Espin b4bbba72ad bsc_subscriber: Drop unused function bsc_subscr_find_by_mi()
Change-Id: I15a51fa8a5c30fd92b34ebb366d0a805f8902cd0
2023-03-15 09:44:22 +00:00
Pau Espin 1da0fcbbbc Move bsc_conn_by_bsub() and make it static
The function was currently in osmo_bsc_sigtran.c but was never used
there, and it really doesn't have any relation to that file.
Let's move it to the only place where it's used so far, and mark it as
static.

Change-Id: I8a8cef45aa378421e0ac328d3b29b9d194698a55
2023-03-15 09:44:22 +00:00
Pau Espin 85062ccad3 Optimize subscr_conns lookup
It was found that, on a busy osmo-bsc (>1000 concurrent calls spread over
several BTS), the CPU consumption looking up for gsm_subscriber_conn
based on SCCP conn_id can take a considerable amount of time (>5% of
osmo-bsc already taking 70% of the CPU time on the core it is running on).

The huge CPU consumption happens because a linear search is done (llist)
over the entire list of SCCP connections every time an SCCP message is
handled.

In order to optimize this lookup, this patch introduces a new struct
bsc_sccp_inst which becomes associated to the libosmo-sccp
osmo_sccp_instance. Each of this strucs maintains an rbtree of
gsm_subscriber_conn ordered by conn_id.
As a result algorithmic complexity adds O(log(N)) during insert, lookup
and delete of SCCP conns, but gets rid of O(N) previous lookup.
As a plus, finding a new conn_id now takes generally O(log(N)), while
before it used to take O(N).

Related: SYS#6200
Change-Id: I667d3ec1dad0ab7bc0fa4799d9611f3a914d07e5
2023-03-15 09:44:22 +00:00
Pau Espin 9c21dc3d16 pcu_sock.c: Call osmo_fd_unregister() before closing and changing bfd->fd
Change-Id: I4f72f4fa80249ed2caafc87b9fdf9926e0f31976
2023-03-14 12:56:49 +00:00
Pau Espin 646d21f2db Assert conn_id being looked up is inside expected range
Change-Id: Iffe580ad5f974fdbef7061a14306b50bd4875eb1
2023-03-13 11:58:49 +01:00
Pau Espin 53cd4ad5fc bscc_sccp: Small optimiztion in bsc_sccp_inst_next_conn_id()
Refactor the double loop to check a code path matching the sccp_instance
once instead of doing so for every subscr_conn.

If for instance let's say we have 1000 concurrent calls in progress,
which means we have 1000 subscr_conn, which means we at least do the
extra check regarding SMLC vs MSC 1000 times (at least, xN times if N
conn_id already used are already found).
That overhead happens every time a new subscr_conn is created (which in
a BSC with already 1000 concurrent calls can potentially happen quite
frequently).

Change-Id: Ic32b1eeb201fc51110e1ee130110824845f81e82
2023-03-13 11:58:49 +01:00
Pau Espin 8958269ea9 get_bsc_conn_by_conn_id(): Properly match sccp_instance
Function bsc_sccp_inst_next_conn_id() allocating conn_id creates address
spaces based on sccp_instance, aka conn_id values can be reused given
the sccp_instance (MSC) is different.

Hence, when looking up a bsc_conn based on a conn_id, it must also match
the sccp_instance, otherwise a bsc_conn from another MSC could be
returned.

Change-Id: I80a54bdec3973917e88483a62bfc2e968b8c0490
2023-03-13 11:58:49 +01:00
Pau Espin 06d1cff11a bscc_sccp: Avoid allocating conn_id 0x00FFFFFF
The 0x00FFFFFF source local reference is reserved in M3UA/SCCP, hence
avoid allocating a conn_id with that value since later on when reused as
a source local reference it would fail to be encoded.

Change-Id: I5c62bbfa89140d754edccb4404503cb70d5fde89
2023-03-13 11:58:49 +01:00
Pau Espin c5b7d94e0f Clarify type and values of sccp.conn_id
Currently, the conn_id is allocated in a range 0..0xffffff by
bsc_sccp_inst_next_conn_id(), and -1 means it is unset.

This means allocation expects "int" to be at least 32 bits integer,
in order to fit 24 bits for 0..0xffffff plus the -1.
Hence, let's define the variable as uint32_t, as already done in
libosmo-sccp. Use last value 0xFFFFFFFF ((uint32_t)-1) and avoid playing
with the value being unsigned sometimes and signed only for "unset"
value.

The value is actually already handled as unsigned (printed with %u) in
most places.

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

Change-Id: I37f078bdc17e128298b956f493ff5c03ef476f98
2023-03-11 04:26:51 +07:00
Vadim Yanitskiy 2acc7b94d2 Makefile.am: remove unneeded AM_LDFLAGS with LIBS
Change-Id: I10150c00dbe69648b95ea4c414db0ad6c6bdd254
2023-03-11 03:56:01 +07:00
Pau Espin c90c63bec0 constify bsc_conn_by_bsub() ptr param
Change-Id: I44b1397e7771c803efdca6bf59750ca5568df365
2023-03-10 15:25:11 +01:00
Vadim Yanitskiy 30ecd0a767 ipaccess_drop_oml(): invalidate the feature vector
It's possible that a BTS gets disconnected, updated to a more recent
version or downgraded to an older version, and then connects to the
BSC again.  That more recent or older BTS version may have a different
set of supported features, so osmo-bsc must not trust the previously
reported feature vector.

Change-Id: Ie93af849d7771b4fff3cdf647c82510cd8543975
2023-03-10 13:43:43 +00:00
Pau Espin 39d214fab5 cosmetic: gsm_data.h: Fix typo in comment
Change-Id: Id59eb176551b2546ee6ff9c7f0eee4d8dd6ed199
2023-03-10 13:41:51 +00:00
Philipp Maier fcb9890675 timeslot_fsm: fix PDCH activation
All non ericsson BTSs we support use a BTS co-located PCU, so we must
not depend on a PCU connection in those cases.

Related: OS#5943
Fixes: ecf825dc ("pcu_sock: activate/deactivate PDCH on pcu reconnect")
Change-Id: I296dfacb451d7b9b5ef1cec940bc1a577f3c43ad
2023-03-09 12:47:15 +01:00
Oliver Smith 2689ad73a8 abis_rsl: CSD: add RTP_CSD_FMT IE to CRCX/MDCX
Related: OS#4393
Change-Id: I4964b268124d29354e252c2ee509866ae75fab6d
2023-03-08 11:52:12 +00:00
Philipp Maier 6d3da5401f pcu_sock: cosmetic: remove whitespace after type cast
Change-Id: Iddc1bd703b4a200202ffa87d24a167e3fe39da18
2023-03-07 12:54:58 +00:00
Philipp Maier 280ad4d966 pcu_sock: rename rc to fd
The variable rc holds the return code of accept(), which returns a file
descriptor on success. So lets call the variable "fd" to make this
clear.

Change-Id: Ic8d22c2af18477f110a3a9115434314ebca95b25
2023-03-07 12:54:58 +00:00
Philipp Maier 7630b88fb5 pcu_sock: improve logging
In many places we have a pointer to the BTS object, so we can use
LOG_BTS.

Change-Id: I4a3ff23ffccf803b1a97e3f2604d3b422c6d6afd
Related: OS#5198
2023-03-07 12:54:58 +00:00
Philipp Maier 6902fccb1b pcu_sock: use struct to transfer IMMEDIATE ASSIGNMENT for PCH
When the IMMEDIATE ASSIGNMENT is sent from the PCU to the BSC using the
"direct TLLI" method, the TLLI (and the last three digits of the IMSI)
is prepended to the MAC block. Currently we are taking the fields apart
manually using offsets. The code for this is difficult to read and the
method is error prone. Let's define a struct that we can just overlay
to access the fields directly. Let's also transfer the full IMSI.

Change-Id: Id6acbd243adf26169e5e8319dd66bb68dd6a3c22
Related: OS#5198
2023-03-07 12:54:58 +00:00
Philipp Maier ecf825dc08 pcu_sock: activate/deactivate PDCH on pcu reconnect
When the PCU is disconnected while the BSC keeps running the PDCH should
be closed. Also the PDCH should be reopened when the PCU is
reconnected.

Change-Id: I9ea0c53a5e68a51c781ef43bae71f947cdb95678
Related: OS#5198
2023-03-07 12:54:58 +00:00
Oliver Smith a8f5dbce77 check_chan_mode_rate_against…: fix never true cond
Fixes: CID#310958
Fixes: 2150b307 ("assignment_fsm: chan mode check: support CSD")
Change-Id: Icb3d0f977267dca7b52fd05312ccb5237fcaa031
2023-03-07 09:50:01 +01:00
Philipp Maier f85f8dd4a1 pcu_sock: get rid of leaking message buffer
When a data request is received from the PCU, some of the switch cases
allocate a message buffer but the message buffer is only used to pass
its data and length to other functions. The message buffer itself is not
passed anywhere and it is also not freed. Lets get rid of the message
buffer and avoid unnecessary memcopy calls.

Related: OS#5198
Change-Id: Ibfaae177585a4d42d797b6bbd90e402641620140
2023-03-06 15:32:25 +00:00
Oliver Smith d83d22bad3 Cosmetic: channel_mode_from_lchan: remove fixme
Remove the FIXME comment, as the function handles CSD now.

Related: OS#4393
Change-Id: Ic074cb814662d73f52d4401d1cf9cdbf682040a9
2023-03-06 10:23:31 +01:00
Oliver Smith 722220f2dc chan_mode_to_mgcp_codec: support CSD
Related: OS#4393
Change-Id: Ib5876ee4dac9e8000cc3ae0c5dd87aae3d723829
2023-03-06 10:23:30 +01:00
Oliver Smith d5ca920cc3 rsl_tx_ipacc_crcx/mdcx: omit speech mode for CSD
Omit the A-bis/IP specific RSL_IE_IPAC_SPEECH_MODE, as it doesn't make
sense for circuit switched data.

Related: OS#4393
Change-Id: I6641b713177276bcf798f08123e1dd2e88ffdce6
2023-03-06 10:23:30 +01:00
Oliver Smith d5eb0f1b57 lchan_select: chan_mode_to_chan_type: support CSD
Related: OS#4393
Change-Id: I6b02d7edbf268a7f07134b54a7289529b2485122
2023-03-06 10:23:30 +01:00
Oliver Smith 41ede5345c requires_voice_stream -> ch_indctr
Use the full gsm0808_chan_indicator value throughout the lchan related
structs (assignment_fsm_data, gsm_lchan, lchan_activate_info,
lchan_modify_info) instead of reducing it to the boolean
requires_voice_stream.

This is needed so we don't lose the information whether an lchan was
requested for data or speech (both need an rtp stream).

Add a new bsc_chan_ind_requires_rtp_stream function and use it in
conditionals like the previous requires_voice_stream.

Related: OS#4393
Change-Id: I1538c1e6d5cd61559af7c1e2860afd0269dda367
2023-03-06 10:23:30 +01:00
Oliver Smith 2fd39821f6 tests/handover: wrap functions from gsm_08_08.c
Prepare to include gsm_08_08.h in more files in the following patch,
without wrapping these functions it won't build anymore. Remove the
unused stub for bsc_assign_compl() while at it.

Related: OS#4393
Change-Id: I6cb84f493204e393fd719148f54b8bbc173588a4
2023-03-06 10:23:30 +01:00
Oliver Smith 2150b307c2 assignment_fsm: chan mode check: support CSD
Replace check_requires_voice_stream, which used to iterate over
ch_mode_rate_list and verify that all entries are either for speech or
signalling. Instead verify in check_chan_mode_rate_against_ch_indctr,
that all entries of ch_mode_rate_list have a chan_mode that matches the
ch_indctr (data, speech, signalling; called "speech / data indicator" in
3GPP TS 48.008 § 3.2.2.11).

This ensures that all of them are either data, speech or signalling and
not mixed.

Related: OS#4393
Change-Id: Iee5cbfee84d7f2ad59ee2d5a19891a2b59bbafff
2023-03-06 10:23:30 +01:00
Oliver Smith 0361b01614 bssmap_handle_ass_req_tp_codec_list: tweak log msg
Remove "speech mode" from the log message, as the log message is
relevant for CSD too. According to 3GPP TS 48.008 § 3.2.1.1 note 13 the
IE shall be included for AoIP unless channel type is signalling.

Related: OS#4393
Change-Id: Idfab0b7f6e97a6b67d140f967ddfe9b29818586e
2023-03-06 10:23:30 +01:00
Oliver Smith b11bf4d651 abis_rsl: ipacc_payload_type: handle CSD
Depends: libsmo-abis Ibf0bfb577faa5c82e10706b42ede8b72dd611655
Change-Id: Ie561d87ecdc161b9a69eb7683889f0395524faa8
2023-03-06 10:23:30 +01:00
Oliver Smith e6e81e09b3 bssmap_handle_ass_req_ct_data: implement
Handle assignment requests for CSD. In this initial version, the code
for non-transparent data mode is a stub.

Related: OS#5763
Depends: libosmocore Ia965cdd9f53af756e5ffaff9b8f389b5ad629969
Change-Id: I350bea15fd2158eb6edc9bc92f2dca48930736e9
2023-03-06 10:23:26 +01:00
Neels Hofmeyr 25947b7aa4 cosmetic: timeslot_fsm.c: move some code to separate function
Cosmetically prepare for patch I9ea0c53a5e68a51c781ef43bae71f947cdb95678

Change-Id: I2c26d937496211e4b876987bac3803f6b2e6c8be
2023-03-06 08:44:02 +00:00
Oliver Smith 17df53ea1a channel_mode_from_lchan: add GSM48_CMODE_DATA_3k6
Related: OS#4393
Change-Id: Id9ec34f77c96d3a209c6f78d2addf1ea0dfa228d
2023-03-05 18:04:41 +00:00
Oliver Smith 5a16fcee93 lchan.h: remove enum lchan_csd_mode
It looks like the idea was to translate the CSD rate from BSSAP to
lchan_csd_mode before translating it to RSL. But instead we can just
directly translate the BSSAP value to the RSL value.

The previous code was not used yet (nothing wrote to csd_mode).

Related: OS#4393
Depends: libosmocore I25bfd02aa1428a35492b20376a31635a442e545f
Change-Id: Ice914744da3a2084e82d125848fb69404b8e8a36
2023-03-05 18:04:41 +00:00
Neels Hofmeyr 071446d1b0 doc: add codec_resolution.msc
Illustrate the various factors that influence picking a codec for a 2G
voice call in osmo-bsc.

Change-Id: I3d63a0d587a43fc18ea54b3982800b19b4d50a08
2023-03-04 22:44:10 +00:00
Neels Hofmeyr 220ef9a380 drop gsm_pchan_ids, use sanitized FSM ids instead
gsm_pchan_ids[] exists only to compose osmo_fsm compliant IDs. We do
have osmo_fsm_inst_update_id_f_sanitize() now, rather use that.

This removes some confusion about which value_string array has an effect
on the VTY command 'ts' / 'phys_chan_config'.

Note that tests/bsc_test.ok does not change, hence the new way of
composing FSM IDs is identical to using the old gsm_pchan_ids[].

Change-Id: Ib85b7aa4ea882ae37919dd3ea0c033e949c083e5
2023-03-04 22:44:10 +00:00
Neels Hofmeyr 896d694977 tweak gsm_pchan_ids[]: DYNAMIC/{OSMOCOM,IPACCESS}
This patch affects *only* on osmo_fsm instance IDs, which are visible on
the CTRL and VTY interfaces to identify FSM instances, and in the log.

Why bother: An upcoming patch wants to replace gsm_pchan_ids[] with
osmo_fsm_inst_update_id_f_sanitize(gsm_pchan_name(x)), this is an
explicit step to match gsm_pchan_names[].

Change-Id: I4a540744cced466f0ca4fc605db4d0ec14ee8e87
2023-03-04 22:44:10 +00:00
Neels Hofmeyr 879e7595f0 bsc_test.c: test FSM IDs that contain pchan names
Show the timeslot_fsm, lchan_fsm, assignment_fsm fi->id strings.

The IDs include the current pchan configuration. I want to tweak the
composition of these in an upcoming patch, so the test should show
whether any FSM IDs change from that.

Change-Id: If369f23fa140b9d7792f5a511815cbbd14b371e9
2023-03-04 22:44:10 +00:00
Neels Hofmeyr 76ea8562db stat: change pchan naming to dynamic/{osmocom,ipaccess}
Change names of stat exports to be consistent with VTY,CTRL:
- from "chan_osmo_dyn" to "chan_dynamic_osmocom"
- from "chan_tch_f_pdch" to "chan_dynamic_ipaccess"

Change-Id: I863ad05e892563442041722bcd57f7c987e1f5ab
2023-03-04 22:44:10 +00:00
Neels Hofmeyr 7214e56b49 VTY,CTRL: add pchan dynamic/{osmocom,ipaccess}
We already use "OSMO_DYN" as C name for "fully dynamic" timeslot config,
when working with osmo-bsc.cfg I dearly miss this short name, it is a
pain / has become ridiculous to write 'tch/f_tch/h_sdcch8_pdch'.

Introduce 'dynamic/osmocom' and 'dynamic/ipaccess' as default names for
our dynamic timeslots on VTY and CTRL. The old 'tch/f_tch/h_sdcch8_pdch'
and 'tch/f_pdch' are still supported.

Change-Id: I37719edd867c777d1ce944b8e2f1efffac38f00e
2023-03-04 22:44:10 +00:00
Neels Hofmeyr 71e838ed02 ensure correct phys_chan_config doc string count on VTY
Add a static assert, and comments indicating the importance of the two
value_string arrays defining pchans on the VTY matching up.

Change-Id: I8118bec35400f7f00ca9ae43b603059ed701fa25
2023-03-04 22:44:10 +00:00
Neels Hofmeyr 822b9dca1f vty: msc / codec-list: forbid invalid codec versions
Change-Id: I421c306aa22dfdad0f30c6ba8b482e1eff188a8e
2023-03-04 22:44:10 +00:00
Neels Hofmeyr 72fe0bf142 vty: msc / codec-list: forbid duplicate entries
Change-Id: Ifdc9e04bf1d623da65bfb8a2fddea765601f6d9b
2023-03-04 22:44:10 +00:00
Neels Hofmeyr 89dd152577 simplify storage of bsc_msc_data->audio_support
Make it a plain array, no dynamic allocation needed.

Change-Id: I625cedc4bb040d649fd6e1794ba468f4c6ad6adc
2023-03-04 22:44:10 +00:00
Oliver Smith 5ea91cdae4 test_codec_support_bts_rate: add missing breaks
Fixes: 3db22c61 ("cosmetic: clarify test_codec_support_bts()")
Fixes: CID#310823
Change-Id: I951783b6310f0a6ef5546a36c962def9d6e66285
2023-03-03 09:05:37 +01:00
Neels Hofmeyr 881b6b2e6d bsc_test: add 'update_exp'
Change-Id: I0e758e264f0bba76a78839931a72245d98936b8f
2023-03-02 17:56:48 +01:00
Neels Hofmeyr c729d82b17 assignment_fsm.c: make two functions static
Change-Id: I33eef9d105bacbb46538dff233502e834f7a3b51
2023-03-02 17:56:48 +01:00
Neels Hofmeyr b599836c7a implicitly register osmo_fsm definitions
I'm going to add a regression test that probes lchan_fsm. I noticed that
I have to call lchan_fsm_init() for osmo_fsm_register(). Let's make this
implicit as we usually do now, to not have to register FSMs in tests.

Change-Id: I58760e743c78a370aedc9720f265c0f8da5c2045
2023-03-02 17:56:48 +01:00
Neels Hofmeyr e073463ec4 add timeslot.vty
Prepare some basic tests for 'timeslot' / 'phys_chan_config', because an
upcoming patch will add the 'osmodyn' alias, and this test shall show
the changes on the VTY.

Change-Id: I2c4aab90bcbc9019ca004fb1d4945476edbb7363
2023-03-02 17:56:48 +01:00
Neels Hofmeyr 7bd795515f select_codecs(): constify ct arg
Change-Id: Icb07374b40629e48d811a036b9a56d026c1d897c
2023-03-02 17:56:48 +01:00
Neels Hofmeyr 89493f76b1 select_codecs(): doc tweak
Change-Id: I52a111b1992db1e335c692d2caee7c5398a6f90e
2023-03-02 17:56:48 +01:00
Neels Hofmeyr 3db22c6116 cosmetic: clarify test_codec_support_bts()
Change-Id: I13d9b158d08f4938c5aa47ef3134819a4b1f7d29
2023-03-02 17:56:48 +01:00
Neels Hofmeyr ce8d39d97c vty: msc / codec-list: tweak error msg
Change-Id: I7ba508cceccb8a25db0936f756f3e4a28ec1333f
2023-03-02 15:03:44 +00:00
Neels Hofmeyr ec6360e005 bsc_vty.c write_msc(): fix weird printf format
Change-Id: I856c2d620b89efcf3239186ef53c6941577dbccc
2023-03-02 15:03:44 +00:00
Neels Hofmeyr f30f630a88 bsc_vty.c: s/bsc/msc for commands under msc node
Change-Id: Id91a82ca8e2eb91b52836e024ccf925245886ae6
2023-03-02 15:03:44 +00:00
Neels Hofmeyr 8196ef5405 vty: improve doc for 'codec-list'
Change-Id: I33e6568997bcb1a9466e1e0c1b00718b703e2904
2023-03-02 15:03:44 +00:00
Neels Hofmeyr 8b55573a73 cosmetic: use i++ instead of ++i in for loop
Change-Id: I9903e54e3eb59db9b9cd22e017bc81b9b86e01e9
2023-03-02 15:03:44 +00:00
Neels Hofmeyr 91ab3fe5a0 cosmetic: use char literals in cfg_net_bsc_codec_list()
Change-Id: I1a29fb54cdcd15c6e9b6447d929db0e9492264f7
2023-03-02 15:03:44 +00:00
Neels Hofmeyr d4a0a2c36a add msc.vty to test 'msc' / 'codec-list' cfg
Show various weird things we allow in codec-list.

Change-Id: I04ce02dff7cadab826611bd6a0df5596a40578b5
2023-03-02 15:03:44 +00:00
Neels Hofmeyr 50558c17f9 pick up all *.vty in EXTRA_DIST
*.vty tests are picked up by the Makefile.am by means of a wildcard --
they are run when they are there. So when you forget to add it to
EXTRA_DIST, it will be run in your local build tree, but it will be
silently omitted from a distribution tar, and nothing will complain
about it gone missing.

Instead, also use a *.vty wildcard in EXTRA_DIST. So any *.vty test
added to the git source will both be run *and* included in distribution
tars implicitly.

Change-Id: I47c9011b5e0e2886d221e34e6aa281d1dd0495c7
2023-03-02 15:03:44 +00:00
Philipp Maier 52b74175dd abis_rsl: guard against over long IMMEDIATE ASSIGNMENT Messages
The length parameter in rsl_imm_assign_cmd_common() may cause a buffer
overflow when it is chosen larger than GSM_MACBLOCK_LEN. Lets make sure
this cannot happen.

Change-Id: I9417b35fb8c0517f2555e17059bf8ac60fa59791
2023-03-02 14:59:41 +01:00
Neels Hofmeyr 7747fecdbe examples: osmo-bsc-minimal.cfg: drop codec-list
A new VTY test is coming up that includes testing the default codec-list
setting. The VTY tests are using osmo-bsc-minimal.cfg, so let's not
overwrite the compile time default for codec-list.

Also, there is no need to define a codec-list, so it is actually minimal
to omit it.

Change-Id: I01bee711f21023e2eab0688f45ff68f81afe1831
2023-03-01 22:03:41 +00:00
Vadim Yanitskiy 4a61575917 utils: fix incorrect string checks in meas_db_insert()
Comparing an array to null is not useful, since the test will
always evaluate as true (NO_EFFECT).

Change-Id: I8a41078070119bc22d594c0dfff5d98b5d16f970
Fixes: fbead4327 utils: store more fields from meas-feed in db
Fixes: CID#310821
2023-03-01 21:53:24 +00:00
Philipp Maier 111b13f9a2 pcu_sock: print OML alerts from PCU
The PCU is able to send OML alerts via the BTS to the BSC. When the PCU
operates in co-location to the BSC we just print the alerts in the log
directly

Change-Id: Id32553556356c2affe32e47ae1c3ae6a514efdce
Related: OS#5198
2023-03-01 11:21:50 +01:00
Oliver Smith 4e54e16b9f codec_pref: split test_codec_support_bts_rate
Move the check for the rate into an extra function, so it can be used
for CSD without checking a speech codec at the same time.

Related: OS#4393
Change-Id: Iea8a23ef3c66ed556110038fe9f3bc7f6eef3e96
2023-03-01 08:11:15 +00:00
Oliver Smith f597a035fa bssmap_handle_ass_req_ct_speech: refactor
Move the translation from osmo_sockaddr_to_str_and_uint into
bssmap_handle_ass_req_tp_rtp_addr, which will be used by
bssmap_handle_ass_req_ct_data in a future patch too.

Pass pointers to variables in req, instead of duplicating variables and
filling it in later (like in bssmap_handle_ass_req_ct_sign).

Related: OS#4393
Change-Id: I6bb16b26d89056dffa50bd8296fefe9315c587ca
2023-03-01 08:11:15 +00:00
Oliver Smith 71c8bdfc56 bssmap_handle_ass_req_ct_speech: split up
Allow reusing common code in an upcoming bssmap_handle_ass_req_ct_data.
It won't use _osmux for now (maybe in the future?), but splitting it
out as well makes it consistent.

Related: OS#4393
Change-Id: I4d9a4df314b1e56b9c1f90c9d7914332b70b56f8
2023-03-01 08:11:15 +00:00
Oliver Smith 31f81d55fc bssmap_handle_assignm_req: split up
Prepare to implement GSM0808_CHAN_DATA without making this function even
longer.

Related: OS#4393
Change-Id: I8580e75e292cff1b52b6ba1bafd12c155c3bbe93
2023-03-01 08:11:15 +00:00
Michael Iedema fbead43271 utils: store more fields from meas-feed in db
More fields need to be captured from meas-feed
to perform meaningful analysis of data from
multi-bts and multi-trx systems.

This patch adds expands the existing db utils
to record nearly all available fields from
meas-feed.

Change-Id: I509c939524b11a4ee455bcfc3ebee6c5c35b9fba
2023-02-28 18:45:48 +00:00
Oliver Smith 146c228df2 Cosmetic: codec_pref: tweak comments
Remove "Helper function for match_codec_pref()" at the beginning of the
descriptions of these functions, looks like a leftover from before this
was moved to its own c file. Remove a duplicated "received" in a
comment.

Change-Id: I30f0744db9aebf2f05077fef840097c332b9dafd
2023-02-28 11:06:47 +00:00
Oliver Smith 0e552cc9c1 Cosmetic: fix various typos
Change-Id: I9225e733e3afa8171f24253e21eaffc654f689af
2023-02-28 11:06:47 +00:00
Philipp Maier 3632ffe65a timeslot_fsm: fix sourcecode indenting
Change-Id: I1cfd377cd8014e42aa45f9f0da664598ee88e02d
2023-02-28 10:01:50 +00:00
Oliver Smith 88133a746d osmo_bsc_main: don't allocate talloc_ctr_ctx
tall_ctr_ctx is not defined or used in osmo-bsc and apparently was only
exported by accident from libosmocore. It's not exported anymore since
libosmocore.map was introduced in I13169c00a59fb59513dfc598de5a71d094492422.

Fix for:
  /usr/bin/ld: osmo_bsc_main.o: in function `main':
  osmo_bsc_main.c:(.text+0x830d): undefined reference to `tall_ctr_ctx'
  /usr/bin/ld: osmo_bsc_main.c:(.text+0x8331): undefined reference to `tall_ctr_ctx'

Change-Id: I558e1ec722f3b1ff1f2e89b3cb97ed1dba9063e3
2023-02-28 09:36:00 +01:00
Harald Welte c4b523a8f3 Work around coverity false positives in macros
We have some macros that may at times have signed arguments, and at
other times unsigned.  Checking for <= 0 is not a bug in this case.
Let's typecast any unsigned arguments to signed int to work around.

Change-Id: I10e60b20c6f8092cf1ce09ebe501e739fd4a9479
Closes: CID#272993, CID#272992 (and many others)
2023-02-27 10:12:13 +00:00
Oliver Smith 4bcfb7e034 fsms: use configurable timers instead of T23042
T23042 was a placeholder for timers to be filled in later. Replace it
with timers that can be configured via VTY.

Previous timeout for the states was 5s, from using the default of 5 for
undefined timers.

* ASSIGNMENT_ST_WAIT_MGW_ENDPOINT_TO_MSC and
  HO_ST_WAIT_MGW_ENDPOINT_TO_MSC:
  * Runs gscon_connect_mgw_to_msc() on enter, which waits for one MGCP
    CRCX or MDCX response (or changes state immediately)
  * Use existing X9 ("Timeout for availability of MGW endpoint"), 5s,
    which is already being used by lchan_rtp_fsm for a similar purpose

* HO_ST_WAIT_RR_HO_DETECT:
  * Handover initiation as described in 3GPP TS 04.08 § 3.4.4.1:
    "The network initiates the handover procedure by sending a HANDOVER
     COMMAND message to the mobile station on the main DCCH. It then
     starts timer T3103."
  * Use existing but unused timer T3103 ("Handover"), 5s

* HO_ST_WAIT_RR_HO_COMPLETE:
  * Handover completion as described in 3GPP TS 04.08 § 3.4.4.3:
    "When receiving the HANDOVER COMPLETE message, the network stops
     timer T3103 and releases the old channels."
  * Continue using T3103 with keep_timer = true

Closes: OS#5787
Change-Id: Id0d4d0788f609f3272fc81c80a754383dde25c16
2023-02-16 14:49:39 +01:00
Oliver Smith cb3eb23ec2 ho: remove timeout for HO_ST_WAIT_LCHAN_ESTABLISHED
Remove placeholder timer T23042. This handover fsm state waits for both
RSL/RR and RTP/MGW to be complete. I've added TTCN-3 tests to ensure
that both cases are covered by existing timer T3101 in lchan fsm state
LCHAN_ST_WAIT_RLL_RTP_ESTABLISH, which on timeout lets the handover
fail.

Related: OS#5787
Related: osmo-ttcn3-hacks I30e1811f97406cff6ba794fcd6882e2bb0205087
Related: osmo-ttcn3-hacks I2f79e3ff988a4315fbef3538f02403b818fa7839
Change-Id: I53468766c3c5fad7d7e275c0f20b5c20677fe4e8
2023-02-16 14:49:39 +01:00
Oliver Smith 23e3e29b7a ho: remove timeout for HO_ST_WAIT_LCHAN_ACTIVE
Remove placeholder timer T23042.

Neels wrote:
> I think the right thing here is to remove this timeout; this needs
> no timeout at all because we can rely on the lchan_fsm to either
> return HO_EV_LCHAN_ACTIVE or HO_EV_LCHAN_ERROR after the usual
> timeouts set for lchan activation. IOW since it is internal to
> osmo-bsc one of the two events is guaranteed to occur.
>
> If we superimpose a timer on top of the lchan timeouts, configuring
> larger lchan activation timeouts becomes complex, because the user
> has to take care to also allow a larger timeout for the same
> procedure during HO.

Related: OS#5787
Change-Id: Ibf740aaa9bddc2de85cf8087ad90bab47aac12c2
2023-02-16 10:37:17 +00:00
Philipp Maier 329e1cdc22 bsc_subscriber_conn_fsm: use subslot 0 in case of E1 full subslot
In classic E1 based GSM networks the audio is usually transfered through
16bkps I.460 subslots while 4 16kbps subslots are multiplexed into one
E1 timeslot. However, there may be setups where still 16kbps subslots
are used, but with 1 instead of 4 channels per timeslot. In those cases
the bit offset is 0, while the rate is still 16kbps.

Change-Id: I0d2bc44acaa8e5a28cccfdf7cfb945bf14a4ed30
Related: OS#5198
2023-02-13 12:39:22 +01:00
Philipp Maier d4044214ca bts_trx_vty: use define constant E1_SUBSLOT_FULL instead magic number
Change-Id: I0be228d4473215c6bd36c668e0e10e64965732e7
2023-02-13 12:39:22 +01:00
Philipp Maier ec1a0a102f pcu_sock: set direct TLLI flag in info indication
osmo-bsc requires the PCU to tag IMMEDIATE ASSIGNMENTS that shall be
sent via PCU with a TLLI. This is required to confirm the sending of the
IMMEDIATE ASSIGNMENT messages to the PCU.

Related: OS#5198
Change-Id: Ib804143a57824632e5435f7ba68f2e94f5f3fb21
2023-02-13 12:39:22 +01:00
Philipp Maier ee43e37528 pcu_sock: transfer E1 connection information to PCU
The BSC has all information about the E1 line configuration of each
timeslot/channel. The PCU is responsible for opening and managing the
CCU connection. To enable the CCU to do that, we have to transfer the E1
connection information (which TS, SS, rate) to the PCU.

Change-Id: I6d44373336b41009ff4c6e459d32d0a81081676c
Related: OS#5198
2023-02-13 12:39:22 +01:00
Philipp Maier f18e9c36f4 pcu_sock: transfer sysinfo to PCU
The PCU needs to be aware of the current system information in order to
work properly.

Change-Id: Ibbfbfaf588a4e406804c36570010aefdfc14328b
Related: OS#5198
2023-02-13 12:39:22 +01:00
Philipp Maier 8a0572256b abis_rsl: constify parameters of rsl_X_imm_assign_cmd
Related: OS#5198
Change-Id: I1bd2e0c844bf273d2c4381eec9e9bb9562254873
2023-02-13 12:39:22 +01:00
Philipp Maier 107d311d96 pcu_sock: use extract_paging_group() for PCU_IF_SAPI_PCH
We have introduced the function extract_paging_group() with the previous
patch. Lets use it for PCU_IF_SAPI_PCH as well to remove code
duplication

Change-Id: If4ffe8eafd2e54e323cbc075c09d457a74ebe83f
Related: OS#5198
2023-02-13 12:39:22 +01:00
Philipp Maier 7a346a547e abis_rsl: add support for sending IMMEDIATE ASSIGNMENT through PCH
The IMMEDIATE ASSIGNMENT for downlink TBFs needs to be sent through the
PCH instead of the AGCH. Since this method is not specified in RSL, it
is usually a vendor specific extension.

Change-Id: I4452f4973d1ec69c96aad527b057226e8a6edf99
Related: OS#5198
2023-02-13 12:39:22 +01:00
Philipp Maier 84811c901e pcu_sock: cosmetic: remove space before tab
Change-Id: I6f3f96120d8a106f7c9e8b428d89ed14999a10a8
2023-02-11 14:06:44 +01:00
Philipp Maier 3c4320f935 pcuif_proto: rename PCU_IF_SAPI_AGCH_DT to PCU_IF_SAPI_PCH_DT
The current name of PCU_IF_SAPI_AGCH_DT is a bit misleading as it
describes a method to send immediate assignment messages (normally AGCH)
via the PCH. The name in the constant should reflect that correctly

Change-Id: I78abeb62d0267baa31a4727c4bdd027b7230f137
Related: OS#5198
2023-02-11 14:06:44 +01:00
Max 54b7cd5392 doc: correct reference and add deprecation notice
Change-Id: I46f1f070cb00c4c27247593527b0173e1fd5de67
2023-02-10 11:41:23 +00:00
179 changed files with 10199 additions and 2689 deletions

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

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

View File

@ -19,7 +19,7 @@ SUBDIRS = \
BUILT_SOURCES = $(top_srcdir)/.version
EXTRA_DIST = \
.version \
contrib/osmo-bsc.spec.in \
README.md \
debian \
git-version-gen \
osmoappdesc.py \

View File

@ -2,24 +2,25 @@ osmo-bsc - Osmocom BSC Implementation
=====================================
This repository contains a C-language implementation of a GSM Base Station
Controller (BSC). IT is part of the
Controller (BSC). It is part of the
[Osmocom](https://osmocom.org/) Open Source Mobile Communications
project.
OsmoBSC exposes
* A over IP towards an MSC (e.g. OsmoMSC): 3GPP AoIP or SCCPlite
* Abis interfaces towards various kinds of BTS (osmo-bts, sysmobts, nanoBTS, Siemens, Nokia, Ericsson)
* The Osmocom typical telnet VTY and CTRL interfaces.
* The Osmocom typical statsd exporter.
* Cell Broadcast Service Protocol (CBSP) towards a CBC (Cell Broadcast Centre, such as osmo-cbc).
* Lb interface towards a SMLC (Serving Mobile Location Centre, such as osmo-smlc).
* *A over IP* towards an MSC (e.g. [osmo-msc](https://osmocom.org/projects/osmomsc/wiki)): 3GPP AoIP or SCCPlite
* *Abis* interfaces towards various kinds of BTS (e.g. [osmo-bts](https://osmocom.org/projects/osmobts/wiki/Wiki), sysmobts, nanoBTS, Siemens, Nokia, Ericsson)
* The Osmocom typical telnet *VTY* and *CTRL* interfaces.
* The Osmocom typical *statsd* exporter.
* Cell Broadcast Service Protocol (*CBSP*) towards a CBC (Cell Broadcast Centre, such as [osmo-cbc](https://osmocom.org/projects/osmo-cbc/wiki)).
* Lb interface towards a *SMLC* (Serving Mobile Location Centre, such as [osmo-smlc](https://osmocom.org/projects/osmo-smlc/wiki/OsmoSMLC)).
Homepage
--------
You can find the OsmoBSC issue tracker and wiki online at
<https://osmocom.org/projects/osmobsc> and <https://osmocom.org/projects/osmobsc/wiki>.
You can find the OsmoBSC homepage with issue tracker and wiki online at
<https://osmocom.org/projects/osmobsc/wiki>.
GIT Repository
@ -49,6 +50,14 @@ Maunal](https://downloads.osmocom.org/docs/latest/osmobsc-cbsp.pdf)
describing the level of CBSP conformance.
Forum
-----
We welcome any osmo-bsc related discussions in the
[Cellular Network Infrastructure -> 2G/3G RAN (GERAN)](https://discourse.osmocom.org/c/cni/geran)
section of the osmocom discourse (web based Forum).
Mailing List
------------
@ -61,6 +70,15 @@ 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-bsc project on osmocom.org](https://osmocom.org/projects/osmobsc/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
------------
@ -90,6 +108,3 @@ worked as a standalone osmo-bsc binary as well as a combination of libbsc and
libmsc, i.e. the old OsmoNITB. Since the standalone OsmoMSC with a true A
interface (and IuCS for 3G support) is available, OsmoBSC exists only as a
separate standalone entity.
OsmoBSC-NAT is a specialized solution to navigating RTP streams through a NAT.
(Todo: describe in more detail)

View File

@ -7,3 +7,5 @@
# 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
libosmocore > 1.9.0 working (compiling) OSMO_SOCKADDR_STR_FMT_ARGS_NOT_NULL
libosmocore > 1.9.0 we use the new osmo_cbsp_segmentation_cb

View File

@ -36,38 +36,52 @@ if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
fi
PKG_PROG_PKG_CONFIG([0.20])
# Enable/disable ipaccess-utils (src/ipacces/)?
AC_ARG_ENABLE([ipaccess-utils], [AS_HELP_STRING([--enable-ipaccess-utils], [Build ipaccess utils: abisip-find, ipaccess-config, ...])],
# Enable/disable ipaccess-utils (src/ipacces/)
AC_ARG_ENABLE([ipaccess-utils], [AS_HELP_STRING([--enable-ipaccess-utils], [Build ipaccess utils: abisip-find, ipaccess-config, ... [default=yes]])],
[osmo_ac_ipa_utils="$enableval"],[osmo_ac_ipa_utils="yes"])
AM_CONDITIONAL(BUILD_IPA_UTILS, test "x$osmo_ac_ipa_utils" = "xyes")
AC_SUBST(osmo_ac_ipa_utils)
# Enable/disable osmo-meas-udp2db
AC_ARG_ENABLE([meas-udp2db], [AS_HELP_STRING([--enable-meas-udp2db], [Build osmo-meas-udp2db: listen to meas_feed on UDP and write it to an sqlite3 database [default=no]])],
[osmo_ac_meas_udp2db="$enableval"],[osmo_ac_meas_udp2db="no"])
AM_CONDITIONAL(BUILD_MEAS_UDP2DB, test "x$osmo_ac_meas_udp2db" = "xyes")
AC_SUBST(osmo_ac_meas_udp2db)
# Enable/disable osmo-meas-pcap2db
AC_ARG_ENABLE([meas-pcap2db], [AS_HELP_STRING([--enable-meas-pcap2db], [Build osmo-meas-pcap2db: read PCAP file with meas_feed data and write it to an sqlite3 database [default=no]])],
[osmo_ac_meas_pcap2db="$enableval"],[osmo_ac_meas_pcap2db="no"])
AM_CONDITIONAL(BUILD_MEAS_PCAP2DB, test "x$osmo_ac_meas_pcap2db" = "xyes")
AC_SUBST(osmo_ac_meas_pcap2db)
# Enable/disable meas_vis
AC_ARG_ENABLE([meas-vis], [AS_HELP_STRING([--enable-meas-vis], [Build meas_vis: curses-visualization of measurements [default=no]])],
[osmo_ac_meas_vis="$enableval"],[osmo_ac_meas_vis="no"])
AM_CONDITIONAL(BUILD_MEAS_VIS, test "x$osmo_ac_meas_vis" = "xyes")
AC_SUBST(osmo_ac_meas_vis)
dnl checks for libraries
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.8.0)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.8.0)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.8.0)
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.8.0)
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.4.0)
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.3.0)
PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.7.0)
PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.11.0)
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0)
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.5.0)
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.4.0)
PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.8.0)
PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.12.0)
dnl checks for header files
AC_HEADER_STDC
found_pcap=yes
AC_CHECK_HEADERS(pcap/pcap.h,,found_pcap=no)
AM_CONDITIONAL(HAVE_PCAP, test "$found_pcap" = yes)
found_cdk=yes
AC_CHECK_HEADERS(cdk/cdk.h,,found_cdk=no)
AM_CONDITIONAL(HAVE_LIBCDK, test "$found_cdk" = yes)
found_sqlite3=yes
PKG_CHECK_MODULES(SQLITE3, sqlite3, ,found_sqlite3=no)
AM_CONDITIONAL(HAVE_SQLITE3, test "$found_sqlite3" = yes)
AC_SUBST(found_sqlite3)
if test "$osmo_ac_meas_pcap2db" = "yes" || test "$osmo_ac_meas_udp2db" = "yes"; then
PKG_CHECK_MODULES(SQLITE3, sqlite3)
fi
if test "$osmo_ac_meas_pcap2db" = "yes"; then
AC_CHECK_HEADERS(pcap/pcap.h, [], AC_MSG_ERROR(Unable to find libpcap))
fi
if test "$osmo_ac_meas_vis" = "yes"; then
AC_CHECK_HEADERS(cdk/cdk.h, [], AC_MSG_ERROR(Unable to find libcdk))
fi
dnl Checks for typedefs, structures and compiler characteristics
@ -77,8 +91,7 @@ AC_ARG_ENABLE(sanitize,
[Compile with address sanitizer enabled],
)],
[sanitize=$enableval], [sanitize="no"])
if test x"$sanitize" = x"yes"
then
if test x"$sanitize" = x"yes"; then
CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
fi
@ -92,8 +105,7 @@ AC_ARG_ENABLE(werror,
]
)],
[werror=$enableval], [werror="no"])
if test x"$werror" = x"yes"
then
if test x"$werror" = x"yes"; then
WERROR_FLAGS="-Werror"
WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
@ -129,8 +141,7 @@ fi
AC_ARG_ENABLE(profile,
[AS_HELP_STRING([--enable-profile], [Compile with profiling support enabled], )],
[profile=$enableval], [profile="no"])
if test x"$profile" = x"yes"
then
if test x"$profile" = x"yes"; then
CFLAGS="$CFLAGS -pg"
CPPFLAGS="$CPPFLAGS -pg"
fi
@ -163,8 +174,7 @@ AC_ARG_ENABLE(manuals,
AM_CONDITIONAL([BUILD_MANUALS], [test x"$osmo_ac_build_manuals" = x"yes"])
AC_ARG_VAR(OSMO_GSM_MANUALS_DIR, [path to common osmo-gsm-manuals files, overriding pkg-config and "../osmo-gsm-manuals"
fallback])
if test x"$osmo_ac_build_manuals" = x"yes"
then
if test x"$osmo_ac_build_manuals" = x"yes"; then
# Find OSMO_GSM_MANUALS_DIR (env, pkg-conf, fallback)
if test -n "$OSMO_GSM_MANUALS_DIR"; then
echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from env)"
@ -241,5 +251,4 @@ AC_OUTPUT(
doc/manuals/Makefile
contrib/Makefile
contrib/systemd/Makefile
contrib/osmo-bsc.spec
Makefile)

View File

@ -4,8 +4,18 @@
# environment variables:
# * WITH_MANUALS: build manual PDFs if set to "1"
# * PUBLISH: upload manuals after building if set to "1" (ignored without WITH_MANUALS = "1")
# * IS_MASTER_BUILD: set to 1 when running from master-builds (not gerrit-verifications)
#
exit_tar_workspace() {
if [ "$IS_MASTER_BUILD" = "1" ]; then
tar -cJf "/tmp/workspace.tar.xz" "$base"
mv /tmp/workspace.tar.xz "$base"
fi
cat-testlogs.sh
}
if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !"
exit 2
@ -50,9 +60,15 @@ osmo-build-dep.sh libosmo-sccp
osmo-build-dep.sh osmo-mgw
# Additional configure options and depends
CONFIG=""
CONFIG="
--enable-external-tests
--enable-meas-pcap2db
--enable-meas-udp2db
--enable-meas-vis
--enable-werror
"
if [ "$WITH_MANUALS" = "1" ]; then
CONFIG="--enable-manuals"
CONFIG="$CONFIG --enable-manuals"
fi
set +x
@ -65,14 +81,14 @@ set -x
cd "$base"
autoreconf --install --force
./configure --enable-sanitize --enable-external-tests --enable-werror $CONFIG
./configure --enable-sanitize $CONFIG
$MAKE $PARALLEL_MAKE
LD_LIBRARY_PATH="$inst/lib" $MAKE check \
|| cat-testlogs.sh
|| exit_tar_workspace
LD_LIBRARY_PATH="$inst/lib" \
DISTCHECK_CONFIGURE_FLAGS="--enable-vty-tests --enable-external-tests --enable-werror $CONFIG" \
DISTCHECK_CONFIGURE_FLAGS="$CONFIG" \
$MAKE $PARALLEL_MAKE distcheck \
|| cat-testlogs.sh
|| exit_tar_workspace
if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
make -C "$base/doc/manuals" publish

View File

@ -1,150 +0,0 @@
#
# spec file for package osmo-bsc
#
# Copyright (c) 2017, Martin Hauke <mardnh@gmx.de>
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
## Disable LTO for now since it breaks compilation of the tests
## https://osmocom.org/issues/4113
%define _lto_cflags %{nil}
Name: osmo-bsc
Version: @VERSION@
Release: 0
Summary: OsmoBSC: Osmocom's Base Station Controller for 2G CS mobile networks
License: AGPL-3.0-or-later AND GPL-2.0-or-later
Group: Hardware/Mobile
URL: https://osmocom.org/projects/osmobsc
Source: %{name}-%{version}.tar.xz
BuildRequires: automake >= 1.9
BuildRequires: libtool >= 2
BuildRequires: pkgconfig >= 0.20
%if 0%{?suse_version}
BuildRequires: systemd-rpm-macros
%endif
BuildRequires: pkgconfig(libcrypto) >= 0.9.5
BuildRequires: pkgconfig(libosmo-mgcp-client) >= 1.11.0
BuildRequires: pkgconfig(libosmo-netif) >= 1.3.0
BuildRequires: pkgconfig(libosmo-sigtran) >= 1.7.0
BuildRequires: pkgconfig(libosmoabis) >= 1.4.0
BuildRequires: pkgconfig(libosmocore) >= 1.8.0
BuildRequires: pkgconfig(libosmoctrl) >= 1.8.0
BuildRequires: pkgconfig(libosmogb) >= 1.8.0
BuildRequires: pkgconfig(libosmogsm) >= 1.8.0
BuildRequires: pkgconfig(libosmovty) >= 1.8.0
BuildRequires: pkgconfig(talloc)
%{?systemd_requires}
%description
OsmoBSC: Osmocom's Base Station Controller for 2G circuit-switched mobile networks.
%package abisip-find
Summary: CLI utility to find ip.access compatible BTS
License: GPL-2.0-or-later
Group: Productivity/Telephony/Utilities
%description abisip-find
Command line utility to find ip.access compatible BTS.
%package ipaccess-utils
Summary: Command line utilities for ip.access nanoBTS
License: GPL-2.0-or-later
Group: Productivity/Telephony/Utilities
%description ipaccess-utils
This package contains utilities that are specific for nanoBTS when being
used together with OpenBSC. It contains mainly two tools: ipaccess-config
and ipaccess-proxy.
%package bs11-utils
Summary: Command line utilities for Siemens BS-11 BTS
License: GPL-2.0-or-later
Group: Productivity/Telephony/Utilities
%description bs11-utils
There is a tool in this package for configuring the Siemens BS-11 BTS.
Additionally, it contains one tool for making use of an ISDN-card and the
public telephone network as frequency standard for the E1 line.
%package meas-utils
Summary: Command line utilities for OsmoBSC's measurement reports
License: GPL-2.0-or-later
Group: Productivity/Telephony/Utilities
%description meas-utils
This package contains utilities for handling OsmoBSC's measurement reports
* meas_json to convert measurement feed into a JSON feed
%prep
%setup -q
%build
echo "%{version}" >.tarball-version
autoreconf -fi
%configure \
--docdir=%{_docdir}/%{name} \
--with-systemdsystemunitdir=%{_unitdir}
make %{?_smp_mflags}
%install
%make_install
%if 0%{?suse_version}
%preun
%service_del_preun %{name}.service
%postun
%service_del_postun %{name}.service
%pre
%service_add_pre %{name}.service
%post
%service_add_post %{name}.service
%endif
%check
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
%files
%license COPYING
%doc AUTHORS README.md
%{_bindir}/osmo-bsc
%dir %{_docdir}/%{name}/examples
%dir %{_docdir}/%{name}/examples/osmo-bsc
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc.cfg
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc-4trx-fh.confmerge
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc-4trx.cfg
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc-minimal.cfg
%dir %{_docdir}/%{name}/examples/osmo-bsc/ericsson
%dir %{_docdir}/%{name}/examples/osmo-bsc/nokia
%dir %{_docdir}/%{name}/examples/osmo-bsc/siemens
%{_docdir}/%{name}/examples/osmo-bsc/*/osmo-bsc*.cfg
%dir %{_sysconfdir}/osmocom
%config(noreplace) %{_sysconfdir}/osmocom/osmo-bsc.cfg
%{_unitdir}/%{name}.service
%files abisip-find
%{_bindir}/abisip-find
%files ipaccess-utils
%{_bindir}/ipaccess-config
%{_bindir}/ipaccess-proxy
%files bs11-utils
%{_bindir}/bs11_config
%{_bindir}/isdnsync
%files meas-utils
%{_bindir}/meas_json
%changelog

View File

@ -1,12 +1,17 @@
[Unit]
Description=Osmocom Base Station Controller (BSC)
Wants=osmo-mgw.service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
Restart=always
LimitNOFILE=65536
StateDirectory=osmocom
WorkingDirectory=%S/osmocom
User=osmocom
Group=osmocom
ExecStart=/usr/bin/osmo-bsc -c /etc/osmocom/osmo-bsc.cfg -s
RestartSec=2

265
debian/changelog vendored
View File

@ -1,3 +1,268 @@
osmo-bsc (1.11.0) unstable; urgency=medium
[ Max ]
* doc: correct reference and add deprecation notice
* pcu_connected(): constify parameter
[ Philipp Maier ]
* pcuif_proto: rename PCU_IF_SAPI_AGCH_DT to PCU_IF_SAPI_PCH_DT
* pcu_sock: cosmetic: remove space before tab
* abis_rsl: add support for sending IMMEDIATE ASSIGNMENT through PCH
* pcu_sock: use extract_paging_group() for PCU_IF_SAPI_PCH
* abis_rsl: constify parameters of rsl_X_imm_assign_cmd
* pcu_sock: transfer sysinfo to PCU
* pcu_sock: transfer E1 connection information to PCU
* pcu_sock: set direct TLLI flag in info indication
* bts_trx_vty: use define constant E1_SUBSLOT_FULL instead magic number
* bsc_subscriber_conn_fsm: use subslot 0 in case of E1 full subslot
* timeslot_fsm: fix sourcecode indenting
* pcu_sock: print OML alerts from PCU
* abis_rsl: guard against over long IMMEDIATE ASSIGNMENT Messages
* pcu_sock: get rid of leaking message buffer
* pcu_sock: activate/deactivate PDCH on pcu reconnect
* pcu_sock: use struct to transfer IMMEDIATE ASSIGNMENT for PCH
* pcu_sock: improve logging
* pcu_sock: rename rc to fd
* pcu_sock: cosmetic: remove whitespace after type cast
* timeslot_fsm: fix PDCH activation
* bts: is_xyz_bts check functions should return bool
* bts: add function to check if a BTS has a BSC co located PCU
* pcu_sock: use is_ericsson_bts() to check for ericsson BTS
* pcu_sock: check BTS type properly in pcu_info_update()
* pcu_sock: drop usage of PCUIF flag PCU_IF_FLAG_DT
* pcu_sock.c: Call osmo_fd_unregister() before closing and changing listen_bfd->fd
* pcu_sock: handle multiple BTSs with one BSC co-located PCU (in theory)
* pcuif_proto: increment version number
* doc: add sample configuration for GPRS with ericsson RBS
* doc: overview: replace section TRAU mapper / E1 sub-channel muxer
* bts: bts: Explain Ericsson's interface switch (IS)
* doc: running: Describe how to configure a co-located PCU
* examples: update erissson GPRS config files
* doc: bts-examples: discuss Ericsson RBS EGPRS configuration
* pcu_sock: fix PCUIF interface (PCH)
* pcu_sock: use correct SAPI in message PCUIF PCU_IF_MSG_DATA_CNF_DT
* pcuif_proto: rename tlli to msg_id
* pcuif_proto: remove unnecessary members from gsm_pcu_if_data_cnf_dt
* pcuif_proto: get rid of _DT, _dt (Direct TLLI)
* pcuif_proto: check confirm flag in struct gsm_pcu_if_pch
* pcu_sock: use PCU_IF_SAPI_AGCH_2 instead PCU_IF_SAPI_AGCH
[ Oliver Smith ]
* ho: remove timeout for HO_ST_WAIT_LCHAN_ACTIVE
* ho: remove timeout for HO_ST_WAIT_LCHAN_ESTABLISHED
* fsms: use configurable timers instead of T23042
* osmo_bsc_main: don't allocate talloc_ctr_ctx
* Cosmetic: fix various typos
* Cosmetic: codec_pref: tweak comments
* bssmap_handle_assignm_req: split up
* bssmap_handle_ass_req_ct_speech: split up
* bssmap_handle_ass_req_ct_speech: refactor
* codec_pref: split test_codec_support_bts_rate
* test_codec_support_bts_rate: add missing breaks
* lchan.h: remove enum lchan_csd_mode
* channel_mode_from_lchan: add GSM48_CMODE_DATA_3k6
* bssmap_handle_ass_req_ct_data: implement
* abis_rsl: ipacc_payload_type: handle CSD
* bssmap_handle_ass_req_tp_codec_list: tweak log msg
* assignment_fsm: chan mode check: support CSD
* tests/handover: wrap functions from gsm_08_08.c
* requires_voice_stream -> ch_indctr
* lchan_select: chan_mode_to_chan_type: support CSD
* rsl_tx_ipacc_crcx/mdcx: omit speech mode for CSD
* chan_mode_to_mgcp_codec: support CSD
* Cosmetic: channel_mode_from_lchan: remove fixme
* check_chan_mode_rate_against…: fix never true cond
* abis_rsl: CSD: add RTP_CSD_FMT IE to CRCX/MDCX
* bsc_mgw_setup: use mgcp_client_pool_empty()
* abis_rsl: fix encoding RSL_IE_IPAC_RTP_CSD_FORMAT
* CSD: support non-transparent data rates
* debian: set compat level to 10
* contrib/jenkins: create workspace.tar.xz on error
* systemd: depend on networking-online.target
* Fix various typos
* Cosmetic: configure: move if … then to same line
* configure: ipa utils: add default=yes to arg help
* Cosmetic: debian/rules: remove boilerplate
* contrib/jenkins.sh: deduplicate configure flags
* configure: add --enable-meas-udp2db/pcap2db/vis
[ Harald Welte ]
* Work around coverity false positives in macros
* abis_nm: Only osmo-bts re-purposes the MANUF_ID for BTS feature flags
* cosmetic: Rename is_ipaccess_bts() to is_ipa_abisip_bts()
* cosmetic: Clarify language ip.access nanoBTS vs. all IPA Abis/IP
* test case fixup: Add missing (void) empty argument list specification
* Support (optional) indication of NCH position in SI1 rest octets
* nanobts: Request "supported features" attribute from BTS and BB_TRANSC
* prevent bogus NCH related error message if no NCH is configured
[ Michael Iedema ]
* utils: store more fields from meas-feed in db
[ Vadim Yanitskiy ]
* utils: fix incorrect string checks in meas_db_insert()
* ipaccess_drop_oml(): invalidate the feature vector
* Makefile.am: remove unneeded AM_LDFLAGS with LIBS
* tests: use -no-install libtool flag to avoid ./lt-* scripts
* fix bs11_read_swl_file(): properly clean up stale file list
* fix ipacc_rtp_csd_fmt_non_transp(): add missing breaks
* tests: $(BUILT_SOURCES) is not defined, depend on osmo-bsc
* osmoappdesc.py: add more config files for testing
* tests: add VTY transcript tests for 'si2quater neighbor-list'
* tests: demonstrate the problems of 'si2quater neighbor-list'
* doc/{examples,manuals}: remove dummy 'gprs nsvc 1'
* tests: rename and extend gprs_{bvci_default->params}.vty
* tests: add more tests for GPRS NSVC parameters
* gprs: fix has_valid_nsvc(): permit local udp port 0
* cosmetic: bts_uarfcn_add(): pass diversity directly to encode_fdd()
* cosmetic: bts_vty: switch is not a function, add a space
* si2quater: bts_uarfcn_add(): check if already added first
* si2quater: bts_uarfcn_add(): modify existsing UARFCNs
* si2quater: bts_earfcn_add(): do not add duplicate EARFCNs
* si2quater: add CTRL commands for deleting neighbor [EU]ARFCNs
* si2quater: check return value of osmo_earfcn_del()
* bts_is_online(): make the BTS pointer const, return bool
* struct gsm_bts_model: rename power_ctrl_{set->send}_c0_power_red
* bootstrap_rsl(): cosmetic: cache trx->bts and use it directly
* bts: st_op_enabled_on_enter(): resume C0 power reduction
* gsm_bts_send_c0_power_red(): check if BTS is online first
* copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH
* fixup: contrib/jenkins: create workspace.tar.xz on error
* tests/{ctrl,vty}_test_runner.py: raise an exception if proc's rc != 0
* contrib/jenkins.sh: remove unrecognized --enable-vty-tests
* lchan_select: fix lchan selection for GSM48_CMODE_DATA_{14k5,12k0}
* fix send_assignment_complete(): proper SCE encoding for CSD
[ Neels Hofmeyr ]
* examples: osmo-bsc-minimal.cfg: drop codec-list
* pick up all *.vty in EXTRA_DIST
* add msc.vty to test 'msc' / 'codec-list' cfg
* cosmetic: use char literals in cfg_net_bsc_codec_list()
* cosmetic: use i++ instead of ++i in for loop
* vty: improve doc for 'codec-list'
* bsc_vty.c: s/bsc/msc for commands under msc node
* bsc_vty.c write_msc(): fix weird printf format
* vty: msc / codec-list: tweak error msg
* cosmetic: clarify test_codec_support_bts()
* select_codecs(): doc tweak
* select_codecs(): constify ct arg
* add timeslot.vty
* implicitly register osmo_fsm definitions
* assignment_fsm.c: make two functions static
* bsc_test: add 'update_exp'
* simplify storage of bsc_msc_data->audio_support
* vty: msc / codec-list: forbid duplicate entries
* vty: msc / codec-list: forbid invalid codec versions
* ensure correct phys_chan_config doc string count on VTY
* VTY,CTRL: add pchan dynamic/{osmocom,ipaccess}
* stat: change pchan naming to dynamic/{osmocom,ipaccess}
* bsc_test.c: test FSM IDs that contain pchan names
* tweak gsm_pchan_ids[]: DYNAMIC/{OSMOCOM,IPACCESS}
* drop gsm_pchan_ids, use sanitized FSM ids instead
* doc: add codec_resolution.msc
* cosmetic: timeslot_fsm.c: move some code to separate function
* vty: codec-list: fix error message
* fix coverity (false) warning in codec-list vty
* segfault: verify lchan presence on Assignment Complete
* add location_services_fsm_bsc.dot
* SCCP N-PCSTATE: trigger MSC status on PC availability
* log: N-PCSTATE: use new value_strings
* fix comment typo
* fix length check in abis_rsl_rx_rll()
* fix mscpool for large msc NRs
[ Pau Espin Pedrol ]
* cosmetic: gsm_data.h: Fix typo in comment
* constify bsc_conn_by_bsub() ptr param
* Clarify type and values of sccp.conn_id
* bscc_sccp: Avoid allocating conn_id 0x00FFFFFF
* get_bsc_conn_by_conn_id(): Properly match sccp_instance
* bscc_sccp: Small optimiztion in bsc_sccp_inst_next_conn_id()
* Assert conn_id being looked up is inside expected range
* pcu_sock.c: Call osmo_fd_unregister() before closing and changing bfd->fd
* Optimize subscr_conns lookup
* Move bsc_conn_by_bsub() and make it static
* bsc_subscriber: Drop unused function bsc_subscr_find_by_mi()
* bsc_subscriber: Mark functions used only internally as static
* bsc_subscriber: Introduce bsc_subscriber_store object
* bsc_subscriber: Optimize lookup of bsub by TMSI
* Fix Lb/A SCCP conn lookup after recent regression in optimization patch
* Use new GSM0408 defines for half-octet tags
* abis_rsl: Document spec ref of CCCH Load Ind
* Move paging queue specific handling to signal callback outside RSL code
* bts-rbs2k: Simplify osmo_fsm_inst_alloc_child_id()
* ipaccess nm: Delay marking TS as usable until OML reports Enabled state
* ipaccess nm: Handle TS_EV_OML_DOWN through NM FSM
* UserManual: Include sigtran*.adoc from osmo-gsm-manuals.git
* Write explicit role & sctp-role fields in ASP configurations
* Use new mgcp_client_conf_alloc() API to alloc mgcp_client_conf
* Use new libosmo-sccp APIs osmo_ss7_asp_get_{name,proto}()
* SI13: Set DRX_TIMER_MAX value actually transmitted
* cosmetic: Document DRX_TIMER_MAX upper limit on BCCH smaller than possible range
* meas_feed: Refactor fd/wqueue lifecycle
* meas_feed: Increase wqueue max_len to 100 and make it vty-configurable
* oml: ipacc: Remove BSSGP value assignment being overwritten afterwards
* oml: ipacc: Use new packed struct abis_nm_ipacc_att_bssgp_cfg from libosmcore
* oml: ipacc: Use new packed struct abis_nm_ipacc_att_ns_cfg from libosmcore
* oml: ipacc: Use new packed struct abis_nm_ipacc_att_rlc_cfg from libosmcore
[ arehbein ]
* gsm_bts_check_ny1: Prevent possible division by zero
* main: Give specific error message
* PCU interface: Log version when starting listener
[ Matan Perelman ]
* ctrl: Add cell reselection offset control
* ctrl: Remove dots from OOM
* ctrl: Add penalty time control
* ctrl: Add cell reselection hysteresis control
* ctrl: Add getting access control class
* ctrl: Add setting access control class
* ctrl: Add getting neighbor list
* ctrl: Add getting SI5 neighbor list
* ctrl: Add setting SI5 neighbor list
* ctrl: Add bsic
* ctrl: Add rach max delay
* ctrl: Add getting si2quater uarfcn neighbor list
* ctrl: Support adding si2quater uarfcn neighbor
* ctrl: Add getting si2quater earfcn neighbor list
* ctrl: Support adding si2quater earfcn neighbor
* control.adoc: Remove short-name and long-name
* control.adoc: Update with recent changes
[ Daniel Willmann ]
* cosmetic: Fix type in VTY description
[ Andreas Eversberg ]
* ASCI: Add new rate counters to support VGCS/VBS messages
* Fix typo in rate counters ASSIGMENT->ASSIGNMENT
* Cleanup code style of rate counters in osmo_bsc_msc.c
* ASCI: Add support for NOTIFICATION COMMAND (RSL) message
* ASCI: Add support for Group/Broadcast channel activation
* ASCI: Add selection reason for VGCS/VBS channels
* ASCI: Add TX support for UPLINK RELEASE message
* ASCI: Make function to add OSMUX IE public
* ASCI: Prepare bssmap_handle_ass_req_ct_speech() for VGCS/VBS
* ASCI: Add new debug category "ASCI" for VGCS/VBS state machines
* ASCI: Do not release channel, if SAPI 0 is released
* ASCI: Do not wait for RLL establishment
* ASCI: Add support for sending RSL UNIT-DATA towards BTS
* ASCI: Add TX support for UPLINK FREE/BUSY messages
* ASCI: Forward UPLINK RELEASE on dedicated channel to MSC
* ASCI: Add encoding of VGCS/VBS A-interface messages
* ASCI: Add processing and FSMs for VGCS/VBS
* ASCI: Add decoding of VGCS/VBS A-interface messages
* ASCI: Forward RLL to VGCS FSM
* ASCI: Forward lchan activation states to VGCS FSM
* ASCI: Indicate release of subscriber connection to VGCS FSM
* ASCI: Add support for reception of TALKER/LISTENER DETECTION
* ASCI: Send release on VGCS/VBS channel via unit data
* ASCI: Add assignment to a VGCS/VBS channel
* Select channel type by enum instead of three boolean
* ASCI: Fix uninitialized values in vgcs_fsm.c, found by gcc 13.1.1.20230714
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 16:40:03 +0200
osmo-bsc (1.10.0) unstable; urgency=medium
[ Vadim Yanitskiy ]

2
debian/compat vendored
View File

@ -1 +1 @@
9
10

14
debian/control vendored
View File

@ -2,7 +2,7 @@ Source: osmo-bsc
Section: net
Priority: extra
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
Build-Depends: debhelper (>=9),
Build-Depends: debhelper (>= 10),
dh-autoreconf,
autotools-dev,
autoconf,
@ -12,12 +12,12 @@ Build-Depends: debhelper (>=9),
python3-minimal,
libcdk5-dev,
libtalloc-dev,
libosmocore-dev (>= 1.8.0),
libosmo-sigtran-dev (>= 1.7.0),
libosmo-abis-dev (>= 1.4.0),
libosmo-netif-dev (>= 1.3.0),
libosmo-mgcp-client-dev (>= 1.11.0),
osmo-gsm-manuals-dev (>= 1.4.0)
libosmocore-dev (>= 1.9.0),
libosmo-sigtran-dev (>= 1.8.0),
libosmo-abis-dev (>= 1.5.0),
libosmo-netif-dev (>= 1.4.0),
libosmo-mgcp-client-dev (>= 1.12.0),
osmo-gsm-manuals-dev (>= 1.5.0)
Standards-Version: 3.9.8
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bsc
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bsc

25
debian/copyright vendored
View File

@ -25,31 +25,6 @@ License: AGPL-3.0+
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/>.
Files: src/libbsc/bsc_ctrl_lookup.c
src/libbsc/pcu_sock.c
Copyright: 2008-2010 Harald Welte <laforge@gnumonks.org>
2009-2012 Andreas Eversberg <jolly@eversberg.eu>
2010-2011 Daniel Willmann <daniel@totalueberwachung.de>
2010-2011 On-Waves
2012 Holger Hans Peter Freyther
License: GPL-2.0+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.
On Debian systems, the complete text of the GNU General Public License
Version 2 can be found in `/usr/share/common-licenses/GPL-2'.
Files: osmoappdesc.py
Copyright: 2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
License: GPL-3.0+

38
debian/postinst vendored Executable file
View File

@ -0,0 +1,38 @@
#!/bin/sh -e
case "$1" in
configure)
# Create the osmocom group and user (if it doesn't exist yet)
if ! getent group osmocom >/dev/null; then
groupadd --system osmocom
fi
if ! getent passwd osmocom >/dev/null; then
useradd \
--system \
--gid osmocom \
--home-dir /var/lib/osmocom \
--shell /sbin/nologin \
--comment "Open Source Mobile Communications" \
osmocom
fi
# Fix permissions of previous (root-owned) install (OS#4107)
if dpkg --compare-versions "$2" le "1.12.0"; then
if [ -e /etc/osmocom/osmo-bsc.cfg ]; then
chown -v osmocom:osmocom /etc/osmocom/osmo-bsc.cfg
chmod -v 0660 /etc/osmocom/osmo-bsc.cfg
fi
if [ -d /etc/osmocom ]; then
chown -v root:osmocom /etc/osmocom
chmod -v 2775 /etc/osmocom
fi
mkdir -p /var/lib/osmocom
chown -R -v osmocom:osmocom /var/lib/osmocom
fi
;;
esac
# dh_installdeb(1) will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#

54
debian/rules vendored
View File

@ -1,57 +1,15 @@
#!/usr/bin/make -f
# You must remove unused comment lines for the released package.
# See debhelper(7) (uncomment to enable)
# This is an autogenerated template for debian/rules.
#
# Output every command that modifies files on the build system.
#export DH_VERBOSE = 1
#
# Copy some variable definitions from pkg-info.mk and vendor.mk
# under /usr/share/dpkg/ to here if they are useful.
#
# See FEATURE AREAS/ENVIRONMENT in dpkg-buildflags(1)
# Apply all hardening options
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# Package maintainers to append CFLAGS
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# Package maintainers to append LDFLAGS
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
#
# With debhelper version 9 or newer, the dh command exports
# all buildflags. So there is no need to include the
# /usr/share/dpkg/buildflags.mk file here if compat is 9 or newer.
#
# These are rarely used code. (START)
#
# The following include for *.mk magically sets miscellaneous
# variables while honoring existing values of pertinent
# environment variables:
#
# Architecture-related variables such as DEB_TARGET_MULTIARCH:
#include /usr/share/dpkg/architecture.mk
# Vendor-related variables such as DEB_VENDOR:
#include /usr/share/dpkg/vendor.mk
# Package-related variables such as DEB_DISTRIBUTION
#include /usr/share/dpkg/pkg-info.mk
#
# You may alternatively set them susing a simple script such as:
# DEB_VENDOR ?= $(shell dpkg-vendor --query Vendor)
#
# These are rarely used code. (END)
#
# main packaging script based on dh7 syntax
%:
dh $@ --with autoreconf
# debmake generated override targets
CONFIGURE_FLAGS += --with-systemdsystemunitdir=/lib/systemd/system --enable-manuals
CONFIGURE_FLAGS += \
--enable-manuals \
--enable-meas-vis \
--with-systemdsystemunitdir=/lib/systemd/system \
$(NULL)
override_dh_auto_configure:
dh_auto_configure -- $(CONFIGURE_FLAGS)
#
# Do not install libtool archive, python .pyc .pyo
#override_dh_install:
# dh_install --list-missing -X.la -X.pyc -X.pyo
# See https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html#bpp-dbg
override_dh_strip:

View File

@ -14,6 +14,7 @@ msc: \
$(builddir)/handover-inter-bsc-in.png \
$(builddir)/mgw-endpoint.png \
$(builddir)/location_services_ta.png \
$(builddir)/codec_resolution.png \
$(NULL)
dot: \
@ -27,6 +28,7 @@ dot: \
$(builddir)/handover-inter-bsc-out-fsm.png \
$(builddir)/handover-inter-bsc-in-fsm.png \
$(builddir)/mscpool-attach.png \
$(builddir)/location_services_fsm_bsc.png \
$(NULL)
$(builddir)/%.png: $(srcdir)/%.msc

48
doc/codec_resolution.msc Normal file
View File

@ -0,0 +1,48 @@
msc {
hscale="1.7";
ms[label="MS/BTS"],cfg[label="osmo-bsc.cfg"],bsc[label="osmo-bsc"],__msc[label="MSC"],sip[label="SIP"];
ms => bsc [label="EST IND / Compl L3"];
cfg => bsc [label="'msc 0'\n'codec-list fr3 hr3 fr2 fr1 hr1'"];
bsc rbox bsc [label="build Speech Codec List\ngen_bss_supported_codec_list()"];
bsc => __msc [label="Compl L3"];
bsc note __msc [label="Speech Codec List (BSS Supported)\n{GSM0808_SCT_FR3 + AMR-cfg,\nGSM0808_SCT_HR3 + AMR-cfg,\nGSM0808_SCT_FR2,\nGSM0808_SCT_FR1,\nGSM0808_SCT_HR1}"];
--- [label="AMR-cfg:"];
bsc note __msc [label="S0-S15: 16bit flags\nS0 = 1: 4.75 ---- ---- ---- ---- ---- ---- ----\nS1 = 1: 4.75 ---- 5.90 ---- 7.40 ---- ---- 12.2\nS2 = 1: ---- ---- 5.90 ---- ---- ---- ---- ----\nS3 = 1: ---- ---- ---- 6.70 ---- ---- ---- ----\nS4 = 1: ---- ---- ---- ---- 7.40 ---- ---- ----\nS5 = 1: ---- ---- ---- ---- ---- 7.95 ---- ----\nS6 = 1: ---- ---- ---- ---- ---- ---- 10.2 ----\nS7 = 1: ---- ---- ---- ---- ---- ---- ---- 12.2\n\nS8 = 1: 4.75 ---- 5.90 ---- ---- ---- ---- ----\nS9 = 1: 4.75 ---- 5.90 6.70 ---- ---- ---- ----\nS10= 1: 4.75 ---- 5.90 6.70 7.40 ---- ---- ----\nS11= 1: ---- ---- ---- ---- ---- ---- ---- ----\nS12= 1: 4.75 ---- 5.90 6.70 ---- ---- 10.2 ----\nS13= 1: ---- ---- ---- ---- ---- ---- ---- ----\nS14= 1: 4.75 ---- 5.90 ---- ---- 7.95 ---- 12.2\nS15= 1: ---- ---- ---- ---- ---- ---- ---- ----\n\n3GPP TS 28.062 Table 7.11.3.1.3-2: \"Preferred Configurations\",\nsome removed as specified in 3GPP TS 48.008 3.2.2.103"];
cfg => bsc [label="'bts 0'\n'amr tch-x modes 0 2 4 7'"];
bsc rbox bsc [label="convert AMR modes to\nbts-S0-S15"];
cfg => bsc [label="'msc 0'\n'amr-config 4_75k allowed'"];
bsc rbox bsc [label="convert AMR modes to\nmsc-S0-S15"];
bsc => __msc [label="Compl L3 Speech Codec List:\nbitwise AND:\nbts-S0-S15 & msc-S0-S15"];
---;
ms => __msc [label="Bearer Capabilities"];
__msc <= sip [label="SDP"];
__msc note sip [label="m=audio 12345 RTP/AVP 112 3 111 110\na=rtpmap:112 AMR/8000\na=fmtp:112 mode-set=0,2,4,7\na=rtpmap:3 GSM/8000\na=rtpmap:111 GSM-HR-08/8000\na=rtpmap:110 GSM-EFR/8000"];
__msc rbox __msc [label="combine:\nBSC: Speech Codec List\nMS: Bearer Cap\nSIP: SDP"];
bsc <= __msc [label="BSSMAP Assignment Request\ncontains\nChannel Type\nSpeech Codec List (MSC Preferred)"];
bsc note __msc [label="Channel Type\nChannel Rate And Type:\n- [prefer] full rate\n- [prefer] half rate\n- indicated by Permitted Speech list\nPermitted Speech [1..9]:\n{GSM0808_PERM_FR3,\nGSM0808_PERM_HR3,\nGSM0808_PERM_FR2,\nGSM0808_PERM_FR1,\nGSM0808_PERM_HR1}"];
bsc note __msc [label="Speech Codec List (MSC Preferred)\n{GSM0808_SCT_FR3 + AMR-cfg,\nGSM0808_SCT_HR3 + AMR-cfg,\nGSM0808_SCT_FR2,\nGSM0808_SCT_FR1,\nGSM0808_SCT_HR1}"];
cfg => bsc [label="'msc 0'\n'codec-list fr3 hr3 fr2 fr1 hr1'"];
cfg => bsc [label="'bts 0'\n'phys_chan_cfg TCH/F'"];
cfg => bsc [label="'bts 0'\n'codec-support amr efr fr hr'"];
cfg rbox bsc [label="combine:\n'msc 0' 'codec-list fr3 hr3 fr2 fr1 hr1'\n'bts 0' 'phys_chan_cfg TCH/F'\n'bts 0' 'codec-support amr efr fr hr'\nMSC: Channel Type\nMSC: Speech Codec List (MSC Preferred)\n=>\n{GSM48_CMODE_SPEECH_AMR, FR, S0-S15},\n{GSM48_CMODE_SPEECH_AMR, HR, S0-S15}"];
cfg => bsc [label="'bts 0'\n'amr tch-x bts threshold'\n'amr tch-x bts hysteresis'"];
ms <= bsc [label="RSL CHANnel ACTIVation"];
ms note bsc [label="Channel Rate and Type: Full/Half rate\nSpeech Coding Algorithm Version: 3 (=AMR)\nMultiRate Configuration:\n- 4.75 | 5.90 | 7.40 | 12.2\n- Threshold / Hysteresis x 3"];
cfg => bsc [label="'bts 0'\n'amr tch-x ms threshold'\n'amr tch-x ms hysteresis'"];
ms <= bsc [label="RSL Assignment Command"];
ms note bsc [label="Channel Description: TCH/F\nSpeech Coding Algorithm Version: 3 (=AMR)\nMultiRate Configuration:\n- 4.75 | 5.90 | 7.40 | 12.2\n- Threshold / Hysteresis x 3"];
bsc => __msc [label="BSSMAP Assignment Complete"];
bsc note __msc [label="Chosen Channel: Speech, Full Rate\nSpeech Version (Chosen): FR3\nSpeech Codec (Chosen): FR AMR, S0-S15"];
__msc => sip [label="SDP (optional)"];
__msc note sip [label="m=audio 12345 RTP/AVP 112\na=rtpmap:112 AMR/8000\na=fmtp:112 mode-set=0,2,4,7"];
}

View File

@ -7,6 +7,12 @@ line vty
no login
!
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 lmi info
logging level linp info
logging level nm debug

View File

@ -0,0 +1,117 @@
!
! OpenBSC (0.9.11.308-62d46) configuration saved from vty
!!
! CAUTION: The 16kbps mode of the Ericcson RBS CCU only allows for a very
! minimal GPRS configuration (C1/C2 only).
!
password foo
!
line vty
no login
!
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 lmi info
logging level linp info
logging level nm debug
logging level rsl debug
logging level llapd notice
network
network country code 901
mobile network code 70
neci 0
paging any use tch 0
handover 0
handover window rxlev averaging 10
handover window rxqual averaging 1
handover window rxlev neighbor averaging 10
handover power budget interval 6
handover power budget hysteresis 3
handover maximum distance 9999
timer t3101 10
timer t3105 40
timer t3109 4
timer t3113 60
pcu-socket /tmp/pcu_bts
bts 0
type rbs2000
band GSM900
om2000 version-limit oml gen 12 rev 10
cell_identity 0
location_area_code 0x0001
training_sequence_code 7
base_station_id_code 63
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
channel allocator mode set-all descending
rach tx integer 9
rach max transmission 7
oml e1 line 0 timeslot 1 sub-slot full
oml e1 tei 62
neighbor-list mode automatic
gprs mode gprs
gprs routing area 0
gprs network-control-order nc0
gprs cell bvci 2
gprs nsei 101
gprs nsvc 0 nsvci 101
gprs nsvc 0 local udp port 23100
gprs nsvc 0 remote udp port 23000
gprs nsvc 0 remote ip 127.0.0.1
is-connection-list add 4 512 4
is-connection-list add 8 516 1
is-connection-list add 12 517 1
is-connection-list add 16 518 1
is-connection-list add 20 519 1
is-connection-list add 24 520 1
is-connection-list add 28 521 1
is-connection-list add 32 522 1
is-connection-list add 36 523 1
trx 0
rf_locked 0
arfcn 123
nominal power 44
max_power_red 0
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 0
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 4 sub-slot 0
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot 0
timeslot 4
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
hopping enabled 0
e1 line 0 timeslot 6 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 7 sub-slot 0
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot 0
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot 0
e1_input
e1_line 0 driver dahdi
e1_line 0 port 2

View File

@ -0,0 +1,106 @@
!
! OpenBSC (0.9.11.308-62d46) configuration saved from vty
!!
password foo
!
line vty
no login
!
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 lmi info
logging level linp info
logging level nm debug
logging level rsl debug
logging level llapd notice
network
network country code 901
mobile network code 70
neci 0
paging any use tch 0
handover 0
handover window rxlev averaging 10
handover window rxqual averaging 1
handover window rxlev neighbor averaging 10
handover power budget interval 6
handover power budget hysteresis 3
handover maximum distance 9999
timer t3101 10
timer t3105 40
timer t3109 4
timer t3113 60
pcu-socket /tmp/pcu_bts
bts 0
type rbs2000
band GSM900
om2000 version-limit oml gen 12 rev 10
cell_identity 0
location_area_code 0x0001
training_sequence_code 7
base_station_id_code 63
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
channel allocator mode set-all descending
rach tx integer 9
rach max transmission 7
oml e1 line 0 timeslot 1 sub-slot full
oml e1 tei 62
neighbor-list mode automatic
gprs mode egprs
gprs routing area 0
gprs network-control-order nc0
gprs cell bvci 2
gprs nsei 101
gprs nsvc 0 nsvci 101
gprs nsvc 0 local udp port 23100
gprs nsvc 0 remote udp port 23000
gprs nsvc 0 remote ip 127.0.0.1
is-connection-list add 4 712 36
trx 0
rf_locked 0
arfcn 123
nominal power 44
max_power_red 0
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot full
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 4 sub-slot full
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot full
timeslot 4
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
hopping enabled 0
e1 line 0 timeslot 6 sub-slot full
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 7 sub-slot full
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot full
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot full
e1_input
e1_line 0 driver dahdi
e1_line 0 port 2

View File

@ -7,6 +7,12 @@ line vty
no login
!
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 lmi info
logging level linp info
logging level nm debug

View File

@ -7,6 +7,12 @@ line vty
no login
!
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 lmi info
logging level linp info
logging level nm debug

View File

@ -7,6 +7,12 @@ line vty
no login
!
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 lmi info
logging level linp info
logging level nm debug

View File

@ -11,7 +11,9 @@ log stderr
logging color 1
logging print category-hex 0
logging print category 1
logging print file 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level llapd notice
logging level nm debug
e1_input

View File

@ -1,4 +1,12 @@
! osmo-bsc configuration example with 4 TRX
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
e1_input
e1_line 0 driver ipa
network
@ -46,22 +54,22 @@ network
phys_chan_config SDCCH8+CBCH
hopping enabled 0
timeslot 2
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 3
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 4
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 5
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 6
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 7
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
trx 1
rf_locked 0
@ -71,28 +79,28 @@ network
max_power_red 20
rsl e1 tei 1
timeslot 0
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 1
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 2
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 3
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 4
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 5
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 6
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 7
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
trx 2
rf_locked 0
@ -102,28 +110,28 @@ network
max_power_red 20
rsl e1 tei 2
timeslot 0
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 1
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 2
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 3
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 4
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 5
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 6
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 7
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
trx 3
rf_locked 0
@ -133,28 +141,28 @@ network
max_power_red 20
rsl e1 tei 3
timeslot 0
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 1
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 2
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 3
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 4
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 5
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 6
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
timeslot 7
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
hopping enabled 0
msc 0
allow-emergency allow

View File

@ -1,3 +1,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
network
network country code 901
mobile network code 70
@ -30,4 +38,3 @@ e1_input
e1_line 0 driver ipa
msc 0
allow-emergency deny
codec-list fr1

View File

@ -1,6 +1,14 @@
! osmo-bsc default configuration
! (assumes STP to run on 127.0.0.1 and uses default point codes)
!
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
e1_input
e1_line 0 driver ipa
network

View File

@ -1,5 +1,13 @@
! osmo-bsc configuration example for custom SCCP addresses
!
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
e1_input
e1_line 0 driver ipa
network
@ -74,6 +82,8 @@ cs7 instance 0
point-code 0.42.1
!asp asp-clnt-OsmoBSC 2905 0 m3ua
! remote-ip 10.23.24.1 ! where to reach the STP
! role asp
! sctp-role client
sccp-address msc_remote
point-code 0.23.1
msc 0

View File

@ -11,8 +11,9 @@ log stderr
logging color 1
logging print category-hex 0
logging print category 1
logging timestamp 1
logging print file 1
logging timestamp 0
logging print file basename last
logging print level 1
logging level llapd notice
logging level linp notice
logging level lmi notice

View File

@ -32,6 +32,7 @@ labelloc=t; label="lchan FSM"
WAIT_TS_READY -> UNUSED [label="error/timeout",style=dashed,constraint=false]
{WAIT_ACTIV_ACK,WAIT_RF_RELEASE_ACK} -> BORKEN [label="error/timeout",style=dashed]
BORKEN -> WAIT_AFTER_ERROR [label="late RF Release ACK"]
BORKEN -> WAIT_RF_RELEASE_ACK [label="late Activation ACK"]
WAIT_RLL_RTP_ESTABLISH -> WAIT_RLL_RTP_RELEASED [label=error,style=dashed]
WAIT_ACTIV_ACK -> rtp [label="LCHAN_RTP_EV_LCHAN_READY",style=dotted]
@ -44,4 +45,13 @@ labelloc=t; label="lchan FSM"
WAIT_RSL_CHAN_MODE_MODIFY_ACK -> ESTABLISHED [label="LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK\nno change to RTP"]
WAIT_RR_CHAN_MODE_MODIFY_ACK -> BORKEN [label="error/timeout",style=dashed]
WAIT_RSL_CHAN_MODE_MODIFY_ACK -> BORKEN [label="error/timeout",style=dashed]
BORKEN -> RECOVER_WAIT_ACTIV_ACK [label="X28"]
RECOVER_WAIT_ACTIV_ACK -> BORKEN [label="error/timeout",style=dashed]
RECOVER_WAIT_ACTIV_ACK -> UNUSED [label="rx ACK"]
RECOVER_WAIT_ACTIV_ACK -> RECOVER_WAIT_RF_RELEASE_ACK [label="rx NACK"]
RECOVER_WAIT_RF_RELEASE_ACK -> UNUSED [label="rx ACK"]
RECOVER_WAIT_RF_RELEASE_ACK -> BORKEN [label="error/timeout",style=dashed]
}

View File

@ -15,7 +15,7 @@ msc {
ts note ts [label="A dyn TS may be in PDCH mode and will asynchronously switch off PDCH first. A
non-dynamic TS is ready immediately."];
|||;
--- [label="IF requires_voice_stream"];
--- [label="IF requires_rtp_stream"];
lchan -> rtp [label="lchan_rtp_fsm_start()"];
rtp abox rtp [label="allocate\n LCHAN_RTP_ST_\nWAIT_MGW_ENDPOINT_\nAVAILABLE"];
--- [label="IF no endpoint-CI yet"];
@ -29,7 +29,7 @@ msc {
rtp note mgwep [label="The CRCX OK has assigned us a new endpoint CI number"];
rtp abox rtp [label="LCHAN_RTP_ST_WAIT_LCHAN_READY"];
--- [label="END: no endpoint-CI yet"];
--- [label="END: requires_voice_stream"];
--- [label="END: requires_rtp_stream"];
|||;
...;
ts -> lchan [label="LCHAN_EV_TS_READY"];
@ -60,7 +60,7 @@ msc {
lchan abox lchan [label="LCHAN_ST_WAIT_\nRLL_RTP_ESTABLISH\nT3101"];
|||;
|||;
--- [label="IF requires_voice_stream"];
--- [label="IF requires_rtp_stream"];
lchan -> rtp [label="LCHAN_RTP_EV_LCHAN_READY"];
|||;
--- [label="IF ip.access style BTS"];
@ -99,7 +99,7 @@ msc {
...;
lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED\nvia gscon_change_primary_lchan()"];
rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];
--- [label="END: requires_voice_stream"];
--- [label="END: requires_rtp_stream"];
|||;
|||;
@ -116,7 +116,7 @@ msc {
lchan rbox lchan [label="dispatch\nHO_EV_LCHAN_ESTABLISHED\n(see Handover FSM diagrams)"];
--- [label="END"];
...;
--- [label="IF requires_voice_stream"];
--- [label="IF requires_rtp_stream"];
lchan rbox lchan [label="Assignment or Handover FSM:"];
lchan -> mgwep [label="CRCX/MDCX to-MSC"];
...;
@ -125,7 +125,7 @@ msc {
lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED"];
rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];
rtp box rtp [label="Forget any Rollback info"];
--- [label="END: requires_voice_stream"];
--- [label="END: requires_rtp_stream"];
...;
...;

View File

@ -0,0 +1,40 @@
digraph G {
rankdir=TB
labelloc=t; label="Location Services FSMs in OsmoBSC"
MSC [label="MSC\nvia\nA interface",shape=box3d]
SMLC [label="SMLC\nvia\nLb interface",shape=box3d]
SMLC2 [label="SMLC\nvia\nLb interface",shape=box3d]
Paging [shape=box3d]
subgraph cluster_LCS_LOC_REQ_FSM {
label="lcs_loc_req_fsm"
INIT -> WAIT_LOCATION_RESPONSE
WAIT_LOCATION_RESPONSE -> BSSLAP_TA_REQ_ONGOING -> GOT_LOCATION_RESPONSE -> terminate
WAIT_LOCATION_RESPONSE -> GOT_LOCATION_RESPONSE
terminate [shape=octagon]
}
MSC -> INIT [label="BSSAP Perform\nLocation Request",style=dashed]
WAIT_LOCATION_RESPONSE -> SMLC [label="BSSMAP-LE Perform\nLocation Req",style=dashed]
SMLC -> WAIT_LOCATION_RESPONSE [label="BSSMAP-LE Perform\nLocation Resp",style=dashed]
GOT_LOCATION_RESPONSE -> MSC [label="BSSAP Perform\nLocation Response",style=dashed]
subgraph cluster_LCS_TA_REQ_FSM {
label="lcs_ta_req_fsm"
INIT2 [label="INIT"]
INIT2 -> WAIT_TA [label="MS idle"]
WAIT_TA -> GOT_TA
INIT2 -> GOT_TA [label="MS active"]
GOT_TA -> terminate2
terminate2 [label="terminate",shape=octagon]
}
SMLC2 -> INIT2 [label="TA Request",style=dashed]
WAIT_TA -> Paging [label="launch Paging",style=dashed]
Paging -> WAIT_TA [label="EV_TA",style=dashed]
GOT_TA -> SMLC2 [label="TA Response",style=dashed]
WAIT_TA -> BSSLAP_TA_REQ_ONGOING [label="EV_TA_REQ_START",style=dashed]
terminate2 -> BSSLAP_TA_REQ_ONGOING [label="EV_TA_REQ_END",style=dashed,constraint=false]
}

View File

@ -175,6 +175,7 @@ For building a multi-TRX setup, you also need to connect the TIB cables
between the two nanoBTS units, as well as the coaxial/RF AUX cabling.
====
[[example_e1_cfg]]
=== Example configuration for OsmoBSC with E1 BTS
The following configuration sample illustrates the usage of BTSs that are
@ -263,7 +264,7 @@ network
<4> OML always requires a TEI (Terminal Equipment Identifier) to set up. This number can be found in the manual of the BTS.
<5> This BTS has an built in “Interface Switch” (IS) that offers flexible way to reconfigure the interconnection between the internal components of the BTS and the external E1 line. This depends on the exact BTS type and configuration.
<5> This BTS has an built in “Interface Switch” (IS) that offers flexible way to reconfigure the interconnection between the internal components of the BTS and the external E1 line. This depends on the exact BTS type and configuration. See also <<cfg_ericsson_rbs_is>>
<6> Similar to OML we assign TS1 to RSL as well.
@ -273,6 +274,135 @@ network
<9> The bandwidth of one E1 timeslot matches the bandwidth of 4 GSM air interface timeslots. The E1 timeslot is split up into four sub-slots, which are then assigned to one GSM air interface timeslot each. Since the first timeslot on the first TRX is already used for signaling we begin the sub-slot counting with sub-slot 1 for alignment reasons.
=== Example configuration for OsmoBSC with Ericsson RBS E1 BTS and EGPRS
The following example illustrates the usage of Ericsson RBS2000/RBS6000 BTSs.
This classic E1 BTS has no built in PCU and therefore requires the configuration
of a BSC co-located OsmoPCU (see also: <<cfg_bsc_co_located_pcu>>).
It should also be noted that the Ericsson RBS2000/RBS6000 series is the first
BTS of this type to be supported by OsmoBTS and OsmoPCU. The implementation has
been made possible through funding by the NLnet Foundation.
Ericsson RBS2000/RBS6000 BTSs feature two GPRS modes. A 16kbps GPRS mode where
only CS1 and CS2 are supported and an EGPRS mode where MCS1 to MCS9 are
supported. OsmoPCU offers support for both modes but since the 16kbps mode only
supports classic GPRS with CS1 and CS2 it is more of experimental interest
and shall not be discussed further. The following example will describe how
to configure the 64kbps mode with EGPRS.
In the following example we also expect that the user is already familliar
with the E1 configuration example above (see also: <<example_e1_cfg>>)
.OsmoBSC configured for single-TRX E1 Ericsson DUG20 with EGPRS
====
----
e1_input
e1_line 0 driver dahdi
e1_line 0 port 3
network
network country code 1
mobile network code 1
encryption a5 0
neci 1
handover 0
pcu-socket /tmp/pcu_bts <1>
bts 0
type rbs2000
band GSM900
om2000 version-limit oml gen 12 rev 10
cell_identity 0
location_area_code 0x0001
training_sequence_code 7
base_station_id_code 63
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
oml e1 line 0 timeslot 1 sub-slot full
oml e1 tei 62
gprs mode egprs <2>
gprs routing area 0
gprs network-control-order nc0
gprs cell bvci 2
gprs nsei 101
gprs nsvc 0 nsvci 101
gprs nsvc 0 local udp port 23100
gprs nsvc 0 remote udp port 23000
gprs nsvc 0 remote ip 127.0.0.1
is-connection-list add 4 712 36 <3>
trx 0
rf_locked 0
arfcn 123
nominal power 42
max_power_red 12
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot full <4>
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 4 sub-slot full
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot full
timeslot 4
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH <5>
hopping enabled 0
e1 line 0 timeslot 6 sub-slot full
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 7 sub-slot full
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot full
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot full
----
====
<1> This configures the PCU socket path (see also: <<cfg_bsc_co_located_pcu>>)
<2> This configures the general GPRS parameters. The configuration is no
different from BTS with built-in PCU.
<3> The Ericsson RBS2000/RBS6000 series has an built in “Interface Switch” (IS)
that offers flexible way to reconfigure the interconnection between the internal
components of the BTS and the external E1 line. Since 16kbps subslots cannot
supply the bandwidth required for EGPRS the IS must be configured to connect
the 64kbps interface of the TRU to the external E1 line. For a more detailed
description of the IS see <<cfg_ericsson_rbs_is>>.
<4> Since we are using the 64kbps TRU interface we must configure a full E1
timeslot per air interface time slot. For Speech this will have no effect on
the TRAU frame format. The only difference is that always the first 16kbps
subslot of the assigned E1 timeslot is used. OsmoMGW will be instructed
accordingly by OsmoBSC, so no re-configuration of OsmoMGW is required.
<5> In this example we will use air interface TS 4 as PDCH. As mentioned
earlier Ericsson RBS2000/RBS6000 supports the 'DYNAMIC/OSMOCOM' timeslot model.
PDCH timeslots must be configured as dynamic timeslots. It is not possible to
configure static PDCHs. Therefore the phys_chan_config must be set to
TCH/F_TCH/H_SDCCH8_PDCH in order to use the air interface timeslot as PDCH.
NOTE: As of March 2023 the BSC co-located PCU support for Ericsson RBS was
tested only with a single BTS. Even though OsmoBSC and OsmoPCU should be able
to handle multiple BTS, unexpected bahviour should be taken into account.
=== E1 Line number and MGCP trunk number
The switching of the voice channels is done via OsmoMGW, which acts as a media
converter between E1 and VoIP (RTP). OsmoBSC will use the E1 line number to

View File

@ -47,7 +47,7 @@ Description: (null)
RF Nominal Power: 23 dBm, reduced by 0 dB, resulting BS power: 23 dBm
NM State: Oper 'Enabled', Admin 2, Avail 'OK'
Baseband Transceiver NM State: Oper 'Enabled', Admin 2, Avail 'OK'
ip.access stream ID: 0x00
IPA Abis/IP stream ID: 0x00
----
The output can be restricted to the TRXs of one specified BTS number
@ -181,6 +181,7 @@ manual-si5::
means of `si5 neighbor-list (add|del) arfcn <0-1023>` for SACCH (SI5).
[[config_gprs_pcu_pars]]
=== Configuring GPRS PCU parameters of a BTS
In the case of BTS models using Abis/IP (IPA), the GPRS PCU is located
@ -296,7 +297,7 @@ all BTS models support dynamic channels.
.Dynamic timeslot support by various BTS models
[cols="50%,25%,25%"]
|===
| |`TCH/F_TCH/H_SDCCH8_PDCH` |`TCH/F_PDCH`
| |`DYNAMIC/OSMOCOM` |`DYNAMIC/IPACCESS`
|ip.access nanoBTS |- |supported
|Ericsson RBS |supported |-
|sysmoBTS using _osmo-bts-sysmo_ |supported |supported
@ -311,11 +312,13 @@ non-standard RSL messages used for these timeslot kinds.
NOTE: Same as for dedicated PDCH timeslots, you need to enable GPRS and operate
a PCU, SGSN and GGSN to provide the actual data service.
==== Osmocom Style Dynamic Timeslots (TCH/F_TCH/H_SDCCH8_PDCH)
==== Osmocom Style Dynamic Timeslots (DYNAMIC/OSMOCOM)
Timeslots of the `TCH/F_TCH/H_SDCCH8_PDCH` type dynamically switch between TCH/F,
`DYNAMIC/OSMOCOM` is an alias for `TCH/F_TCH/H_SDCCH8_PDCH`.
Timeslots of the `DYNAMIC/OSMOCOM` type dynamically switch between TCH/F,
TCH/H, SDCCH8 and PDCH, depending on the channel kind requested by the MSC. The RSL
messaging for `TCH/F_TCH/H_SDCCH8_PDCH` timeslots is compatible with Ericsson RBS.
messaging for these timeslots is compatible with Ericsson RBS.
BTS models supporting this timeslot kind are shown in <<dyn_ts_compat>>.
@ -334,10 +337,12 @@ network
In OsmoNITB, disabling TCH/F on Osmocom dynamic timeslots is the default. In
OsmoBSC, the default is to allow both.
==== ip.access Style Dynamic Timeslots (TCH/F_PDCH)
==== ip.access Style Dynamic Timeslots (DYNAMIC/IPACCESS)
Timeslots of the `TCH/F_PDCH` type dynamically switch between TCH/F and PDCH.
The RSL messaging for `TCH/F_PDCH` timeslots is compatible with ip.access
`DYNAMIC/IPACCESS` is an alias for `TCH/F_PDCH`.
Timeslots of the `DYNAMIC/IPACCESS` type dynamically switch between TCH/F and PDCH.
The RSL messaging for `DYNAMIC/IPACCESS` timeslots is compatible with ip.access
nanoBTS.
BTS models supporting this timeslot kind are shown in <<dyn_ts_compat>>.
@ -350,7 +355,7 @@ timeslots to TCH, and no PDCH timeslots would be left for GPRS service.
==== Dynamic Timeslot Configuration Examples
This is an extract of an `osmo-bsc`` config file. A timeslot configuration with
This is an extract of an `osmo-bsc` config file. A timeslot configuration with
five Osmocom style dynamic timeslots and one dedicated PDCH may look like this:
----
@ -362,20 +367,20 @@ network
timeslot 1
phys_chan_config SDCCH8
timeslot 2
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
timeslot 3
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
timeslot 4
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
timeslot 5
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
timeslot 6
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
phys_chan_config DYNAMIC/OSMOCOM
timeslot 7
phys_chan_config PDCH
----
With the ip.access nanoBTS, only `TCH/F_PDCH` dynamic timeslots are supported,
With the ip.access nanoBTS, only `DYNAMIC/IPACCESS` dynamic timeslots are supported,
and hence a nanoBTS configuration may look like this:
----
@ -387,15 +392,15 @@ network
timeslot 1
phys_chan_config SDCCH8
timeslot 2
phys_chan_config TCH/F_PDCH
phys_chan_config DYNAMIC/IPACCESS
timeslot 3
phys_chan_config TCH/F_PDCH
phys_chan_config DYNAMIC/IPACCESS
timeslot 4
phys_chan_config TCH/F_PDCH
phys_chan_config DYNAMIC/IPACCESS
timeslot 5
phys_chan_config TCH/F_PDCH
phys_chan_config DYNAMIC/IPACCESS
timeslot 6
phys_chan_config TCH/F_PDCH
phys_chan_config DYNAMIC/IPACCESS
timeslot 7
phys_chan_config PDCH
----
@ -641,3 +646,140 @@ network
<2> This number affects how long the MS waits before (re-)transmitting RACH
requests.
<3> How often to retransmit the RACH request.
[[cfg_ericsson_rbs_is]]
=== Configuring Ericsson RBS Interface Switch (IS)
Ericsson RBS2000/RBS6000 base stations feature a so called "Interface Switch" (IS),
which is a built-in switchboard that interconnects between internal components
of the BTS. It also connects to the external E1 connections. This allows to
adapt the BTS to specific E1 networking requirements that may differ from the
usual timeslot configuration.
The internals of an Ericsson RBS are quite complex. In the following we will
only explain how to connect transceiver units (TRU) to an E1 interface pointing
to the outside world.
==== Understanding the is-connection-list VTY option
The IS operates on 16kbps subslots (ICPs), which means that there are no fixed
borders between E1 timeslots. Any number of consecutive subslots may be
connected through. However, depending on the components that are connected it
may still be a requirement to align on E1 timeslot borders.
The configuration of the IS is done using the is-connection-list command. The
first two numbers are the ICP numbers that specify the first subslot on both
sides that shall be interconnected. The third number (contiguity index) specifies
how many of the following subslots shall be connected.
In the following example we connect 4 blocks with 12 subslot each. The numbers
on the left are the ICP numbers of the E1 connection pointing to the outside.
The numbers in the middle are the ICP numbers of the subslots occupied by the
transceivers (one TRX per block). The third number is the contiguity index that
spans over 12 subslots or 3 E1 timeslots.
.Example: 4 TRX BTS (4 x 12 subslots)
----
network
bts 0
is-connection-list add 4 512 12
is-connection-list add 16 524 12
is-connection-list add 28 536 12
is-connection-list add 40 548 12
----
==== E1 port and TRU ICP numbers
On the outside connection, the ICP counting begins at E1 timeslot 0 (port A)
but since E1 TS 0 is reserved for framing and synchronization of the E1 line
itself the first usable subslot is subslot 4 (beginning of E1 TS 1). Depending
on the configuration the BTS may have multiple E1 ports. The counting scheme
will repeat itself. This means the next usable ICP can be found at an offset
of 128.
.External connections of a BTS with two E1 ports
[options="header",cols="50%,25%,25%"]
|===
|Function |Subslot offset (ICP) |ICP count
|E1 port A |4 |124
|E1 port B |132 |124
|===
Depending on the transceiver configuration, a RBS2000/RBS6000 base station
usually features two sets of ICPs for each TRX. The reason for this is that with
the introduction of EGPRS more bandwidth than a single 16kbps subslot could
deliver was required. The solution to this was to add an entirely new set of IS
ICPs where full 64kbps E1 timeslots instead of 16kbps subslots could be
used to serve a single air interface timeslot. The two sets of ICPs must not be
mixed. Only one set may be used at a time.
.ICPs to use TRU with 16kbps subslots per TRAU
[options="header",cols="50%,25%,25%"]
|===
|Function |Subslot offset (ICP) |ICP count
|TRU-0, RSL/OML |512 |4
|TRU-0, TRAU TS0..TS7 |516 |8
|TRU-1, RSL/OML |524 |4
|TRU-1, TRAU TS0..TS7 |528 |8
|TRU-2, RSL/OML |536 |4
|TRU-2, TRAU TS0..TS7 |540 |8
|TRU-3, RSL/OML |548 |4
|TRU-3, TRAU TS0..TS7 |552 |8
|TRU-4, RSL/OML |560 |4
|TRU-4, TRAU TS0..TS7 |564 |8
|TRU-5, RSL/OML |572 |4
|TRU-5, TRAU TS0..TS7 |576 |8
|TRU-6, RSL/OML |640 |4
|TRU-6, TRAU TS0..TS7 |644 |8
|TRU-7, RSL/OML |652 |4
|TRU-7, TRAU TS0..TS7 |656 |8
|TRU-8, RSL/OML |664 |4
|TRU-8, TRAU TS0..TS7 |668 |8
|TRU-9, RSL/OML |676 |4
|TRU-9, TRAU TS0..TS7 |680 |8
|TRU-10, RSL/OML |688 |4
|TRU-10, TRAU TS0..TS7 |692 |8
|TRU-11, RSL/OML |700 |4
|TRU-11, TRAU TS0..TS7 |704 |8
|===
NOTE: Each air interface timeslot is served by its individual TRAU, so it is
possible to route each subslot (ICP) dedicated to TRAU individually. The
connections on the other end may contain gaps and do not have to be
consecutive.
.ICPs to use TRU with 64kbps subslots per TRAU
[options="header",cols="50%,25%,25%"]
|===
|Function |Subslot offset (ICP) |ICP count
|TRU-0, RSL/OML |712 |4
|TRU-0, TRAU TS0..TS7 |716 |32
|TRU-1, RSL/OML |748 |4
|TRU-1, TRAU TS0..TS7 |752 |32
|TRU-2, RSL/OML |784 |4
|TRU-2, TRAU TS0..TS7 |788 |32
|TRU-3, RSL/OML |820 |4
|TRU-3, TRAU TS0..TS7 |824 |32
|TRU-4, RSL/OML |856 |4
|TRU-4, TRAU TS0..TS7 |860 |32
|TRU-5, RSL/OML |928 |4
|TRU-5, TRAU TS0..TS7 |932 |32
|TRU-6, RSL/OML |964 |4
|TRU-6, TRAU TS0..TS7 |968 |32
|TRU-7, RSL/OML |1000 |4
|TRU-7, TRAU TS0..TS7 |1004 |32
|TRU-8, RSL/OML |1036 |4
|TRU-8, TRAU TS0..TS7 |1040 |32
|TRU-9, RSL/OML |1072 |4
|TRU-9, TRAU TS0..TS7 |1076 |32
|TRU-10, RSL/OML |1108 |4
|TRU-10, TRAU TS0..TS7 |1112 |32
|TRU-11, RSL/OML |1144 |4
|TRU-11, TRAU TS0..TS7 |1148 |32
|===
NOTE: In case voice TRAU frames are transferred, only the first of the four
16kbps subslots is used. When the timeslot is switched to GPRS/EGPRS, the
full 64kbps bandwidth will be used. This also means that the set of four
ICPs per TRAU must be connected consecutively. Also the connection
to the outside must be aligned to E1 timeslot borders.

View File

@ -20,8 +20,6 @@ TRX-specific commands are additionally prefixed with TRX number e. g.
|apply-configuration|WO|No|"restart"|Restart all BTSes.
|mnc|RW|No|"<mnc>"|Set/Get MNC (value between (0, 999)).
|mcc|RW|No|"<mcc>"|Set/Get MCC (value between (1, 999)).
|short-name|RW|No|"<name>"|Set/Get network's short name.
|long-name|RW|No|"<name>"|Set/Get network's long name.
|mcc-mnc-apply|WO|No|"<mcc>,<mnc>"|Apply new MCC/MNC values if different from currently used one.
|notification|WO|Yes|Arbitrary value| See <<notif>> for details.
|inform-msc-v1|WO|Yes|Arbitrary value| See <<infomsc>> for details.
@ -31,6 +29,8 @@ TRX-specific commands are additionally prefixed with TRX number e. g.
|write-config-file|WO|No|"overwrite", "<filename>"|Write running configuration to file.
|bts.N.location-area-code|RW|No|"<lac>"|Set/Get LAC (value between (0, 65535)).
|bts.N.cell-identity|RW|No|"<id>"|Set/Get Cell Identity (value between (0, 65535)).
|bts.N.bsic|RW|No|"<bsic>"|Set/Get BSIC (value between (0, 63)).
|bts.N.rach-max-delay|RW|No|"<delay>"|Set/Get RACH max delay (value between (1, 127)).
|bts.N.apply-configuration|WO|No|Ignored|Restart BTS via OML.
|bts.N.send-new-system-informations|WO|No|Ignored|Regenerate and resend System Information messages for given BTS.
|bts.N.send-power-control-defaults|WO|No|Ignored|Resend default power control parameters for given BTS.
@ -39,6 +39,12 @@ TRX-specific commands are additionally prefixed with TRX number e. g.
|bts.N.oml-uptime|RO|No|<uptime>|Return OML link uptime in seconds.
|bts.N.gprs-mode|RW|No|"<mode>"|See <<gprsm>> for details.
|bts.N.rf_state|RO|No|"<oper>,<admin>,<pol>"|See <<rfs>> for details.
|bts.N.cell-reselection-offset|RW|No|"<cro>"|Set/Get cell reselection offset (value between (0, 126), steps of 2).
|bts.N.cell-reselection-penalty-time|RW|No|"<penalty-time>","reserved"|Set/Get cell reselection penalty time (value between (20, 620), steps of 20).
|bts.N.cell-reselection-hysteresis|RW|No|"<crh>"|Set/Get cell reselection hysteresis (value between (0, 14), steps of 2).
|bts.N.rach-access-control-classes|RO|No|"<class>,(barred|allowed)"|Get concatenated pairs of RACH access control classes.
|bts.N.rach-access-control-class.bar|WO|No|"<class>","emergency"|Set RACH access control class as barred.
|bts.N.rach-access-control-class.allow|WO|No|"<class>","emergency"|Set RACH access control class as allowed.
|bts.N.trx.M.arfcn|RW|No|"<arfcn>"|Set/Get ARFCN (value between (0, 1023)).
|bts.N.trx.M.max-power-reduction|RW|No|"<mpr>"|See <<mpr>> for details.
|[bts.N.]handover.active|RW|No|"0","1","default"|Enable/disable handover.
@ -72,6 +78,16 @@ TRX-specific commands are additionally prefixed with TRX number e. g.
|bts.N.neighbor-list.mode|WO|No|"automatic","manual","manual-si5"|Mode of Neighbor List generation.
|bts.N.neighbor-list.add|WO|No|<0-1023>|Add to manual neighbor list.
|bts.N.neighbor-list.del|WO|No|<0-1023>|Delete from manual neighbor list.
|bts.N.neighbor-list.si5-add|WO|No|<0-1023>|Add to manual SI5 neighbor list.
|bts.N.neighbor-list.si5-del|WO|No|<0-1023>|Delete from manual SI5 neighbor list.
|bts.N.neighbor-list.si2|RO|No|"<arfcn>"|Get space concatenated list of SI2 neighbor ARFCNs.
|bts.N.neighbor-list.si5|RO|No|"<arfcn>"|Get space concatenated list of SI5 neighbor ARFCNs.
|bts.N.neighbor-list.si2quater.uarfcns|RO|No|"<uarfcn>,<scrambling code>,<diversity bit>"|Get space concatenated list of UARFCN neighbors.
|bts.N.neighbor-list.si2quater.earfcns|RO|No|"<earfcn>,<thresh-hi>,<thresh-lo>,<prio>,<qrxlv>,<meas>"|Get space concatenated list of EARFCN neighbors.
|bts.N.si2quater-neighbor-list.add.uarfcn|WO|No|"<uarfcn>,<scrambling code>,<diversity bit>"|Add UARFCN neighbor.
|bts.N.si2quater-neighbor-list.del.uarfcn|WO|No|"<uarfcn>,<scrambling code>"|Delete UARFCN neighbor.
|bts.N.si2quater-neighbor-list.add.earfcn|WO|No|"<earfcn>,<thresh-hi>,<thresh-lo>,<prio>,<qrxlv>,<meas>"|Add EARFCN neighbor.
|bts.N.si2quater-neighbor-list.del.earfcn|WO|No|"<earfcn>"|Delete EARFCN neighbor (value between (0, 65535)).
|===
[[notif]]

View File

@ -63,7 +63,7 @@ PDCH resources should be allocated for interference reasons.
NOTE: Currently osmo-bsc makes no use of PDCH interference reports, neither
they get forwarded to the BSC co-located PCU over the PCUIF.
For dynamic timeslots (`TCH/F_TCH/H_SDCCH/8_PDCH` and `TCH/F_PDCH`), the
For dynamic timeslots (`DYNAMIC/OSMOCOM` and `DYNAMIC/IPACCESS`), the
following expectations apply:
* when in TCH/F mode: no interference reports, because the only sub-channel is active;

View File

@ -135,11 +135,13 @@ Station Controller, i.e.
For more information, see <<net>>, <<bts>> and <<bts-examples>>.
==== TRAU mapper / E1 sub-channel muxer
==== Speech traffic
Unlike classic GSM networks, OsmoBSC does not perform any transcoding.
Rather, a compatible codec is selected for both legs of a call, and
codec frames are passed through transparently. In order to achieve this
with E1 based BTS, OsmoBSC contains a E1 sub-channel de- and
re-multiplexer as well as a TRAU mapper that can map uplink to downlink
frames and vice versa.
OsmoBSC, by itself, does not perform any transcoding or relaying of user plane
speech traffic. This task is handled entirely by a BSC co-located media gateway,
such as OsmoMGW, which will take care of relaying the RTP traffic from the BTS
into the core network.
In case classic E1 based BTSs are used, OsmoBSC will instruct the MGW to
convert between TRAU frames on the E1 side and RTP frames on the IP based core
network side.

View File

@ -69,6 +69,24 @@ To run multiple OsmoBSC instances on the same A-interface (SCCP/M3UA), each BSC
has to configure a distinct point-code. See <<cs7_config>>.
=== Configure limits
When connecting hundreds of TRX to OsmoBSC, it may be necessary to adjust the
operating system's limit on open file descriptors for the osmo-bsc process. A
typical default limit imposed by operating systems is 1024; this would be
exceeded by, for example, about 205 BTS with 4 TRX each. (Each BTS with 4 TRX
requires 5 file descriptors for Abis; 205 * 5 already exceeds 1024, sockets for
other interfaces not considered yet.)
It should be ok to set an OS limit on open file descriptors as high as 65536
for osmo-bsc, which practically rules out failure from running out of file
descriptors anywhere (<50,000 TRX).
When using systemd, the file descriptor limit may be adjusted in the service
file by the `LimitNOFILE` setting ("Number of Open FILE descriptors"). OsmoBSC
ships a systemd service file with a high LimitNOFILE setting.
=== Configure primary links
==== Connect to an MSC's _A_ interface
@ -87,6 +105,7 @@ cs7 instance 0
point-code 1.23.3
asp asp-clnt-msc-0 2905 0 m3ua
remote-ip 127.0.0.1
role asp
sctp-role client
sccp-address msc
point-code 0.23.1
@ -218,3 +237,47 @@ smlc
----
More detailed configuration is described in <<smlc-config>>.
[[cfg_bsc_co_located_pcu]]
==== Configure BSC co-located PCU
While small IP based BTSs usually come with a built in PCU (BTS co-located
PCU), this does not have to be the case with any BTS. Especially larger E1 BTS
usually make use of a BSC co-located PCU.
In the case of OsmoBSC this means that an instance of OsmoPCU is running next
to OsmoBSC. Both processes share a unix domain socket to exchange signaling
traffic and configuration parameters.
.OsmoBSC with co-located OsmoPCU'
[graphviz]
----
digraph G {
rankdir=LR;
BTS [label="BTS"];
subgraph cluster_ran {
label="RAN";
PCU [label="OsmoPCU"];
BSC [label="OsmoBSC"];
MGW [label="OsmoMGW"];
{ rank=same BSC MGW PCU }
}
BTS->PCU [label="GPRS/TRAU", style=dotted];
BTS->BSC [label="Abis"];
BTS->MGW [label="SPEECH/TRAU", style=dotted];
BSC->MGW [label="MGCP"];
BSC->PCU [label="PCU_SOCK"];
}
----
Apart from the configuration of the PCU socket path the configuration is not
much different from those where the PCU is integrated inside the BTS. See also
see also <<config_gprs_pcu_pars>> for a detailed description.
.Configure socket path to co-located PCU
----
network
pcu-socket /tmp/pcu_bts
----

View File

@ -16,6 +16,10 @@ include::./common/chapters/vty.adoc[]
include::./common/chapters/logging.adoc[]
include::./common/chapters/sigtran.adoc[]
include::./common/chapters/sigtran-osmocom.adoc[]
include::./common/chapters/cs7-config.adoc[]
include::{srcdir}/chapters/bts.adoc[]

View File

@ -1,5 +1,5 @@
msc {
bts [label="MS/BTS"], bsc[label="BSC"], bsc_ts[label="BSC timeslot FSM"], bsc_lchan[label="BSC lchan FSM"];
bts [label="MS/BTS"], bsc[label="BSC"], bsc_ts[label="BSC timeslot FSM"], bsc_lchan[label="BSC lchan FSM"], pcu_sock[label="PCU socket"];
bsc_ts abox bsc_ts [label="NOT_INITIALIZED"];
@ -88,6 +88,24 @@ msc {
bsc_ts rbox bsc_ts [label="Continue at 'IN_USE' above"];
...;
...;
bts rbox bsc_lchan [label="on PCU disconnect (Ericsson RBS)
for all timeslots in state PDCH:" ];
bsc_ts abox bsc_ts [label="PDCH"];
bsc_ts <- pcu_sock [label="TS_EV_PDCH_DEACT"];
bts note bsc_ts [label="PDCH release, see WAIT_PDCH_DEACT above"];
...;
bsc_ts abox bsc_ts [label="UNUSED"];
...;
...;
bts rbox bsc_lchan [label="on PCU reconnect (Ericsson RBS)
for all timeslots in state UNUSED:" ];
bsc_ts abox bsc_ts [label="UNUSED"];
bsc_ts <- pcu_sock [label="TS_EV_PDCH_ACT"];
bts note bsc_ts [label="PDCH activation, see WAIT_PDCH_ACT above"];
...;
bsc_ts abox bsc_ts [label="PDCH"];
...;
...;
bts rbox bsc_lchan [label="on erratic event"];
bsc_ts -> bsc_lchan [label="LCHAN_EV_TS_ERROR"];

View File

@ -19,6 +19,7 @@ noinst_HEADERS = \
chan_alloc.h \
chan_counts.h \
codec_pref.h \
data_rate_pref.h \
ctrl.h \
debug.h \
e1_config.h \
@ -45,7 +46,6 @@ noinst_HEADERS = \
neighbor_ident.h \
network_listen.h \
nm_common_fsm.h \
openbscdefines.h \
osmo_bsc.h \
osmo_bsc_grace.h \
osmo_bsc_rf.h \
@ -66,4 +66,5 @@ noinst_HEADERS = \
osmo_bsc_lcls.h \
smscb.h \
power_control.h \
vgcs_fsm.h \
$(NULL)

View File

@ -29,9 +29,6 @@
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/signal.h>
/* max number of attributes represented as 3GPP TS 52.021 §9.4.62 SW Description array */
#define MAX_BTS_ATTR 5
/* The BCCH info from an ip.access test, in host byte order
* and already parsed... */
struct ipac_bcch_info {
@ -89,7 +86,8 @@ int abis_nm_set_bts_attr(struct gsm_bts *bts, uint8_t *attr, int attr_len);
int abis_nm_set_radio_attr(struct gsm_bts_trx *trx, uint8_t *attr, int attr_len);
int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, uint8_t chan_comb);
int abis_nm_sw_act_req_ack(struct gsm_bts *bts, uint8_t obj_class, uint8_t i1,
uint8_t i2, uint8_t i3, int nack, uint8_t *attr, int att_len);
uint8_t i2, uint8_t i3, int nack,
const uint8_t *attr, unsigned int attr_len);
int abis_nm_raw_msg(struct gsm_bts *bts, int len, uint8_t *msg);
int abis_nm_event_reports(struct gsm_bts *bts, int on);
int abis_nm_reset_resource(struct gsm_bts *bts);

View File

@ -55,17 +55,20 @@ int rsl_encryption_cmd(struct msgb *msg);
int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group,
const struct osmo_mobile_identity *mi,
uint8_t chan_needed, bool is_gprs);
int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val);
int rsl_notification_cmd(struct gsm_bts *bts, struct gsm_lchan *lchan, struct gsm0808_group_callref *gc, uint8_t *drx);
int rsl_imm_assign_cmd(const struct gsm_bts *bts, uint8_t len, const uint8_t *val);
int rsl_tx_imm_assignment(struct gsm_lchan *lchan);
int rsl_tx_imm_ass_rej(struct gsm_bts *bts, struct gsm48_req_ref *rqd_ref);
int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, uint8_t power_command);
int rsl_data_request(struct msgb *msg, uint8_t link_id);
int rsl_unit_data_request(struct msgb *msg, uint8_t link_id);
int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id);
int rsl_relase_request(struct gsm_lchan *lchan, uint8_t link_id);
/* Ericcson vendor specific RSL extensions */
int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val);
int rsl_ericsson_imm_assign_cmd(const struct gsm_bts *bts, uint32_t msg_id, uint8_t len,
const uint8_t *val, uint8_t pag_grp, bool confirm);
/* Siemens vendor-specific RSL extensions */
int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
@ -119,6 +122,11 @@ int rsl_tx_dyn_ts_pdch_act_deact(struct gsm_bts_trx_ts *ts, bool activate);
int rsl_forward_layer3_info(struct gsm_lchan *lchan, const uint8_t *l3_info, uint8_t l3_info_len);
int ipacc_rtp_csd_fmt_transp(const struct channel_mode_and_rate *ch_mode_rate,
const enum rsl_ipac_rtp_csd_format_d format_d);
int ipacc_rtp_csd_fmt_non_transp(const struct channel_mode_and_rate *ch_mode_rate,
const enum rsl_ipac_rtp_csd_format_d format_d);
int ipacc_speech_mode(enum gsm48_chan_mode tch_mode, enum gsm_chan_t type);
void ipacc_speech_mode_set_direction(uint8_t *speech_mode, bool send);
int ipacc_payload_type(enum gsm48_chan_mode tch_mode, enum gsm_chan_t type);

View File

@ -40,7 +40,7 @@ enum assignment_fsm_event {
ASSIGNMENT_EV_CONN_RELEASING,
};
void assignment_fsm_init(void);
void bssap_extend_osmux(struct msgb *msg, uint8_t cid);
int reassignment_request_to_lchan(enum assign_for assign_for, struct gsm_lchan *lchan, struct gsm_lchan *to_lchan,
int tsc_set, int tsc);
@ -50,3 +50,4 @@ int reassignment_request_to_chan_type(enum assign_for assign_for, struct gsm_lch
void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts *bts,
struct assignment_request *req);
void assignment_reset(struct gsm_subscriber_connection *conn);
void assignment_fsm_update_id(struct gsm_subscriber_connection *conn);

View File

@ -71,6 +71,15 @@ enum {
MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR,
MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_REQUEST,
MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_ABORT,
MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_SETUP,
MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_ASSIGN_RQST,
MSC_CTR_BSSMAP_RX_DT1_UPLINK_RQST_ACKNOWLEDGE,
MSC_CTR_BSSMAP_RX_DT1_UPLINK_REJECT_CMD,
MSC_CTR_BSSMAP_RX_DT1_UPLINK_RELEASE_CMD,
MSC_CTR_BSSMAP_RX_DT1_UPLINK_SEIZED_CMD,
MSC_CTR_BSSMAP_RX_DT1_VGCS_ADDL_INFO,
MSC_CTR_BSSMAP_RX_DT1_VGCS_SMS,
MSC_CTR_BSSMAP_RX_DT1_NOTIFICATION_DATA,
/* Tx message counters (per connection type) */
MSC_CTR_BSSMAP_TX_BSS_MANAGEMENT,
@ -86,8 +95,8 @@ enum {
MSC_CTR_BSSMAP_TX_UDT_RESET_ACK,
MSC_CTR_BSSMAP_TX_DT1_CLEAR_RQST,
MSC_CTR_BSSMAP_TX_DT1_CLEAR_COMPLETE,
MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_FAILURE,
MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_COMPLETE,
MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_FAILURE,
MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_COMPLETE,
MSC_CTR_BSSMAP_TX_DT1_SAPI_N_REJECT,
MSC_CTR_BSSMAP_TX_DT1_CIPHER_COMPLETE,
MSC_CTR_BSSMAP_TX_DT1_CIPHER_REJECT,
@ -102,6 +111,17 @@ enum {
MSC_CTR_BSSMAP_TX_DT1_DTAP,
MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_SUCCESS,
MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_FAILURE,
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_ACK,
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_REFUSE,
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_RESULT,
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_FAIL,
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_QUEUING_INDICATION,
MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST,
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGNMENT_STATUS,
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_AREA_CELL_INFO,
MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST_CONFIRMATION,
MSC_CTR_BSSMAP_TX_DT1_UPLINK_RELEASE_INDICATION,
MSC_CTR_BSSMAP_TX_DT1_UPLINK_APP_DATA,
MSC_CTR_MSCPOOL_SUBSCR_NEW,
MSC_CTR_MSCPOOL_SUBSCR_REATTACH,
@ -133,8 +153,13 @@ struct bsc_msc_data {
/* audio codecs */
struct gsm48_multi_rate_conf amr_conf;
bool amr_octet_aligned;
struct gsm_audio_support **audio_support;
/* Practically, there can be only 5 entries in osmo-bsc: FR1 FR2 FR3 HR1 HR3. Historically, osmo-bsc allowed
* *any* number of entries -- we should not break too strictly on old cfg files. Theoretically, there should be
* room for FR1 to FR7 plus HR1 to HR7 less HR2. Let's just give ample room for all these aspects: */
struct gsm_audio_support audio_support[16];
int audio_length;
enum bsc_lcls_mode lcls_mode;
bool lcls_codec_mismatch_allow;

View File

@ -57,8 +57,6 @@ struct osmo_mgcpc_ep_ci;
struct assignment_request;
struct gsm_lchan;
void bsc_subscr_conn_fsm_init(void);
/* Allocate a subscriber connection and its associated FSM */
struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *net);
void gscon_update_id(struct gsm_subscriber_connection *conn);

View File

@ -5,6 +5,7 @@
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/linuxrbtree.h>
#include <osmocom/core/use_count.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
#include <osmocom/gsm/gsm48.h>
@ -12,8 +13,19 @@
struct log_target;
struct gsm_bts;
struct bsc_subscr_store {
struct llist_head bsub_list; /* list containing "struct bsc_subscr" */
/* rbtree root of 'struct bsc_subscr', ordered by tmsi */
struct rb_root bsub_tree_tmsi;
};
struct bsc_subscr_store *bsc_subscr_store_alloc(void *ctx);
struct bsc_subscr {
struct llist_head entry;
struct bsc_subscr_store *store; /* backpointer to "struct bsc_subscr_store" */
struct llist_head entry; /* entry in (struct bsc_subscr_store)->bsub_list */
/* entry in (struct bsc_subscr_store)->bsub_tree_tmsi. Inserted if tmsi != GSM_RESERVED_TMSI: */
struct rb_node node_tmsi;
struct osmo_use_count use_count;
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
@ -28,30 +40,21 @@ struct bsc_subscr {
const char *bsc_subscr_name(struct bsc_subscr *bsub);
const char *bsc_subscr_id(struct bsc_subscr *bsub);
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list,
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct bsc_subscr_store *bsubst,
const char *imsi,
const char *use_token);
struct bsc_subscr *bsc_subscr_find_or_create_by_imei(struct llist_head *list,
const char *imei,
const char *use_token);
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct llist_head *list,
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct bsc_subscr_store *bsubst,
uint32_t tmsi,
const char *use_token);
struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct bsc_subscr_store *bsubst,
const struct osmo_mobile_identity *mi,
const char *use_token);
struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
struct bsc_subscr *bsc_subscr_find_by_imsi(struct bsc_subscr_store *bsubst,
const char *imsi,
const char *use_token);
struct bsc_subscr *bsc_subscr_find_by_imei(struct llist_head *list,
const char *imei,
const char *use_token);
struct bsc_subscr *bsc_subscr_find_by_tmsi(struct llist_head *list,
uint32_t tmsi,
const char *use_token);
struct bsc_subscr *bsc_subscr_find_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
const char *use_token);
int bsc_subscr_set_tmsi(struct bsc_subscr *bsub, uint32_t tmsi);
void bsc_subscr_set_imsi(struct bsc_subscr *bsub, const char *imsi);
void bsc_subscr_set_imei(struct bsc_subscr *bsub, const char *imei);

View File

@ -28,4 +28,5 @@ struct bssmap_reset {
struct bssmap_reset *bssmap_reset_alloc(void *ctx, const char *label, const struct bssmap_reset_cfg *cfg);
bool bssmap_reset_is_conn_ready(const struct bssmap_reset *bssmap_reset);
void bssmap_reset_resend_reset(struct bssmap_reset *bssmap_reset);
void bssmap_reset_set_disconnected(struct bssmap_reset *bssmap_reset);
void bssmap_reset_term_and_free(struct bssmap_reset *bssmap_reset);

View File

@ -300,7 +300,7 @@ struct gsm_bts_model {
/* (Optional) function for sending default MS/BS Power Control paramaters */
int (*power_ctrl_send_def_params)(const struct gsm_bts_trx *trx);
/* (Optional) function for toggling BCCH carrier power reduction operation */
int (*power_ctrl_set_c0_power_red)(const struct gsm_bts *bts, const uint8_t red);
int (*power_ctrl_send_c0_power_red)(const struct gsm_bts *bts, const uint8_t red);
void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);
void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);
@ -375,8 +375,8 @@ struct gsm_bts {
struct e1inp_sign_link *oml_link;
/* Timer to use for deferred drop of OML link, see \ref ipaccess_drop_oml_deferred */
struct osmo_timer_list oml_drop_link_timer;
/* when OML link was established */
time_t uptime;
/* when OML link was established or lost */
time_t updowntime;
/* Abis network management O&M handle */
struct abis_nm_h *nmh;
@ -523,6 +523,7 @@ struct gsm_bts {
bool chan_alloc_chan_req_reverse;
bool chan_alloc_assignment_reverse;
bool chan_alloc_handover_reverse;
bool chan_alloc_vgcs_reverse;
/* Whether to use dynamic allocation mode for assignment */
bool chan_alloc_assignment_dynamic;
@ -568,6 +569,11 @@ struct gsm_bts {
uint16_t scramble_list[MAX_EARFCN_LIST];
} data;
} si_common;
/* NCH (Notification Channel) related parameters */
struct {
uint8_t num_blocks; /* NCH number of CCCH blocks (0 = no NCH) */
uint8_t first_block; /* NCH first block number */
} nch;
bool early_classmark_allowed;
bool early_classmark_allowed_3g;
/* for testing only: Have an infinitely long radio link timeout */
@ -600,10 +606,6 @@ struct gsm_bts {
/* osmux config: */
enum osmux_usage use_osmux;
/* PCU socket state */
char *pcu_sock_path;
struct pcu_sock_state *pcu_state;
struct rate_ctr_group *bts_ctrs;
struct osmo_stat_item_group *bts_statg;
@ -661,6 +663,9 @@ struct gsm_bts {
/* We will ignore CHAN RQD with access delay greater than rach_max_delay */
uint8_t rach_max_delay;
/* We will ignore CHAN RQD sitting in the queue for period greater than rach_expiry_timeout */
uint8_t rach_expiry_timeout;
/* Is Fast return to LTE allowed during Chan Release in this BTS? */
bool srvcc_fast_return_allowed;
@ -678,77 +683,100 @@ struct gsm_bts {
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
/* this actually refers to the IPA transport, not the BTS model */
static inline int is_ipaccess_bts(const struct gsm_bts *bts)
static inline bool is_ipa_abisip_bts(const struct gsm_bts *bts)
{
switch (bts->type) {
case GSM_BTS_TYPE_NANOBTS:
case GSM_BTS_TYPE_OSMOBTS:
return 1;
return true;
default:
break;
}
return 0;
return false;
}
static inline int is_osmobts(const struct gsm_bts *bts)
static inline bool is_nanobts(const struct gsm_bts *bts)
{
switch (bts->type) {
case GSM_BTS_TYPE_NANOBTS:
return true;
default:
break;
}
return false;
}
static inline bool is_osmobts(const struct gsm_bts *bts)
{
switch (bts->type) {
case GSM_BTS_TYPE_OSMOBTS:
return 1;
return true;
default:
break;
}
return 0;
return false;
}
static inline int is_siemens_bts(const struct gsm_bts *bts)
static inline bool is_siemens_bts(const struct gsm_bts *bts)
{
switch (bts->type) {
case GSM_BTS_TYPE_BS11:
return 1;
return true;
default:
break;
}
return 0;
return false;
}
static inline int is_nokia_bts(const struct gsm_bts *bts)
static inline bool is_nokia_bts(const struct gsm_bts *bts)
{
switch (bts->type) {
case GSM_BTS_TYPE_NOKIA_SITE:
return 1;
return true;
default:
break;
}
return 0;
return false;
}
static inline int is_ericsson_bts(const struct gsm_bts *bts)
static inline bool is_ericsson_bts(const struct gsm_bts *bts)
{
switch (bts->type) {
case GSM_BTS_TYPE_RBS2000:
return 1;
return true;
default:
break;
}
return 0;
return false;
}
static inline int is_e1_bts(const struct gsm_bts *bts)
static inline bool is_e1_bts(const struct gsm_bts *bts)
{
switch (bts->type) {
case GSM_BTS_TYPE_BS11:
case GSM_BTS_TYPE_RBS2000:
case GSM_BTS_TYPE_NOKIA_SITE:
return 1;
return true;
default:
break;
}
return 0;
return false;
}
static inline bool bsc_co_located_pcu(const struct gsm_bts *bts)
{
switch (bts->type) {
case GSM_BTS_TYPE_RBS2000:
return true;
default:
break;
}
return false;
}
static inline const struct osmo_location_area_id *bts_lai(struct gsm_bts *bts)
@ -787,7 +815,7 @@ int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);
#define BTS_STORE_UPTIME_INTERVAL 10 /* in seconds */
void bts_store_uptime(struct gsm_bts *bts);
unsigned long long bts_uptime(const struct gsm_bts *bts);
unsigned long long bts_updowntime(const struct gsm_bts *bts);
#define BTS_STORE_LCHAN_DURATIONS_INTERVAL 1 /* in seconds */
void bts_store_lchan_durations(struct gsm_bts *bts);
@ -814,6 +842,7 @@ void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data);
int gsm_bts_set_system_infos(struct gsm_bts *bts);
int gsm_bts_send_c0_power_red(const struct gsm_bts *bts, const uint8_t red);
int gsm_bts_set_c0_power_red(struct gsm_bts *bts, const uint8_t red);
void gsm_bts_stats_reset(struct gsm_bts *bts);

View File

@ -23,12 +23,19 @@
#include <stdint.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/tlv.h>
struct gsm_bts_sm;
struct gsm_bts;
struct gsm_bts_trx;
struct gsm_gprs_nsvc;
extern const struct tlv_definition ipacc_eie_tlv_def;
int ipacc_parse_supp_features(const struct gsm_bts *bts,
const struct abis_om_fom_hdr *foh,
const uint8_t *data, uint16_t data_len);
struct msgb *nanobts_gen_set_bts_attr(struct gsm_bts *bts);
struct msgb *nanobts_gen_set_nse_attr(struct gsm_bts_sm *bts_sm);
struct msgb *nanobts_gen_set_cell_attr(struct gsm_bts *bts);

View File

@ -1,6 +1,6 @@
/* BTS Site Manager */
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* All Rights Reserved
@ -40,6 +40,7 @@ struct gsm_gprs_nsvc {
/* data read via VTY config file, to configure the BTS
* via OML from BSC */
int id;
bool enabled;
uint16_t nsvci;
uint16_t local_port; /* on the BTS */
struct osmo_sockaddr remote;

View File

@ -43,7 +43,6 @@ struct gsm_bts_trx {
struct e1inp_sign_link *oml_link;
struct gsm_abis_mo mo;
struct tlv_parsed nm_attr;
struct gsm_bts_bb_trx bb_transc;
uint16_t arfcn;

View File

@ -17,6 +17,10 @@ enum rate_pref {
RATE_PREF_FR,
};
int match_codec_pref_data(struct channel_mode_and_rate *ch_mode_rate,
const struct gsm0808_channel_type *ct,
const bool full_rate);
int match_codec_pref(struct channel_mode_and_rate *ch_mode_rate,
const struct gsm0808_channel_type *ct,
const struct gsm0808_speech_codec_list *scl,

View File

@ -1,6 +1,7 @@
#pragma once
#include <osmocom/ctrl/control_cmd.h>
#include <osmocom/bsc/gsm_data.h>
struct gsm_network;
struct gsm_bts;
@ -11,8 +12,14 @@ struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net, uint16_t port);
/* Used internally in different ctrl source code files: */
int bsc_bts_ctrl_cmds_install(void);
int bsc_bts_trx_ctrl_cmds_install(void);
int bsc_bts_trx_ts_ctrl_cmds_install(void);
int bsc_bts_trx_ts_lchan_ctrl_cmds_install(void);
void ctrl_generate_bts_location_state_trap(struct gsm_bts *bts, struct bsc_msc_data *msc);
void osmo_bsc_send_trap(struct ctrl_cmd *cmd, struct bsc_msc_data *msc_data);
char *lchan_dump_full_ctrl(const void *t, struct gsm_lchan *lchan);
char *ts_lchan_dump_full_ctrl(const void *t, struct gsm_bts_trx_ts *ts);
char *trx_lchan_dump_full_ctrl(const void *t, struct gsm_bts_trx *trx);
char *bts_lchan_dump_full_ctrl(const void *t, struct gsm_bts *bts);
enum bsc_ctrl_node {

View File

@ -0,0 +1,11 @@
#pragma once
#include <stdbool.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
struct gsm0808_channel_type;
struct channel_mode_and_rate;
int match_data_rate_pref(struct channel_mode_and_rate *ch_mode_rate,
const struct gsm0808_channel_type *ct,
const bool full_rate);

View File

@ -28,6 +28,7 @@ enum {
DAS,
DCBS,
DLCS,
DASCI,
DRESET,
DLOOP,
Debug_LastEntry,

View File

@ -2,6 +2,7 @@
#include <stdint.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/bitvec.h>
enum handover_scope;
@ -18,7 +19,7 @@ struct gsm_subscriber_connection;
void gsm_net_update_ctype(struct gsm_network *network);
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *network, uint8_t ra);
int get_reason_by_chreq(uint8_t ra, int neci);
int gsm48_send_rr_release(struct gsm_lchan *lchan);
int gsm48_send_rr_release(struct gsm_lchan *lchan, bool ui);
int send_siemens_mrpci(struct gsm_lchan *lchan,
uint8_t *classmark2_lv);
int gsm48_send_rr_classmark_enquiry(struct gsm_lchan *lchan);
@ -33,7 +34,11 @@ int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan,
int gsm48_send_rr_app_info(struct gsm_lchan *lchan, uint8_t apdu_id, uint8_t apdu_flags,
const uint8_t *apdu_data, ssize_t apdu_data_len);
int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t mode);
int gsm48_send_uplink_release(struct gsm_lchan *lchan, uint8_t cause);
int gsm48_send_uplink_busy(struct gsm_lchan *lchan);
int gsm48_send_uplink_free(struct gsm_lchan *lchan, uint8_t acc_bit, uint8_t *uic);
int gsm48_rx_rr_modif_ack(struct msgb *msg);
int neigh_list_get_arfcn(struct gsm_bts *bts, const struct bitvec *nbv, unsigned int idx);
int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value);

View File

@ -13,3 +13,4 @@ void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct ms
void bsc_cm_update(struct gsm_subscriber_connection *conn,
const uint8_t *cm2, uint8_t cm2_len,
const uint8_t *cm3, uint8_t cm3_len);
bool bsc_chan_ind_requires_rtp_stream(enum gsm0808_chan_indicator ch_indctr);

View File

@ -19,6 +19,8 @@
#include <osmocom/core/fsm.h>
#include <osmocom/core/tdef.h>
#include <osmocom/core/time_cc.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/linuxrbtree.h>
#include <osmocom/crypt/auth.h>
@ -51,6 +53,9 @@
* with delta = time between expiration of T3124 and receiving HANDOVER FAILURE by the serving BSC. */
#define GSM_NY1_DEFAULT ((unsigned long)((GSM_T3124_MAX + GSM_NY1_REQ_DELTA)/GSM_T3105_DEFAULT + 1))
#define SCCP_CONN_ID_UNSET 0xFFFFFFFF
#define SCCP_CONN_ID_MAX 0x00FFFFFE
struct mgcp_client_conf;
struct mgcp_client;
struct gsm0808_cell_id;
@ -137,6 +142,7 @@ struct assignment_request {
enum assign_for assign_for;
bool aoip;
bool vgcs;
uint16_t msc_assigned_cic;
@ -163,6 +169,9 @@ struct assignment_request {
/* The TSC to use if 'use' is true, otherwise automatically determine the TSC value to use. Valid range is 0 to
* 7, as described in 3GPP TS 45.002. */
struct optional_val tsc;
/* The "speech / data indicator" from 3GPP TS 48.008 § 3.2.2.11 Channel Type (speech/data/signalling). */
enum gsm0808_chan_indicator ch_indctr;
};
/* State of an ongoing Assignment, while the assignment_fsm is still busy. This serves as state separation to keep the
@ -176,7 +185,7 @@ struct assignment_fsm_data {
*/
struct assignment_request req;
bool requires_voice_stream;
enum gsm0808_chan_indicator ch_indctr;
struct channel_mode_and_rate selected_ch_mode_rate;
struct osmo_fsm_inst *fi;
@ -273,6 +282,21 @@ struct handover {
struct osmo_mgcpc_ep_ci *created_ci_for_msc;
};
struct gsm_subscriber_connection;
struct bscp_sccp_conn_node {
/* entry in (struct bsc_sccp_inst)->connections */
struct rb_node node;
/* Sigtran connection ID:
* if set: Range (0..SCCP_CONN_ID_MAX) (24 bit)
* if unset: SCCP_CONN_ID_UNSET (-1) if unset */
uint32_t conn_id;
/* backpointer where this sccp conn belongs to: */
struct gsm_subscriber_connection *gscon;
};
void bscp_sccp_conn_node_init(struct bscp_sccp_conn_node *sccp_conn, struct gsm_subscriber_connection *gscon);
/* active radio connection of a mobile subscriber */
struct gsm_subscriber_connection {
/* global linked list of subscriber_connections */
@ -320,14 +344,12 @@ struct gsm_subscriber_connection {
/* flag to prevent multiple simultaneous ciphering commands */
int ciphering_handled;
/* SCCP connection associatd with this subscriber_connection */
/* SCCP connection associated with this subscriber_connection */
struct {
/* SCCP connection related */
struct bsc_msc_data *msc;
/* Sigtran connection ID */
int conn_id;
enum subscr_sccp_state state;
struct bscp_sccp_conn_node conn;
} sccp;
/* for audio handling */
@ -376,8 +398,8 @@ struct gsm_subscriber_connection {
/* Lb interface to the SMLC: BSSMAP-LE/SCCP connection associated with this subscriber */
struct {
int conn_id;
enum subscr_sccp_state state;
struct bscp_sccp_conn_node conn;
} lb;
} lcs;
@ -391,6 +413,60 @@ struct gsm_subscriber_connection {
} fast_return;
enum gsm0808_cause clear_cause;
/* VGCS/VBS "call controling" connection */
struct {
/* Features supported by MSC/BSC */
bool ff_present;
struct gsm0808_vgcs_feature_flags ff;
/* Group Call Reference IE */
struct gsm0808_group_callref gc_ie;
enum gsm0808_service_flag sf;
uint32_t call_ref;
/* Call (BSC) FSM */
struct osmo_fsm_inst *fi;
/* Current talker */
struct gsm_subscriber_connection *talker;
/* L3 info of link establihment (Talker established) */
struct llist_head l3_queue;
/* Flag and cause (Talker released) */
bool talker_rel;
uint8_t talker_cause;
/* Flag that states acknowledgement of the talker by MSC */
bool msc_ack;
/* List of VGCS/VBS "resource controling" connections */
struct llist_head chan_list;
} vgcs_call;
/* VGCS/VBS "resource controling" connection */
struct {
/* List entry of chan_list of "call controling" connection */
struct llist_head list;
/* Group Call Reference IE */
struct gsm0808_group_callref gc_ie;
enum gsm0808_service_flag sf;
uint32_t call_ref;
/* Channel type IE */
struct gsm0808_channel_type ct;
/* Channel mode and rate */
struct channel_mode_and_rate ch_mode_rate;
/* Cell Identifier IE */
struct gsm0808_cell_id ci;
char ci_str[16];
/* Assignment Requirements IE */
enum gsm0808_assignment_requirement ar;
/* Call Identifier IE */
uint32_t call_id;
/* Pointer to VGCS/VBS "call controling" gsconn */
struct gsm_subscriber_connection *call;
/* Cell (BTS) FSM */
struct osmo_fsm_inst *fi;
/* lchan to be assigned */
struct gsm_lchan *new_lchan;
/* MGW peer */
char msc_rtp_addr[INET6_ADDRSTRLEN];
uint16_t msc_rtp_port;
} vgcs_chan;
};
@ -450,9 +526,9 @@ struct gsm_abis_mo {
struct abis_om_obj_inst obj_inst;
const char *name;
struct gsm_nm_state nm_state;
struct tlv_parsed *nm_attr;
struct gsm_bts *bts;
struct osmo_fsm_inst *fi;
bool sw_act_rep_received;
bool opstart_sent;
bool adm_unlock_sent;
bool get_attr_sent;
@ -462,6 +538,12 @@ struct gsm_abis_mo {
bool rsl_connect_sent;
bool rsl_connect_ack_received;
bool force_rf_lock;
/* vendor specific fields below */
union {
struct {
uint8_t obj_version;
} ipaccess;
};
};
/* Ericsson OM2000 Managed Object */
@ -495,9 +577,9 @@ struct om2k_mo {
*
* These macros convert from n to the other representations:
*/
#define ALG_A5_NR_TO_RSL(A5_N) ((A5_N) >= 0 ? (A5_N)+1 : 0)
#define ALG_A5_NR_TO_RSL(A5_N) ((int)(A5_N) >= 0 ? (A5_N)+1 : 0)
#define ALG_A5_NR_TO_BSSAP(A5_N) ALG_A5_NR_TO_RSL(A5_N)
#define ALG_A5_NR_TO_PERM_ALG_BITS(A5_N) ((A5_N) >= 0 ? 1<<(A5_N) : 0)
#define ALG_A5_NR_TO_PERM_ALG_BITS(A5_N) ((int)(A5_N) >= 0 ? 1<<(A5_N) : 0)
/* Up to 16 SI2quater are multiplexed; each fits 3 EARFCNS, so the practical maximum is 3*16.
* The real maximum that fits in a total of 16 SI2quater rest octets also depends on the bits left by other SI2quater
@ -592,7 +674,6 @@ struct gsm_bts_trx_ts {
bool is_rsl_ready;
struct gsm_abis_mo mo;
struct tlv_parsed nm_attr;
uint8_t nm_chan_comb;
int tsc; /* -1 == use BTS TSC */
@ -806,10 +887,7 @@ struct gsm_bts *gsm_bts_by_cell_id(const struct gsm_network *net,
extern const struct value_string gsm_chreq_descs[];
extern const struct value_string gsm_pchant_names[];
extern const struct value_string gsm_pchant_descs[];
extern const struct value_string gsm_pchan_ids[];
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
static inline const char *gsm_pchan_id(enum gsm_phys_chan_config c)
{ return get_value_string(gsm_pchan_ids, c); }
enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);
@ -819,6 +897,8 @@ void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3);
struct gsm_abis_mo *gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
const struct abis_om_obj_inst *obj_inst);
struct gsm_nm_state *
gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
const struct abis_om_obj_inst *obj_inst);
@ -863,6 +943,19 @@ struct all_allocated {
struct osmo_time_cc static_tch;
};
struct bsc_sccp_inst {
struct osmo_sccp_instance *sccp; /* backpointer */
/* rbtree root of 'struct bscp_sccp_conn_node' in this instance, ordered by conn_id */
struct rb_root connections;
uint32_t next_id; /* next id to allocate */
};
struct bsc_sccp_inst *bsc_sccp_inst_alloc(void *ctx);
uint32_t bsc_sccp_inst_next_conn_id(struct bsc_sccp_inst *bsc_sccp);
int bsc_sccp_inst_register_gscon(struct bsc_sccp_inst *bsc_sccp, struct bscp_sccp_conn_node *sccp_conn);
void bsc_sccp_inst_unregister_gscon(struct bsc_sccp_inst *bsc_sccp, struct bscp_sccp_conn_node *sccp_conn);
struct gsm_subscriber_connection *bsc_sccp_inst_get_gscon_by_conn_id(const struct bsc_sccp_inst *bsc_sccp, uint32_t conn_id);
struct gsm_network {
struct osmo_plmn_id plmn;
@ -899,10 +992,10 @@ struct gsm_network {
/* msc configuration */
struct llist_head mscs;
uint8_t mscs_round_robin_next_nr;
unsigned int mscs_round_robin_next_nr;
/* Emergency calls potentially select a different set of MSCs, so to not mess up the normal round-robin
* behavior, emergency calls need a separate round-robin counter. */
uint8_t mscs_round_robin_next_emerg_nr;
unsigned int mscs_round_robin_next_emerg_nr;
/* rf ctl related bits */
int mid_call_timeout;
@ -928,13 +1021,8 @@ struct gsm_network {
* OsmoMSC, this should be tied to the location area code (LAC). */
struct gsm_tz tz;
/* List of all struct bsc_subscr used in libbsc. This llist_head is
* allocated so that the llist_head pointer itself can serve as a
* talloc context (useful to not have to pass the entire gsm_network
* struct to the bsc_subscr_* API, and for bsc_susbscr unit tests to
* not require gsm_data.h). In an MSC-without-BSC environment, this
* pointer is NULL to indicate absence of a bsc_subscribers list. */
struct llist_head *bsc_subscribers;
/* Keeps track of struct bsc_subcr. */
struct bsc_subscr_store *bsc_subscribers;
/* Timer for periodic channel load measurements to maintain each BTS's T3122. */
struct osmo_timer_list t3122_chan_load_timer;
@ -977,6 +1065,11 @@ struct gsm_network {
struct chan_counts chan_counts;
struct all_allocated all_allocated;
/* PCU socket state */
char *pcu_sock_path;
unsigned int pcu_sock_wqueue_len_max;
struct pcu_sock_state *pcu_state;
};
struct gsm_audio_support {
@ -984,6 +1077,8 @@ struct gsm_audio_support {
ver : 7;
};
int gsm_audio_support_cmp(const struct gsm_audio_support *a, const struct gsm_audio_support *b);
extern void talloc_ctx_init(void *ctx_root);
enum gsm_bts_type parse_btstype(const char *arg);
@ -1020,8 +1115,6 @@ enum gsm_phys_chan_config gsm_pchan_by_lchan_type(enum gsm_chan_t type);
enum gsm48_rr_cause bsc_gsm48_rr_cause_from_gsm0808_cause(enum gsm0808_cause c);
enum gsm48_rr_cause bsc_gsm48_rr_cause_from_rsl_cause(uint8_t c);
int bsc_sccp_inst_next_conn_id(struct osmo_sccp_instance *sccp);
/* Interference Measurement Parameters */
struct gsm_interf_meas_params {
/* Intave: Interference Averaging period (see 3GPP TS 45.008, table A.1) */

View File

@ -55,8 +55,6 @@ struct handover_rr_detect_data {
const uint8_t *access_delay;
};
void handover_fsm_init(void);
int handover_request(struct handover_out_req *req);
void handover_start(struct handover_out_req *req);
void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn,

View File

@ -8,6 +8,7 @@
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/protocol/gsm_08_58.h>
#include <osmocom/gsm/gsm23003.h>
#include <osmocom/bsc/meas_rep.h>
@ -44,24 +45,16 @@ enum channel_rate {
enum channel_rate chan_t_to_chan_rate(enum gsm_chan_t chan_t);
enum lchan_csd_mode {
LCHAN_CSD_M_NT,
LCHAN_CSD_M_T_1200_75,
LCHAN_CSD_M_T_600,
LCHAN_CSD_M_T_1200,
LCHAN_CSD_M_T_2400,
LCHAN_CSD_M_T_9600,
LCHAN_CSD_M_T_14400,
LCHAN_CSD_M_T_29000,
LCHAN_CSD_M_T_32000,
};
struct channel_mode_and_rate {
enum gsm48_chan_mode chan_mode;
enum channel_rate chan_rate;
uint16_t s15_s0;
/* only used for GSM48_CMODE_DATA_* */
enum lchan_csd_mode csd_mode;
bool data_transparent;
union {
enum rsl_cmod_csd_t t;
enum rsl_cmod_csd_nt nt;
} data_rate;
};
/* Channel Request reason */
@ -108,10 +101,18 @@ enum lchan_activate_for {
ACTIVATE_FOR_MS_CHANNEL_REQUEST,
ACTIVATE_FOR_ASSIGNMENT,
ACTIVATE_FOR_HANDOVER,
ACTIVATE_FOR_VGCS_CHANNEL,
ACTIVATE_FOR_VTY,
ACTIVATE_FOR_MODE_MODIFY_RTP,
};
enum lchan_type_for {
LCHAN_TYPE_FOR_NORMAL = 0,
LCHAN_TYPE_FOR_VAMOS,
LCHAN_TYPE_FOR_VGCS,
LCHAN_TYPE_FOR_VBS,
};
extern const struct value_string lchan_activate_mode_names[];
static inline const char *lchan_activate_mode_name(enum lchan_activate_for activ_for)
{ return get_value_string(lchan_activate_mode_names, activ_for); }
@ -129,7 +130,7 @@ struct lchan_activate_info {
struct gsm_subscriber_connection *for_conn;
struct channel_mode_and_rate ch_mode_rate;
struct gsm_encr encr;
bool requires_voice_stream;
enum gsm0808_chan_indicator ch_indctr;
bool wait_before_switching_rtp; /*< true = requires LCHAN_EV_READY_TO_SWITCH_RTP */
uint16_t msc_assigned_cic;
/* During intra-BSC handover, we keep the MGW endpoint intact and just re-route to the new lchan. This
@ -145,7 +146,7 @@ struct lchan_activate_info {
* 7, as described in 3GPP TS 45.002. */
struct optional_val tsc;
bool vamos;
enum lchan_type_for type_for;
/* A copy of bts->imm_ass_time at the time where Channel Activation was requested. A change in the VTY
* configuration has immediate effect on the value, so make sure we don't get mixed up when it gets changed
@ -166,7 +167,7 @@ static inline const char *lchan_modify_for_name(enum lchan_modify_for modify_for
struct lchan_modify_info {
enum lchan_modify_for modify_for;
struct channel_mode_and_rate ch_mode_rate;
bool requires_voice_stream;
enum gsm0808_chan_indicator ch_indctr;
uint16_t msc_assigned_cic;
/* The TSC Set to use if 'use' is true, otherwise automatically determine the TSC Set value to use. Valid range
@ -176,7 +177,7 @@ struct lchan_modify_info {
* 7, as described in 3GPP TS 45.002. */
struct optional_val tsc;
bool vamos;
enum lchan_type_for type_for;
};
/* Measurement pre-processing state */
@ -223,6 +224,7 @@ struct gsm_lchan {
struct channel_mode_and_rate ch_mode_rate;
struct gsm48_multi_rate_conf mr_conf_filtered;
enum gsm0808_chan_indicator ch_indctr;
bool activ_ack; /*< true as soon as RSL Chan Activ Ack is received */
bool immediate_assignment_sent;
/*! This flag ensures that when an lchan activation has succeeded, and we have already
@ -246,6 +248,7 @@ struct gsm_lchan {
struct channel_mode_and_rate ch_mode_rate;
struct gsm48_multi_rate_conf mr_conf_filtered;
enum gsm0808_chan_indicator ch_indctr;
/* Actually used TSC Set. */
int tsc_set;
/* Actually used TSC. */
@ -291,6 +294,7 @@ struct gsm_lchan {
uint16_t conn_id;
uint8_t rtp_payload;
uint8_t rtp_payload2;
uint8_t rtp_csd_fmt;
uint8_t speech_mode;
/* info we need to postpone the AoIP
@ -331,6 +335,7 @@ struct gsm_lchan {
* channel_mode_and_rate. */
struct channel_mode_and_rate current_ch_mode_rate;
struct gsm48_multi_rate_conf current_mr_conf;
enum gsm0808_chan_indicator current_ch_indctr;
/* Circuit-Switched TSC Set in use, or -1 if no specific TSC Set was requested. The valid range is 1-4 as
* described in the spec 3GPP TS 45.002. */

View File

@ -33,6 +33,8 @@ enum lchan_fsm_state {
LCHAN_ST_WAIT_RF_RELEASE_ACK,
LCHAN_ST_WAIT_AFTER_ERROR,
LCHAN_ST_BORKEN,
LCHAN_ST_RECOVER_WAIT_ACTIV_ACK, /*< Attempt to recover from BORKEN: first try to activate the lchan */
LCHAN_ST_RECOVER_WAIT_RF_RELEASE_ACK, /*< Attempt to recover from BORKEN: then try to release it */
};
enum lchan_fsm_event {
@ -56,8 +58,6 @@ enum lchan_fsm_event {
LCHAN_EV_REQUEST_MODE_MODIFY,
};
void lchan_fsm_init(void);
void lchan_fsm_alloc(struct gsm_lchan *lchan);
void lchan_release(struct gsm_lchan *lchan, bool do_rr_release,
bool err, enum gsm48_rr_cause cause_rr,
@ -80,6 +80,8 @@ static inline bool lchan_state_is(const struct gsm_lchan *lchan, uint32_t state)
bool lchan_may_receive_data(struct gsm_lchan *lchan);
bool lchan_is_asci(struct gsm_lchan *lchan);
void lchan_forget_conn(struct gsm_lchan *lchan);
void lchan_fsm_skip_error(struct gsm_lchan *lchan);

View File

@ -5,6 +5,7 @@ enum lchan_select_reason {
SELECT_FOR_MS_CHAN_REQ,
SELECT_FOR_ASSIGNMENT,
SELECT_FOR_HANDOVER,
SELECT_FOR_VGCS,
};
extern const struct value_string lchan_select_reason_names[];

View File

@ -35,9 +35,12 @@ enum meas_feed_msgtype {
};
#define MEAS_FEED_VERSION 1
#define MEAS_FEED_TXQUEUE_MAX_LEN_DEFAULT 100
int meas_feed_cfg_set(const char *dst_host, uint16_t dst_port);
void meas_feed_scenario_set(const char *name);
void meas_feed_txqueue_max_length_set(unsigned int max_length);
void meas_feed_cfg_get(char **host, uint16_t *port);
const char *meas_feed_scenario_get(void);
unsigned int meas_feed_txqueue_max_length_get(void);

View File

@ -1,7 +1,7 @@
/* Header for all NM FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21:
GSM 12.21 Objects' Operational state and availability status behaviour during initialization */
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* All Rights Reserved

View File

@ -1,34 +0,0 @@
/*
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef OPENBSCDEFINES_H
#define OPENBSCDEFINES_H
#ifdef BUILDING_ON_WINDOWS
#ifdef BUILDING_OPENBSC
#define BSC_API __declspec(dllexport)
#else
#define BSC_API __declspec(dllimport)
#endif
#else
#define BSC_API __attribute__((visibility("default")))
#endif
#endif

View File

@ -26,7 +26,6 @@
/* Allocate resources to make a new connection oriented sigtran connection
* (not the connection ittself!) */
enum bsc_con osmo_bsc_sigtran_new_conn(struct gsm_subscriber_connection *conn, struct bsc_msc_data *msc);
struct gsm_subscriber_connection *bsc_conn_by_bsub(struct bsc_subscr *bsub);
/* Open a new connection oriented sigtran connection */
int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg);

View File

@ -150,9 +150,6 @@ void paging_request_stop(struct bsc_msc_data **msc_p, enum bsc_paging_reason *re
struct gsm_bts *bts, struct bsc_subscr *bsub);
void paging_request_cancel(struct bsc_subscr *bsub, enum bsc_paging_reason reasons);
/* update paging load */
void paging_update_buffer_space(struct gsm_bts *bts, uint16_t);
/* pending paging requests */
unsigned int paging_pending_requests_nr(const struct gsm_bts *bts);

View File

@ -1,19 +1,24 @@
#ifndef _PCU_IF_H
#define _PCU_IF_H
#include <osmocom/core/write_queue.h>
#include <osmocom/gsm/l1sap.h>
extern int pcu_direct;
#define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u))
#define BSC_PCU_SOCK_WQUEUE_LEN_DEFAULT 100
struct pcu_sock_state {
struct gsm_network *net;
struct gsm_network *net; /* backpointer to GSM network */
struct osmo_fd listen_bfd; /* fd for listen socket */
struct osmo_fd conn_bfd; /* fd for connection to lcr */
struct llist_head upqueue; /* queue for sending messages */
struct osmo_wqueue upqueue; /* For sending messages; has fd for conn. to PCU */
};
/* Check if BTS has a PCU connection */
bool pcu_connected(const struct gsm_network *net);
/* PCU relevant information has changed; Inform PCU (if connected) */
void pcu_info_update(struct gsm_bts *bts);
@ -21,17 +26,13 @@ void pcu_info_update(struct gsm_bts *bts);
int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn,
uint8_t is_11bit, enum ph_burst_type burst_type);
/* Confirm the sending of an immediate assignment to the pcu */
int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli);
/* Confirm the sending of an immediate assignment to the pcu */
int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli);
/* Confirm the sending of an AGCH or PCH MAC block to the pcu */
int pcu_tx_data_cnf(struct gsm_bts *bts, uint32_t msg_id, uint8_t sapi);
/* Open connection to PCU */
int pcu_sock_init(const char *path, struct gsm_bts *bts);
int pcu_sock_init(struct gsm_network *net);
/* Close connection to PCU */
void pcu_sock_exit(struct gsm_bts *bts);
void pcu_sock_exit(struct gsm_network *net);
#endif /* _PCU_IF_H */

View File

@ -3,20 +3,21 @@
#include <osmocom/gsm/l1sap.h>
#include <arpa/inet.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
#define PCU_IF_VERSION 0x0a
#define PCU_IF_VERSION 0x0c
#define TXT_MAX_LEN 128
/* msg_type */
#define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */
#define PCU_IF_MSG_DATA_CNF 0x01 /* confirm (e.g. transmission on PCH) */
#define PCU_IF_MSG_DATA_IND 0x02 /* receive data from given channel */
#define PCU_IF_MSG_SUSP_REQ 0x03 /* BTS forwards GPRS SUSP REQ to PCU */
#define PCU_IF_MSG_APP_INFO_REQ 0x04 /* BTS asks PCU to transmit APP INFO via PACCH */
#define PCU_IF_MSG_RTS_REQ 0x10 /* ready to send request */
#define PCU_IF_MSG_DATA_CNF_DT 0x11 /* confirm (with direct tlli) */
#define PCU_IF_MSG_DATA_CNF_2 0x11 /* confirm (using message id) */
#define PCU_IF_MSG_RACH_IND 0x22 /* receive RACH */
#define PCU_IF_MSG_INFO_IND 0x32 /* retrieve BTS info */
#define PCU_IF_MSG_E1_CCU_IND 0x33 /* retrieve E1 CCU comm. parameters */
@ -33,17 +34,16 @@
/* sapi */
#define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */
#define PCU_IF_SAPI_AGCH 0x02 /* assignment on AGCH */
#define PCU_IF_SAPI_PCH 0x03 /* paging/assignment on PCH */
#define PCU_IF_SAPI_BCCH 0x04 /* SI on BCCH */
#define PCU_IF_SAPI_PDTCH 0x05 /* packet data/control/ccch block */
#define PCU_IF_SAPI_PRACH 0x06 /* packet random access channel */
#define PCU_IF_SAPI_PTCCH 0x07 /* packet TA control channel */
#define PCU_IF_SAPI_AGCH_DT 0x08 /* assignment on AGCH but with additional TLLI */
#define PCU_IF_SAPI_PCH_2 0x08 /* assignment on PCH (confirmed using message id) */
#define PCU_IF_SAPI_AGCH_2 0x09 /* assignment on AGCH (confirmed using message id) */
/* flags */
#define PCU_IF_FLAG_ACTIVE (1 << 0)/* BTS is active */
#define PCU_IF_FLAG_SYSMO (1 << 1)/* access PDCH of sysmoBTS directly */
#define PCU_IF_FLAG_DIRECT_PHY (1 << 1)/* access PHY directly via dedicated hardware support */
#define PCU_IF_FLAG_CS1 (1 << 16)
#define PCU_IF_FLAG_CS2 (1 << 17)
#define PCU_IF_FLAG_CS3 (1 << 18)
@ -63,6 +63,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
@ -91,19 +102,10 @@ struct gsm_pcu_if_data {
int16_t lqual_cb; /* !< \brief Link quality in centiBel */
} __attribute__ ((packed));
/* data confirmation with direct tlli (instead of raw mac block with tlli) */
struct gsm_pcu_if_data_cnf_dt {
/* data confirmation with message id (instead of raw mac block) */
struct gsm_pcu_if_data_cnf {
uint8_t sapi;
uint32_t tlli;
uint32_t fn;
uint16_t arfcn;
uint8_t trx_nr;
uint8_t ts_nr;
uint8_t block_nr;
int8_t rssi;
uint16_t ber10k; /* !< \brief BER in units of 0.01% */
int16_t ta_offs_qbits; /* !< \brief Burst TA Offset in quarter bits */
int16_t lqual_cb; /* !< \brief Link quality in centiBel */
uint32_t msg_id;
} __attribute__ ((packed));
struct gsm_pcu_if_rts_req {
@ -185,6 +187,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));
/* E1 CCU connection parameters */
@ -269,6 +272,32 @@ struct gsm_pcu_if_neigh_addr_cnf {
} cgi_ps;
} __attribute__ ((packed));
/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via PCH. The struct is sent as a data request
* (data_req) under SAPI PCU_IF_SAPI_PCH_2. */
struct gsm_pcu_if_pch {
/* message id as reference for confirmation */
uint32_t msg_id;
/* IMSI (to derive paging group) */
char imsi[OSMO_IMSI_BUF_SIZE];
/* GSM mac-block (with immediate assignment message) */
uint8_t data[GSM_MACBLOCK_LEN];
/* Set to true in case the receiving end must send a confirmation
* when the MAC block (data) has been sent. */
bool confirm;
} __attribute__((packed));
/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via AGCH. The struct is sent as a data request
* (data_req) under SAPI PCU_IF_SAPI_AGCH_2. */
struct gsm_pcu_if_agch {
/* message id as reference for confirmation */
uint32_t msg_id;
/* GSM mac-block (with immediate assignment message) */
uint8_t data[GSM_MACBLOCK_LEN];
/* Set to true in case the receiving end must send a confirmation
* when the MAC block (data) has been sent. */
bool confirm;
} __attribute__((packed));
struct gsm_pcu_if {
/* context based information */
uint8_t msg_type; /* message type */
@ -277,8 +306,7 @@ struct gsm_pcu_if {
union {
struct gsm_pcu_if_data data_req;
struct gsm_pcu_if_data data_cnf;
struct gsm_pcu_if_data_cnf_dt data_cnf_dt;
struct gsm_pcu_if_data_cnf data_cnf2;
struct gsm_pcu_if_data data_ind;
struct gsm_pcu_if_susp_req susp_req;
struct gsm_pcu_if_rts_req rts_req;

View File

@ -5,18 +5,24 @@
#include <osmocom/gsm/gsm48_arfcn_range_encode.h>
/* Complete length of SYSTEM INFORMATION 10 (SACCH) */
#define SI10_LENGTH 21
struct gsm_bts;
int band_compatible(const struct gsm_bts *bts, int arfcn);
int generate_cell_chan_alloc(struct gsm_bts *bts);
int generate_cell_chan_list(uint8_t *chan_list, struct gsm_bts *bts);
int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type);
int gsm_generate_si10(struct gsm48_system_information_type_10 *si10, size_t len,
const struct gsm_subscriber_connection *conn);
size_t si2q_earfcn_count(const struct osmo_earfcn_si2q *e);
unsigned range1024_p(unsigned n);
unsigned range512_q(unsigned m);
int range_encode(enum osmo_gsm48_range r, int *arfcns, int arfcns_used, int *w,
int f0, uint8_t *chan_list);
uint8_t si2q_num(struct gsm_bts *bts);
int bts_earfcn_del(struct gsm_bts *bts, uint16_t earfcn);
int bts_earfcn_add(struct gsm_bts *bts, uint16_t earfcn, uint8_t thresh_hi, uint8_t thresh_lo, uint8_t prio,
uint8_t qrx, uint8_t meas_bw);
int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble);

View File

@ -36,10 +36,18 @@ enum ts_fsm_event {
TS_EV_RSL_DOWN,
TS_EV_LCHAN_REQUESTED,
TS_EV_LCHAN_UNUSED,
/* RSL responses received from the BTS: */
TS_EV_PDCH_ACT_ACK,
TS_EV_PDCH_ACT_NACK,
TS_EV_PDCH_DEACT_ACK,
TS_EV_PDCH_DEACT_NACK,
TS_EV_PDCH_ACT_NACK,
TS_EV_PDCH_DEACT_ACK,
TS_EV_PDCH_DEACT_NACK,
/* BSC co-located PCU disconnects from PCU socket, deactivate PDCH */
TS_EV_PDCH_DEACT,
/* BSC co-located PCU (re)connects to PCU socket, activate PDCH */
TS_EV_PDCH_ACT,
};
void ts_fsm_alloc(struct gsm_bts_trx_ts *ts);
@ -52,3 +60,6 @@ bool ts_is_pchan_switching(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config
bool ts_usable_as_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan, bool allow_pchan_switch);
void ts_set_pchan_is(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pchan_is);
void ts_pdch_act(struct gsm_bts_trx_ts *ts);
void ts_pdch_deact(struct gsm_bts_trx_ts *ts);

View File

@ -0,0 +1,121 @@
/* Handle a call via VGCS/VBCS (Voice Group/Broadcast Call Service). */
/*
* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
*
* Author: Andreas Eversberg
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/* Events for both VGCS/VBS state machines. */
enum vgcs_fsm_event {
/* The BSC sets up a VGCS/VBS call. */
VGCS_EV_SETUP,
/* The BSC wants to assign a VGCS/VBS channel. */
VGCS_EV_ASSIGN_REQ,
/* The BTS detects a talker on a channel. */
VGCS_EV_TALKER_DET,
/* The BTS detects a listener on a channel. */
VGCS_EV_LISTENER_DET,
/* The MSC accepts a talker. */
VGCS_EV_MSC_ACK,
/* The MSC rejects a talker. */
VGCS_EV_MSC_REJECT,
/* The MSC seizes all channels. (blocking for calls) */
VGCS_EV_MSC_SEIZE,
/* The MSC releases all channels. (unblocking for calls) */
VGCS_EV_MSC_RELEASE,
/* The MSC sends message to talker. (E.g. CONNECT) */
VGCS_EV_MSC_DTAP,
/* Channel is now active. Waiting for Talker. */
VGCS_EV_LCHAN_ACTIVE,
/* Channel activation error. */
VGCS_EV_LCHAN_ERROR,
/* MGW connection is now active. Waiting for Talker. */
VGCS_EV_MGW_OK,
/* MGW connection error. */
VGCS_EV_MGW_FAIL,
/* Channel link established. (Talker establised.) */
VGCS_EV_TALKER_EST,
/* Channel link data. (Talker sends data.) */
VGCS_EV_TALKER_DATA,
/* Channel link released. (Talker released.) */
VGCS_EV_TALKER_REL,
/* Channel link failed. (Talker failed.) */
VGCS_EV_TALKER_FAIL,
/* Channel is blocked by BSC. */
VGCS_EV_BLOCK,
/* Channel is rejected by BSC. */
VGCS_EV_REJECT,
/* Channel is unblocked by BSC. */
VGCS_EV_UNBLOCK,
/* The connection will be destroyed. (free VGCS resources) */
VGCS_EV_CLEANUP,
/* The calling subscriber has been assigned to the group channel. */
VGCS_EV_CALLING_ASSIGNED,
};
/* States of the VGCS/VBS call state machine */
enum vgcs_call_fsm_state {
/* Call is not setup. Initial state when instance is created. */
VGCS_CALL_ST_NULL = 0,
/* Call is idle. */
VGCS_CALL_ST_IDLE,
/* Call is busy, due to a talker in this BSC. */
VGCS_CALL_ST_BUSY,
/* Call is blocked, due to a talker in a different BSC. */
VGCS_CALL_ST_BLOCKED,
};
/* States of the VGCS/VBS channel state machine */
enum vgcs_chan_fsm_state {
/* Channel not assigned. Initial state when instance is created. */
VGCS_CHAN_ST_NULL = 0,
/* Wait for establishment of VGCS/VBS channel at BTS. */
VGCS_CHAN_ST_WAIT_EST,
/* Channel active and idle. Channel is marked as uplink busy. */
VGCS_CHAN_ST_ACTIVE_BLOCKED,
/* Channel active and idle. Channel is marked as uplink free. */
VGCS_CHAN_ST_ACTIVE_FREE,
/* Channel active and talker was detected, L2 must be established. */
VGCS_CHAN_ST_ACTIVE_INIT,
/* Channel active and talker established L2. */
VGCS_CHAN_ST_ACTIVE_EST,
/* Channel active and wait for talker to release L2. */
VGCS_CHAN_ST_ACTIVE_REL,
};
int vgcs_vbs_chan_start(struct gsm_subscriber_connection *conn, struct msgb *msg);
int vgcs_vbs_call_start(struct gsm_subscriber_connection *conn, struct msgb *msg);
int bssmap_handle_ass_req_ct_speech(struct gsm_subscriber_connection *conn, struct gsm_bts *bts,
struct tlv_parsed *tp, struct gsm0808_channel_type *ct,
struct assignment_request *req, uint8_t *cause);
void bsc_tx_setup_ack(struct gsm_subscriber_connection *conn, struct gsm0808_vgcs_feature_flags *ff);
void bsc_tx_setup_refuse(struct gsm_subscriber_connection *conn, uint8_t cause);
void bsc_tx_vgcs_vbs_assignment_result(struct gsm_subscriber_connection *conn, struct gsm0808_channel_type *ct,
struct gsm0808_cell_id *ci, uint32_t call_id);
void bsc_tx_vgcs_vbs_assignment_fail(struct gsm_subscriber_connection *conn, uint8_t cause);
void bsc_tx_uplink_req(struct gsm_subscriber_connection *conn);
void bsc_tx_uplink_req_conf(struct gsm_subscriber_connection *conn, struct gsm0808_cell_id *ci, uint8_t *l3_info,
uint8_t length);
void bsc_tx_uplink_app_data(struct gsm_subscriber_connection *conn, struct gsm0808_cell_id *ci, uint8_t *l3_info,
uint8_t length);
void bsc_tx_uplink_release_ind(struct gsm_subscriber_connection *conn, uint8_t cause);
struct gsm_lchan *vgcs_vbs_find_lchan(struct gsm_bts *bts, struct gsm0808_group_callref *gc);

View File

@ -51,6 +51,7 @@ struct gsm_network *gsmnet_from_vty(struct vty *vty);
int bts_vty_init(void);
void bts_dump_vty(struct vty *vty, struct gsm_bts *bts);
void bts_dump_vty_oml_link_state(struct vty *vty, struct gsm_bts *bts);
void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx, bool print_rsl, bool show_connected);
void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts);
void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan);

View File

@ -15,7 +15,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>
app_configs = {
# TODO: doc/examples/osmo-bsc/{ericsson,nokia,siemens}
"osmo-bsc": ["doc/examples/osmo-bsc/osmo-bsc.cfg",
"doc/examples/osmo-bsc/osmo-bsc-minimal.cfg",
"doc/examples/osmo-bsc/osmo-bsc-4trx.cfg",
"doc/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg"]
}

View File

@ -13,12 +13,6 @@ AM_CFLAGS = \
$(COVERAGE_CFLAGS) \
$(NULL)
AM_LDFLAGS = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(COVERAGE_LDFLAGS) \
$(NULL)
SUBDIRS = \
osmo-bsc \
utils \

View File

@ -46,6 +46,8 @@ libbsc_la_SOURCES = \
bts.c \
bts_trx.c \
bts_trx_ctrl.c \
bts_trx_ts_ctrl.c \
bts_trx_ts_lchan_ctrl.c \
bts_ericsson_rbs2000.c \
bts_init.c \
bts_ipaccess_nanobts.c \
@ -62,6 +64,7 @@ libbsc_la_SOURCES = \
chan_alloc.c \
chan_counts.c \
codec_pref.c \
data_rate_pref.c \
e1_config.c \
gsm_04_08_rr.c \
gsm_data.c \
@ -72,6 +75,7 @@ libbsc_la_SOURCES = \
handover_fsm.c \
handover_logic.c \
handover_vty.c \
vgcs_fsm.c \
lb.c \
lchan.c \
lchan_fsm.c \

View File

@ -42,7 +42,7 @@ static void a_reset_tx_reset_ack(void *data)
static void a_reset_link_up(void *data)
{
struct bsc_msc_data *msc = data;
LOGP(DMSC, LOGL_NOTICE, "(msc%d) BSSMAP assocation is up\n", msc->nr);
LOGP(DMSC, LOGL_NOTICE, "(msc%d) BSSMAP association is up\n", msc->nr);
osmo_stat_item_inc(osmo_stat_item_group_get_item(msc->msc_statg, MSC_STAT_MSC_LINKS_ACTIVE), 1);
osmo_stat_item_inc(osmo_stat_item_group_get_item(msc->network->bsc_statg, BSC_STAT_NUM_MSC_CONNECTED), 1);
osmo_signal_dispatch(SS_MSC, S_MSC_CONNECTED, msc);
@ -51,7 +51,7 @@ static void a_reset_link_up(void *data)
static void a_reset_link_lost(void *data)
{
struct bsc_msc_data *msc = data;
LOGP(DMSC, LOGL_NOTICE, "(msc%d) BSSMAP assocation is down\n", msc->nr);
LOGP(DMSC, LOGL_NOTICE, "(msc%d) BSSMAP association is down\n", msc->nr);
osmo_stat_item_dec(osmo_stat_item_group_get_item(msc->msc_statg, MSC_STAT_MSC_LINKS_ACTIVE), 1);
osmo_stat_item_dec(osmo_stat_item_group_get_item(msc->network->bsc_statg, BSC_STAT_NUM_MSC_CONNECTED), 1);
osmo_signal_dispatch(SS_MSC, S_MSC_LOST, msc);

View File

@ -52,11 +52,15 @@
#include <osmocom/bsc/nm_common_fsm.h>
#include <osmocom/gsm/bts_features.h>
#include <osmocom/bsc/ipaccess.h>
#include <osmocom/bsc/bts_ipaccess_nanobts_omlattr.h>
#define OM_ALLOC_SIZE 1024
#define OM_HEADROOM_SIZE 128
#define IPACC_SEGMENT_SIZE 245
/* max number of SW Description IEs we can parse */
#define SW_DESCR_MAX 5
#define LOGPMO(mo, ss, lvl, fmt, args ...) \
LOGP(ss, lvl, "OC=%s(%02x) INST=(%02x,%02x,%02x): " fmt, \
get_value_string(abis_nm_obj_class_names, (mo)->obj_class), \
@ -560,6 +564,45 @@ static inline const uint8_t *parse_attr_resp_info_unreported(const struct abis_o
return ari + num_unreported + 1; /* we have to account for 1st byte with number of unreported attributes */
}
/* Parse Attribute Response Info content for 3GPP TS 52.021 §9.4.30 Manufacturer Id */
static void parse_osmo_bts_features(struct gsm_bts *bts,
const uint8_t *data, uint16_t data_len)
{
/* log potential BTS feature vector overflow */
if (data_len > sizeof(bts->_features_data)) {
LOGPMO(&bts->mo, DNM, LOGL_NOTICE,
"Get Attributes Response: feature vector is truncated "
"(from %u to %zu bytes)\n", data_len, sizeof(bts->_features_data));
data_len = sizeof(bts->_features_data);
}
/* check that max. expected BTS attribute is above given feature vector length */
if (data_len > OSMO_BYTES_FOR_BITS(_NUM_BTS_FEAT)) {
LOGPMO(&bts->mo, DNM, LOGL_NOTICE,
"Get Attributes Response: reported unexpectedly long (%u bytes) "
"feature vector - most likely it was compiled against newer BSC headers. "
"Consider upgrading your BSC to later version.\n", data_len);
}
memcpy(bts->_features_data, data, data_len);
bts->features_known = true;
/* Log each BTS feature in the reported vector */
for (unsigned int i = 0; i < data_len * 8; i++) {
if (!osmo_bts_has_feature(&bts->features, i))
continue;
if (i >= _NUM_BTS_FEAT) {
LOGPMO(&bts->mo, DNM, LOGL_NOTICE,
"Get Attributes Response: unknown feature 0x%02x is supported\n", i);
} else {
LOGPMO(&bts->mo, DNM, LOGL_NOTICE,
"Get Attributes Response: feature '%s' is supported\n",
osmo_bts_features_name(i));
}
}
}
/* Handle 3GPP TS 52.021 §8.11.3 Get Attribute Response (with nanoBTS specific attribute formatting) */
static int parse_attr_resp_info_attr(struct gsm_bts *bts, const struct gsm_bts_trx *trx, struct abis_om_fom_hdr *foh, struct tlv_parsed *tp)
{
@ -570,55 +613,22 @@ static int parse_attr_resp_info_attr(struct gsm_bts *bts, const struct gsm_bts_t
uint16_t port;
struct in_addr ia = {0};
char unit_id[40];
struct abis_nm_sw_desc sw_descr[MAX_BTS_ATTR];
/* Parse Attribute Response Info content for 3GPP TS 52.021 §9.4.30 Manufacturer Id */
if (TLVP_PRES_LEN(tp, NM_ATT_MANUF_ID, 2)) {
len = TLVP_LEN(tp, NM_ATT_MANUF_ID);
/* log potential BTS feature vector overflow */
if (len > sizeof(bts->_features_data)) {
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: feature vector is truncated "
"(from %u to %zu bytes)\n", len, sizeof(bts->_features_data));
len = sizeof(bts->_features_data);
switch (bts->type) {
case GSM_BTS_TYPE_OSMOBTS:
if (TLVP_PRES_LEN(tp, NM_ATT_MANUF_ID, 2)) {
parse_osmo_bts_features(bts, TLVP_VAL(tp, NM_ATT_MANUF_ID),
TLVP_LEN(tp, NM_ATT_MANUF_ID));
}
/* check that max. expected BTS attribute is above given feature vector length */
if (len > OSMO_BYTES_FOR_BITS(_NUM_BTS_FEAT)) {
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: reported unexpectedly long (%u bytes) "
"feature vector - most likely it was compiled against newer BSC headers. "
"Consider upgrading your BSC to later version.\n", len);
}
memcpy(bts->_features_data, TLVP_VAL(tp, NM_ATT_MANUF_ID), len);
bts->features_known = true;
/* Log each BTS feature in the reported vector */
for (i = 0; i < len * 8; i++) {
if (!osmo_bts_has_feature(&bts->features, i))
continue;
if (i >= _NUM_BTS_FEAT)
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: unknown feature 0x%02x is"
" supported\n", i);
else
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: feature '%s' is"
" supported\n", osmo_bts_features_name(i));
}
/* Add features from the BTS model: nanobts may support more
* features than it reports, since we extend the enum of
* features for osmo-bts. */
if (bts->type == GSM_BTS_TYPE_NANOBTS) {
for (i = 0; i < _NUM_BTS_FEAT; i++) {
if (osmo_bts_has_feature(&bts->model->features, i) /* intentional check against bts model */
&& !osmo_bts_has_feature(&bts->features, i)) {
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: feature '%s' is"
" assumed to be supported\n", osmo_bts_features_name(i));
osmo_bts_set_feature(&bts->features, i);
}
}
/* fall-through */
case GSM_BTS_TYPE_NANOBTS:
if (TLVP_PRESENT(tp, NM_ATT_IPACC_SUPP_FEATURES)) {
ipacc_parse_supp_features(bts, foh, TLVP_VAL(tp, NM_ATT_IPACC_SUPP_FEATURES),
TLVP_LEN(tp, NM_ATT_IPACC_SUPP_FEATURES));
}
break;
default:
break;
}
/* Parse Attribute Response Info content for 3GPP TS 52.021 §9.4.28 Manufacturer Dependent State */
@ -630,6 +640,7 @@ static int parse_attr_resp_info_attr(struct gsm_bts *bts, const struct gsm_bts_t
/* Parse Attribute Response Info content for 3GPP TS 52.021 §9.4.61 SW Configuration */
if (TLVP_PRESENT(tp, NM_ATT_SW_CONFIG)) {
struct abis_nm_sw_desc sw_descr[SW_DESCR_MAX];
data = TLVP_VAL(tp, NM_ATT_SW_CONFIG);
len = TLVP_LEN(tp, NM_ATT_SW_CONFIG);
/* after parsing manufacturer-specific attributes there's list of replies in form of sw-conf structure: */
@ -741,15 +752,20 @@ static int abis_nm_rx_sw_act_req(struct msgb *mb)
struct tlv_parsed tp;
const uint8_t *sw_config;
int ret, sw_config_len, len;
struct abis_nm_sw_desc sw_descr[MAX_BTS_ATTR];
struct abis_nm_sw_desc sw_descr[SW_DESCR_MAX];
DEBUGPFOH(DNM, foh, "Software Activate Request, ACKing and Activating\n");
if (oh->length < sizeof(*foh)) {
LOGPFOH(DNM, LOGL_ERROR, foh, "Software Activate Request with length too small: %u\n", oh->length);
return -EINVAL;
}
ret = abis_nm_sw_act_req_ack(sign_link->trx->bts, foh->obj_class,
foh->obj_inst.bts_nr,
foh->obj_inst.trx_nr,
foh->obj_inst.ts_nr, 0,
foh->data, oh->length-sizeof(*foh));
foh->data, oh->length - sizeof(*foh));
if (ret != 0) {
LOGPFOH(DNM, LOGL_ERROR, foh, "Sending SW ActReq ACK failed: %d\n", ret);
return ret;
@ -1682,7 +1698,7 @@ int abis_nm_software_load(struct gsm_bts *bts, int trx_nr, const char *fname,
break;
case GSM_BTS_TYPE_NANOBTS:
sw->obj_class = NM_OC_BASEB_TRANSC;
sw->obj_instance[0] = sw->bts->nr;
sw->obj_instance[0] = sw->bts->bts_nr;
sw->obj_instance[1] = sw->trx_nr;
sw->obj_instance[2] = 0xff;
break;
@ -2153,12 +2169,13 @@ int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, uint8_t chan_comb)
}
int abis_nm_sw_act_req_ack(struct gsm_bts *bts, uint8_t obj_class, uint8_t i1,
uint8_t i2, uint8_t i3, int nack, uint8_t *attr, int att_len)
uint8_t i2, uint8_t i3, int nack,
const uint8_t *attr, unsigned int attr_len)
{
struct abis_om_hdr *oh;
struct msgb *msg = nm_msgb_alloc();
uint8_t msgtype = NM_MT_SW_ACT_REQ_ACK;
uint8_t len = att_len;
uint8_t len = attr_len;
if (nack) {
len += 2;
@ -2166,12 +2183,10 @@ int abis_nm_sw_act_req_ack(struct gsm_bts *bts, uint8_t obj_class, uint8_t i1,
}
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
fill_om_fom_hdr(oh, att_len, msgtype, obj_class, i1, i2, i3);
fill_om_fom_hdr(oh, len, msgtype, obj_class, i1, i2, i3);
if (attr) {
uint8_t *ptr = msgb_put(msg, att_len);
memcpy(ptr, attr, att_len);
}
if (attr != NULL && attr_len > 0)
memcpy(msgb_put(msg, attr_len), attr, attr_len);
if (nack)
msgb_tv_put(msg, NM_ATT_NACK_CAUSES, NM_NACK_OBJCLASS_NOTSUPP);
@ -2645,8 +2660,8 @@ struct file_list_entry *fl_dequeue(struct llist_head *queue)
static int bs11_read_swl_file(struct abis_nm_bs11_sw *bs11_sw)
{
struct file_list_entry *fle;
char linebuf[255];
struct llist_head *lh, *lh2;
FILE *swl;
int rc = 0;
@ -2655,10 +2670,8 @@ static int bs11_read_swl_file(struct abis_nm_bs11_sw *bs11_sw)
return -ENODEV;
/* zero the stale file list, if any */
llist_for_each_safe(lh, lh2, &bs11_sw->file_list) {
llist_del(lh);
talloc_free(lh);
}
while ((fle = fl_dequeue(&bs11_sw->file_list)))
talloc_free(fle);
while (fgets(linebuf, sizeof(linebuf), swl)) {
char file_id[12+1];
@ -3093,7 +3106,7 @@ int abis_nm_ipaccess_restart(struct gsm_bts_trx *trx)
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
fill_om_fom_hdr(oh, 0, NM_MT_IPACC_RESTART, NM_OC_BASEB_TRANSC,
trx->bts->nr, trx->nr, 0xff);
trx->bts->bts_nr, trx->nr, 0xff);
return abis_nm_sendmsg_direct(trx->bts, msg);
}

View File

@ -68,20 +68,11 @@ struct osmo_fsm_inst *osmo_fsm_inst_alloc_child_id(struct osmo_fsm *fsm,
{
struct osmo_fsm_inst *fi;
fi = osmo_fsm_inst_alloc(fsm, parent, NULL, parent->log_level,
id ? id : parent->id);
if (!fi) {
/* indicate immediate termination to caller */
osmo_fsm_inst_dispatch(parent, parent_term_event, NULL);
fi = osmo_fsm_inst_alloc_child(fsm, parent, parent_term_event);
if (!fi)
return NULL;
}
LOGPFSM(fi, "is child of %s\n", osmo_fsm_inst_name(parent));
fi->proc.parent = parent;
fi->proc.parent_term_event = parent_term_event;
llist_add(&fi->proc.child, &parent->proc.children);
if (id)
osmo_fsm_inst_update_id_f_sanitize(fi, '-', id);
return fi;
}

View File

@ -44,6 +44,7 @@
#include <osmocom/gsm/rsl.h>
#include <osmocom/core/talloc.h>
#include <osmocom/bsc/pcu_if.h>
#include <osmocom/bsc/pcuif_proto.h>
#include <osmocom/bsc/gsm_08_08.h>
#include <osmocom/netif/rtp.h>
#include <osmocom/core/tdef.h>
@ -58,6 +59,7 @@
#include <osmocom/bsc/power_control.h>
#include <osmocom/bsc/chan_counts.h>
#include <osmocom/bsc/lchan.h>
#include <osmocom/bsc/vgcs_fsm.h>
static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
struct gsm_meas_rep *resp)
@ -405,12 +407,11 @@ int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan)
static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
struct gsm_lchan *lchan,
const struct channel_mode_and_rate *ch_mode_rate,
bool vamos)
enum lchan_type_for type_for)
{
int rc;
memset(cm, 0, sizeof(*cm));
/* FIXME: what to do with data calls ? */
cm->dtx_dtu = 0;
if (lchan->ts->trx->bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
cm->dtx_dtu |= RSL_CMOD_DTXu;
@ -430,10 +431,34 @@ static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
cm->chan_rt = RSL_CMOD_CRT_SDCCH;
break;
case GSM_LCHAN_TCH_F:
cm->chan_rt = vamos ? RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm : RSL_CMOD_CRT_TCH_Bm;
switch (type_for) {
case LCHAN_TYPE_FOR_VAMOS:
cm->chan_rt = RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm;
break;
case LCHAN_TYPE_FOR_VGCS:
cm->chan_rt = RSL_CMOD_CRT_TCH_GROUP_Bm;
break;
case LCHAN_TYPE_FOR_VBS:
cm->chan_rt = RSL_CMOD_CRT_TCH_BCAST_Bm;
break;
default:
cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
}
break;
case GSM_LCHAN_TCH_H:
cm->chan_rt = vamos ? RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm : RSL_CMOD_CRT_TCH_Lm;
switch (type_for) {
case LCHAN_TYPE_FOR_VAMOS:
cm->chan_rt = RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm;
break;
case LCHAN_TYPE_FOR_VGCS:
cm->chan_rt = RSL_CMOD_CRT_TCH_GROUP_Lm;
break;
case LCHAN_TYPE_FOR_VBS:
cm->chan_rt = RSL_CMOD_CRT_TCH_BCAST_Lm;
break;
default:
cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
}
break;
case GSM_LCHAN_NONE:
case GSM_LCHAN_UNKNOWN:
@ -460,54 +485,13 @@ static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
case GSM48_CMODE_DATA_14k5:
case GSM48_CMODE_DATA_12k0:
case GSM48_CMODE_DATA_6k0:
switch (ch_mode_rate->csd_mode) {
case LCHAN_CSD_M_NT:
/* non-transparent CSD with RLP */
switch (ch_mode_rate->chan_mode) {
case GSM48_CMODE_DATA_14k5:
cm->chan_rate = RSL_CMOD_SP_NT_14k5;
break;
case GSM48_CMODE_DATA_12k0:
cm->chan_rate = RSL_CMOD_SP_NT_12k0;
break;
case GSM48_CMODE_DATA_6k0:
cm->chan_rate = RSL_CMOD_SP_NT_6k0;
break;
default:
LOGP(DRSL, LOGL_ERROR,
"unsupported lchan->tch_mode %u\n",
ch_mode_rate->chan_mode);
return -EINVAL;
}
break;
/* transparent data services below */
case LCHAN_CSD_M_T_1200_75:
cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
break;
case LCHAN_CSD_M_T_600:
cm->chan_rate = RSL_CMOD_CSD_T_600;
break;
case LCHAN_CSD_M_T_1200:
cm->chan_rate = RSL_CMOD_CSD_T_1200;
break;
case LCHAN_CSD_M_T_2400:
cm->chan_rate = RSL_CMOD_CSD_T_2400;
break;
case LCHAN_CSD_M_T_9600:
cm->chan_rate = RSL_CMOD_CSD_T_9600;
break;
case LCHAN_CSD_M_T_14400:
cm->chan_rate = RSL_CMOD_CSD_T_14400;
break;
case LCHAN_CSD_M_T_29000:
cm->chan_rate = RSL_CMOD_CSD_T_29000;
break;
case LCHAN_CSD_M_T_32000:
cm->chan_rate = RSL_CMOD_CSD_T_32000;
break;
default:
LOGP(DRSL, LOGL_ERROR, "unsupported csd_mode %u\n", ch_mode_rate->csd_mode);
return -EINVAL;
case GSM48_CMODE_DATA_3k6:
/* 3GPP TS 48.058 § 9.3.6 Channel Mode octet 6 */
if (ch_mode_rate->data_transparent) {
cm->chan_rate = ch_mode_rate->data_rate.t;
} else {
cm->chan_rate = ch_mode_rate->data_rate.nt;
cm->chan_rate |= 0x40;
}
break;
default:
@ -616,7 +600,7 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
/* PDCH activation is a job for rsl_tx_dyn_ts_pdch_act_deact(); */
OSMO_ASSERT(act_type != RSL_ACT_OSMO_PDCH);
rc = channel_mode_from_lchan(&cm, lchan, &lchan->activate.ch_mode_rate, lchan->activate.info.vamos);
rc = channel_mode_from_lchan(&cm, lchan, &lchan->activate.ch_mode_rate, lchan->activate.info.type_for);
if (rc < 0) {
LOGP(DRSL, LOGL_ERROR,
"%s Cannot find channel mode from lchan type\n",
@ -718,7 +702,7 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
put_top_acch_cap_ie(lchan, &cm, msg);
/* Selecting a specific TSC Set is only applicable to VAMOS mode */
if (lchan->activate.info.vamos && lchan->activate.tsc_set >= 1)
if (lchan->activate.info.type_for == LCHAN_TYPE_FOR_VAMOS && lchan->activate.tsc_set >= 1)
put_osmo_training_sequence_ie(msg, lchan->activate.tsc_set, lchan->activate.tsc);
msg->dst = rsl_chan_link(lchan);
@ -753,7 +737,7 @@ int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
if (chan_nr < 0)
return chan_nr;
rc = channel_mode_from_lchan(&cm, lchan, &lchan->modify.ch_mode_rate, lchan->modify.info.vamos);
rc = channel_mode_from_lchan(&cm, lchan, &lchan->modify.ch_mode_rate, lchan->modify.info.type_for);
if (rc < 0)
return rc;
@ -791,7 +775,8 @@ int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
/* Selecting a specific TSC Set is only applicable to VAMOS mode. Send this Osmocom specific IE only to OsmoBTS
* types. */
if (lchan->modify.info.vamos && lchan->modify.tsc_set >= 1 && bts->model->type == GSM_BTS_TYPE_OSMOBTS)
if (lchan->modify.info.type_for == LCHAN_TYPE_FOR_VAMOS && lchan->modify.tsc_set >= 1 &&
bts->model->type == GSM_BTS_TYPE_OSMOBTS)
put_osmo_training_sequence_ie(msg, lchan->modify.tsc_set, lchan->modify.tsc);
msg->dst = rsl_chan_link(lchan);
@ -912,6 +897,45 @@ int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group,
return abis_rsl_sendmsg(msg);
}
/* Chapter 8.5.10: NOTIFICATION COMMAND */
int rsl_notification_cmd(struct gsm_bts *bts, struct gsm_lchan *lchan, struct gsm0808_group_callref *gc, uint8_t *drx)
{
struct abis_rsl_cchan_hdr *cch;
struct msgb *msg = rsl_msgb_alloc();
struct gsm48_chan_desc cd;
uint8_t sti = (lchan) ? RSL_CMD_INDICATOR_START : RSL_CMD_INDICATOR_STOP;
uint8_t *t;
int rc;
cch = (struct abis_rsl_cchan_hdr *) msgb_put(msg, sizeof(*cch));
rsl_init_cchan_hdr(cch, RSL_MT_NOT_CMD);
cch->chan_nr = RSL_CHAN_PCH_AGCH;
msgb_tlv_put(msg, RSL_IE_CMD_INDICATOR, 1, &sti);
/* Use TLV encoding from TS 08.08. Change different IE type. */
t = msg->tail;
gsm0808_enc_group_callref(msg, gc);
*t = RSL_IE_GROUP_CALL_REF;
if (lchan) {
memset(&cd, 0, sizeof(cd));
rc = gsm48_lchan2chan_desc(&cd, lchan, lchan->activate.tsc, true);
if (rc) {
LOG_LCHAN(lchan, LOGL_ERROR, "Error encoding Channel Number\n");
msgb_free(msg);
return rc;
}
msgb_tlv_put(msg, RSL_IE_CHAN_DESC, sizeof(cd), (const uint8_t *)&cd);
if (drx)
msgb_tlv_put(msg, RSL_IE_NCH_DRX_INFO, 1, drx);
}
msg->dst = bts->c0->rsl_link_primary;
return abis_rsl_sendmsg(msg);
}
int rsl_forward_layer3_info(struct gsm_lchan *lchan, const uint8_t *l3_info, uint8_t l3_info_len)
{
struct msgb *msg;
@ -928,12 +952,20 @@ int rsl_forward_layer3_info(struct gsm_lchan *lchan, const uint8_t *l3_info, uin
}
/* Chapter 8.5.6 */
struct msgb *rsl_imm_assign_cmd_common(struct gsm_bts *bts, uint8_t len, uint8_t *val)
struct msgb *rsl_imm_assign_cmd_common(const struct gsm_bts *bts, uint8_t len, const uint8_t *val)
{
struct msgb *msg = rsl_msgb_alloc();
struct msgb *msg;
struct abis_rsl_dchan_hdr *dh;
uint8_t buf[GSM_MACBLOCK_LEN];
if (len > sizeof(buf)) {
LOGP(DRSL, LOGL_ERROR,
"Cannot send IMMEDIATE ASSIGNMENT message with excessive length (%u)\n", len);
return NULL;
}
msg = rsl_msgb_alloc();
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
dh->chan_nr = RSL_CHAN_PCH_AGCH;
@ -955,7 +987,7 @@ struct msgb *rsl_imm_assign_cmd_common(struct gsm_bts *bts, uint8_t len, uint8_t
}
/* Chapter 8.5.6 */
int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
int rsl_imm_assign_cmd(const struct gsm_bts *bts, uint8_t len, const uint8_t *val)
{
struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
if (!msg)
@ -964,16 +996,23 @@ int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
}
/* Chapter 8.5.6 Immediate Assignment Command (with Ericcson vendor specific RSL extension) */
int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val)
int rsl_ericsson_imm_assign_cmd(const struct gsm_bts *bts, uint32_t msg_id, uint8_t len,
const uint8_t *val, uint8_t pag_grp, bool confirm)
{
struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
if (!msg)
return 1;
/* Append ericsson proprietary paging group IE, this will instruct the BTS to
* send this immediate assignment through PCH instead of AGCH. */
msgb_tv_put(msg, RSL_IE_ERIC_PAGING_GROUP, pag_grp);
/* ericsson can handle a reference at the end of the message which is used in
* the confirm message. The confirm message is only sent if the trailer is present */
msgb_put_u8(msg, RSL_IE_ERIC_MOBILE_ID);
msgb_put_u32(msg, tlli);
if (confirm) {
msgb_put_u8(msg, RSL_IE_ERIC_MOBILE_ID);
msgb_put_u32(msg, msg_id);
}
return abis_rsl_sendmsg(msg);
}
@ -1132,6 +1171,31 @@ int rsl_data_request(struct msgb *msg, uint8_t link_id)
return abis_rsl_sendmsg(msg);
}
/* Send "UNIT DATA REQUEST" message with given L3 Info payload */
/* Chapter 8.3.11 */
int rsl_unit_data_request(struct msgb *msg, uint8_t link_id)
{
int chan_nr;
if (msg->lchan == NULL) {
LOGP(DRSL, LOGL_ERROR, "cannot send UNIT DATA REQUEST to unknown lchan\n");
msgb_free(msg);
return -EINVAL;
}
chan_nr = gsm_lchan2chan_nr(msg->lchan, true);
if (chan_nr < 0) {
msgb_free(msg);
return chan_nr;
}
rsl_rll_push_l3(msg, RSL_MT_UNIT_DATA_REQ, chan_nr, link_id, 1);
msg->dst = rsl_chan_link(msg->lchan);
return abis_rsl_sendmsg(msg);
}
/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
/* Chapter 8.3.1 */
int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
@ -1253,6 +1317,15 @@ static int rsl_rx_conn_fail(struct msgb *msg)
break;
}
/* Report to VGCS FSM */
if (lchan_is_asci(lchan)) {
if (lchan->conn && lchan->conn->vgcs_chan.fi) {
uint8_t cause = GSM0808_CAUSE_RADIO_INTERFACE_FAILURE;
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_FAIL, &cause);
}
return 0;
}
/* If the lchan is associated with a conn, we shall notify the MSC of the RSL Conn Failure, and
* the connection will presumably be torn down and lead to an lchan release. During initial
* Channel Request from the MS, an lchan has no conn yet, so in that case release now. */
@ -1484,6 +1557,66 @@ static int rsl_rx_hando_det(struct msgb *msg)
return 0;
}
/* Chapter 8.4.21: TALKER DETECTION */
static int rsl_rx_talker_det(struct msgb *msg)
{
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
struct tlv_parsed tp;
/* We use this struct, because it has same data. */
struct handover_rr_detect_data d = {
.msg = msg,
};
if (rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg) - sizeof(*dh)) < 0) {
LOG_LCHAN(msg->lchan, LOGL_ERROR, "Failed to parse RSL %s\n",
rsl_or_ipac_msg_name(dh->c.msg_type));
return -EINVAL;
}
if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
d.access_delay = TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY);
if (!msg->lchan->conn || !msg->lchan->conn->vgcs_chan.fi) {
LOGP(DRSL, LOGL_ERROR, "%s TALKER DETECTION but no VGCS channel\n",
gsm_lchan_name(msg->lchan));
return 0;
}
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_DET, &d);
return 0;
}
/* Chapter 8.4.22: LISTENER DETECTION */
static int rsl_rx_listener_det(struct msgb *msg)
{
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
struct tlv_parsed tp;
/* We use this struct, because it has same data. */
struct handover_rr_detect_data d = {
.msg = msg,
};
if (rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg) - sizeof(*dh)) < 0) {
LOG_LCHAN(msg->lchan, LOGL_ERROR, "Failed to parse RSL %s\n",
rsl_or_ipac_msg_name(dh->c.msg_type));
return -EINVAL;
}
if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
d.access_delay = TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY);
if (!msg->lchan->conn || !msg->lchan->conn->vgcs_chan.fi) {
LOGP(DRSL, LOGL_ERROR, "%s LISTENER DETECTION but no VGCS channel\n",
gsm_lchan_name(msg->lchan));
return 0;
}
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_LISTENER_DET, &d);
return 0;
}
static int rsl_rx_ipacc_pdch(struct msgb *msg, char *name, uint32_t ts_ev)
{
struct gsm_bts_trx_ts *ts = msg->lchan->ts;
@ -1532,6 +1665,10 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
switch (rslh->c.msg_type) {
case RSL_MT_CHAN_ACTIV_ACK:
/* Ignore acknowlegement of channel reactivation, if a VGCS/VBS channel was reactivated to assign
* the calling subscriber to it. */
if (msg->lchan->conn && msg->lchan->conn->assignment.req.vgcs)
break;
if (msg_for_osmocom_dyn_ts(msg))
osmo_fsm_inst_dispatch(msg->lchan->ts->fi, TS_EV_PDCH_ACT_ACK, NULL);
else {
@ -1551,6 +1688,12 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
case RSL_MT_HANDO_DET:
rc = rsl_rx_hando_det(msg);
break;
case RSL_MT_TALKER_DET:
rc = rsl_rx_talker_det(msg);
break;
case RSL_MT_LISTENER_DET:
rc = rsl_rx_listener_det(msg);
break;
case RSL_MT_RF_CHAN_REL_ACK:
if (msg_for_osmocom_dyn_ts(msg))
osmo_fsm_inst_dispatch(msg->lchan->ts->fi, TS_EV_PDCH_DEACT_ACK, NULL);
@ -1581,8 +1724,6 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
break;
case RSL_MT_PHY_CONTEXT_CONF:
case RSL_MT_PREPROC_MEAS_RES:
case RSL_MT_TALKER_DET:
case RSL_MT_LISTENER_DET:
case RSL_MT_REMOTE_CODEC_CONF_REP:
case RSL_MT_MR_CODEC_MOD_ACK:
case RSL_MT_MR_CODEC_MOD_NACK:
@ -1834,7 +1975,6 @@ static int rsl_rx_pchan_rqd(struct chan_rqd *rqd)
* requests from the queue to prevent the queue from growing indefinetly. */
static void reduce_rach_dos(struct gsm_bts *bts)
{
int rlt = gsm_bts_get_radio_link_timeout(bts);
time_t timestamp_current = time(NULL);
struct chan_rqd *rqd;
struct chan_rqd *rqd_tmp;
@ -1842,9 +1982,9 @@ static void reduce_rach_dos(struct gsm_bts *bts)
/* Drop all expired channel requests in the list */
llist_for_each_entry_safe(rqd, rqd_tmp, &bts->chan_rqd_queue, entry) {
/* If the channel request is older than the radio link timeout we drop it. This also means that the
/* If the channel request is older than the rach expiry timeout we drop it. This also means that the
* queue is under its overflow limit again. */
if (timestamp_current - rqd->timestamp > rlt) {
if (timestamp_current - rqd->timestamp > bts->rach_expiry_timeout) {
LOG_BTS(bts, DRSL, LOGL_INFO, "CHAN RQD: tossing expired channel request"
"(ra=0x%02x, neci=0x%02x, chreq_reason=0x%02x)\n",
rqd->ref.ra, bts->network->neci, rqd->reason);
@ -2025,12 +2165,12 @@ static bool force_free_lchan_for_emergency(struct chan_rqd *rqd)
return false;
}
/* No free TCH/F or TCH/H was found, we now select one of the busy lchans and initate a release on that lchan.
* This will take a short amount of time. We need to come back and check regulary to see if we managed to
/* No free TCH/F or TCH/H was found, we now select one of the busy lchans and initiate a release on that lchan.
* This will take a short amount of time. We need to come back and check regularly to see if we managed to
* free up another lchan. */
if (!rqd->release_lchan) {
struct gsm_lchan *release_lchan;
/* Pick any busy TCH/F or TCH/H lchan and inititate a channel
/* Pick any busy TCH/F or TCH/H lchan and initiate a channel
* release to make room for the incoming emergency call */
rqd->release_lchan = release_lchan = get_any_lchan(rqd->bts);
if (!release_lchan) {
@ -2325,7 +2465,7 @@ int rsl_tx_imm_assignment(struct gsm_lchan *lchan)
return rc;
}
/* current load on the CCCH */
/* 5.4 and 8.5.2 Rx CCCH Load Ind */
static int rsl_rx_ccch_load(struct msgb *msg)
{
struct e1inp_sign_link *sign_link = msg->dst;
@ -2340,10 +2480,9 @@ static int rsl_rx_ccch_load(struct msgb *msg)
switch (rslh->data[0]) {
case RSL_IE_PAGING_LOAD:
sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == UINT16_MAX) {
if (is_ipa_abisip_bts(sd.bts) && sd.pg_buf_space == UINT16_MAX) {
sd.pg_buf_space = paging_estimate_available_slots(sd.bts, sd.bts->ccch_load_ind_period);
}
paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
break;
case RSL_IE_RACH_LOAD:
@ -2415,7 +2554,7 @@ static int rsl_rx_ericsson_imm_assign_sent(struct msgb *msg)
{
struct e1inp_sign_link *sign_link = msg->dst;
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
uint32_t tlli;
uint32_t msg_id;
LOGP(DRSL, LOGL_INFO, "IMM.ass sent\n");
msgb_pull(msg, sizeof(*dh));
@ -2427,8 +2566,8 @@ static int rsl_rx_ericsson_imm_assign_sent(struct msgb *msg)
LOGP(DRSL, LOGL_ERROR, "unsupported IMM.ass message format! (please fix)\n");
else {
msgb_pull(msg, 1); /* drop previous data to use msg_pull_u32 */
tlli = msgb_pull_u32(msg);
pcu_tx_imm_ass_sent(sign_link->trx->bts, tlli);
msg_id = msgb_pull_u32(msg);
pcu_tx_data_cnf(sign_link->trx->bts, msg_id, PCU_IF_SAPI_PCH_2);
}
return 0;
}
@ -2503,6 +2642,13 @@ static int rsl_rx_rll_err_ind(struct msgb *msg)
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RLL_ERR_IND, &rlm_cause);
/* Report to VGCS FSM */
if (lchan_is_asci(msg->lchan)) {
if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi) {
uint8_t cause = GSM0808_CAUSE_RADIO_INTERFACE_FAILURE;
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_FAIL, &cause);
}
}
return 0;
}
@ -2530,10 +2676,17 @@ static int abis_rsl_rx_rll(struct msgb *msg)
switch (rllh->c.msg_type) {
case RSL_MT_DATA_IND:
LOG_LCHAN(msg->lchan, LOGL_DEBUG, "SAPI=%u DATA INDICATION\n", sapi);
if (msgb_l2len(msg) >
sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
if (msgb_l2len(msg) > (sizeof(*rllh) + 3) &&
rllh->data[0] == RSL_IE_L3_INFO) {
msg->l3h = &rllh->data[3];
/* Data message on a VGCS channel is handled by VGCS FSM only. */
if (lchan_is_asci(msg->lchan)) {
if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi)
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_DATA,
msg);
return 0;
}
return gsm0408_rcvmsg(msg, rllh->link_id);
}
break;
@ -2573,8 +2726,14 @@ static int abis_rsl_rx_rll(struct msgb *msg)
msg->lchan->sapis[sapi] = LCHAN_SAPI_MS;
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RLL_ESTABLISH_IND, msg);
if (msgb_l2len(msg) >
sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
/* Establishment message on a VGCS channel is handled by VGCS FSM only. */
if (lchan_is_asci(msg->lchan)) {
if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi)
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_EST, msg);
break;
}
if (msgb_l2len(msg) > (sizeof(*rllh) + 3) &&
rllh->data[0] == RSL_IE_L3_INFO) {
msg->l3h = &rllh->data[3];
return gsm0408_rcvmsg(msg, rllh->link_id);
@ -2589,6 +2748,14 @@ static int abis_rsl_rx_rll(struct msgb *msg)
case RSL_MT_REL_IND:
/* BTS informs us of having received DISC from MS */
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RLL_REL_IND, &rllh->link_id);
/* Report to VGCS FSM */
if (lchan_is_asci(msg->lchan)) {
if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi) {
uint8_t cause = GSM0808_CAUSE_CALL_CONTROL;
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_REL, &cause);
}
}
break;
case RSL_MT_REL_CONF:
/* BTS informs us of having received UA from MS,
@ -2611,6 +2778,68 @@ static int abis_rsl_rx_rll(struct msgb *msg)
return rc;
}
/* Return an ip.access RTP CSD FMT value (uint8_t) or negative on error. */
int ipacc_rtp_csd_fmt_transp(const struct channel_mode_and_rate *ch_mode_rate,
const enum rsl_ipac_rtp_csd_format_d format_d)
{
uint8_t ret = format_d;
switch (ch_mode_rate->data_rate.t) {
case RSL_CMOD_CSD_T_32k0:
case RSL_CMOD_CSD_T_29k0:
ret |= RSL_IPAC_RTP_CSD_IR_32k << 4;
break;
case RSL_CMOD_CSD_T_14k4:
case RSL_CMOD_CSD_T_9k6:
ret |= RSL_IPAC_RTP_CSD_IR_16k << 4;
break;
case RSL_CMOD_CSD_T_4k8:
case RSL_CMOD_CSD_T_2k4:
case RSL_CMOD_CSD_T_1k2:
case RSL_CMOD_CSD_T_600:
case RSL_CMOD_CSD_T_1200_75:
ret |= RSL_IPAC_RTP_CSD_IR_8k << 4;
break;
default:
return -EINVAL;
}
return ret;
}
/* Return an ip.access RTP CSD FMT value (uint8_t) or negative on error. */
int ipacc_rtp_csd_fmt_non_transp(const struct channel_mode_and_rate *ch_mode_rate,
const enum rsl_ipac_rtp_csd_format_d format_d)
{
uint8_t ret = format_d;
switch (ch_mode_rate->data_rate.nt) {
case RSL_CMOD_CSD_NTA_43k5_14k5:
case RSL_CMOD_CSD_NTA_43k5_29k0:
case RSL_CMOD_CSD_NTA_14k5_43k5:
case RSL_CMOD_CSD_NTA_29k0_43k5:
case RSL_CMOD_CSD_NT_43k5:
ret |= RSL_IPAC_RTP_CSD_IR_64k << 4;
break;
case RSL_CMOD_CSD_NTA_29k0_14k5:
case RSL_CMOD_CSD_NTA_14k5_29k0:
case RSL_CMOD_CSD_NT_28k8:
ret |= RSL_IPAC_RTP_CSD_IR_32k << 4;
break;
case RSL_CMOD_CSD_NT_14k5:
case RSL_CMOD_CSD_NT_12k0:
ret |= RSL_IPAC_RTP_CSD_IR_16k << 4;
break;
case RSL_CMOD_CSD_NT_6k0:
ret |= RSL_IPAC_RTP_CSD_IR_8k << 4;
break;
default:
return -EINVAL;
}
return ret;
}
/* Return an ip.access BTS speech mode value (uint8_t) or negative on error. */
int ipacc_speech_mode(enum gsm48_chan_mode tch_mode, enum gsm_chan_t type)
{
@ -2663,6 +2892,11 @@ void ipacc_speech_mode_set_direction(uint8_t *speech_mode, bool send)
int ipacc_payload_type(enum gsm48_chan_mode tch_mode, enum gsm_chan_t type)
{
switch (gsm48_chan_mode_to_non_vamos(tch_mode)) {
case GSM48_CMODE_DATA_14k5:
case GSM48_CMODE_DATA_12k0:
case GSM48_CMODE_DATA_6k0:
case GSM48_CMODE_DATA_3k6:
return RTP_PT_CSDATA;
case GSM48_CMODE_SPEECH_V1:
switch (type) {
case GSM_LCHAN_TCH_F:
@ -2778,16 +3012,27 @@ int rsl_tx_ipacc_crcx(const struct gsm_lchan *lchan)
dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
dh->chan_nr = chan_nr;
/* 0x1- == receive-only, 0x-1 == EFR codec */
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
if (lchan->current_ch_indctr == GSM0808_CHAN_DATA) {
msgb_tv_put(msg, RSL_IE_IPAC_RTP_CSD_FMT, lchan->abis_ip.rtp_csd_fmt);
LOG_LCHAN(lchan, LOGL_DEBUG,
"Sending IPACC CRCX to BTS: rtp_csd_fmt=0x%02x RTP_PAYLOAD=%d (CSD) osmux_use=%d osmux_loc_cid=%d\n",
lchan->abis_ip.rtp_csd_fmt, lchan->abis_ip.rtp_payload,
lchan->abis_ip.osmux.use, lchan->abis_ip.osmux.local_cid);
} else {
/* 0x1- == receive-only, 0x-1 == EFR codec */
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
LOG_LCHAN(lchan, LOGL_DEBUG,
"Sending IPACC CRCX to BTS: speech_mode=0x%02x RTP_PAYLOAD=%d osmux_use=%d osmux_loc_cid=%d\n",
lchan->abis_ip.speech_mode, lchan->abis_ip.rtp_payload,
lchan->abis_ip.osmux.use, lchan->abis_ip.osmux.local_cid);
}
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
if (lchan->abis_ip.osmux.use)
msgb_tlv_put(msg, RSL_IE_OSMO_OSMUX_CID, 1, &lchan->abis_ip.osmux.local_cid);
LOG_LCHAN(lchan, LOGL_DEBUG,
"Sending IPACC CRCX to BTS: speech_mode=0x%02x RTP_PAYLOAD=%d osmux_use=%d osmux_loc_cid=%d\n",
lchan->abis_ip.speech_mode, lchan->abis_ip.rtp_payload,
lchan->abis_ip.osmux.use, lchan->abis_ip.osmux.local_cid);
msg->dst = rsl_chan_link(lchan);
@ -2821,7 +3066,12 @@ struct msgb *rsl_make_ipacc_mdcx(const struct gsm_lchan *lchan, uint32_t dest_ip
att_ip = (uint32_t *)msgb_put(msg, sizeof(uint32_t));
*att_ip = htonl(dest_ip);
msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, dest_port);
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
if (lchan->current_ch_indctr == GSM0808_CHAN_DATA)
msgb_tv_put(msg, RSL_IE_IPAC_RTP_CSD_FMT, lchan->abis_ip.rtp_csd_fmt);
else
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
if (lchan->abis_ip.rtp_payload2)
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, lchan->abis_ip.rtp_payload2);
@ -2844,14 +3094,24 @@ int rsl_tx_ipacc_mdcx(const struct gsm_lchan *lchan)
if (!msg)
return -EINVAL;
LOG_LCHAN(lchan, LOGL_DEBUG, "Sending IPACC MDCX to BTS:"
" %s:%u rtp_payload=%u rtp_payload2=%u conn_id=%u speech_mode=0x%02x\n",
ip_to_a(lchan->abis_ip.connect_ip),
lchan->abis_ip.connect_port,
lchan->abis_ip.rtp_payload,
lchan->abis_ip.rtp_payload2,
lchan->abis_ip.conn_id,
lchan->abis_ip.speech_mode);
if (lchan->current_ch_indctr == GSM0808_CHAN_DATA)
LOG_LCHAN(lchan, LOGL_DEBUG, "Sending IPACC MDCX to BTS:"
" %s:%u rtp_payload=%u (CSD) rtp_payload2=%u conn_id=%u rtp_csd_fmt=0x%02x\n",
ip_to_a(lchan->abis_ip.connect_ip),
lchan->abis_ip.connect_port,
lchan->abis_ip.rtp_payload,
lchan->abis_ip.rtp_payload2,
lchan->abis_ip.conn_id,
lchan->abis_ip.rtp_csd_fmt);
else
LOG_LCHAN(lchan, LOGL_DEBUG, "Sending IPACC MDCX to BTS:"
" %s:%u rtp_payload=%u rtp_payload2=%u conn_id=%u speech_mode=0x%02x\n",
ip_to_a(lchan->abis_ip.connect_ip),
lchan->abis_ip.connect_port,
lchan->abis_ip.rtp_payload,
lchan->abis_ip.rtp_payload2,
lchan->abis_ip.conn_id,
lchan->abis_ip.speech_mode);
return abis_rsl_sendmsg(msg);
}

View File

@ -42,7 +42,7 @@
static struct osmo_fsm assignment_fsm;
struct gsm_subscriber_connection *assignment_fi_conn(struct osmo_fsm_inst *fi)
static struct gsm_subscriber_connection *assignment_fi_conn(struct osmo_fsm_inst *fi)
{
OSMO_ASSERT(fi);
OSMO_ASSERT(fi->fsm == &assignment_fsm);
@ -54,7 +54,7 @@ static const struct osmo_tdef_state_timeout assignment_fsm_timeouts[32] = {
[ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE] = { .T = 10 },
[ASSIGNMENT_ST_WAIT_RR_ASS_COMPLETE] = { .keep_timer = true },
[ASSIGNMENT_ST_WAIT_LCHAN_ESTABLISHED] = { .keep_timer = true },
[ASSIGNMENT_ST_WAIT_MGW_ENDPOINT_TO_MSC] = { .T = 23042 },
[ASSIGNMENT_ST_WAIT_MGW_ENDPOINT_TO_MSC] = { .T = -9 },
};
/* Transition to a state, using the T timer defined in assignment_fsm_timeouts.
@ -152,7 +152,8 @@ static void on_assignment_failure(struct gsm_subscriber_connection *conn)
if (!resp) {
LOG_ASSIGNMENT(conn, LOGL_ERROR, "Unable to compose BSSMAP Assignment Failure message\n");
} else {
rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_FAILURE));
rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs,
MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_FAILURE));
gscon_sigtran_send(conn, resp);
}
}
@ -164,7 +165,7 @@ static void on_assignment_failure(struct gsm_subscriber_connection *conn)
}
}
static void _gsm0808_ass_compl_extend_osmux(struct msgb *msg, uint8_t cid)
void bssap_extend_osmux(struct msgb *msg, uint8_t cid)
{
OSMO_ASSERT(msg->l3h[1] == msgb_l3len(msg) - 2); /*TL not in len */
msgb_tv_put(msg, GSM0808_IE_OSMO_OSMUX_CID, cid);
@ -185,6 +186,11 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
struct gsm_lchan *lchan = conn->lchan;
struct osmo_fsm_inst *fi = conn->fi;
if (!lchan) {
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE, "Assignment interrupted: primary lchan lost");
return;
}
chosen_channel = gsm0808_chosen_channel(lchan->type, lchan->current_ch_mode_rate.chan_mode);
if (!chosen_channel) {
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
@ -194,21 +200,26 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
return;
}
/* Generate voice related fields */
if (conn->assignment.requires_voice_stream) {
if (gscon_is_aoip(conn) && bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr)) {
if (!osmo_mgcpc_ep_ci_get_crcx_info_to_sockaddr(conn->user_plane.mgw_endpoint_ci_msc,
&addr_local)) {
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
"Unable to compose RTP address of MGW -> MSC");
return;
}
addr_local_p = &addr_local;
}
/* Generate rtp related fields */
switch (conn->assignment.ch_indctr) {
case GSM0808_CHAN_SPEECH:
perm_spch = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode);
if (gscon_is_aoip(conn)) {
if (!osmo_mgcpc_ep_ci_get_crcx_info_to_sockaddr(conn->user_plane.mgw_endpoint_ci_msc,
&addr_local)) {
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
"Unable to compose RTP address of MGW -> MSC");
return;
}
addr_local_p = &addr_local;
}
/* below is AoIP specific logic */
if (!gscon_is_aoip(conn))
break;
if (gscon_is_aoip(conn) && conn->assignment.req.use_osmux) {
if (conn->assignment.req.use_osmux) {
if (!osmo_mgcpc_ep_ci_get_crcx_info_to_osmux_cid(conn->user_plane.mgw_endpoint_ci_msc,
&osmux_cid)) {
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
@ -217,14 +228,28 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
}
}
/* Only AoIP networks include a speech codec (choosen) in the
* assignment complete message. */
if (gscon_is_aoip(conn)) {
/* Extrapolate speech codec from speech mode */
gsm0808_speech_codec_from_chan_type(&sc, perm_spch);
sc.cfg = conn->lchan->current_ch_mode_rate.s15_s0;
sc_ptr = &sc;
}
/* Extrapolate speech codec from speech mode */
gsm0808_speech_codec_from_chan_type(&sc, perm_spch);
sc.cfg = conn->lchan->current_ch_mode_rate.s15_s0;
sc_ptr = &sc;
break;
case GSM0808_CHAN_DATA:
/* below is AoIP specific logic */
if (!gscon_is_aoip(conn))
break;
/* The coding of Speech Codec Element for the CSData Codec Type
* is defined in 3GPP TS 48.008 section 3.2.2.103 */
sc = (struct gsm0808_speech_codec) {
.pi = true, /* PI indicates CSDoIP support */
.pt = false, /* PT indicates CSDoTDM support */
.type = GSM0808_SCT_CSD,
.cfg = 0, /* R2/R3 not set (redundancy not supported) */
};
sc_ptr = &sc;
break;
default:
break;
}
resp = gsm0808_create_ass_compl2(lchan->abis_ip.ass_compl.rr_cause,
@ -238,11 +263,11 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
return;
}
if (gscon_is_aoip(conn) && conn->assignment.requires_voice_stream &&
if (gscon_is_aoip(conn) && bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr) &&
conn->assignment.req.use_osmux)
_gsm0808_ass_compl_extend_osmux(resp, osmux_cid);
bssap_extend_osmux(resp, osmux_cid);
rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_COMPLETE));
rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_COMPLETE));
rc = gscon_sigtran_send(conn, resp);
if (rc) {
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
@ -255,9 +280,11 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
static void assignment_success(struct gsm_subscriber_connection *conn)
{
struct gsm_bts *bts;
bool lchan_changed = (conn->assignment.new_lchan != NULL);
bool lchan_changed = (conn->assignment.new_lchan != NULL && !conn->assignment.req.vgcs);
/* Take on the new lchan. If there only was a Channel Mode Modify, then there is no new lchan to take on. */
/* Take on the new lchan. If there only was a Channel Mode Modify, then there is no new lchan to take on.
* In case of VGCS/VBS channel, the assignment is handled by its state machine. This subscriber connection will
* be released by MSC. */
if (lchan_changed) {
gscon_change_primary_lchan(conn, conn->assignment.new_lchan);
@ -303,7 +330,7 @@ static void assignment_success(struct gsm_subscriber_connection *conn)
osmo_fsm_inst_term(conn->assignment.fi, OSMO_FSM_TERM_REGULAR, 0);
}
static void assignment_fsm_update_id(struct gsm_subscriber_connection *conn)
void assignment_fsm_update_id(struct gsm_subscriber_connection *conn)
{
/* Assignment can do a new channel activation, in which case new_lchan points at the new lchan.
* Or assignment can Channel Mode Modify the already used lchan, in which case new_lchan == NULL. */
@ -313,15 +340,16 @@ static void assignment_fsm_update_id(struct gsm_subscriber_connection *conn)
return;
}
osmo_fsm_inst_update_id_f(conn->assignment.fi, "%s_%u-%u-%u-%s%s%s-%s%u",
conn->fi->id,
new_lchan->ts->trx->bts->nr, new_lchan->ts->trx->nr, new_lchan->ts->nr,
gsm_pchan_id(new_lchan->ts->pchan_on_init),
(new_lchan->ts->pchan_on_init == new_lchan->ts->pchan_is)? "" : "as",
(new_lchan->ts->pchan_on_init == new_lchan->ts->pchan_is)? ""
: gsm_pchan_id(new_lchan->ts->pchan_is),
new_lchan->vamos.is_secondary ? "shadow" : "",
new_lchan->nr - (new_lchan->vamos.is_secondary ? new_lchan->ts->max_primary_lchans : 0));
osmo_fsm_inst_update_id_f_sanitize(conn->assignment.fi, '_', "%s_%u-%u-%u-%s%s%s-%s%u",
conn->fi->id,
new_lchan->ts->trx->bts->nr, new_lchan->ts->trx->nr, new_lchan->ts->nr,
gsm_pchan_name(new_lchan->ts->pchan_on_init),
(new_lchan->ts->pchan_on_init == new_lchan->ts->pchan_is) ? "" : "as",
(new_lchan->ts->pchan_on_init == new_lchan->ts->pchan_is) ?
"" : gsm_pchan_name(new_lchan->ts->pchan_is),
new_lchan->vamos.is_secondary ? "shadow" : "",
new_lchan->nr - (new_lchan->vamos.is_secondary ?
new_lchan->ts->max_primary_lchans : 0));
}
static bool lchan_type_compat_with_mode(enum gsm_chan_t type, const struct channel_mode_and_rate *ch_mode_rate)
@ -364,48 +392,42 @@ static bool lchan_type_compat_with_mode(enum gsm_chan_t type, const struct chann
}
}
void assignment_fsm_init(void)
static __attribute__((constructor)) void assignment_fsm_init(void)
{
OSMO_ASSERT(osmo_fsm_register(&assignment_fsm) == 0);
}
static int check_requires_voice(bool *requires_voice, enum gsm48_chan_mode chan_mode)
static int chan_mode_to_ch_indctr(enum gsm48_chan_mode chan_mode)
{
*requires_voice = false;
switch (gsm48_chan_mode_to_non_vamos(chan_mode)) {
case GSM48_CMODE_DATA_14k5:
case GSM48_CMODE_DATA_12k0:
case GSM48_CMODE_DATA_6k0:
case GSM48_CMODE_DATA_3k6:
return GSM0808_CHAN_DATA;
case GSM48_CMODE_SPEECH_V1:
case GSM48_CMODE_SPEECH_EFR:
case GSM48_CMODE_SPEECH_AMR:
*requires_voice = true;
break;
return GSM0808_CHAN_SPEECH;
case GSM48_CMODE_SIGN:
*requires_voice = false;
break;
return GSM0808_CHAN_SIGN;
default:
return -EINVAL;
}
return 0;
}
/* Check if the incoming assignment requests requires a voice stream or not,
* we will look at the preferred and the alternate channel mode and also make
* sure that both are consistent. */
static int check_requires_voice_stream(struct gsm_subscriber_connection *conn)
/* Check if the incoming assignment request has a channel mode that is
* inconsistent with ch_indctr, e.g. GSM48_CMODE_DATA_14k5 and
* GSM0808_CHAN_SPEECH */
static int check_chan_mode_rate_against_ch_indctr(struct gsm_subscriber_connection *conn)
{
bool requires_voice_pref = false, requires_voice_alt;
struct assignment_request *req = &conn->assignment.req;
struct osmo_fsm_inst *fi = conn->fi;
int i, rc;
/* When the assignment request indicates that there is an alternate
* rate available (e.g. "Full or Half rate channel, Half rate
* preferred..."), then both must be either voice or either signalling,
* a mismatch is not permitted */
int i;
int rc;
for (i = 0; i < req->n_ch_mode_rate; i++) {
rc = check_requires_voice(&requires_voice_alt, req->ch_mode_rate_list[i].chan_mode);
rc = chan_mode_to_ch_indctr(req->ch_mode_rate_list[i].chan_mode);
if (rc < 0) {
assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP,
"Channel mode not supported (prev level %d): %s", i,
@ -413,18 +435,15 @@ static int check_requires_voice_stream(struct gsm_subscriber_connection *conn)
return -EINVAL;
}
if (i==0)
requires_voice_pref = requires_voice_alt;
else if (requires_voice_alt != requires_voice_pref) {
if (rc != req->ch_indctr) {
assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP,
"Requested a mix of Signalling and non-Signalling channel modes: %s != %s",
gsm48_chan_mode_name(req->ch_mode_rate_list[0].chan_mode),
gsm48_chan_mode_name(req->ch_mode_rate_list[i].chan_mode));
"Channel mode %s has ch_indctr %d, channel type has ch_indctr %d",
gsm48_chan_mode_name(req->ch_mode_rate_list[i].chan_mode),
rc, req->ch_indctr);
return -EINVAL;
}
}
conn->assignment.requires_voice_stream = requires_voice_pref;
return 0;
}
@ -470,6 +489,8 @@ static int _reassignment_request(enum assign_for assign_for, struct gsm_lchan *l
.present = (tsc >= 0),
.val = tsc,
},
.ch_indctr = chan_mode_to_ch_indctr(lchan->current_ch_mode_rate.chan_mode),
};
if (to_lchan)
@ -528,10 +549,9 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
assignment_count(CTR_ASSIGNMENT_ATTEMPTED);
/* Check if we need a voice stream. If yes, set the appropriate struct
* members in conn */
if (check_requires_voice_stream(conn) < 0)
if (check_chan_mode_rate_against_ch_indctr(conn) < 0)
return;
conn->assignment.ch_indctr = req->ch_indctr;
if (!req->target_lchan && reuse_existing_lchan(conn)) {
/* The already existing lchan is suitable for this mode */
@ -570,7 +590,10 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
return;
}
if (req->target_lchan) {
if (req->vgcs) {
/* When assigning to a VGCS/VBS, the target lchan is already defined. */
conn->assignment.new_lchan = req->target_lchan;
} else if (req->target_lchan) {
bool matching_mode;
/* The caller already picked a target lchan to assign to. No need to try re-using the current lchan or
@ -644,7 +667,9 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
req->aoip ? "yes" : "no", req->msc_rtp_addr, req->msc_rtp_port,
req->use_osmux ? "yes" : "no");
assignment_fsm_state_chg(ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE);
/* Wait for lchan to become active before send assignment. In case of VGCS/VBS directly send assignment,
* because the channel is already active. */
assignment_fsm_state_chg(req->vgcs ? ASSIGNMENT_ST_WAIT_RR_ASS_COMPLETE : ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE);
}
static void assignment_fsm_wait_lchan_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
@ -656,15 +681,16 @@ static void assignment_fsm_wait_lchan_active_onenter(struct osmo_fsm_inst *fi, u
.for_conn = conn,
.ch_mode_rate = conn->assignment.selected_ch_mode_rate,
.encr = conn->lchan->encr,
.requires_voice_stream = conn->assignment.requires_voice_stream,
.ch_indctr = conn->assignment.ch_indctr,
.msc_assigned_cic = req->msc_assigned_cic,
.re_use_mgw_endpoint_from_lchan = conn->lchan,
.ta = conn->lchan->last_ta,
.ta_known = true,
.tsc_set = req->tsc_set,
.tsc = req->tsc,
.vamos = conn->assignment.new_lchan->vamos.is_secondary,
};
if (conn->assignment.new_lchan->vamos.is_secondary)
activ_info.type_for = LCHAN_TYPE_FOR_VAMOS;
lchan_activate(conn->assignment.new_lchan, &activ_info);
}
@ -772,7 +798,7 @@ static void assignment_fsm_wait_lchan_established(struct osmo_fsm_inst *fi, uint
static void assignment_fsm_post_lchan_established(struct osmo_fsm_inst *fi)
{
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
if (conn->assignment.requires_voice_stream)
if (bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr))
assignment_fsm_state_chg(ASSIGNMENT_ST_WAIT_MGW_ENDPOINT_TO_MSC);
else
assignment_success(conn);
@ -782,7 +808,7 @@ static void assignment_fsm_wait_mgw_endpoint_to_msc_onenter(struct osmo_fsm_inst
{
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
OSMO_ASSERT(conn->assignment.requires_voice_stream);
OSMO_ASSERT(bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr));
LOG_ASSIGNMENT(conn, LOGL_DEBUG,
"Connecting MGW endpoint to the MSC's RTP port: %s:%u\n",
@ -846,7 +872,7 @@ static void assignment_fsm_wait_lchan_modified_onenter(struct osmo_fsm_inst *fi,
struct lchan_modify_info modif_info = {
.modify_for = MODIFY_FOR_ASSIGNMENT,
.ch_mode_rate = conn->assignment.selected_ch_mode_rate,
.requires_voice_stream = conn->assignment.requires_voice_stream,
.ch_indctr = conn->assignment.ch_indctr,
.msc_assigned_cic = req->msc_assigned_cic,
/* keep previous training sequence code. TSC is always present, TSC Set may or may not be an explicit
* value. */
@ -987,7 +1013,7 @@ static int assignment_fsm_timer_cb(struct osmo_fsm_inst *fi)
return 0;
}
void assignment_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
static void assignment_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
assignment_reset(conn);

View File

@ -187,7 +187,7 @@ static int set_net_apply_config(struct ctrl_cmd *cmd, void *data)
struct gsm_bts *bts;
llist_for_each_entry(bts, &net->bts_list, list) {
if (!is_ipaccess_bts(bts))
if (!is_ipa_abisip_bts(bts))
continue;
/*
@ -332,7 +332,7 @@ static int set_net_rf_lock(struct ctrl_cmd *cmd, void *data)
cmd->reply = talloc_asprintf(cmd, "%u", locked);
if (!cmd->reply) {
cmd->reply = "OOM.";
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
@ -367,7 +367,7 @@ static int get_net_rf_states(struct ctrl_cmd *cmd, void *data)
{
cmd->reply = bsc_rf_states_c(cmd);
if (!cmd->reply) {
cmd->reply = "OOM.";
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
return CTRL_CMD_REPLY;
@ -686,7 +686,7 @@ static int sccplite_asp_ctrl_cmd_send(struct osmo_ss7_asp *asp, struct ctrl_cmd
struct msgb *msg;
/* don't attempt to send CTRL on a non-SCCPlite ASP */
if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA)
if (osmo_ss7_asp_get_proto(asp) != OSMO_SS7_ASP_PROT_IPA)
return 0;
msg = ctrl_cmd_make(cmd);
@ -820,6 +820,45 @@ static int set_net_inform_msc(struct ctrl_cmd *cmd, void *data)
return CTRL_CMD_HANDLED;
}
/* Return full information about all logical channels.
* format: show-lchan.full
* result format: New line delimited list of <bts>,<trx>,<ts>,<lchan>,<type>,<connection>,<state>,<last error>,<bs power>,
* <ms power>,<interference dbm>, <interference band>,<channel mode>,<imsi>,<tmsi>,<ipa bound ip>,<ipa bound port>,
* <ipa bound conn id>,<ipa conn ip>,<ipa conn port>,<ipa conn speech mode>
*/
static int get_net_show_lchan_full(struct ctrl_cmd *cmd, void *data)
{
struct gsm_network *net = cmd->node;
int bts_nr;
bool first_bts = true;
char *bts_dump;
cmd->reply = talloc_strdup(cmd, "");
if (!cmd->reply) {
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
bts_dump = bts_lchan_dump_full_ctrl(cmd, gsm_bts_num(net, bts_nr));
if (!bts_dump) {
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
if (!strlen(bts_dump))
continue;
cmd->reply = talloc_asprintf_append(cmd->reply, first_bts ? "%s" : "\n%s", bts_dump);
if (!cmd->reply) {
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
first_bts = false;
}
return CTRL_CMD_REPLY;
}
CTRL_CMD_DEFINE_RO(net_show_lchan_full, "show-lchan full");
static int bsc_base_ctrl_cmds_install(struct gsm_network *net)
{
int rc = 0;
@ -837,8 +876,9 @@ static int bsc_base_ctrl_cmds_install(struct gsm_network *net)
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_msc0_connection_status);
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_notification);
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_inform_msc);
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_show_lchan_full);
rc = ctrl_cmd_install(CTRL_NODE_MSC, &cmd_msc_connection_status);
rc |= ctrl_cmd_install(CTRL_NODE_MSC, &cmd_msc_connection_status);
rc |= osmo_signal_register_handler(SS_L_INPUT, &bts_connection_status_trap_cb, net);
rc |= osmo_signal_register_handler(SS_MSC, &msc_connection_status_trap_cb, net);

View File

@ -6,14 +6,14 @@
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
*/
@ -43,6 +43,7 @@ static int bsc_ctrl_node_lookup(void *data, vector vline, int *node_type,
struct gsm_bts *bts = NULL;
struct gsm_bts_trx *trx = NULL;
struct gsm_bts_trx_ts *ts = NULL;
struct gsm_lchan *lchan = NULL;
struct bsc_msc_data *msc = NULL;
char *token = vector_slot(vline, *i);
long num;
@ -89,6 +90,20 @@ static int bsc_ctrl_node_lookup(void *data, vector vline, int *node_type,
goto err_missing;
*node_data = ts;
*node_type = CTRL_NODE_TS;
} else if (!strcmp(token, "lchan")) {
if (*node_type != CTRL_NODE_TS || !*node_data)
goto err_missing;
ts = *node_data;
(*i)++;
if (!ctrl_parse_get_num(vline, *i, &num))
goto err_index;
if ((num >= 0) && (num < TS_MAX_LCHAN))
lchan = &ts->lchan[num];
if (!lchan)
goto err_missing;
*node_data = lchan;
*node_type = CTRL_NODE_LCHAN;
} else if (!strcmp(token, "msc")) {
if (*node_type != CTRL_NODE_ROOT || !net)
goto err_missing;

View File

@ -204,6 +204,7 @@ static struct gsm_network *bsc_network_init(void *ctx)
net->cbc->client.remote_addr = (struct osmo_sockaddr_str){ .port = CBSP_TCP_PORT, };
net->cbc->client.local_addr = (struct osmo_sockaddr_str){};
net->pcu_sock_wqueue_len_max = BSC_PCU_SOCK_WQUEUE_LEN_DEFAULT;
return net;
err_free_all:

View File

@ -303,7 +303,7 @@ static void rf_check_cb(void *_data)
struct gsm_bts_trx *trx;
/* don't bother to check a booting or missing BTS */
if (!bts->oml_link || !is_ipaccess_bts(bts))
if (!bts->oml_link || !is_ipa_abisip_bts(bts))
continue;
/* Exclude the BTS from the global lock */

View File

@ -21,44 +21,120 @@
*
*/
#include <osmocom/core/utils.h>
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/lb.h>
/* We need an unused SCCP conn_id across all SCCP users. */
int bsc_sccp_inst_next_conn_id(struct osmo_sccp_instance *sccp)
void bscp_sccp_conn_node_init(struct bscp_sccp_conn_node *sccp_conn, struct gsm_subscriber_connection *gscon)
{
static uint32_t next_id = 1;
int i;
/* This looks really suboptimal, but in most cases the static next_id should indicate exactly the next unused
* conn_id, and we only iterate all conns once to make super sure that it is not already in use. */
for (i = 0; i < 0xFFFFFF; i++) {
struct gsm_subscriber_connection *conn;
uint32_t conn_id = next_id;
bool conn_id_already_used = false;
next_id = (next_id + 1) & 0xffffff;
llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) {
if (conn->sccp.msc && conn->sccp.msc->a.sccp == sccp) {
if (conn_id == conn->sccp.conn_id) {
conn_id_already_used = true;
break;
}
}
if (bsc_gsmnet->smlc->sccp == sccp
&& conn->lcs.lb.state != SUBSCR_SCCP_ST_NONE) {
if (conn_id == conn->lcs.lb.conn_id) {
conn_id_already_used = true;
break;
}
}
}
if (!conn_id_already_used)
return conn_id;
}
return -1;
sccp_conn->conn_id = SCCP_CONN_ID_UNSET;
sccp_conn->gscon = gscon;
}
struct bsc_sccp_inst *bsc_sccp_inst_alloc(void *ctx)
{
struct bsc_sccp_inst *bsc_sccp;
bsc_sccp = talloc_zero(ctx, struct bsc_sccp_inst);
OSMO_ASSERT(bsc_sccp);
bsc_sccp->next_id = 1;
return bsc_sccp;
}
int bsc_sccp_inst_register_gscon(struct bsc_sccp_inst *bsc_sccp, struct bscp_sccp_conn_node *sccp_conn)
{
struct rb_node **n = &(bsc_sccp->connections.rb_node);
struct rb_node *parent = NULL;
uint32_t conn_id = sccp_conn->conn_id;
OSMO_ASSERT(conn_id != SCCP_CONN_ID_UNSET);
while (*n) {
struct bscp_sccp_conn_node *it = container_of(*n, struct bscp_sccp_conn_node, node);
parent = *n;
if (conn_id < it->conn_id) {
n = &((*n)->rb_left);
} else if (conn_id > it->conn_id) {
n = &((*n)->rb_right);
} else {
LOGP(DMSC, LOGL_ERROR,
"Trying to reserve already reserved conn_id %u\n", conn_id);
return -EEXIST;
}
}
rb_link_node(&sccp_conn->node, parent, n);
rb_insert_color(&sccp_conn->node, &bsc_sccp->connections);
return 0;
}
void bsc_sccp_inst_unregister_gscon(struct bsc_sccp_inst *bsc_sccp, struct bscp_sccp_conn_node *sccp_conn)
{
OSMO_ASSERT(sccp_conn->conn_id != SCCP_CONN_ID_UNSET);
rb_erase(&sccp_conn->node, &bsc_sccp->connections);
}
/* Helper function to Check if the given connection id is already assigned */
struct gsm_subscriber_connection *bsc_sccp_inst_get_gscon_by_conn_id(const struct bsc_sccp_inst *bsc_sccp, uint32_t conn_id)
{
const struct rb_node *node = bsc_sccp->connections.rb_node;
OSMO_ASSERT(conn_id != SCCP_CONN_ID_UNSET);
/* Range (0..SCCP_CONN_ID_MAX) expected, see bsc_sccp_inst_next_conn_id() */
OSMO_ASSERT(conn_id <= SCCP_CONN_ID_MAX);
while (node) {
struct bscp_sccp_conn_node *sccp_conn = container_of(node, struct bscp_sccp_conn_node, node);
if (conn_id < sccp_conn->conn_id)
node = node->rb_left;
else if (conn_id > sccp_conn->conn_id)
node = node->rb_right;
else
return sccp_conn->gscon;
}
return NULL;
}
/* We need an unused SCCP conn_id across all SCCP users. */
uint32_t bsc_sccp_inst_next_conn_id(struct bsc_sccp_inst *bsc_sccp)
{
uint32_t first_id, test_id;
first_id = test_id = bsc_sccp->next_id;
/* SUA: RFC3868 sec 3.10.4:
* The source reference number is a 4 octet long integer.
* This is allocated by the source SUA instance.
* M3UA/SCCP: ITU-T Q.713 sec 3.3:
* The "source local reference" parameter field is a three-octet field containing a
* reference number which is generated and used by the local node to identify the
* connection section after the connection section is set up.
* The coding "all ones" is reserved for future use.
*Hence, as we currently use the connection ID also as local reference,
*let's simply use 24 bit ids to fit all link types (excluding 0x00ffffff).
*/
while (bsc_sccp_inst_get_gscon_by_conn_id(bsc_sccp, test_id)) {
/* Optimized modulo operation (% SCCP_CONN_ID_MAX) using bitwise AND plus CMP: */
test_id = (test_id + 1) & 0x00FFFFFF;
if (OSMO_UNLIKELY(test_id == 0x00FFFFFF))
test_id = 0;
/* Did a whole loop, all used, fail */
if (OSMO_UNLIKELY(test_id == first_id))
return SCCP_CONN_ID_UNSET;
}
bsc_sccp->next_id = test_id;
/* Optimized modulo operation (% SCCP_CONN_ID_MAX) using bitwise AND plus CMP: */
bsc_sccp->next_id = (bsc_sccp->next_id + 1) & 0x00FFFFFF;
if (OSMO_UNLIKELY(bsc_sccp->next_id == 0x00FFFFFF))
bsc_sccp->next_id = 0;
return test_id;
}

View File

@ -50,6 +50,7 @@
#include <osmocom/core/byteswap.h>
#include <osmocom/bsc/lb.h>
#include <osmocom/bsc/lcs_loc_req.h>
#include <osmocom/bsc/vgcs_fsm.h>
#define S(x) (1 << (x))
@ -80,7 +81,7 @@ static const struct value_string gscon_fsm_event_names[] = {
{GSCON_EV_MO_COMPL_L3, "MO_COMPL_L3"},
{GSCON_EV_A_CONN_CFM, "MO-CONNECT.cfm"},
{GSCON_EV_A_CLEAR_CMD, "CLEAR_CMD"},
{GSCON_EV_A_DISC_IND, "DISCONNET.ind"},
{GSCON_EV_A_DISC_IND, "DISCONNECT.ind"},
{GSCON_EV_A_COMMON_ID_IND, "COMMON_ID.ind"},
{GSCON_EV_ASSIGNMENT_START, "ASSIGNMENT_START"},
{GSCON_EV_ASSIGNMENT_END, "ASSIGNMENT_END"},
@ -212,6 +213,12 @@ void gscon_fsm_wait_sccp_rlsd_onenter(struct osmo_fsm_inst *fi, uint32_t prev_st
if (conn->lcs.loc_req)
osmo_fsm_inst_dispatch(conn->lcs.loc_req->fi, LCS_LOC_REQ_EV_CONN_CLEAR, NULL);
if (conn->vgcs_call.fi)
osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_CLEANUP, NULL);
if (conn->vgcs_chan.fi)
osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_CLEANUP, NULL);
gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(conn->clear_cause));
osmo_mgcpc_ep_clear(conn->user_plane.mgw_endpoint);
@ -246,6 +253,8 @@ static void gscon_release_lchan(struct gsm_subscriber_connection *conn, struct g
conn->lchan = NULL;
if (conn->ho.fi && conn->ho.new_lchan == lchan)
conn->ho.new_lchan = NULL;
if (conn->vgcs_chan.new_lchan == lchan)
conn->vgcs_chan.new_lchan = NULL;
if (conn->assignment.new_lchan == lchan)
conn->assignment.new_lchan = NULL;
lchan_release(lchan, do_rr_release, err, cause_rr,
@ -303,6 +312,8 @@ static int validate_initial_user_data(struct osmo_fsm_inst *fi, struct msgb *msg
switch (bssmap_type) {
case BSS_MAP_MSG_HANDOVER_RQST:
case BSS_MAP_MSG_PERFORM_LOCATION_RQST:
case BSS_MAP_MSG_VGCS_VBS_SETUP:
case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST:
return 0;
default:
@ -343,6 +354,20 @@ static void handle_initial_user_data(struct osmo_fsm_inst *fi, struct msgb *msg)
lcs_loc_req_start(conn, msg);
return;
case BSS_MAP_MSG_VGCS_VBS_SETUP:
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_SETUP]);
/* VGCS: MSC asks vor voice group/bcast call. */
conn_fsm_state_chg(ST_ACTIVE);
vgcs_vbs_call_start(conn, msg);
return;
case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST:
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_ASSIGN_RQST]);
/* VGCS: MSC asks vor resource (channel) for voice group/bcast call. */
conn_fsm_state_chg(ST_ACTIVE);
vgcs_vbs_chan_start(conn, msg);
return;
default:
LOGPFSML(fi, LOGL_ERROR, "No support for initial BSSMAP: %s: %s\n",
gsm0808_bssap_name(bs->type), gsm0808_bssmap_name(bssmap_type));
@ -717,13 +742,19 @@ struct osmo_mgcpc_ep *gscon_ensure_mgw_endpoint(struct gsm_subscriber_connection
msc_assigned_cic, osmo_mgcpc_ep_name(conn->user_plane.mgw_endpoint));
} else if (gscon_is_aoip(conn)) {
if (is_ipaccess_bts(for_lchan->ts->trx->bts))
if (is_ipa_abisip_bts(for_lchan->ts->trx->bts))
/* use dynamic RTPBRIDGE endpoint allocation in MGW */
epname = mgcp_client_rtpbridge_wildcard(mgcp_client);
else {
uint8_t i460_bit_offs;
if (for_lchan->ts->e1_link.e1_ts_ss == E1_SUBSLOT_FULL)
i460_bit_offs = 0;
else
i460_bit_offs = for_lchan->ts->e1_link.e1_ts_ss * 2;
epname = mgcp_client_e1_epname(conn, mgcp_client, for_lchan->ts->e1_link.e1_nr,
for_lchan->ts->e1_link.e1_ts, 16,
for_lchan->ts->e1_link.e1_ts_ss*2);
i460_bit_offs);
}
conn->user_plane.mgw_endpoint =
@ -763,7 +794,7 @@ bool gscon_connect_mgw_to_msc(struct gsm_subscriber_connection *conn,
mgw_info = (struct mgcp_conn_peer){
.port = port,
.call_id = conn->sccp.conn_id,
.call_id = conn->sccp.conn.conn_id,
.ptime = 20,
.x_osmo_osmux_use = conn->assignment.req.use_osmux,
.x_osmo_osmux_cid = conn->assignment.req.osmux_cid,
@ -930,6 +961,10 @@ void gscon_lchan_releasing(struct gsm_subscriber_connection *conn, struct gsm_lc
if (conn->ho.fi)
osmo_fsm_inst_dispatch(conn->ho.fi, HO_EV_LCHAN_ERROR, lchan);
}
if (conn->vgcs_chan.new_lchan == lchan) {
if (conn->vgcs_chan.fi)
osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_LCHAN_ERROR, lchan);
}
if (conn->lchan == lchan) {
lchan_forget_conn(conn->lchan);
conn->lchan = NULL;
@ -966,6 +1001,10 @@ void gscon_forget_lchan(struct gsm_subscriber_connection *conn, struct gsm_lchan
conn->ho.new_lchan = NULL;
detach_label = "ho.new_lchan";
}
if (conn->vgcs_chan.new_lchan == lchan) {
conn->vgcs_chan.new_lchan = NULL;
detach_label = "vgcs.new_lchan";
}
if (conn->lchan == lchan) {
conn->lchan = NULL;
detach_label = "primary lchan";
@ -984,6 +1023,7 @@ void gscon_forget_lchan(struct gsm_subscriber_connection *conn, struct gsm_lchan
if (!conn->lchan
&& !conn->ho.new_lchan
&& !conn->assignment.new_lchan
&& !conn->vgcs_chan.new_lchan
&& !conn->lcs.loc_req)
gscon_bssmap_clear(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE);
}
@ -1005,6 +1045,7 @@ static void gscon_forget_mgw_endpoint(struct gsm_subscriber_connection *conn)
conn->ho.created_ci_for_msc = NULL;
lchan_forget_mgw_endpoint(conn->lchan);
lchan_forget_mgw_endpoint(conn->assignment.new_lchan);
lchan_forget_mgw_endpoint(conn->vgcs_chan.new_lchan);
lchan_forget_mgw_endpoint(conn->ho.new_lchan);
}
@ -1094,6 +1135,7 @@ static void gscon_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cau
lchan_forget_conn(conn->lchan);
lchan_forget_conn(conn->assignment.new_lchan);
lchan_forget_conn(conn->vgcs_chan.new_lchan);
lchan_forget_conn(conn->ho.new_lchan);
lb_close_conn(conn);
@ -1102,9 +1144,14 @@ static void gscon_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cau
LOGPFSML(fi, LOGL_DEBUG, "Disconnecting SCCP\n");
struct bsc_msc_data *msc = conn->sccp.msc;
/* FIXME: include a proper cause value / error message? */
osmo_sccp_tx_disconn(msc->a.sccp_user, conn->sccp.conn_id, &msc->a.bsc_addr, 0);
osmo_sccp_tx_disconn(msc->a.sccp_user, conn->sccp.conn.conn_id, &msc->a.bsc_addr, 0);
conn->sccp.state = SUBSCR_SCCP_ST_NONE;
}
if (conn->sccp.conn.conn_id != SCCP_CONN_ID_UNSET && conn->sccp.msc) {
struct bsc_sccp_inst *bsc_sccp = osmo_sccp_get_priv(conn->sccp.msc->a.sccp);
bsc_sccp_inst_unregister_gscon(bsc_sccp, &conn->sccp.conn);
conn->sccp.conn.conn_id = SCCP_CONN_ID_UNSET;
}
if (conn->bsub) {
LOGPFSML(fi, LOGL_DEBUG, "Putting bsc_subscr\n");
@ -1141,6 +1188,12 @@ static void gscon_pre_term(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause ca
conn->lcls.fi = NULL;
}
if (conn->vgcs_call.fi)
osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_CLEANUP, NULL);
if (conn->vgcs_chan.fi)
osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_CLEANUP, NULL);
LOGPFSML(fi, LOGL_DEBUG, "Releasing all lchans (if any) because this conn is terminating\n");
gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(conn->clear_cause));
@ -1202,7 +1255,7 @@ static struct osmo_fsm gscon_fsm = {
.event_names = gscon_fsm_event_names,
};
void bsc_subscr_conn_fsm_init(void)
static __attribute__((constructor)) void bsc_subscr_conn_fsm_init(void)
{
OSMO_ASSERT(osmo_fsm_register(&gscon_fsm) == 0);
OSMO_ASSERT(osmo_fsm_register(&lcls_fsm) == 0);
@ -1220,8 +1273,8 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *ne
conn->network = net;
INIT_LLIST_HEAD(&conn->dtap_queue);
INIT_LLIST_HEAD(&conn->hodec2.penalty_timers);
conn->sccp.conn_id = -1;
bscp_sccp_conn_node_init(&conn->sccp.conn, conn);
bscp_sccp_conn_node_init(&conn->lcs.lb.conn, conn);
/* Default clear cause (on RR translates to GSM48_RR_CAUSE_ABNORMAL_UNSPEC) */
conn->clear_cause = GSM0808_CAUSE_EQUIPMENT_FAILURE;
@ -1394,7 +1447,7 @@ void gscon_update_id(struct gsm_subscriber_connection *conn)
{
osmo_fsm_inst_update_id_f(conn->fi, "msc%u-conn%u%s%s",
conn->sccp.msc ? conn->sccp.msc->nr : UINT_MAX,
conn->sccp.conn_id,
conn->sccp.conn.conn_id,
conn->bsub? "_" : "",
conn->bsub? bsc_subscr_id(conn->bsub) : "");
}

View File

@ -65,14 +65,27 @@ static int bsub_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, co
return 0;
}
static struct bsc_subscr *bsc_subscr_alloc(struct llist_head *list)
struct bsc_subscr_store *bsc_subscr_store_alloc(void *ctx)
{
struct bsc_subscr_store *bsubst;
bsubst = talloc_zero(ctx, struct bsc_subscr_store);
if (!bsubst)
return NULL;
INIT_LLIST_HEAD(&bsubst->bsub_list);
return bsubst;
}
static struct bsc_subscr *bsc_subscr_alloc(struct bsc_subscr_store *bsubst)
{
struct bsc_subscr *bsub;
bsub = talloc_zero(list, struct bsc_subscr);
bsub = talloc_zero(bsubst, struct bsc_subscr);
if (!bsub)
return NULL;
bsub->store = bsubst;
bsub->tmsi = GSM_RESERVED_TMSI;
bsub->use_count = (struct osmo_use_count){
.talloc_object = bsub,
@ -80,12 +93,12 @@ static struct bsc_subscr *bsc_subscr_alloc(struct llist_head *list)
};
INIT_LLIST_HEAD(&bsub->active_paging_requests);
llist_add_tail(&bsub->entry, list);
llist_add_tail(&bsub->entry, &bsubst->bsub_list);
return bsub;
}
struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
struct bsc_subscr *bsc_subscr_find_by_imsi(struct bsc_subscr_store *bsubst,
const char *imsi,
const char *use_token)
{
@ -94,7 +107,7 @@ struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
if (!imsi || !*imsi)
return NULL;
llist_for_each_entry(bsub, list, entry) {
llist_for_each_entry(bsub, &bsubst->bsub_list, entry) {
if (!strcmp(bsub->imsi, imsi)) {
bsc_subscr_get(bsub, use_token);
return bsub;
@ -103,16 +116,16 @@ struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
return NULL;
}
struct bsc_subscr *bsc_subscr_find_by_imei(struct llist_head *list,
const char *imei,
const char *use_token)
static struct bsc_subscr *bsc_subscr_find_by_imei(struct bsc_subscr_store *bsubst,
const char *imei,
const char *use_token)
{
struct bsc_subscr *bsub;
if (!imei || !*imei)
return NULL;
llist_for_each_entry(bsub, list, entry) {
llist_for_each_entry(bsub, &bsubst->bsub_list, entry) {
if (!strcmp(bsub->imei, imei)) {
bsc_subscr_get(bsub, use_token);
return bsub;
@ -121,39 +134,83 @@ struct bsc_subscr *bsc_subscr_find_by_imei(struct llist_head *list,
return NULL;
}
struct bsc_subscr *bsc_subscr_find_by_tmsi(struct llist_head *list,
uint32_t tmsi,
const char *use_token)
static struct bsc_subscr *bsc_subscr_find_by_tmsi(struct bsc_subscr_store *bsubst,
uint32_t tmsi,
const char *use_token)
{
const struct rb_node *node = bsubst->bsub_tree_tmsi.rb_node;
struct bsc_subscr *bsub;
if (tmsi == GSM_RESERVED_TMSI)
return NULL;
llist_for_each_entry(bsub, list, entry) {
if (bsub->tmsi == tmsi) {
while (node) {
bsub = container_of(node, struct bsc_subscr, node_tmsi);
if (tmsi < bsub->tmsi)
node = node->rb_left;
else if (tmsi > bsub->tmsi)
node = node->rb_right;
else {
bsc_subscr_get(bsub, use_token);
return bsub;
}
}
return NULL;
}
struct bsc_subscr *bsc_subscr_find_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
const char *use_token)
static int bsc_subscr_store_insert_bsub_tmsi(struct bsc_subscr *bsub)
{
if (!mi)
return NULL;
switch (mi->type) {
case GSM_MI_TYPE_IMSI:
return bsc_subscr_find_by_imsi(list, mi->imsi, use_token);
case GSM_MI_TYPE_IMEI:
return bsc_subscr_find_by_imei(list, mi->imei, use_token);
case GSM_MI_TYPE_TMSI:
return bsc_subscr_find_by_tmsi(list, mi->tmsi, use_token);
default:
return NULL;
struct bsc_subscr_store *bsubst = bsub->store;
struct rb_node **n = &(bsubst->bsub_tree_tmsi.rb_node);
struct rb_node *parent = NULL;
OSMO_ASSERT(bsub->tmsi != GSM_RESERVED_TMSI);
while (*n) {
struct bsc_subscr *it;
it = container_of(*n, struct bsc_subscr, node_tmsi);
parent = *n;
if (bsub->tmsi < it->tmsi) {
n = &((*n)->rb_left);
} else if (bsub->tmsi > it->tmsi) {
n = &((*n)->rb_right);
} else {
LOGP(DMSC, LOGL_ERROR, "Trying to reserve already reserved tmsi %u\n", bsub->tmsi);
return -EEXIST;
}
}
rb_link_node(&bsub->node_tmsi, parent, n);
rb_insert_color(&bsub->node_tmsi, &bsubst->bsub_tree_tmsi);
return 0;
}
int bsc_subscr_set_tmsi(struct bsc_subscr *bsub, uint32_t tmsi)
{
int rc = 0;
if (!bsub)
return -EINVAL;
if (bsub->tmsi == tmsi)
return 0;
/* bsub was already inserted, remove and re-insert with new tmsi */
if (bsub->tmsi != GSM_RESERVED_TMSI)
rb_erase(&bsub->node_tmsi, &bsub->store->bsub_tree_tmsi);
bsub->tmsi = tmsi;
/* If new tmsi is set, insert bsub into rbtree: */
if (bsub->tmsi != GSM_RESERVED_TMSI) {
if ((rc = bsc_subscr_store_insert_bsub_tmsi(bsub)) < 0)
bsub->tmsi = GSM_RESERVED_TMSI;
}
return rc;
}
void bsc_subscr_set_imsi(struct bsc_subscr *bsub, const char *imsi)
@ -170,15 +227,15 @@ void bsc_subscr_set_imei(struct bsc_subscr *bsub, const char *imei)
osmo_strlcpy(bsub->imei, imei, sizeof(bsub->imei));
}
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list,
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct bsc_subscr_store *bsubst,
const char *imsi,
const char *use_token)
{
struct bsc_subscr *bsub;
bsub = bsc_subscr_find_by_imsi(list, imsi, use_token);
bsub = bsc_subscr_find_by_imsi(bsubst, imsi, use_token);
if (bsub)
return bsub;
bsub = bsc_subscr_alloc(list);
bsub = bsc_subscr_alloc(bsubst);
if (!bsub)
return NULL;
bsc_subscr_set_imsi(bsub, imsi);
@ -186,15 +243,15 @@ struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list,
return bsub;
}
struct bsc_subscr *bsc_subscr_find_or_create_by_imei(struct llist_head *list,
const char *imei,
const char *use_token)
static struct bsc_subscr *bsc_subscr_find_or_create_by_imei(struct bsc_subscr_store *bsubst,
const char *imei,
const char *use_token)
{
struct bsc_subscr *bsub;
bsub = bsc_subscr_find_by_imei(list, imei, use_token);
bsub = bsc_subscr_find_by_imei(bsubst, imei, use_token);
if (bsub)
return bsub;
bsub = bsc_subscr_alloc(list);
bsub = bsc_subscr_alloc(bsubst);
if (!bsub)
return NULL;
bsc_subscr_set_imei(bsub, imei);
@ -202,34 +259,37 @@ struct bsc_subscr *bsc_subscr_find_or_create_by_imei(struct llist_head *list,
return bsub;
}
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct llist_head *list,
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct bsc_subscr_store *bsubst,
uint32_t tmsi,
const char *use_token)
{
struct bsc_subscr *bsub;
bsub = bsc_subscr_find_by_tmsi(list, tmsi, use_token);
bsub = bsc_subscr_find_by_tmsi(bsubst, tmsi, use_token);
if (bsub)
return bsub;
bsub = bsc_subscr_alloc(list);
bsub = bsc_subscr_alloc(bsubst);
if (!bsub)
return NULL;
bsub->tmsi = tmsi;
if (bsc_subscr_set_tmsi(bsub, tmsi) < 0) {
bsc_subscr_free(bsub);
return NULL;
}
bsc_subscr_get(bsub, use_token);
return bsub;
}
struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct bsc_subscr_store *bsubst, const struct osmo_mobile_identity *mi,
const char *use_token)
{
if (!mi)
return NULL;
switch (mi->type) {
case GSM_MI_TYPE_IMSI:
return bsc_subscr_find_or_create_by_imsi(list, mi->imsi, use_token);
return bsc_subscr_find_or_create_by_imsi(bsubst, mi->imsi, use_token);
case GSM_MI_TYPE_IMEI:
return bsc_subscr_find_or_create_by_imei(list, mi->imei, use_token);
return bsc_subscr_find_or_create_by_imei(bsubst, mi->imei, use_token);
case GSM_MI_TYPE_TMSI:
return bsc_subscr_find_or_create_by_tmsi(list, mi->tmsi, use_token);
return bsc_subscr_find_or_create_by_tmsi(bsubst, mi->tmsi, use_token);
default:
return NULL;
}
@ -272,6 +332,10 @@ const char *bsc_subscr_id(struct bsc_subscr *bsub)
static void bsc_subscr_free(struct bsc_subscr *bsub)
{
OSMO_ASSERT(llist_empty(&bsub->active_paging_requests));
if (bsub->tmsi != GSM_RESERVED_TMSI)
rb_erase(&bsub->node_tmsi, &bsub->store->bsub_tree_tmsi);
llist_del(&bsub->entry);
talloc_free(bsub);
}

View File

@ -67,6 +67,7 @@
#include <osmocom/bsc/bssmap_reset.h>
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/lchan.h>
#include <osmocom/bsc/pcu_if.h>
#include <inttypes.h>
@ -218,6 +219,9 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net)
vty_out(vty, " Last RF Lock Command: %s%s",
net->rf_ctrl->last_rf_lock_ctrl_command,
VTY_NEWLINE);
if (net->pcu_sock_path)
vty_out(vty, " PCU Socket Path: %s%s", net->pcu_sock_path, VTY_NEWLINE);
}
DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
@ -253,6 +257,22 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
return CMD_SUCCESS;
}
DEFUN(show_bts_brief, show_bts_brief_cmd, "show bts brief",
SHOW_STR "Display information about a BTS\n"
"Display availability status of all BTS\n")
{
struct gsm_network *net = gsmnet_from_vty(vty);
struct gsm_bts *bts;
/* Print OML state of BTSs. */
llist_for_each_entry(bts, &net->bts_list, list) {
vty_out(vty, "BTS %d:", bts->nr);
bts_dump_vty_oml_link_state(vty, bts);
}
return CMD_SUCCESS;
}
DEFUN(show_bts_fail_rep, show_bts_fail_rep_cmd, "show bts <0-255> fail-rep [reset]",
SHOW_STR "Display information about a BTS\n"
"BTS number\n" "OML failure reports\n"
@ -381,6 +401,7 @@ static int config_write_net(struct vty *vty)
uint16_t meas_port;
char *meas_host;
const char *meas_scenario;
unsigned int max_len = meas_feed_txqueue_max_length_get();
meas_feed_cfg_get(&meas_host, &meas_port);
meas_scenario = meas_feed_scenario_get();
@ -391,6 +412,9 @@ static int config_write_net(struct vty *vty)
if (strlen(meas_scenario) > 0)
vty_out(vty, " meas-feed scenario %s%s",
meas_scenario, VTY_NEWLINE);
if (max_len != MEAS_FEED_TXQUEUE_MAX_LEN_DEFAULT)
vty_out(vty, " meas-feed write-queue-max-length %u%s",
max_len, VTY_NEWLINE);
}
if (gsmnet->allow_unusable_timeslots)
@ -406,6 +430,12 @@ static int config_write_net(struct vty *vty)
vty_out(vty, "%s", VTY_NEWLINE);
}
if (gsmnet->pcu_sock_path)
vty_out(vty, " pcu-socket %s%s", gsmnet->pcu_sock_path, VTY_NEWLINE);
if (gsmnet->pcu_sock_wqueue_len_max != BSC_PCU_SOCK_WQUEUE_LEN_DEFAULT)
vty_out(vty, " pcu-socket-wqueue-length %u%s", gsmnet->pcu_sock_wqueue_len_max,
VTY_NEWLINE);
neighbor_ident_vty_write_network(vty, " ");
mgcp_client_pool_config_write(vty, " ");
@ -727,7 +757,7 @@ DEFUN(show_lchan_summary_all,
static void dump_one_subscr_conn(struct vty *vty, const struct gsm_subscriber_connection *conn)
{
vty_out(vty, "conn ID=%u, MSC=%u, hodec2_fail=%d, mgw_ep=%s%s",
conn->sccp.conn_id, conn->sccp.msc->nr, conn->hodec2.failures,
conn->sccp.conn.conn_id, conn->sccp.msc->nr, conn->hodec2.failures,
osmo_mgcpc_ep_name(conn->user_plane.mgw_endpoint), VTY_NEWLINE);
if (conn->lcls.global_call_ref_len) {
vty_out(vty, " LCLS GCR: %s%s",
@ -753,14 +783,12 @@ DEFUN(show_subscr_conn,
struct gsm_subscriber_connection *conn;
struct gsm_network *net = gsmnet_from_vty(vty);
bool no_conns = true;
unsigned int count = 0;
vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
llist_for_each_entry(conn, &net->subscr_conns, entry) {
dump_one_subscr_conn(vty, conn);
no_conns = false;
count++;
}
if (no_conns)
@ -862,8 +890,7 @@ static int trigger_vamos_mode_modify(struct vty *vty, struct gsm_lchan *lchan, b
struct lchan_modify_info info = {
.modify_for = MODIFY_FOR_VTY,
.ch_mode_rate = lchan->current_ch_mode_rate,
.requires_voice_stream = (lchan->fi_rtp != NULL),
.vamos = vamos,
.ch_indctr = lchan->current_ch_indctr,
.tsc_set = {
.present = (tsc_set >= 0),
.val = tsc_set,
@ -873,6 +900,8 @@ static int trigger_vamos_mode_modify(struct vty *vty, struct gsm_lchan *lchan, b
.val = tsc,
},
};
if (vamos)
info.type_for = LCHAN_TYPE_FOR_VAMOS;
lchan_mode_modify(lchan, &info);
return CMD_SUCCESS;
@ -1261,8 +1290,8 @@ DEFUN(drop_bts,
return CMD_WARNING;
}
if (!is_ipaccess_bts(bts)) {
vty_out(vty, "%% This command only works for ipaccess.%s", VTY_NEWLINE);
if (!is_ipa_abisip_bts(bts)) {
vty_out(vty, "%% This command only works for IPA Abis/IP.%s", VTY_NEWLINE);
return CMD_WARNING;
}
@ -1308,8 +1337,8 @@ DEFUN(restart_bts, restart_bts_cmd,
return CMD_WARNING;
}
if (!is_ipaccess_bts(bts) || is_osmobts(bts)) {
vty_out(vty, "%% This command only works for ipaccess nanoBTS.%s",
if (!is_ipa_abisip_bts(bts)) {
vty_out(vty, "%% This command only works for IPA Abis/IP.%s",
VTY_NEWLINE);
return CMD_WARNING;
}
@ -1419,18 +1448,22 @@ DEFUN(bts_c0_power_red,
}
rc = gsm_bts_set_c0_power_red(bts, red);
if (rc == -ENOTSUP) {
switch (rc) {
case 0: /* success */
return CMD_SUCCESS;
case -ENOTCONN:
vty_out(vty, "%% BTS%u is offline%s", bts_nr, VTY_NEWLINE);
return CMD_WARNING;
case -ENOTSUP:
vty_out(vty, "%% BCCH carrier power reduction operation mode "
"is not supported for BTS%u%s", bts_nr, VTY_NEWLINE);
return CMD_WARNING;
} else if (rc != 0) {
default:
vty_out(vty, "%% Failed to %sable BCCH carrier power reduction "
"operation mode for BTS%u%s", red ? "en" : "dis",
bts_nr, VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
/* this command is now hidden, as it's a low-level debug hack, and people should
@ -1521,8 +1554,8 @@ DEFUN(pdch_act, pdch_act_cmd,
return CMD_WARNING;
}
if (!is_ipaccess_bts(ts->trx->bts)) {
vty_out(vty, "%% This command only works for ipaccess BTS%s",
if (!is_ipa_abisip_bts(ts->trx->bts)) {
vty_out(vty, "%% This command only works for IPA Abis/IP BTS%s",
VTY_NEWLINE);
return CMD_WARNING;
}
@ -1625,11 +1658,11 @@ static int lchan_act_single(struct vty *vty, struct gsm_lchan *lchan, const char
}
info.activ_for = ACTIVATE_FOR_VTY;
info.requires_voice_stream = false;
info.ch_indctr = GSM0808_CHAN_SIGN;
info.ch_mode_rate.chan_rate = chan_t_to_chan_rate(lchan_t);
if (activate == 2 || lchan->vamos.is_secondary) {
info.vamos = true;
info.type_for = LCHAN_TYPE_FOR_VAMOS;
if (lchan->vamos.is_secondary) {
info.tsc_set.present = true;
info.tsc_set.val = 1;
@ -2055,8 +2088,8 @@ DEFUN(lchan_mdcx, lchan_mdcx_cmd,
lchan = &ts->lchan[ss_nr];
if (!is_ipaccess_bts(lchan->ts->trx->bts)) {
vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
if (!is_ipa_abisip_bts(lchan->ts->trx->bts)) {
vty_out(vty, "%% BTS is not of IPA Abis/IP type%s", VTY_NEWLINE);
return CMD_WARNING;
}
@ -2404,6 +2437,16 @@ DEFUN_ATTR(cfg_net_meas_feed_scenario, cfg_net_meas_feed_scenario_cmd,
return CMD_SUCCESS;
}
DEFUN_ATTR(cfg_net_meas_feed_wqueue_max_len, cfg_net_meas_feed_wqueue_max_len_cmd,
"meas-feed write-queue-max-length <1-65535>",
MEAS_FEED_STR "Set the maximum length of the message write queue towards the UDP socket\n"
"Maximum number of messages to be queued waiting for transmission\n",
CMD_ATTR_IMMEDIATE)
{
meas_feed_txqueue_max_length_set(atoi(argv[0]));
return CMD_SUCCESS;
}
static void legacy_timers(struct vty *vty, const char **T_arg)
{
if (!strcmp((*T_arg), "T993111") || !strcmp((*T_arg), "t993111")) {
@ -2460,6 +2503,63 @@ DEFUN(cfg_net_allow_unusable_timeslots, cfg_net_allow_unusable_timeslots_cmd,
return CMD_SUCCESS;
}
DEFUN_ATTR(cfg_bts_pcu_sock_wqueue_len, cfg_bts_pcu_sock_wqueue_len_cmd,
"pcu-socket-wqueue-length <1-2147483646>",
"Configure the PCU socket queue length\n"
"Queue length\n",
CMD_ATTR_IMMEDIATE)
{
size_t dropped_msgs = 0;
struct gsm_network *net = gsmnet_from_vty(vty);
size_t old = net->pcu_sock_wqueue_len_max;
net->pcu_sock_wqueue_len_max = atoi(argv[0]);
if (net->pcu_state)
dropped_msgs = osmo_wqueue_set_maxlen(&net->pcu_state->upqueue, net->pcu_sock_wqueue_len_max);
if (dropped_msgs) {
LOGP(DPCU, LOGL_INFO, "Have dropped %zu messages due to shortened max. message queue size (from: %zu to %u)\n",
dropped_msgs, old, net->pcu_sock_wqueue_len_max);
vty_out(vty, "Have dropped %zu messages due to shortened max. message queue size (from: %zu to %u)%s",
dropped_msgs, old, net->pcu_sock_wqueue_len_max, VTY_NEWLINE);
}
return CMD_SUCCESS;
}
DEFUN_ATTR(cfg_net_pcu_sock_path,
cfg_net_pcu_sock_path_cmd,
"pcu-socket PATH",
"PCU Socket Path for using OsmoPCU co-located with BSC\n"
"Path in the file system for the unix-domain PCU socket\n",
CMD_ATTR_IMMEDIATE)
{
struct gsm_network *net = gsmnet_from_vty(vty);
int rc;
osmo_talloc_replace_string(net, &net->pcu_sock_path, argv[0]);
pcu_sock_exit(net);
rc = pcu_sock_init(net);
if (rc < 0) {
vty_out(vty, "%% Error creating PCU socket `%s'%s",
net->pcu_sock_path, VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
DEFUN_ATTR(cfg_net_no_pcu_sock,
cfg_net_no_pcu_sock_cmd,
"no pcu-socket",
NO_STR "Disable BSC co-located PCU\n",
CMD_ATTR_IMMEDIATE)
{
struct gsm_network *net = gsmnet_from_vty(vty);
pcu_sock_exit(net);
talloc_free(net->pcu_sock_path);
net->pcu_sock_path = NULL;
return CMD_SUCCESS;
}
static struct bsc_msc_data *bsc_msc_data(struct vty *vty)
{
return vty->index;
@ -2550,10 +2650,10 @@ static void write_msc(struct vty *vty, struct bsc_msc_data *msc)
if (i != 0)
vty_out(vty, " ");
if (msc->audio_support[i]->hr)
vty_out(vty, "hr%.1u", msc->audio_support[i]->ver);
if (msc->audio_support[i].hr)
vty_out(vty, "hr%u", msc->audio_support[i].ver);
else
vty_out(vty, "fr%.1u", msc->audio_support[i]->ver);
vty_out(vty, "fr%u", msc->audio_support[i].ver);
}
vty_out(vty, "%s", VTY_NEWLINE);
@ -2640,8 +2740,8 @@ static int config_write_bsc(struct vty *vty)
return CMD_SUCCESS;
}
DEFUN_ATTR(cfg_net_bsc_ncc,
cfg_net_bsc_ncc_cmd,
DEFUN_ATTR(cfg_net_msc_ncc,
cfg_net_msc_ncc_cmd,
"core-mobile-network-code <1-999>",
"Use this network code for the core network\n" "MNC value\n",
CMD_ATTR_IMMEDIATE)
@ -2659,8 +2759,8 @@ DEFUN_ATTR(cfg_net_bsc_ncc,
return CMD_SUCCESS;
}
DEFUN_ATTR(cfg_net_bsc_mcc,
cfg_net_bsc_mcc_cmd,
DEFUN_ATTR(cfg_net_msc_mcc,
cfg_net_msc_mcc_cmd,
"core-mobile-country-code <1-999>",
"Use this country code for the core network\n" "MCC value\n",
CMD_ATTR_IMMEDIATE)
@ -2675,8 +2775,8 @@ DEFUN_ATTR(cfg_net_bsc_mcc,
return CMD_SUCCESS;
}
DEFUN_DEPRECATED(cfg_net_bsc_lac,
cfg_net_bsc_lac_cmd,
DEFUN_DEPRECATED(cfg_net_msc_lac,
cfg_net_msc_lac_cmd,
"core-location-area-code <0-65535>",
"Legacy configuration that no longer has any effect\n-\n")
{
@ -2684,8 +2784,8 @@ DEFUN_DEPRECATED(cfg_net_bsc_lac,
return CMD_SUCCESS;
}
DEFUN_DEPRECATED(cfg_net_bsc_ci,
cfg_net_bsc_ci_cmd,
DEFUN_DEPRECATED(cfg_net_msc_ci,
cfg_net_msc_ci_cmd,
"core-cell-identity <0-65535>",
"Legacy configuration that no longer has any effect\n-\n")
{
@ -2693,8 +2793,8 @@ DEFUN_DEPRECATED(cfg_net_bsc_ci,
return CMD_SUCCESS;
}
DEFUN_DEPRECATED(cfg_net_bsc_rtp_base,
cfg_net_bsc_rtp_base_cmd,
DEFUN_DEPRECATED(cfg_net_msc_rtp_base,
cfg_net_msc_rtp_base_cmd,
"ip.access rtp-base <1-65000>",
"deprecated\n" "deprecated, RTP is handled by the MGW\n" "deprecated\n")
{
@ -2702,56 +2802,64 @@ DEFUN_DEPRECATED(cfg_net_bsc_rtp_base,
return CMD_SUCCESS;
}
DEFUN_USRATTR(cfg_net_bsc_codec_list,
cfg_net_bsc_codec_list_cmd,
DEFUN_USRATTR(cfg_net_msc_codec_list,
cfg_net_msc_codec_list_cmd,
BSC_VTY_ATTR_NEW_LCHAN,
"codec-list .LIST",
"Set the allowed audio codecs\n"
"List of audio codecs, e.g. fr3 fr1 hr3\n")
"Set the allowed audio codecs and their order of preference\n"
"List of audio codecs in order of preference, e.g. 'codec-list fr3 fr2 fr1 hr3 hr1'."
" (fr3: AMR-FR, hr3: AMR-HR, fr2: GSM-EFR, fr1: GSM-FR, hr1: GSM-HR)\n")
{
struct bsc_msc_data *data = bsc_msc_data(vty);
struct gsm_audio_support tmp[ARRAY_SIZE(data->audio_support)];
const char *arg = NULL;
int i;
/* Nr of arguments must fit in the array */
if (argc > ARRAY_SIZE(data->audio_support)) {
vty_out(vty, "Too many items in 'msc' / 'codec-list': %d. There can be at most %zu entries.%s",
argc, ARRAY_SIZE(data->audio_support), VTY_NEWLINE);
return CMD_ERR_EXEED_ARGC_MAX;
}
/* check all given arguments first */
for (i = 0; i < argc; ++i) {
/* check for hrX or frX */
if (strlen(argv[i]) != 3
|| argv[i][1] != 'r'
|| (argv[i][0] != 'h' && argv[i][0] != 'f')
|| argv[i][2] < 0x30
|| argv[i][2] > 0x39)
goto error;
for (i = 0; i < argc; i++) {
int j;
int ver;
arg = argv[i];
if (strncmp("hr", arg, 2) == 0)
tmp[i].hr = 1;
else if (strncmp("fr", arg, 2) == 0)
tmp[i].hr = 0;
else
goto invalid_arg;
ver = atoi(arg + 2);
if (ver < 1 || ver > 7)
goto invalid_arg;
tmp[i].ver = ver;
if (tmp[i].hr == 1 && ver == 2)
goto invalid_arg;
/* prevent duplicate entries */
for (j = 0; j < i; j++) {
if (gsm_audio_support_cmp(&tmp[j], &tmp[i]) == 0) {
vty_out(vty, "duplicate entry in 'msc' / 'codec-list': %s%s", argv[i], VTY_NEWLINE);
return CMD_WARNING;
}
}
}
/* free the old list... if it exists */
if (data->audio_support) {
talloc_free(data->audio_support);
data->audio_support = NULL;
data->audio_length = 0;
}
/* create a new array */
data->audio_support =
talloc_zero_array(bsc_gsmnet, struct gsm_audio_support *, argc);
memcpy(data->audio_support, tmp, sizeof(data->audio_support));
data->audio_length = argc;
for (i = 0; i < argc; ++i) {
data->audio_support[i] = talloc_zero(data->audio_support,
struct gsm_audio_support);
data->audio_support[i]->ver = atoi(argv[i] + 2);
if (strncmp("hr", argv[i], 2) == 0)
data->audio_support[i]->hr = 1;
else if (strncmp("fr", argv[i], 2) == 0)
data->audio_support[i]->hr = 0;
}
return CMD_SUCCESS;
error:
vty_out(vty, "Codec name must be hrX or frX. Was '%s'%s",
argv[i], VTY_NEWLINE);
return CMD_ERR_INCOMPLETE;
invalid_arg:
vty_out(vty, "%s is not a valid codec version%s", osmo_quote_cstr_c(OTC_SELECT, arg, -1), VTY_NEWLINE);
return CMD_WARNING;
}
#define LEGACY_STR "This command has no effect, it is kept to support legacy config files\n"
@ -3158,13 +3266,19 @@ DEFUN(show_mscs,
{
struct bsc_msc_data *msc;
llist_for_each_entry(msc, &bsc_gsmnet->mscs, entry) {
vty_out(vty, "%d %s %s ",
vty_out(vty, "MSC %d: %s <-> ",
msc->a.cs7_instance,
osmo_ss7_asp_protocol_name(msc->a.asp_proto),
osmo_sccp_inst_addr_name(msc->a.sccp, &msc->a.bsc_addr));
vty_out(vty, "%s%s",
osmo_sccp_inst_addr_name(msc->a.sccp, &msc->a.msc_addr),
VTY_NEWLINE);
vty_out(vty, " ASP protocol: %s%s",
osmo_ss7_asp_protocol_name(msc->a.asp_proto),
VTY_NEWLINE);
vty_out(vty, " BSSMAP state: %s%s",
msc->a.bssmap_reset ? osmo_fsm_inst_state_name(msc->a.bssmap_reset->fi) : "",
VTY_NEWLINE);
}
return CMD_SUCCESS;
@ -3275,7 +3389,7 @@ DEFUN(show_subscr_all,
vty_out(vty, " IMSI TMSI Use%s", VTY_NEWLINE);
/* " 001010123456789 ffffffff 1" */
llist_for_each_entry(bsc_subscr, bsc_gsmnet->bsc_subscribers, entry)
llist_for_each_entry(bsc_subscr, &bsc_gsmnet->bsc_subscribers->bsub_list, entry)
dump_one_sub(vty, bsc_subscr);
return CMD_SUCCESS;
@ -3524,14 +3638,19 @@ int bsc_vty_init(struct gsm_network *network)
install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);
install_element(GSMNET_NODE, &cfg_net_meas_feed_dest_cmd);
install_element(GSMNET_NODE, &cfg_net_meas_feed_scenario_cmd);
install_element(GSMNET_NODE, &cfg_net_meas_feed_wqueue_max_len_cmd);
install_element(GSMNET_NODE, &cfg_net_timer_cmd);
install_element(GSMNET_NODE, &cfg_net_allow_unusable_timeslots_cmd);
install_element(GSMNET_NODE, &cfg_net_pcu_sock_path_cmd);
install_element(GSMNET_NODE, &cfg_bts_pcu_sock_wqueue_len_cmd);
install_element(GSMNET_NODE, &cfg_net_no_pcu_sock_cmd);
/* Timer configuration commands (generic osmo_tdef API) */
osmo_tdef_vty_groups_init(GSMNET_NODE, bsc_tdef_group);
install_element_ve(&bsc_show_net_cmd);
install_element_ve(&show_bts_cmd);
install_element_ve(&show_bts_brief_cmd);
install_element_ve(&show_bts_fail_rep_cmd);
install_element_ve(&show_rejected_bts_cmd);
install_element_ve(&show_trx_cmd);
@ -3614,12 +3733,12 @@ int bsc_vty_init(struct gsm_network *network)
install_element(BSC_NODE, &cfg_bsc_bts_setup_ramping_step_interval_cmd);
install_node(&msc_node, config_write_msc);
install_element(MSC_NODE, &cfg_net_bsc_ncc_cmd);
install_element(MSC_NODE, &cfg_net_bsc_mcc_cmd);
install_element(MSC_NODE, &cfg_net_bsc_lac_cmd);
install_element(MSC_NODE, &cfg_net_bsc_ci_cmd);
install_element(MSC_NODE, &cfg_net_bsc_rtp_base_cmd);
install_element(MSC_NODE, &cfg_net_bsc_codec_list_cmd);
install_element(MSC_NODE, &cfg_net_msc_ncc_cmd);
install_element(MSC_NODE, &cfg_net_msc_mcc_cmd);
install_element(MSC_NODE, &cfg_net_msc_lac_cmd);
install_element(MSC_NODE, &cfg_net_msc_ci_cmd);
install_element(MSC_NODE, &cfg_net_msc_rtp_base_cmd);
install_element(MSC_NODE, &cfg_net_msc_codec_list_cmd);
install_element(MSC_NODE, &cfg_net_msc_dest_cmd);
install_element(MSC_NODE, &cfg_net_msc_no_dest_cmd);
install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd);

View File

@ -198,7 +198,7 @@ static int bssmap_reset_fsm_timer_cb(struct osmo_fsm_inst *fi)
static struct osmo_fsm_state bssmap_reset_fsm_states[] = {
[BSSMAP_RESET_ST_DISC] = {
.name = "DISC",
.name = "DISCONNECTED",
.in_event_mask = 0
| S(BSSMAP_RESET_EV_RX_RESET)
| S(BSSMAP_RESET_EV_RX_RESET_ACK)
@ -213,7 +213,7 @@ static struct osmo_fsm_state bssmap_reset_fsm_states[] = {
.action = bssmap_reset_disc_action,
},
[BSSMAP_RESET_ST_CONN] = {
.name = "CONN",
.name = "CONNECTED",
.in_event_mask = 0
| S(BSSMAP_RESET_EV_RX_RESET)
| S(BSSMAP_RESET_EV_RX_RESET_ACK)
@ -251,6 +251,12 @@ void bssmap_reset_resend_reset(struct bssmap_reset *bssmap_reset)
osmo_fsm_inst_state_chg_ms(bssmap_reset->fi, BSSMAP_RESET_ST_DISC, 1, 0);
}
void bssmap_reset_set_disconnected(struct bssmap_reset *bssmap_reset)
{
/* Go to disconnected state, with the normal RESET timeout to re-send RESET. */
bssmap_reset_fsm_state_chg(bssmap_reset->fi, BSSMAP_RESET_ST_DISC);
}
static __attribute__((constructor)) void bssmap_reset_fsm_init(void)
{
OSMO_ASSERT(osmo_fsm_register(&bssmap_reset_fsm) == 0);

View File

@ -49,7 +49,7 @@ const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
{ BTS_OSMO_LITECELL15, "osmo-bts-lc15" },
{ BTS_OSMO_OCTPHY, "osmo-bts-octphy" },
{ BTS_OSMO_SYSMO, "osmo-bts-sysmo" },
{ BTS_OSMO_TRX, "omso-bts-trx" },
{ BTS_OSMO_TRX, "osmo-bts-trx" },
{ 0, NULL }
};
@ -117,8 +117,20 @@ int gsm_bts_model_register(struct gsm_bts_model *model)
return 0;
}
static const uint8_t bts_cell_timer_default[] =
{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
static const uint8_t bts_cell_timer_default[11] = {
3, /* blocking timer (T1) */
3, /* blocking retries */
3, /* unblocking retries */
3, /* reset timer (T2) */
3, /* reset retries */
10, /* suspend timer (T3) in 100ms */
3, /* suspend retries */
10, /* resume timer (T4) in 100ms */
3, /* resume retries */
10, /* capability update timer (T5) */
3, /* capability update retries */
};
static const struct gprs_rlc_cfg rlc_cfg_default = {
.parameter = {
[RLC_T3142] = 20,
@ -458,6 +470,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm
bts->interf_meas_params_cfg = interf_meas_params_def;
bts->rach_max_delay = 63;
bts->rach_expiry_timeout = 32;
/* SRVCC is enabled by default */
bts->srvcc_fast_return_allowed = true;
@ -753,7 +766,8 @@ struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)
void bts_store_uptime(struct gsm_bts *bts)
{
osmo_stat_item_set(osmo_stat_item_group_get_item(bts->bts_statg, BTS_STAT_UPTIME_SECONDS), bts_uptime(bts));
osmo_stat_item_set(osmo_stat_item_group_get_item(bts->bts_statg, BTS_STAT_UPTIME_SECONDS),
bts->oml_link ? bts_updowntime(bts) : 0);
}
void bts_store_lchan_durations(struct gsm_bts *bts)
@ -811,20 +825,20 @@ void bts_store_lchan_durations(struct gsm_bts *bts)
rate_ctr_add(rate_ctr_group_get_ctr(bts->bts_ctrs, BTS_CTR_CHAN_SDCCH_ACTIVE_MILLISECONDS_TOTAL), elapsed_sdcch_ms);
}
unsigned long long bts_uptime(const struct gsm_bts *bts)
unsigned long long bts_updowntime(const struct gsm_bts *bts)
{
struct timespec tp;
if (!bts->uptime || !bts->oml_link)
if (!bts->updowntime)
return 0;
if (osmo_clock_gettime(CLOCK_MONOTONIC, &tp) != 0) {
LOGP(DNM, LOGL_ERROR, "BTS %u uptime computation failure: %s\n", bts->nr, strerror(errno));
LOGP(DNM, LOGL_ERROR, "BTS %u uptime/downtime computation failure: %s\n", bts->nr, strerror(errno));
return 0;
}
/* monotonic clock helps to ensure that the conversion is valid */
return difftime(tp.tv_sec, bts->uptime);
return difftime(tp.tv_sec, bts->updowntime);
}
char *get_model_oml_status(const struct gsm_bts *bts)
@ -888,14 +902,14 @@ int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)
return (base->depends_on[idx] & (1U << bit)) > 0;
}
static int bts_is_online(struct gsm_bts *bts)
static bool bts_is_online(const struct gsm_bts *bts)
{
/* TODO: support E1 BTS too */
if (!is_ipaccess_bts(bts))
return 1;
if (!is_ipa_abisip_bts(bts))
return true;
if (!bts->oml_link)
return 0;
return false;
return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED;
}
@ -978,21 +992,32 @@ int gsm_bts_set_system_infos(struct gsm_bts *bts)
return 0;
}
/* Send the given C0 power reduction value to the BTS */
int gsm_bts_send_c0_power_red(const struct gsm_bts *bts, const uint8_t red)
{
if (!bts_is_online(bts))
return -ENOTCONN;
if (!osmo_bts_has_feature(&bts->features, BTS_FEAT_BCCH_POWER_RED))
return -ENOTSUP;
if (bts->model->power_ctrl_send_c0_power_red == NULL)
return -ENOTSUP;
return bts->model->power_ctrl_send_c0_power_red(bts, red);
}
/* Send the given C0 power reduction value to the BTS and update the internal state */
int gsm_bts_set_c0_power_red(struct gsm_bts *bts, const uint8_t red)
{
struct gsm_bts_trx *c0 = bts->c0;
unsigned int tn;
int rc;
if (!osmo_bts_has_feature(&bts->features, BTS_FEAT_BCCH_POWER_RED))
return -ENOTSUP;
if (bts->model->power_ctrl_set_c0_power_red == NULL)
return -ENOTSUP;
rc = bts->model->power_ctrl_set_c0_power_red(bts, red);
rc = gsm_bts_send_c0_power_red(bts, red);
if (rc != 0)
return rc;
LOG_BTS(bts, DRSL, LOGL_NOTICE, "%sabling BCCH carrier power reduction "
"operation mode (maximum %u dB)\n", red ? "En" : "Dis", red);
/* Timeslot 0 is always transmitting BCCH/CCCH */
c0->ts[0].c0_max_power_red_db = 0;
@ -1003,7 +1028,7 @@ int gsm_bts_set_c0_power_red(struct gsm_bts *bts, const uint8_t red)
switch (ts->pchan_is) {
/* Not allowed on CCCH/BCCH */
case GSM_PCHAN_CCCH:
/* Preceeding timeslot shall not exceed 2 dB */
/* Preceding timeslot shall not exceed 2 dB */
if (prev->c0_max_power_red_db > 0)
prev->c0_max_power_red_db = 2;
/* fall-through */
@ -1632,12 +1657,12 @@ const struct osmo_stat_item_desc bts_stat_desc[] = {
"Number of SDCCH8 channels total",
"", 60, 0 },
[BTS_STAT_CHAN_TCH_F_PDCH_USED] = \
{ "chan_tch_f_pdch:used",
"Number of TCH/F_PDCH channels used",
{ "chan_dynamic_ipaccess:used",
"Number of DYNAMIC/IPACCESS channels used",
"", 60, 0 },
[BTS_STAT_CHAN_TCH_F_PDCH_TOTAL] = \
{ "chan_tch_f_pdch:total",
"Number of TCH/F_PDCH channels total",
{ "chan_dynamic_ipaccess:total",
"Number of DYNAMIC/IPACCESS channels total",
"", 60, 0 },
[BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED] = \
{ "chan_ccch_sdcch4_cbch:used",
@ -1656,12 +1681,12 @@ const struct osmo_stat_item_desc bts_stat_desc[] = {
"Number of SDCCH8+CBCH channels total",
"", 60, 0 },
[BTS_STAT_CHAN_OSMO_DYN_USED] = \
{ "chan_osmo_dyn:used",
"Number of TCH/F_TCH/H_SDCCH8_PDCH channels used",
{ "chan_dynamic_osmocom:used",
"Number of DYNAMIC/OSMOCOM channels used",
"", 60, 0 },
[BTS_STAT_CHAN_OSMO_DYN_TOTAL] = \
{ "chan_osmo_dyn:total",
"Number of TCH/F_TCH/H_SDCCH8_PDCH channels total",
{ "chan_dynamic_osmocom:total",
"Number of DYNAMIC/OSMOCOM channels total",
"", 60, 0 },
[BTS_STAT_T3122] = \
{ "T3122",

File diff suppressed because it is too large Load Diff

View File

@ -131,7 +131,7 @@ struct gsm_bts_model bts_model_nanobts = {
[NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
},
},
.features_get_reported = true,
.features_get_reported = false,
};
@ -150,7 +150,7 @@ static int nm_statechg_event(int evt, struct nm_statechg_signal_data *nsd)
struct gsm_gprs_nse *nse;
struct gsm_gprs_cell *cell;
if (!is_ipaccess_bts(nsd->bts))
if (!is_ipa_abisip_bts(nsd->bts))
return 0;
switch (obj_class) {
@ -195,157 +195,78 @@ static int nm_statechg_event(int evt, struct nm_statechg_signal_data *nsd)
/* Callback function to be called every time we receive a 12.21 SW activated report */
static int sw_activ_rep(struct msgb *mb)
{
struct abis_om_fom_hdr *foh = msgb_l3(mb);
const struct abis_om_fom_hdr *foh = msgb_l3(mb);
struct e1inp_sign_link *sign_link = mb->dst;
struct gsm_bts *bts = sign_link->trx->bts;
struct gsm_bts_trx *trx;
struct gsm_gprs_nsvc *nsvc;
struct gsm_bts_trx_ts *ts;
struct gsm_abis_mo *mo;
struct tlv_parsed tp;
if (!is_ipaccess_bts(bts))
if (!is_ipa_abisip_bts(bts))
return 0;
switch (foh->obj_class) {
case NM_OC_SITE_MANAGER:
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SW_ACT_REP, NULL);
break;
case NM_OC_BTS:
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_SW_ACT_REP, NULL);
break;
case NM_OC_BASEB_TRANSC:
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
return -EINVAL;
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT_REP, NULL);
break;
case NM_OC_RADIO_CARRIER:
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
return -EINVAL;
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT_REP, NULL);
break;
case NM_OC_CHANNEL:
if (!(ts = abis_nm_get_ts(mb)))
return -EINVAL;
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_SW_ACT_REP, NULL);
break;
case NM_OC_GPRS_NSE:
osmo_fsm_inst_dispatch(bts->site_mgr->gprs.nse.mo.fi, NM_EV_SW_ACT_REP, NULL);
break;
case NM_OC_GPRS_CELL:
osmo_fsm_inst_dispatch(bts->gprs.cell.mo.fi, NM_EV_SW_ACT_REP, NULL);
break;
case NM_OC_GPRS_NSVC:
if (!(nsvc = gsm_bts_sm_nsvc_num(bts->site_mgr, foh->obj_inst.trx_nr)))
return -EINVAL;
osmo_fsm_inst_dispatch(nsvc->mo.fi, NM_EV_SW_ACT_REP, NULL);
break;
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
if (mo == NULL) {
LOGPFOH(DNM, LOGL_ERROR, foh, "Rx SW activated report for non-existent MO\n");
return -ENOENT;
}
return 0;
}
static void nm_rx_opstart_ack_chan(struct msgb *oml_msg)
{
struct gsm_bts_trx_ts *ts;
ts = abis_nm_get_ts(oml_msg);
if (!ts)
/* error already logged in abis_nm_get_ts() */
return;
if (!ts->fi) {
LOG_TS(ts, LOGL_ERROR, "Channel OPSTART ACK for uninitialized TS\n");
return;
if (abis_nm_tlv_parse(&tp, bts, &foh->data[0], msgb_l3len(mb) - sizeof(*foh)) < 0) {
LOGPFOH(DNM, LOGL_ERROR, foh, "%s(): tlv_parse failed\n", __func__);
return -EINVAL;
}
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_OPSTART_ACK, NULL);
osmo_fsm_inst_dispatch(ts->fi, TS_EV_OML_READY, NULL);
mo->ipaccess.obj_version = 0; /* implicit default */
if (TLVP_PRES_LEN(&tp, NM_ATT_IPACC_OBJ_VERSION, 1)) {
const uint8_t *versions = TLVP_VAL(&tp, NM_ATT_IPACC_OBJ_VERSION);
char buf[256];
struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) };
/* nanoBTS may report several Object Versions; the first one will
* be used by default unless requested explicitly before OPSTARTing. */
mo->ipaccess.obj_version = versions[0];
OSMO_STRBUF_PRINTF(sb, "%u (default)", versions[0]);
for (uint16_t i = 1; i < TLVP_LEN(&tp, NM_ATT_IPACC_OBJ_VERSION); i++)
OSMO_STRBUF_PRINTF(sb, ", %u", versions[i]);
LOGPFOH(DNM, LOGL_INFO, foh, "IPA Object Versions supported: %s\n", buf);
}
osmo_fsm_inst_dispatch(mo->fi, NM_EV_SW_ACT_REP, NULL);
return 0;
}
static void nm_rx_opstart_ack(struct msgb *oml_msg)
{
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
const struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
struct e1inp_sign_link *sign_link = oml_msg->dst;
struct gsm_bts *bts = sign_link->trx->bts;
struct gsm_bts_trx *trx;
struct gsm_gprs_nsvc *nsvc;
struct gsm_abis_mo *mo;
switch (foh->obj_class) {
case NM_OC_SITE_MANAGER:
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_BTS:
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_RADIO_CARRIER:
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
return;
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_BASEB_TRANSC:
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
return;
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_CHANNEL:
nm_rx_opstart_ack_chan(oml_msg);
break;
case NM_OC_GPRS_NSE:
osmo_fsm_inst_dispatch(bts->site_mgr->gprs.nse.mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_GPRS_CELL:
osmo_fsm_inst_dispatch(bts->gprs.cell.mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_GPRS_NSVC:
if (!(nsvc = gsm_bts_sm_nsvc_num(bts->site_mgr, foh->obj_inst.trx_nr)))
return;
osmo_fsm_inst_dispatch(nsvc->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
default:
break;
}
if (!is_ipa_abisip_bts(bts))
return;
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
if (mo == NULL)
LOGPFOH(DNM, LOGL_ERROR, foh, "Rx OPSTART ACK for non-existent MO\n");
else
osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL);
}
static void nm_rx_opstart_nack(struct msgb *oml_msg)
{
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
const struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
struct e1inp_sign_link *sign_link = oml_msg->dst;
struct gsm_bts *bts = sign_link->trx->bts;
struct gsm_bts_trx *trx;
struct gsm_bts_trx_ts *ts;
struct gsm_gprs_nsvc *nsvc;
struct gsm_abis_mo *mo;
switch (foh->obj_class) {
case NM_OC_SITE_MANAGER:
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OPSTART_NACK, NULL);
break;
case NM_OC_BTS:
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_RADIO_CARRIER:
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
return;
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK, NULL);
break;
case NM_OC_BASEB_TRANSC:
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
return;
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_OPSTART_NACK, NULL);
break;
case NM_OC_CHANNEL:
if (!(ts = abis_nm_get_ts(oml_msg)))
return;
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_OPSTART_NACK, NULL);
break;
case NM_OC_GPRS_NSE:
osmo_fsm_inst_dispatch(bts->site_mgr->gprs.nse.mo.fi, NM_EV_OPSTART_NACK, NULL);
break;
case NM_OC_GPRS_CELL:
osmo_fsm_inst_dispatch(bts->gprs.cell.mo.fi, NM_EV_OPSTART_NACK, NULL);
break;
case NM_OC_GPRS_NSVC:
if (!(nsvc = gsm_bts_sm_nsvc_num(bts->site_mgr, foh->obj_inst.trx_nr)))
return;
osmo_fsm_inst_dispatch(nsvc->mo.fi, NM_EV_OPSTART_NACK, NULL);
break;
default:
break;
}
if (!is_ipa_abisip_bts(bts))
return;
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
if (mo == NULL)
LOGPFOH(DNM, LOGL_ERROR, foh, "Rx OPSTART NACK for non-existent MO\n");
else
osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_NACK, NULL);
}
static void nm_rx_get_attr_rep(struct msgb *oml_msg)
@ -353,20 +274,16 @@ static void nm_rx_get_attr_rep(struct msgb *oml_msg)
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
struct e1inp_sign_link *sign_link = oml_msg->dst;
struct gsm_bts *bts = sign_link->trx->bts;
struct gsm_bts_trx *trx;
struct gsm_abis_mo *mo;
switch (foh->obj_class) {
case NM_OC_BTS:
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_GET_ATTR_REP, NULL);
break;
case NM_OC_BASEB_TRANSC:
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
return;
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_GET_ATTR_REP, NULL);
break;
default:
LOGPFOH(DNM, LOGL_ERROR, foh, "Get Attributes Response received on incorrect object class %d!\n", foh->obj_class);
}
if (!is_ipa_abisip_bts(bts))
return;
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
if (mo == NULL)
LOGPFOH(DNM, LOGL_ERROR, foh, "Rx Get Attribute Report for non-existent MO\n");
else
osmo_fsm_inst_dispatch(mo->fi, NM_EV_GET_ATTR_REP, NULL);
}
static void nm_rx_set_bts_attr_ack(struct msgb *oml_msg)
@ -375,6 +292,9 @@ static void nm_rx_set_bts_attr_ack(struct msgb *oml_msg)
struct e1inp_sign_link *sign_link = oml_msg->dst;
struct gsm_bts *bts = sign_link->trx->bts;
if (!is_ipa_abisip_bts(bts))
return;
if (foh->obj_class != NM_OC_BTS) {
LOG_BTS(bts, DNM, LOGL_ERROR, "Set BTS Attr Ack received on non BTS object!\n");
return;
@ -388,8 +308,12 @@ static void nm_rx_set_radio_attr_ack(struct msgb *oml_msg)
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
struct e1inp_sign_link *sign_link = oml_msg->dst;
struct gsm_bts *bts = sign_link->trx->bts;
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
struct gsm_bts_trx *trx;
if (!is_ipa_abisip_bts(bts))
return;
trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
if (!trx || foh->obj_class != NM_OC_RADIO_CARRIER) {
LOGPFOH(DNM, LOGL_ERROR, foh, "Set Radio Carrier Attr Ack received on non Radio Carrier object!\n");
return;
@ -400,8 +324,14 @@ static void nm_rx_set_radio_attr_ack(struct msgb *oml_msg)
static void nm_rx_set_chan_attr_ack(struct msgb *oml_msg)
{
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
struct gsm_bts_trx_ts *ts = abis_nm_get_ts(oml_msg);
struct e1inp_sign_link *sign_link = oml_msg->dst;
struct gsm_bts *bts = sign_link->trx->bts;
struct gsm_bts_trx_ts *ts;
if (!is_ipa_abisip_bts(bts))
return;
ts = abis_nm_get_ts(oml_msg);
if (!ts || foh->obj_class != NM_OC_CHANNEL) {
LOGPFOH(DNM, LOGL_ERROR, foh, "Set Channel Attr Ack received on non Radio Channel object!\n");
return;
@ -565,7 +495,7 @@ find_bts_by_unitid(struct gsm_network *net, uint16_t site_id, uint16_t bts_id)
struct gsm_bts *bts;
llist_for_each_entry(bts, &net->bts_list, list) {
if (!is_ipaccess_bts(bts))
if (!is_ipa_abisip_bts(bts))
continue;
if (bts->ip_access.site_id == site_id &&
@ -597,6 +527,8 @@ void ipaccess_drop_oml(struct gsm_bts *bts, const char *reason)
struct gsm_bts_trx_ts *ts ;
uint8_t tn;
uint8_t i;
struct timespec tp;
int rc;
/* First of all, remove deferred drop if enabled */
osmo_timer_del(&bts->oml_drop_link_timer);
@ -607,7 +539,8 @@ void ipaccess_drop_oml(struct gsm_bts *bts, const char *reason)
LOG_BTS(bts, DLINP, LOGL_NOTICE, "Dropping OML link: %s\n", reason);
e1inp_sign_link_destroy(bts->oml_link);
bts->oml_link = NULL;
bts->uptime = 0;
rc = osmo_clock_gettime(CLOCK_MONOTONIC, &tp);
bts->updowntime = (rc < 0) ? 0 : tp.tv_sec; /* we don't need sub-second precision for downtime */
osmo_stat_item_dec(osmo_stat_item_group_get_item(bts->bts_statg, BTS_STAT_OML_CONNECTED), 1);
gsm_bts_stats_reset(bts);
@ -637,10 +570,14 @@ void ipaccess_drop_oml(struct gsm_bts *bts, const char *reason)
for (i = 0; i < ARRAY_SIZE(bts->site_mgr->gprs.nsvc); i++)
osmo_fsm_inst_dispatch(bts->site_mgr->gprs.nsvc[i].mo.fi, NM_EV_OML_DOWN, NULL);
gsm_bts_all_ts_dispatch(bts, TS_EV_OML_DOWN, NULL);
bts->ip_access.flags = 0;
if (bts->model->features_get_reported) {
/* Reset the feature vector */
memset(bts->_features_data, 0, sizeof(bts->_features_data));
bts->features_known = false;
}
/*
* Go through the list and see if we are the depndency of a BTS
* and then drop the BTS. This can lead to some recursion but it
@ -776,7 +713,7 @@ ipaccess_sign_link_up(void *unit_data, struct e1inp_line *line,
E1INP_SIGN_OML, bts->c0,
bts->oml_tei, 0);
rc = osmo_clock_gettime(CLOCK_MONOTONIC, &tp);
bts->uptime = (rc < 0) ? 0 : tp.tv_sec; /* we don't need sub-second precision for uptime */
bts->updowntime = (rc < 0) ? 0 : tp.tv_sec; /* we don't need sub-second precision for uptime */
if (!(sign_link->trx->bts->ip_access.flags & OML_UP)) {
e1inp_event(sign_link->ts, S_L_INP_TEI_UP,
sign_link->tei, sign_link->sapi);

View File

@ -1,6 +1,6 @@
/* ip.access nanoBTS specific code, OML attribute table generator */
/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
/* (C) 2016-2023 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Philipp Maier
@ -26,13 +26,81 @@
#include <osmocom/bsc/bts.h>
#include <osmocom/gsm/bts_features.h>
const struct tlv_definition ipacc_eie_tlv_def = {
.def = {
/* TODO: add more values from enum ipac_eie */
[NM_IPAC_EIE_FREQ_BANDS] = { TLV_TYPE_TL16V },
[NM_IPAC_EIE_MAX_TA] = { TLV_TYPE_TL16V },
[NM_IPAC_EIE_CIPH_ALGOS] = { TLV_TYPE_TL16V },
[NM_IPAC_EIE_CHAN_TYPES] = { TLV_TYPE_TL16V },
[NM_IPAC_EIE_CHAN_MODES] = { TLV_TYPE_TL16V },
[NM_IPAC_EIE_GPRS_CODING] = { TLV_TYPE_TL16V },
[NM_IPAC_EIE_RTP_FEATURES] = { TLV_TYPE_TL16V },
[NM_IPAC_EIE_RSL_FEATURES] = { TLV_TYPE_TL16V },
}
};
static inline uint32_t ipacc_parse_supp_flags(const struct abis_om_fom_hdr *foh,
const struct value_string *flags,
const struct tlv_p_entry *e,
const char *text)
{
uint32_t u32 = 0;
for (unsigned int i = 0; i < OSMO_MAX(e->len, 4); i++)
u32 |= e->val[i] << (i * 8);
for (const struct value_string *vs = flags; vs->value && vs->str; vs++) {
if (u32 & vs->value)
LOGPFOH(DNM, LOGL_INFO, foh, "%s '%s' is supported\n", text, vs->str);
}
return u32;
}
/* Parse ip.access Supported Features IE */
int ipacc_parse_supp_features(const struct gsm_bts *bts,
const struct abis_om_fom_hdr *foh,
const uint8_t *data, uint16_t data_len)
{
const struct tlv_p_entry *e;
struct tlv_parsed tp;
if (tlv_parse(&tp, &ipacc_eie_tlv_def, data, data_len, 0, 0) < 0) {
LOGPFOH(DNM, LOGL_ERROR, foh, "%s(): tlv_parse failed\n", __func__);
return -EINVAL;
}
/* TODO: store the flags in the respective MO state */
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_FREQ_BANDS)) != NULL)
ipacc_parse_supp_flags(foh, abis_nm_ipacc_freq_band_desc, e, "Freq. band");
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_CIPH_ALGOS)) != NULL)
ipacc_parse_supp_flags(foh, abis_nm_ipacc_ciph_algo_desc, e, "Ciphering algorithm");
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_CHAN_TYPES)) != NULL)
ipacc_parse_supp_flags(foh, abis_nm_ipacc_chant_desc, e, "Channel type");
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_CHAN_MODES)) != NULL)
ipacc_parse_supp_flags(foh, abis_nm_ipacc_chanm_desc, e, "Channel mode");
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_GPRS_CODING)) != NULL)
ipacc_parse_supp_flags(foh, abis_nm_ipacc_gprs_coding_desc, e, "GPRS Coding Scheme");
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_RTP_FEATURES)) != NULL)
ipacc_parse_supp_flags(foh, abis_nm_ipacc_rtp_feat_desc, e, "RTP Feature");
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_RSL_FEATURES)) != NULL)
ipacc_parse_supp_flags(foh, abis_nm_ipacc_rsl_feat_desc, e, "RSL Feature");
if (TLVP_PRES_LEN(&tp, NM_IPAC_EIE_MAX_TA, 1)) {
uint8_t u8 = *TLVP_VAL(&tp, NM_IPAC_EIE_MAX_TA);
LOGPFOH(DNM, LOGL_DEBUG, foh, "Max Timing Advance %u\n", u8);
}
return 0;
}
/* 3GPP TS 52.021 section 8.6.1 Set BTS Attributes */
struct msgb *nanobts_gen_set_bts_attr(struct gsm_bts *bts)
{
struct msgb *msgb;
uint8_t buf[256];
int rlt;
msgb = msgb_alloc(1024, "nanobts_attr_bts");
msgb = msgb_alloc(1024, __func__);
if (!msgb)
return NULL;
@ -112,9 +180,12 @@ struct msgb *nanobts_gen_set_bts_attr(struct gsm_bts *bts)
struct msgb *nanobts_gen_set_nse_attr(struct gsm_bts_sm *bts_sm)
{
struct msgb *msgb;
uint8_t buf[256];
uint8_t buf[2];
struct abis_nm_ipacc_att_ns_cfg ns_cfg;
struct abis_nm_ipacc_att_bssgp_cfg bssgp_cfg;
struct gsm_bts *bts = gsm_bts_sm_get_bts(bts_sm);
msgb = msgb_alloc(1024, "nanobts_attr_bts");
msgb = msgb_alloc(1024, __func__);
if (!msgb)
return NULL;
@ -123,36 +194,45 @@ struct msgb *nanobts_gen_set_nse_attr(struct gsm_bts_sm *bts_sm)
buf[1] = bts_sm->gprs.nse.nsei & 0xff;
msgb_tl16v_put(msgb, NM_ATT_IPACC_NSEI, 2, buf);
/* all timers in seconds */
OSMO_ASSERT(ARRAY_SIZE(bts_sm->gprs.nse.timer) < sizeof(buf));
memcpy(buf, bts_sm->gprs.nse.timer, ARRAY_SIZE(bts_sm->gprs.nse.timer));
msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_CFG, 7, buf);
osmo_static_assert(ARRAY_SIZE(bts_sm->gprs.nse.timer) == 7, nse_timer_array_wrong_size);
ns_cfg = (struct abis_nm_ipacc_att_ns_cfg){
.un_blocking_timer = bts_sm->gprs.nse.timer[0],
.un_blocking_retries = bts_sm->gprs.nse.timer[1],
.reset_timer = bts_sm->gprs.nse.timer[2],
.reset_retries = bts_sm->gprs.nse.timer[3],
.test_timer = bts_sm->gprs.nse.timer[4],
.alive_timer = bts_sm->gprs.nse.timer[5],
.alive_retries = bts_sm->gprs.nse.timer[6],
};
msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_CFG, sizeof(ns_cfg), (const uint8_t *)&ns_cfg);
/* all timers in seconds */
buf[0] = 3; /* blockimg timer (T1) */
buf[1] = 3; /* blocking retries */
buf[2] = 3; /* unblocking retries */
buf[3] = 3; /* reset timer (T2) */
buf[4] = 3; /* reset retries */
buf[5] = 10; /* suspend timer (T3) in 100ms */
buf[6] = 3; /* suspend retries */
buf[7] = 10; /* resume timer (T4) in 100ms */
buf[8] = 3; /* resume retries */
buf[9] = 10; /* capability update timer (T5) */
buf[10] = 3; /* capability update retries */
OSMO_ASSERT(ARRAY_SIZE(bts->gprs.cell.timer) < sizeof(buf));
memcpy(buf, bts->gprs.cell.timer, ARRAY_SIZE(bts->gprs.cell.timer));
msgb_tl16v_put(msgb, NM_ATT_IPACC_BSSGP_CFG, 11, buf);
osmo_static_assert(ARRAY_SIZE(bts->gprs.cell.timer) == 11, cell_timer_array_wrong_size);
bssgp_cfg = (struct abis_nm_ipacc_att_bssgp_cfg){
.t1_s = bts->gprs.cell.timer[0],
.t1_blocking_retries = bts->gprs.cell.timer[1],
.t1_unblocking_retries = bts->gprs.cell.timer[2],
.t2_s = bts->gprs.cell.timer[3],
.t2_retries = bts->gprs.cell.timer[4],
.t3_100ms = bts->gprs.cell.timer[5],
.t3_retries = bts->gprs.cell.timer[6],
.t4_100ms = bts->gprs.cell.timer[7],
.t4_retries = bts->gprs.cell.timer[8],
.t5_s = bts->gprs.cell.timer[9],
.t5_retries = bts->gprs.cell.timer[10],
};
msgb_tl16v_put(msgb, NM_ATT_IPACC_BSSGP_CFG, sizeof(bssgp_cfg), (const uint8_t *)&bssgp_cfg);
return msgb;
}
struct msgb *nanobts_gen_set_cell_attr(struct gsm_bts *bts)
{
const struct gsm_gprs_cell *cell = &bts->gprs.cell;
const struct gprs_rlc_cfg *rlcc = &cell->rlc_cfg;
struct msgb *msgb;
uint8_t buf[256];
msgb = msgb_alloc(1024, "nanobts_attr_bts");
uint8_t buf[2];
msgb = msgb_alloc(1024, __func__);
if (!msgb)
return NULL;
@ -160,49 +240,88 @@ struct msgb *nanobts_gen_set_cell_attr(struct gsm_bts *bts)
buf[0] = bts->gprs.rac;
msgb_tl16v_put(msgb, NM_ATT_IPACC_RAC, 1, buf);
buf[0] = 5; /* repeat time (50ms) */
buf[1] = 3; /* repeat count */
buf[0] = rlcc->paging.repeat_time / 50; /* units of 50ms */
buf[1] = rlcc->paging.repeat_count;
msgb_tl16v_put(msgb, NM_ATT_IPACC_GPRS_PAGING_CFG, 2, buf);
/* BVCI 925 */
buf[0] = bts->gprs.cell.bvci >> 8;
buf[1] = bts->gprs.cell.bvci & 0xff;
buf[0] = cell->bvci >> 8;
buf[1] = cell->bvci & 0xff;
msgb_tl16v_put(msgb, NM_ATT_IPACC_BVCI, 2, buf);
/* all timers in seconds, unless otherwise stated */
buf[0] = 20; /* T3142 */
buf[1] = 5; /* T3169 */
buf[2] = 5; /* T3191 */
buf[3] = 160; /* T3193 (units of 10ms) */
buf[4] = 5; /* T3195 */
buf[5] = 10; /* N3101 */
buf[6] = 4; /* N3103 */
buf[7] = 8; /* N3105 */
buf[8] = 15; /* RLC CV countdown */
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG, 9, buf);
const struct abis_nm_ipacc_att_rlc_cfg rlc_cfg = {
.t3142 = rlcc->parameter[RLC_T3142],
.t3169 = rlcc->parameter[RLC_T3169],
.t3191 = rlcc->parameter[RLC_T3191],
.t3193_10ms = rlcc->parameter[RLC_T3193],
.t3195 = rlcc->parameter[RLC_T3195],
.n3101 = rlcc->parameter[RLC_N3101],
.n3103 = rlcc->parameter[RLC_N3103],
.n3105 = rlcc->parameter[RLC_N3105],
.rlc_cv_countdown = rlcc->parameter[CV_COUNTDOWN],
};
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG, sizeof(rlc_cfg), (const uint8_t *)&rlc_cfg);
if (bts->gprs.mode == BTS_GPRS_EGPRS) {
buf[0] = 0x8f;
buf[1] = 0xff;
} else {
buf[0] = 0x0f;
switch (bts->type) {
case GSM_BTS_TYPE_NANOBTS:
if (cell->mo.ipaccess.obj_version < 4)
break;
/* fall-through */
case GSM_BTS_TYPE_OSMOBTS:
/* CS1..CS4 flags encoded in the first octet */
buf[0] = rlcc->cs_mask & 0x0f;
/* MCS1..MSC8 flags encoded in the second octet */
buf[1] = 0x00;
if (bts->gprs.mode == BTS_GPRS_EGPRS) {
/* MSC9 is special and also goes to the first octet */
if (rlcc->cs_mask & (1 << GPRS_MCS9))
buf[0] |= (1 << 7);
buf[1] = (rlcc->cs_mask >> 4) & 0xff;
}
msgb_tl16v_put(msgb, NM_ATT_IPACC_CODING_SCHEMES, 2, buf);
break;
default:
break;
}
msgb_tl16v_put(msgb, NM_ATT_IPACC_CODING_SCHEMES, 2, buf);
buf[0] = 0; /* T downlink TBF extension (0..500, high byte) */
buf[1] = 250; /* T downlink TBF extension (0..500, low byte) */
buf[2] = 0; /* T uplink TBF extension (0..500, high byte) */
buf[3] = 250; /* T uplink TBF extension (0..500, low byte) */
buf[4] = 2; /* CS2 */
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_2, 5, buf);
switch (bts->type) {
case GSM_BTS_TYPE_NANOBTS:
if (cell->mo.ipaccess.obj_version < 20)
break;
/* fall-through */
case GSM_BTS_TYPE_OSMOBTS:
{
const struct abis_nm_ipacc_att_rlc_cfg_2 rlc_cfg_2 = {
.t_dl_tbf_ext_10ms = htons(rlcc->parameter[T_DL_TBF_EXT] / 10),
.t_ul_tbf_ext_10ms = htons(rlcc->parameter[T_UL_TBF_EXT] / 10),
.initial_cs = rlcc->initial_cs,
};
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_2,
sizeof(rlc_cfg_2), (const uint8_t *)&rlc_cfg_2);
break;
}
default:
break;
}
#if 0
/* EDGE model only, breaks older models.
* Should inquire the BTS capabilities */
buf[0] = 2; /* MCS2 */
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_3, 1, buf);
#endif
switch (bts->type) {
case GSM_BTS_TYPE_NANOBTS:
if (cell->mo.ipaccess.obj_version < 30)
break;
/* fall-through */
case GSM_BTS_TYPE_OSMOBTS:
{
const struct abis_nm_ipacc_att_rlc_cfg_3 rlc_cfg_3 = {
.initial_mcs = rlcc->initial_mcs,
};
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_3,
sizeof(rlc_cfg_3), (const uint8_t *)&rlc_cfg_3);
break;
}
default:
break;
}
return msgb;
}
@ -211,7 +330,8 @@ struct msgb *nanobts_gen_set_nsvc_attr(struct gsm_gprs_nsvc *nsvc)
{
struct msgb *msgb;
uint8_t buf[256];
msgb = msgb_alloc(1024, "nanobts_attr_bts");
msgb = msgb_alloc(1024, __func__);
if (!msgb)
return NULL;
@ -256,7 +376,8 @@ struct msgb *nanobts_gen_set_radio_attr(struct gsm_bts *bts,
{
struct msgb *msgb;
uint8_t buf[256];
msgb = msgb_alloc(1024, "nanobts_attr_bts");
msgb = msgb_alloc(1024, __func__);
if (!msgb)
return NULL;

View File

@ -1338,7 +1338,7 @@ static int find_element(uint8_t * data, int len, uint16_t id, uint8_t * value,
GET_NEXT_BYTE;
/* encoding bit, construced means that other elements are contained */
/* encoding bit, constructed means that other elements are contained */
constructed = ((ub & 0x20) ? 1 : 0);
if ((ub & 0x1F) == 0x1F) {
@ -1397,7 +1397,7 @@ static int dump_elements(uint8_t * data, int len)
GET_NEXT_BYTE;
/* encoding bit, construced means that other elements are contained */
/* encoding bit, constructed means that other elements are contained */
constructed = ((ub & 0x20) ? 1 : 0);
if ((ub & 0x1F) == 0x1F) {

View File

@ -1,7 +1,7 @@
/* Osmocom OsmoBTS specific code */
/* (C) 2010-2012 by Harald Welte <laforge@gnumonks.org>
* (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
*
* All Rights Reserved
*
@ -159,8 +159,7 @@ void osmobts_enc_power_params_osmo_ext(struct msgb *msg, const struct gsm_power_
*ie_len = msg->tail - (ie_len + 1);
}
static int power_ctrl_set_c0_power_red(const struct gsm_bts *bts,
const uint8_t red)
static int power_ctrl_send_c0_power_red(const struct gsm_bts *bts, const uint8_t red)
{
struct abis_rsl_dchan_hdr *dh;
struct msgb *msg;
@ -169,10 +168,6 @@ static int power_ctrl_set_c0_power_red(const struct gsm_bts *bts,
if (msg == NULL)
return -ENOMEM;
LOGP(DRSL, LOGL_NOTICE, "%sabling BCCH carrier power reduction "
"operation mode for BTS%u (maximum %u dB)\n",
red ? "En" : "Dis", bts->nr, red);
/* Abuse the standard BS POWER CONTROL message by specifying 'Common Channel'
* in the Protocol Discriminator field and 'BCCH' in the Channel Number IE. */
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
@ -193,12 +188,13 @@ int bts_model_osmobts_init(void)
model_osmobts = bts_model_nanobts;
model_osmobts.name = "osmo-bts";
model_osmobts.type = GSM_BTS_TYPE_OSMOBTS;
model_osmobts.features_get_reported = true;
/* Unlike nanoBTS, osmo-bts does support SI2bis and SI2ter fine */
model_osmobts.force_combined_si = false;
/* Power control API */
model_osmobts.power_ctrl_set_c0_power_red = &power_ctrl_set_c0_power_red;
model_osmobts.power_ctrl_send_c0_power_red = &power_ctrl_send_c0_power_red;
model_osmobts.features.data = &model_osmobts._features_data[0];
model_osmobts.features.data_len =

View File

@ -401,7 +401,7 @@ static void nm_reconfig_ts(struct gsm_bts_trx_ts *ts)
abis_nm_set_channel_attr(ts, ccomb);
if (is_ipaccess_bts(ts->trx->bts))
if (is_ipa_abisip_bts(ts->trx->bts))
return;
switch (ts->pchan_from_config) {
@ -423,57 +423,35 @@ static void nm_reconfig_trx(struct gsm_bts_trx *trx)
patch_nm_tables(trx->bts);
switch (trx->bts->type) {
case GSM_BTS_TYPE_BS11:
/* FIXME: discover this by fetching an attribute */
/* FIXME: discover this by fetching an attribute */
#if 0
trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
#else
trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
#endif
abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
e1l->e1_ts_ss);
abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei_primary);
abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
e1l->e1_ts_ss);
abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei_primary);
/* Set Radio Attributes */
if (trx == trx->bts->c0)
abis_nm_set_radio_attr(trx, bs11_attr_radio,
sizeof(bs11_attr_radio));
else {
uint8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
uint8_t arfcn_low = trx->arfcn & 0xff;
uint8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
memcpy(trx1_attr_radio, bs11_attr_radio,
sizeof(trx1_attr_radio));
/* Set Radio Attributes */
if (trx == trx->bts->c0)
abis_nm_set_radio_attr(trx, bs11_attr_radio,
sizeof(bs11_attr_radio));
else {
uint8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
uint8_t arfcn_low = trx->arfcn & 0xff;
uint8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
memcpy(trx1_attr_radio, bs11_attr_radio,
sizeof(trx1_attr_radio));
/* patch ARFCN into TRX Attributes */
trx1_attr_radio[2] &= 0xf0;
trx1_attr_radio[2] |= arfcn_high;
trx1_attr_radio[3] = arfcn_low;
/* patch ARFCN into TRX Attributes */
trx1_attr_radio[2] &= 0xf0;
trx1_attr_radio[2] |= arfcn_high;
trx1_attr_radio[3] = arfcn_low;
abis_nm_set_radio_attr(trx, trx1_attr_radio,
sizeof(trx1_attr_radio));
}
break;
case GSM_BTS_TYPE_NANOBTS:
switch (trx->bts->band) {
case GSM_BAND_850:
case GSM_BAND_900:
trx->nominal_power = 20;
break;
case GSM_BAND_1800:
case GSM_BAND_1900:
trx->nominal_power = 23;
break;
default:
LOGP(DNM, LOGL_ERROR, "Unsupported nanoBTS GSM band %s\n",
gsm_band_name(trx->bts->band));
break;
}
break;
default:
break;
abis_nm_set_radio_attr(trx, trx1_attr_radio,
sizeof(trx1_attr_radio));
}
for (i = 0; i < TRX_NR_TS; i++)
@ -484,17 +462,11 @@ static void nm_reconfig_bts(struct gsm_bts *bts)
{
struct gsm_bts_trx *trx;
switch (bts->type) {
case GSM_BTS_TYPE_BS11:
patch_nm_tables(bts);
abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
break;
default:
break;
}
patch_nm_tables(bts);
abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
llist_for_each_entry(trx, &bts->trx_list, list)
nm_reconfig_trx(trx);

View File

@ -264,7 +264,7 @@ void gsm_trx_lock_rf(struct gsm_bts_trx *trx, bool locked, const char *reason)
bool trx_is_usable(const struct gsm_bts_trx *trx)
{
/* FIXME: How does this behave for BS-11 ? */
if (is_ipaccess_bts(trx->bts)) {
if (is_ipa_abisip_bts(trx->bts)) {
if (!nm_is_running(&trx->mo.nm_state) ||
!nm_is_running(&trx->bb_transc.mo.nm_state))
return false;

View File

@ -19,112 +19,11 @@
*
*/
#include <errno.h>
#include <time.h>
#include <osmocom/ctrl/control_cmd.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/misc.h>
#include <osmocom/bsc/ctrl.h>
#include <osmocom/bsc/osmo_bsc_rf.h>
#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/ipaccess.h>
#include <osmocom/bsc/chan_alloc.h>
#include <osmocom/bsc/abis_nm.h>
#include <osmocom/bsc/neighbor_ident.h>
#include <osmocom/bsc/system_information.h>
/*********************
* TS_NODE
*********************/
static int verify_ts_hopping_arfcn_add(struct ctrl_cmd *cmd, const char *value, void *_data)
{
int64_t arfcn;
enum gsm_band unused;
if (osmo_str_to_int64(&arfcn, value, 10, 0, 1024) < 0)
return 1;
if (gsm_arfcn2band_rc(arfcn, &unused) < 0) {
return 1;
}
return 0;
}
static int set_ts_hopping_arfcn_add(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts_trx_ts *ts = cmd->node;
int arfcn = atoi(cmd->value);
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ONE);
/* Update Cell Allocation (list of all the frequencies allocated to a cell) */
if (generate_cell_chan_alloc(ts->trx->bts) != 0) {
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ZERO); /* roll-back */
cmd->reply = "Failed to re-generate Cell Allocation";
return CTRL_CMD_ERROR;
}
cmd->reply = "OK";
return CTRL_CMD_REPLY;
}
/* Parameter format: "<arfcn>" */
CTRL_CMD_DEFINE_WO(ts_hopping_arfcn_add, "hopping-arfcn-add");
static int verify_ts_hopping_arfcn_del(struct ctrl_cmd *cmd, const char *value, void *_data)
{
int64_t arfcn;
enum gsm_band unused;
if (strcmp(value, "all") == 0)
return 0;
if (osmo_str_to_int64(&arfcn, value, 10, 0, 1024) < 0)
return 1;
if (gsm_arfcn2band_rc(arfcn, &unused) < 0) {
return 1;
}
return 0;
}
static int set_ts_hopping_arfcn_del(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts_trx_ts *ts = cmd->node;
bool all = (strcmp(cmd->value, "all") == 0);
int arfcn;
if (all) {
bitvec_zero(&ts->hopping.arfcns);
} else {
arfcn = atoi(cmd->value);
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ZERO);
}
/* Update Cell Allocation (list of all the frequencies allocated to a cell) */
if (generate_cell_chan_alloc(ts->trx->bts) != 0) {
if (!all)
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ONE); /* roll-back */
cmd->reply = "Failed to re-generate Cell Allocation";
return CTRL_CMD_ERROR;
}
cmd->reply = "OK";
return CTRL_CMD_REPLY;
}
/* Parameter format: "(<arfcn>|all)" */
CTRL_CMD_DEFINE_WO(ts_hopping_arfcn_del, "hopping-arfcn-del");
static int bsc_bts_trx_ts_ctrl_cmds_install(void)
{
int rc = 0;
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_hopping_arfcn_add);
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_hopping_arfcn_del);
return rc;
}
/*********************
* TRX_NODE
*********************/
static int get_trx_rf_locked(struct ctrl_cmd *cmd, void *data)
{
@ -198,6 +97,51 @@ static int set_trx_max_power(struct ctrl_cmd *cmd, void *_data)
}
CTRL_CMD_DEFINE(trx_max_power, "max-power-reduction");
char *trx_lchan_dump_full_ctrl(const void *t, struct gsm_bts_trx *trx)
{
int ts_nr;
bool first_ts = true;
char *ts_dump, *dump;
dump = talloc_strdup(t, "");
if (!dump)
return NULL;
for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
ts_dump = ts_lchan_dump_full_ctrl(t, &trx->ts[ts_nr]);
if (!ts_dump)
return NULL;
if (!strlen(ts_dump))
continue;
dump = talloc_asprintf_append(dump, first_ts ? "%s" : "\n%s", ts_dump);
if (!dump)
return NULL;
first_ts = false;
}
return dump;
}
/* Return full information about all logical channels in a TRX.
* format: bts.<0-255>.trx.<0-255>.show-lchan.full
* result format: New line delimited list of <bts>,<trx>,<ts>,<lchan>,<type>,<connection>,<state>,<last error>,<bs power>,
* <ms power>,<interference dbm>, <interference band>,<channel mode>,<imsi>,<tmsi>,<ipa bound ip>,<ipa bound port>,
* <ipa bound conn id>,<ipa conn ip>,<ipa conn port>,<ipa conn speech mode>
*/
static int get_trx_show_lchan_full(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts_trx *trx = cmd->node;
cmd->reply = trx_lchan_dump_full_ctrl(cmd, trx);
if (!cmd->reply) {
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
return CTRL_CMD_REPLY;
}
CTRL_CMD_DEFINE_RO(trx_show_lchan_full, "show-lchan full");
int bsc_bts_trx_ctrl_cmds_install(void)
{
int rc = 0;
@ -205,6 +149,7 @@ int bsc_bts_trx_ctrl_cmds_install(void)
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_max_power);
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_arfcn);
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_rf_locked);
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_show_lchan_full);
rc |= bsc_bts_trx_ts_ctrl_cmds_install();

View File

@ -0,0 +1,151 @@
/*
* (C) 2013-2015 by Holger Hans Peter Freyther
* (C) 2013-2022 by sysmocom s.f.m.c. GmbH
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <osmocom/ctrl/control_cmd.h>
#include <osmocom/bsc/ctrl.h>
#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/system_information.h>
static int verify_ts_hopping_arfcn_add(struct ctrl_cmd *cmd, const char *value, void *_data)
{
int64_t arfcn;
enum gsm_band unused;
if (osmo_str_to_int64(&arfcn, value, 10, 0, 1024) < 0)
return 1;
if (gsm_arfcn2band_rc(arfcn, &unused) < 0)
return 1;
return 0;
}
static int set_ts_hopping_arfcn_add(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts_trx_ts *ts = cmd->node;
int arfcn = atoi(cmd->value);
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ONE);
/* Update Cell Allocation (list of all the frequencies allocated to a cell) */
if (generate_cell_chan_alloc(ts->trx->bts) != 0) {
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ZERO); /* roll-back */
cmd->reply = "Failed to re-generate Cell Allocation";
return CTRL_CMD_ERROR;
}
cmd->reply = "OK";
return CTRL_CMD_REPLY;
}
/* Parameter format: "<arfcn>" */
CTRL_CMD_DEFINE_WO(ts_hopping_arfcn_add, "hopping-arfcn-add");
static int verify_ts_hopping_arfcn_del(struct ctrl_cmd *cmd, const char *value, void *_data)
{
int64_t arfcn;
enum gsm_band unused;
if (strcmp(value, "all") == 0)
return 0;
if (osmo_str_to_int64(&arfcn, value, 10, 0, 1024) < 0)
return 1;
if (gsm_arfcn2band_rc(arfcn, &unused) < 0)
return 1;
return 0;
}
static int set_ts_hopping_arfcn_del(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts_trx_ts *ts = cmd->node;
bool all = (strcmp(cmd->value, "all") == 0);
int arfcn;
if (all) {
bitvec_zero(&ts->hopping.arfcns);
} else {
arfcn = atoi(cmd->value);
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ZERO);
}
/* Update Cell Allocation (list of all the frequencies allocated to a cell) */
if (generate_cell_chan_alloc(ts->trx->bts) != 0) {
if (!all)
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ONE); /* roll-back */
cmd->reply = "Failed to re-generate Cell Allocation";
return CTRL_CMD_ERROR;
}
cmd->reply = "OK";
return CTRL_CMD_REPLY;
}
/* Parameter format: "(<arfcn>|all)" */
CTRL_CMD_DEFINE_WO(ts_hopping_arfcn_del, "hopping-arfcn-del");
char *ts_lchan_dump_full_ctrl(const void *t, struct gsm_bts_trx_ts *ts)
{
bool first_lchan = true;
char *lchan_dump, *dump;
struct gsm_lchan *lchan;
dump = talloc_strdup(t, "");
if (!dump)
return NULL;
ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
lchan_dump = lchan_dump_full_ctrl(t, lchan);
if (!lchan_dump)
return NULL;
dump = talloc_asprintf_append(dump, first_lchan ? "%s" : "\n%s", lchan_dump);
if (!dump)
return NULL;
first_lchan = false;
}
return dump;
}
/* Return full information about all logical channels in a timeslot.
* format: bts.<0-255>.trx.<0-255>.ts.<0-8>.show-lchan.full
* result format: New line delimited list of <bts>,<trx>,<ts>,<lchan>,<type>,<connection>,<state>,<last error>,<bs power>,
* <ms power>,<interference dbm>, <interference band>,<channel mode>,<imsi>,<tmsi>,<ipa bound ip>,<ipa bound port>,
* <ipa bound conn id>,<ipa conn ip>,<ipa conn port>,<ipa conn speech mode>
*/
static int get_ts_show_lchan_full(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts_trx_ts *ts = cmd->node;
cmd->reply = ts_lchan_dump_full_ctrl(cmd, ts);
if (!cmd->reply) {
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
return CTRL_CMD_REPLY;
}
CTRL_CMD_DEFINE_RO(ts_show_lchan_full, "show-lchan full");
int bsc_bts_trx_ts_ctrl_cmds_install(void)
{
int rc = 0;
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_hopping_arfcn_add);
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_hopping_arfcn_del);
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_show_lchan_full);
rc |= bsc_bts_trx_ts_lchan_ctrl_cmds_install();
return rc;
}

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