mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-bts.git
synced 2025-11-18 12:43:33 +00:00
Compare commits
1 Commits
keith/dtx-
...
daniel/abi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08f337abec |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -93,7 +93,6 @@ debian/tmp/
|
|||||||
doc/manuals/*.html
|
doc/manuals/*.html
|
||||||
doc/manuals/*.svg
|
doc/manuals/*.svg
|
||||||
doc/manuals/*.pdf
|
doc/manuals/*.pdf
|
||||||
doc/manuals/vty/*.pdf
|
|
||||||
doc/manuals/*__*.png
|
doc/manuals/*__*.png
|
||||||
doc/manuals/*.check
|
doc/manuals/*.check
|
||||||
doc/manuals/generated/
|
doc/manuals/generated/
|
||||||
|
|||||||
@@ -7,4 +7,6 @@
|
|||||||
# If any interfaces have been added since the last public release: c:r:a + 1.
|
# 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.
|
# If any interfaces have been removed or changed since the last public release: c:r:0.
|
||||||
#library what description / commit summary line
|
#library what description / commit summary line
|
||||||
libosmogsm >1.8.0 <osmocom/gsm/protocol/gsm_44_060.h> added
|
libosmocore >1.7.0 BTS_FEAT_OSMUX, RSL_IE_OSMO_OSMUX_CID
|
||||||
|
libosmo-netif >1.2.0 OSMUX_DEFAULT_PORT, new osmux APIs
|
||||||
|
libosmo-abis >1.3.0 e1inp_ipa_bts_rsl_close_n()
|
||||||
|
|||||||
19
configure.ac
19
configure.ac
@@ -69,15 +69,16 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
dnl checks for libraries
|
dnl checks for libraries
|
||||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.8.0)
|
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.8.0)
|
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.8.0)
|
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.8.0)
|
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.8.0)
|
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.8.0)
|
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.4.0)
|
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.3.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.4.0)
|
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.3.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.3.0)
|
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.2.0)
|
||||||
|
#FIXME: ^ it actually needs > 1.2.0
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to enable support for sysmobts calibration tool])
|
AC_MSG_CHECKING([whether to enable support for sysmobts calibration tool])
|
||||||
AC_ARG_ENABLE(sysmobts-calib,
|
AC_ARG_ENABLE(sysmobts-calib,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export LD_LIBRARY_PATH="$inst/lib"
|
|||||||
|
|
||||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
osmo-build-dep.sh libosmo-abis
|
||||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
|||||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
export LD_LIBRARY_PATH="$inst/lib"
|
export LD_LIBRARY_PATH="$inst/lib"
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
osmo-build-dep.sh libosmo-abis
|
||||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
|||||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
export LD_LIBRARY_PATH="$inst/lib"
|
export LD_LIBRARY_PATH="$inst/lib"
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
osmo-build-dep.sh libosmo-abis
|
||||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
|||||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
export LD_LIBRARY_PATH="$inst/lib"
|
export LD_LIBRARY_PATH="$inst/lib"
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
osmo-build-dep.sh libosmo-abis
|
||||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export LD_LIBRARY_PATH="$inst/lib"
|
|||||||
|
|
||||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
osmo-build-dep.sh libosmo-abis
|
||||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
|||||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
export LD_LIBRARY_PATH="$inst/lib"
|
export LD_LIBRARY_PATH="$inst/lib"
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
osmo-build-dep.sh libosmo-abis
|
||||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|||||||
@@ -27,15 +27,17 @@ BuildRequires: pkgconfig >= 0.20
|
|||||||
%if 0%{?suse_version}
|
%if 0%{?suse_version}
|
||||||
BuildRequires: systemd-rpm-macros
|
BuildRequires: systemd-rpm-macros
|
||||||
%endif
|
%endif
|
||||||
BuildRequires: pkgconfig(libosmocodec) >= 1.8.0
|
BuildRequires: pkgconfig(libosmocodec) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(libosmocoding) >= 1.8.0
|
BuildRequires: pkgconfig(libosmocoding) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(libosmocore) >= 1.8.0
|
BuildRequires: pkgconfig(libosmocore) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.8.0
|
BuildRequires: pkgconfig(libosmoctrl) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(libosmogsm) >= 1.8.0
|
BuildRequires: pkgconfig(libosmogsm) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(libosmovty) >= 1.8.0
|
BuildRequires: pkgconfig(libosmovty) >= 1.7.0
|
||||||
BuildRequires: pkgconfig(libosmoabis) >= 1.4.0
|
BuildRequires: pkgconfig(libosmoabis) >= 1.3.0
|
||||||
BuildRequires: pkgconfig(libosmotrau) >= 1.4.0
|
BuildRequires: pkgconfig(libosmotrau) >= 1.3.0
|
||||||
BuildRequires: pkgconfig(libosmo-netif) >= 1.3.0
|
BuildRequires: pkgconfig(libosmo-netif) >= 1.2.0
|
||||||
|
### FIXME: DependencyHACK to include osmocom/gprs/protocol/gsm_04_60.h
|
||||||
|
BuildRequires: pkgconfig(libosmogb)
|
||||||
%{?systemd_requires}
|
%{?systemd_requires}
|
||||||
|
|
||||||
%description
|
%description
|
||||||
|
|||||||
90
debian/changelog
vendored
90
debian/changelog
vendored
@@ -1,93 +1,3 @@
|
|||||||
osmo-bts (1.6.0) unstable; urgency=medium
|
|
||||||
|
|
||||||
[ Vadim Yanitskiy ]
|
|
||||||
* osmo-bts-trx: call osmo_timer_del() unconditionally
|
|
||||||
* osmo-bts-trx: amr_loop: trigger the loop unconditionally
|
|
||||||
* osmo-bts-trx: fix handling of ciphering params in PRIM_INFO_MODIFY
|
|
||||||
* osmo-bts-trx: rx_rach_fn(): properly detect handover RACH
|
|
||||||
* osmo-bts-trx: handle MTS 0b0110 indicating an Access Burst
|
|
||||||
* osmo-bts-trx: use lookup tables for checking AMR CMI/CMR on Downlink
|
|
||||||
* osmo-bts-trx: drop ul_amr_fn_is_cmi() / dl_amr_fn_is_cmi()
|
|
||||||
|
|
||||||
[ Pau Espin Pedrol ]
|
|
||||||
* rsl: rx ipac crcx/mdcx: Log payload_type2
|
|
||||||
* logging: Move category descriptions to be in order with enum
|
|
||||||
* Clean up osmo-bts-*/Makefile.am
|
|
||||||
* Split out lchan rtp socket creation from rsl handling code
|
|
||||||
* Avoid counting lchan->dl_tch_queue length every time a msg is enqueued
|
|
||||||
* Use libosmocore API msgb_queue_free() to free lists
|
|
||||||
* rsl: Reduce scope of variable
|
|
||||||
* Move lchan_dl_tch_queue_enqueue to lchan.c and make it public
|
|
||||||
* cosmetic: Fix formatting of if-else block brackets
|
|
||||||
* Depend on libosmo-netif
|
|
||||||
* Clarify RTP AMR header offset in TCH enc/dec
|
|
||||||
* tests/*/Makefile.am: Fix typo in LIBOSMONETIF_CFLAGS
|
|
||||||
* tests/*/Makefile.am: Add missing libosmo-netif cflags
|
|
||||||
* oc2g: Makefile.am Fix typo in LIBOSMONETIF_LIBS
|
|
||||||
* Introduce Osmux support
|
|
||||||
* abis: Avoid TCP/IPA RSL sockets continue conn establishment while shutting down
|
|
||||||
* osmux: Log sendto() error
|
|
||||||
* lchan: Reset Abis RTP/Osmux config during lchan release
|
|
||||||
* vty: Fix SPEECH_MODE printed with hex prefix but dec value
|
|
||||||
* vty: Print Osmux CID on lchans using Osmux
|
|
||||||
* Allocate struct osmux_in_handle through new libosmo-netif APIs
|
|
||||||
* osmux: Drop logging of osmux internal counters
|
|
||||||
* osmux: Match remote address in osmux_lchan_find()
|
|
||||||
* osmux: Log remote address upon rx of osmux pkt
|
|
||||||
* osmux: Lower log level when osmux batch received for unknown CID
|
|
||||||
* osmux: nullify osmux.rtpst after freeing it
|
|
||||||
* osmux: Skip lchans in lookup which still have no remote associated
|
|
||||||
* osmux: Close osmux socket when bts is freed
|
|
||||||
* osmux: Fix null ptr dereference sending UL data before the remote is configured
|
|
||||||
* osmux: Rotate over available Osmux CID when allocating a new one
|
|
||||||
* osmux: Use new osmux_xfrm_input API to set name on each link
|
|
||||||
* vty: Fix typo in write-config: osmux / local-port
|
|
||||||
* vty: Fix typo in symbol name
|
|
||||||
|
|
||||||
[ Max ]
|
|
||||||
* Set working directory in systemd service file
|
|
||||||
* Don't manually create pid file
|
|
||||||
* Document realtime options in .service units
|
|
||||||
* Update realtime scheduling priority in service file
|
|
||||||
* ctrl: take both address and port from vty config
|
|
||||||
* Add SI10 support
|
|
||||||
|
|
||||||
[ Philipp Maier ]
|
|
||||||
* pcu_sock: fix sourcecode formatting
|
|
||||||
* measurement: do not call msgb_l3len without checking
|
|
||||||
* l1sap: do not call msgb_l2hlen without checking
|
|
||||||
* rsl: use unsigned int
|
|
||||||
* pcuif_proto: cosmetic: add constant PCU_IF_NUM_NSVC and replace magic numbers
|
|
||||||
* sched_lchan_tchf: replace numeric constant with define constant
|
|
||||||
* l1sap: remove unused pointer variable
|
|
||||||
* pcuif_proto: use define constant to specify nax number of trx
|
|
||||||
* pcu_sock: use ARRAY_SIZE rather then magic number
|
|
||||||
|
|
||||||
[ Keith ]
|
|
||||||
* osmo-bts-trx: respond to tx-attenuation config in real time.
|
|
||||||
|
|
||||||
[ Harald Welte ]
|
|
||||||
* update outdated vty copyright statement
|
|
||||||
|
|
||||||
[ Daniel Willmann ]
|
|
||||||
* shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C
|
|
||||||
* shutdown_fsm: Add power_ramp_force() to jump straight to the tgt power
|
|
||||||
|
|
||||||
[ daniel ]
|
|
||||||
* Revert "shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C"
|
|
||||||
|
|
||||||
[ Alexander Couzens ]
|
|
||||||
* OML: NSVC[1] MO should have the same initial state as NVSC[0]
|
|
||||||
|
|
||||||
[ Oliver Smith ]
|
|
||||||
* oc2gbts_mgr_calib: fix build against gpsd >= 3.20
|
|
||||||
* contrib/jenkins: build libosmo-abis without dahdi
|
|
||||||
|
|
||||||
[ arehbein ]
|
|
||||||
* osmo-bts: Transition to use of 'telnet_init_default'
|
|
||||||
|
|
||||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 17:15:52 +0100
|
|
||||||
|
|
||||||
osmo-bts (1.5.0) unstable; urgency=medium
|
osmo-bts (1.5.0) unstable; urgency=medium
|
||||||
|
|
||||||
[ Pau Espin Pedrol ]
|
[ Pau Espin Pedrol ]
|
||||||
|
|||||||
8
debian/control
vendored
8
debian/control
vendored
@@ -7,12 +7,12 @@ Build-Depends: debhelper (>= 9),
|
|||||||
dh-autoreconf,
|
dh-autoreconf,
|
||||||
autotools-dev,
|
autotools-dev,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
libosmocore-dev (>= 1.8.0),
|
libosmocore-dev (>= 1.7.0),
|
||||||
libosmo-abis-dev (>= 1.4.0),
|
libosmo-abis-dev (>= 1.3.0),
|
||||||
libosmo-netif-dev (>= 1.3.0),
|
libosmo-netif-dev (>= 1.2.0),
|
||||||
libgps-dev,
|
libgps-dev,
|
||||||
txt2man,
|
txt2man,
|
||||||
osmo-gsm-manuals-dev (>= 1.4.0)
|
osmo-gsm-manuals-dev (>= 1.3.0)
|
||||||
Standards-Version: 3.9.8
|
Standards-Version: 3.9.8
|
||||||
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
||||||
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
||||||
|
|||||||
@@ -192,7 +192,6 @@ Conforms to 3GPP TS 48.058 § 8.4.20, with these exceptions:
|
|||||||
| 0x06 | RSL_SYSTEM_INFO_6
|
| 0x06 | RSL_SYSTEM_INFO_6
|
||||||
| 0x0d | RSL_SYSTEM_INFO_5bis
|
| 0x0d | RSL_SYSTEM_INFO_5bis
|
||||||
| 0x0e | RSL_SYSTEM_INFO_5ter
|
| 0x0e | RSL_SYSTEM_INFO_5ter
|
||||||
| 0x0f | RSL_SYSTEM_INFO_10
|
|
||||||
| 0x47 | RSL_EXT_MEAS_ORDER
|
| 0x47 | RSL_EXT_MEAS_ORDER
|
||||||
| 0x48 | RSL_MEAS_INFO
|
| 0x48 | RSL_MEAS_INFO
|
||||||
|===
|
|===
|
||||||
@@ -517,7 +516,6 @@ number*.
|
|||||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
||||||
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
|
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
|
||||||
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
||||||
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
|
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[rsl_crcx_msg_ack]]
|
[[rsl_crcx_msg_ack]]
|
||||||
@@ -578,7 +576,6 @@ properties of a user-plane RTP connection.
|
|||||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
||||||
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
|
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
|
||||||
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
||||||
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
|
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[rsl_mdcx_msg_ack]]
|
[[rsl_mdcx_msg_ack]]
|
||||||
@@ -874,7 +871,6 @@ addition to those indicated in 3GPP TS 48.058 Section 9.3:
|
|||||||
| 0xf5 | RSL_IE_IPAC_LOCAL_IP | <<RSL_IE_IPAC_LOCAL_IP>>
|
| 0xf5 | RSL_IE_IPAC_LOCAL_IP | <<RSL_IE_IPAC_LOCAL_IP>>
|
||||||
| 0xf6 | RSL_IE_IPAC_CONN_STAT | <<RSL_IE_IPAC_CONN_STAT>>
|
| 0xf6 | RSL_IE_IPAC_CONN_STAT | <<RSL_IE_IPAC_CONN_STAT>>
|
||||||
| 0xf8 | RSL_IE_IPAC_CONN_ID | <<RSL_IE_IPAC_CONN_ID>>
|
| 0xf8 | RSL_IE_IPAC_CONN_ID | <<RSL_IE_IPAC_CONN_ID>>
|
||||||
| 0xf9 | RSL_IE_IPAC_RTP_CSD_FORMAT | <<RSL_IE_IPAC_RTP_CSD_FORMAT>>
|
|
||||||
| 0xfc | RSL_IE_IPAC_RTP_PAYLOAD2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>>
|
| 0xfc | RSL_IE_IPAC_RTP_PAYLOAD2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>>
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -1089,39 +1085,6 @@ for future use.
|
|||||||
| 8..255 | reserved values
|
| 8..255 | reserved values
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[RSL_IE_IPAC_RTP_CSD_FORMAT]]
|
|
||||||
==== RSL_IE_IPAC_RTP_CSD_FORMAT
|
|
||||||
|
|
||||||
This information element contains the RTP Circuit Switched Data format.
|
|
||||||
|
|
||||||
.A-bis/IP RTP CSD Format
|
|
||||||
[options="header",width="60%",cols="15%,15%,70%"]
|
|
||||||
|===
|
|
||||||
| Offset | Size | Description
|
|
||||||
| 0 | 4 | RTP CSD Format D
|
|
||||||
| 4 | 4 | RTP CSD Format IR
|
|
||||||
|===
|
|
||||||
|
|
||||||
.A-bis/IP RTP CSD Format D Values
|
|
||||||
[options="header",width="40%",cols="20%,80%"]
|
|
||||||
|===
|
|
||||||
| Value | Description
|
|
||||||
| 0 | External TRAU format
|
|
||||||
| 1 | Non-TRAU Packed format
|
|
||||||
| 2 | TRAU within the BTS
|
|
||||||
| 3 | IWF-Free BTS-BTS Data
|
|
||||||
|===
|
|
||||||
|
|
||||||
.A-bis/IP RTP CSD Format IR Values
|
|
||||||
[options="header",width="40%",cols="20%,80%"]
|
|
||||||
|===
|
|
||||||
| Value | Description
|
|
||||||
| 0 | 8 kb/s
|
|
||||||
| 1 | 16 kb/s
|
|
||||||
| 2 | 32 kb/s
|
|
||||||
| 3 | 48 kb/s
|
|
||||||
|===
|
|
||||||
|
|
||||||
=== A-bis RSL Initialization / BTS bring-up
|
=== A-bis RSL Initialization / BTS bring-up
|
||||||
|
|
||||||
Upon receiving the 'IPA RSL CONNECT' OML message by the respective
|
Upon receiving the 'IPA RSL CONNECT' OML message by the respective
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ order to specify which PHY instance is allocated to this specific TRX.
|
|||||||
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
|
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
|
||||||
| common | bts_controlif_setup() | Initialization of Control Interface
|
| common | bts_controlif_setup() | Initialization of Control Interface
|
||||||
| bts-specific | bts_model_ctrl_cmds_install() | Install model-specific control interface commands
|
| bts-specific | bts_model_ctrl_cmds_install() | Install model-specific control interface commands
|
||||||
| common | telnet_init_default() | Initialization of telnet interface
|
| common | telnet_init() | Initialization of telnet interface
|
||||||
| common | pcu_sock_init() | Initialization of PCU socket
|
| common | pcu_sock_init() | Initialization of PCU socket
|
||||||
| common | main() | Installation of signal handlers
|
| common | main() | Installation of signal handlers
|
||||||
| common | abis_open() | Start of the A-bis connection to BSC
|
| common | abis_open() | Start of the A-bis connection to BSC
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ The start-up procedure of OsmoBTS can be described as follows:
|
|||||||
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
|
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
|
||||||
| common | bts_controlif_setup() | Initialization of Control Interface
|
| common | bts_controlif_setup() | Initialization of Control Interface
|
||||||
| bts-specific | bts_model_ctrl_cmds_install()
|
| bts-specific | bts_model_ctrl_cmds_install()
|
||||||
| common | telnet_init_default() | Initialization of telnet interface
|
| common | telnet_init() | Initialization of telnet interface
|
||||||
| common | pcu_sock_init() | Initialization of PCU socket
|
| common | pcu_sock_init() | Initialization of PCU socket
|
||||||
| common | main() | Installation of signal handlers
|
| common | main() | Installation of signal handlers
|
||||||
| common | abis_open() | Start of the A-bis connection to BSC
|
| common | abis_open() | Start of the A-bis connection to BSC
|
||||||
|
|||||||
@@ -366,7 +366,6 @@ struct gsm_bts {
|
|||||||
struct {
|
struct {
|
||||||
struct gsmtap_inst *inst;
|
struct gsmtap_inst *inst;
|
||||||
char *remote_host;
|
char *remote_host;
|
||||||
char *local_host;
|
|
||||||
uint32_t sapi_mask;
|
uint32_t sapi_mask;
|
||||||
uint8_t sapi_acch;
|
uint8_t sapi_acch;
|
||||||
} gsmtap;
|
} gsmtap;
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ struct gsm_bts_trx {
|
|||||||
uint16_t arfcn;
|
uint16_t arfcn;
|
||||||
int nominal_power; /* in dBm */
|
int nominal_power; /* in dBm */
|
||||||
unsigned int max_power_red; /* in actual dB */
|
unsigned int max_power_red; /* in actual dB */
|
||||||
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
|
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
|
||||||
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
|
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
|
||||||
|
|
||||||
uint8_t ta_ctrl_interval; /* 1 step is 2 SACCH periods */
|
uint8_t ta_ctrl_interval; /* 1 step is 2 SACCH periods */
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int bts_ctrl_cmds_install(struct gsm_bts *bts);
|
int bts_ctrl_cmds_install(struct gsm_bts *bts);
|
||||||
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port);
|
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
|
||||||
|
const char *bind_addr, uint16_t port);
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ struct gsm_network {
|
|||||||
/* lchans 0..3 are SDCCH in combined channel configuration,
|
/* lchans 0..3 are SDCCH in combined channel configuration,
|
||||||
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
|
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
|
||||||
#define CCCH_LCHAN 4
|
#define CCCH_LCHAN 4
|
||||||
#define CBCH_LCHAN 2
|
|
||||||
|
|
||||||
#define TRX_NR_TS 8
|
#define TRX_NR_TS 8
|
||||||
#define TS_MAX_LCHAN 8
|
#define TS_MAX_LCHAN 8
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
|
|||||||
const uint8_t *identity_lv, uint8_t chan_needed);
|
const uint8_t *identity_lv, uint8_t chan_needed);
|
||||||
|
|
||||||
/* Add an IMM.ASS message to the paging queue */
|
/* Add an IMM.ASS message to the paging queue */
|
||||||
int paging_add_imm_ass(struct paging_state *ps,
|
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
|
||||||
const uint8_t *data, uint8_t len);
|
uint8_t len, bool from_pcu);
|
||||||
|
|
||||||
/* generate paging message for given gsm time */
|
/* generate paging message for given gsm time */
|
||||||
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
|
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
|
||||||
|
|||||||
@@ -5,6 +5,13 @@
|
|||||||
|
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
|
||||||
|
/* Whether a logical channel must be activated automatically */
|
||||||
|
#define TRX_CHAN_FLAG_AUTO_ACTIVE (1 << 0)
|
||||||
|
|
||||||
|
/* FIXME: we should actually activate 'auto-active' channels */
|
||||||
|
#define TRX_CHAN_IS_ACTIVE(state, chan) \
|
||||||
|
(trx_chan_desc[chan].flags & TRX_CHAN_FLAG_AUTO_ACTIVE || (state)->active)
|
||||||
|
|
||||||
#define TRX_GMSK_NB_TSC(br) \
|
#define TRX_GMSK_NB_TSC(br) \
|
||||||
_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
|
_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
|
||||||
|
|
||||||
@@ -185,9 +192,6 @@ int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pch
|
|||||||
/*! \brief set all matching logical channels active/inactive */
|
/*! \brief set all matching logical channels active/inactive */
|
||||||
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active);
|
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active);
|
||||||
|
|
||||||
/*! \brief set all logical channels of BCCH/CCCH active/inactive */
|
|
||||||
int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool active);
|
|
||||||
|
|
||||||
/*! \brief set mode of all matching logical channels to given mode(s) */
|
/*! \brief set mode of all matching logical channels to given mode(s) */
|
||||||
int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,
|
int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,
|
||||||
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
|
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
|
||||||
|
|||||||
@@ -88,12 +88,14 @@ err_index:
|
|||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port)
|
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
|
||||||
|
const char *bind_addr, uint16_t port)
|
||||||
{
|
{
|
||||||
struct ctrl_handle *hdl;
|
struct ctrl_handle *hdl;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
hdl = ctrl_interface_setup(bts, port, bts_ctrl_node_lookup);
|
hdl = ctrl_interface_setup_dynip(bts, bind_addr, port,
|
||||||
|
bts_ctrl_node_lookup);
|
||||||
if (!hdl)
|
if (!hdl)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -227,13 +227,10 @@ int trx_link_estab(struct gsm_bts_trx *trx)
|
|||||||
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_RSL_UP, NULL);
|
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_RSL_UP, NULL);
|
||||||
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_RSL_UP, NULL);
|
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_RSL_UP, NULL);
|
||||||
|
|
||||||
if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED ||
|
if ((rc = rsl_tx_rf_res(trx)) < 0)
|
||||||
trx->bb_transc.mo.nm_state.operational == NM_OPSTATE_ENABLED) {
|
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
|
||||||
rc = rsl_tx_rf_res(trx);
|
"Failed to establish RSL link (%d)", rc);
|
||||||
if (rc < 0)
|
|
||||||
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
|
|
||||||
"Failed to establish RSL link (%d)", rc);
|
|
||||||
}
|
|
||||||
if (trx == trx->bts->c0)
|
if (trx == trx->bts->c0)
|
||||||
load_timer_start(trx->bts);
|
load_timer_start(trx->bts);
|
||||||
|
|
||||||
|
|||||||
@@ -139,8 +139,12 @@ static int get_smscb_block(struct bts_smscb_state *bts_ss, uint8_t *out, uint8_t
|
|||||||
block_type->seq_nr = block_nr;
|
block_type->seq_nr = block_nr;
|
||||||
|
|
||||||
/* determine if this is the last block */
|
/* determine if this is the last block */
|
||||||
block_type->lb = (block_nr + 1 == msg->num_segs);
|
if (block_nr + 1 == msg->num_segs)
|
||||||
if (block_type->lb) {
|
block_type->lb = 1;
|
||||||
|
else
|
||||||
|
block_type->lb = 0;
|
||||||
|
|
||||||
|
if (block_nr == 4) {
|
||||||
if (msg != bts_ss->default_msg) {
|
if (msg != bts_ss->default_msg) {
|
||||||
DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n",
|
DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n",
|
||||||
chan_name, msg);
|
chan_name, msg);
|
||||||
|
|||||||
@@ -137,24 +137,17 @@ static uint32_t fn_ms_adj(uint32_t fn, const struct gsm_lchan *lchan)
|
|||||||
/* 12/13 frames usable for audio in TCH,
|
/* 12/13 frames usable for audio in TCH,
|
||||||
160 samples per RTP packet,
|
160 samples per RTP packet,
|
||||||
1 RTP packet per 4 frames */
|
1 RTP packet per 4 frames */
|
||||||
|
|
||||||
/*! Return the difference of two specified TDMA frame numbers (subtraction) */
|
|
||||||
const uint32_t _num_fn = (fn - lchan->tch.last_fn) * 12 * 160 / (13 * 4); //GSM_TDMA_FN_SUB(fn, lchan->tch.last_fn);
|
|
||||||
const uint32_t num_fn = GSM_TDMA_FN_SUB(fn, lchan->tch.last_fn);
|
const uint32_t num_fn = GSM_TDMA_FN_SUB(fn, lchan->tch.last_fn);
|
||||||
|
|
||||||
samples_passed = num_fn * 12 * 160 / (13 * 4);
|
samples_passed = num_fn * 12 * 160 / (13 * 4);
|
||||||
//LOGPLCHAN(lchan, DRTP, LOGL_NOTICE, "OLD [%d], NEW [%d]\n", _num_fn, samples_passed);
|
|
||||||
/* round number of samples to the nearest multiple of
|
/* round number of samples to the nearest multiple of
|
||||||
GSM_RTP_DURATION = 160 */
|
GSM_RTP_DURATION */
|
||||||
r = samples_passed + GSM_RTP_DURATION / 2;
|
r = samples_passed + GSM_RTP_DURATION / 2;
|
||||||
r -= r % GSM_RTP_DURATION;
|
r -= r % GSM_RTP_DURATION;
|
||||||
|
|
||||||
if (r != GSM_RTP_DURATION) {
|
if (r != GSM_RTP_DURATION)
|
||||||
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "RTP clock out of sync with lower layer:"
|
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "RTP clock out of sync with lower layer:"
|
||||||
" %"PRIu32" vs %d (%"PRIu32"->%"PRIu32") DIFF[%d] SAMPLES[%d]\n ",
|
" %"PRIu32" vs %d (%"PRIu32"->%"PRIu32")\n",
|
||||||
r, GSM_RTP_DURATION, lchan->tch.last_fn, fn, num_fn, samples_passed);
|
r, GSM_RTP_DURATION, lchan->tch.last_fn, fn);
|
||||||
//return r;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return GSM_RTP_DURATION;
|
return GSM_RTP_DURATION;
|
||||||
}
|
}
|
||||||
@@ -188,8 +181,7 @@ int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg,
|
|||||||
{
|
{
|
||||||
struct osmo_phsap_prim *l1sap;
|
struct osmo_phsap_prim *l1sap;
|
||||||
|
|
||||||
if (rmsg->len > 0)
|
LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "Rx -> RTP: %s\n", osmo_hexdump(rmsg->data, rmsg->len));
|
||||||
LOGPLCHAN(lchan, DL1P, LOGL_INFO, "Rx -> RTP: %s\n", osmo_hexdump(rmsg->data, rmsg->len));
|
|
||||||
|
|
||||||
rmsg->l2h = rmsg->data;
|
rmsg->l2h = rmsg->data;
|
||||||
rmsg->l1h = msgb_push(rmsg, sizeof(*l1sap));
|
rmsg->l1h = msgb_push(rmsg, sizeof(*l1sap));
|
||||||
@@ -623,9 +615,6 @@ static void l1sap_interf_meas_report(struct gsm_bts *bts)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED ||
|
|
||||||
trx->bb_transc.mo.nm_state.operational != NM_OPSTATE_ENABLED)
|
|
||||||
continue;
|
|
||||||
/* Calculate the average of all received samples */
|
/* Calculate the average of all received samples */
|
||||||
l1sap_interf_meas_calc_avg(trx);
|
l1sap_interf_meas_calc_avg(trx);
|
||||||
/* Report to the BSC over the A-bis/RSL */
|
/* Report to the BSC over the A-bis/RSL */
|
||||||
@@ -643,7 +632,7 @@ static int l1sap_info_time_ind(struct gsm_bts *bts,
|
|||||||
unsigned int frames_expired;
|
unsigned int frames_expired;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
//DEBUGPFN(DL1P, info_time_ind->fn, "Rx MPH_INFO time ind\n");
|
DEBUGPFN(DL1P, info_time_ind->fn, "Rx MPH_INFO time ind\n");
|
||||||
|
|
||||||
/* Calculate and check frame difference */
|
/* Calculate and check frame difference */
|
||||||
frames_expired = GSM_TDMA_FN_SUB(info_time_ind->fn, bts->gsm_time.fn);
|
frames_expired = GSM_TDMA_FN_SUB(info_time_ind->fn, bts->gsm_time.fn);
|
||||||
@@ -1611,54 +1600,35 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap,
|
|||||||
* the content is not available due to decoding issues. Content not
|
* the content is not available due to decoding issues. Content not
|
||||||
* available is expected as empty payload. We also check if quality is
|
* available is expected as empty payload. We also check if quality is
|
||||||
* good enough. */
|
* good enough. */
|
||||||
//if (1 == 1) {
|
if (msg->len && tch_ind->lqual_cb >= bts->min_qual_norm) {
|
||||||
if (!msg->len || (tch_ind->lqual_cb / 10 < bts->min_qual_norm)) {
|
/* hand msg to RTP code for transmission */
|
||||||
LOGPGT(DRTP, LOGL_NOTICE, &g_time, "Skipping RTP frame with lost payload (chan_nr=0x%02x)\n",
|
if (lchan->abis_ip.osmux.use) {
|
||||||
|
lchan_osmux_send_frame(lchan, msg->data, msg->len,
|
||||||
|
fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
|
||||||
|
} else if (lchan->abis_ip.rtp_socket) {
|
||||||
|
osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket,
|
||||||
|
msg->data, msg->len, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
|
||||||
|
}
|
||||||
|
/* if loopback is enabled, also queue received RTP data */
|
||||||
|
if (lchan->loopback) {
|
||||||
|
/* add new frame to queue, make sure the queue doesn't get too long */
|
||||||
|
lchan_dl_tch_queue_enqueue(lchan, msg, 1);
|
||||||
|
/* Return 1 to signal that we're still using msg and it should not be freed */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* Only clear the marker bit once we have sent a RTP packet with it */
|
||||||
|
lchan->rtp_tx_marker = false;
|
||||||
|
} else {
|
||||||
|
DEBUGPGT(DRTP, &g_time, "Skipping RTP frame with lost payload (chan_nr=0x%02x)\n",
|
||||||
chan_nr);
|
chan_nr);
|
||||||
if (lchan->abis_ip.osmux.use)
|
if (lchan->abis_ip.osmux.use)
|
||||||
lchan_osmux_skipped_frame(lchan, fn_ms_adj(fn, lchan));
|
lchan_osmux_skipped_frame(lchan, fn_ms_adj(fn, lchan));
|
||||||
else if (lchan->abis_ip.rtp_socket)
|
else if (lchan->abis_ip.rtp_socket)
|
||||||
osmo_rtp_skipped_frame(lchan->abis_ip.rtp_socket, fn_ms_adj(fn, lchan));
|
osmo_rtp_skipped_frame(lchan->abis_ip.rtp_socket, fn_ms_adj(fn, lchan));
|
||||||
|
|
||||||
lchan->rtp_tx_marker = true;
|
lchan->rtp_tx_marker = true;
|
||||||
lchan->tch.last_fn = fn;
|
|
||||||
//lchan->tch.dtx.is_speech_resume = false;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lchan->abis_ip.osmux.use) {
|
|
||||||
lchan_osmux_send_frame(lchan, msg->data, msg->len,
|
|
||||||
fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
|
|
||||||
} else if (lchan->abis_ip.rtp_socket) {
|
|
||||||
if (msg->len > 0 || lchan->rtp_tx_marker)
|
|
||||||
LOGPGT(DL1P, LOGL_INFO, &g_time, "Send RTP Frame [%d]--> %s\n",
|
|
||||||
msg->len, osmo_hexdump(msg->data, msg->len));
|
|
||||||
/*
|
|
||||||
int osmo_rtp_send_frame_ext(struct osmo_rtp_socket *rs, const uint8_t *payload,
|
|
||||||
unsigned int payload_len, unsigned int duration,
|
|
||||||
bool marker);
|
|
||||||
|
|
||||||
--> duration in number of RTP clock ticks.
|
|
||||||
The duration is the timestamp increase
|
|
||||||
|
|
||||||
*/
|
|
||||||
osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket,
|
|
||||||
msg->data, msg->len, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker);
|
|
||||||
}
|
|
||||||
/* if loopback is enabled, also queue received RTP data */
|
|
||||||
if (lchan->loopback) {
|
|
||||||
/* add new frame to queue, make sure the queue doesn't get too long */
|
|
||||||
lchan_dl_tch_queue_enqueue(lchan, msg, 1);
|
|
||||||
/* Return 1 to signal that we're still using msg and it should not be freed */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/* Only clear the marker bit once we have sent a RTP packet with it */
|
|
||||||
//lchan->rtp_tx_marker = false;
|
|
||||||
|
|
||||||
lchan->tch.last_fn = fn;
|
lchan->tch.last_fn = fn;
|
||||||
if (lchan->tch.dtx.is_speech_resume)
|
|
||||||
lchan->tch.dtx.is_speech_resume = false;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See 3GPP TS 44.018 Table 10.5.2.5.1 "Channel Description information element" */
|
/* See Table 10.5.25 of GSM04.08 */
|
||||||
static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
||||||
uint8_t ts_nr, uint8_t lchan_nr)
|
uint8_t ts_nr, uint8_t lchan_nr)
|
||||||
{
|
{
|
||||||
@@ -367,13 +367,13 @@ static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
|||||||
cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
|
cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
|
||||||
break;
|
break;
|
||||||
case GSM_PCHAN_NONE:
|
case GSM_PCHAN_NONE:
|
||||||
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s not expected!\n",
|
LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",
|
||||||
ts_nr, lchan_nr, gsm_pchan_name(pchan));
|
gsm_pchan_name(pchan));
|
||||||
cbits = 0x00; /* Reserved */
|
cbits = 0x00;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s (0x%02x) not expected!\n",
|
LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",
|
||||||
ts_nr, lchan_nr, gsm_pchan_name(pchan), (int)pchan);
|
gsm_pchan_name(pchan), (int)pchan);
|
||||||
OSMO_ASSERT(0);
|
OSMO_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,20 +354,21 @@ int bts_main(int argc, char **argv)
|
|||||||
/* TODO: move this to gsm_bts_alloc() */
|
/* TODO: move this to gsm_bts_alloc() */
|
||||||
if (g_bts->gsmtap.remote_host != NULL) {
|
if (g_bts->gsmtap.remote_host != NULL) {
|
||||||
LOGP(DLGLOBAL, LOGL_NOTICE,
|
LOGP(DLGLOBAL, LOGL_NOTICE,
|
||||||
"Setting up GSMTAP Um forwarding '%s->'%s:%u'\n",
|
"Setting up GSMTAP Um forwarding to '%s:%u'\n",
|
||||||
g_bts->gsmtap.local_host, g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
|
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
|
||||||
g_bts->gsmtap.inst = gsmtap_source_init2(g_bts->gsmtap.local_host, 0,
|
g_bts->gsmtap.inst = gsmtap_source_init(g_bts->gsmtap.remote_host,
|
||||||
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT, 1);
|
GSMTAP_UDP_PORT, 1);
|
||||||
if (g_bts->gsmtap.inst == NULL) {
|
if (g_bts->gsmtap.inst == NULL) {
|
||||||
fprintf(stderr, "Failed during gsmtap_source_init2()\n");
|
fprintf(stderr, "Failed during gsmtap_source_init()\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
gsmtap_source_add_sink(g_bts->gsmtap.inst);
|
gsmtap_source_add_sink(g_bts->gsmtap.inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
bts_controlif_setup(g_bts, OSMO_CTRL_PORT_BTS);
|
bts_controlif_setup(g_bts, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BTS);
|
||||||
|
|
||||||
rc = telnet_init_default(tall_bts_ctx, NULL, g_vty_port_num);
|
rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(),
|
||||||
|
g_vty_port_num);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Error initializing telnet\n");
|
fprintf(stderr, "Error initializing telnet\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
@@ -268,8 +268,8 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add an IMM.ASS message to the paging queue */
|
/* Add an IMM.ASS message to the paging queue */
|
||||||
int paging_add_imm_ass(struct paging_state *ps,
|
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
|
||||||
const uint8_t *data, uint8_t len)
|
uint8_t len, bool from_pcu)
|
||||||
{
|
{
|
||||||
struct llist_head *group_q;
|
struct llist_head *group_q;
|
||||||
struct paging_record *pr;
|
struct paging_record *pr;
|
||||||
@@ -277,7 +277,7 @@ int paging_add_imm_ass(struct paging_state *ps,
|
|||||||
|
|
||||||
check_congestion(ps);
|
check_congestion(ps);
|
||||||
|
|
||||||
if (ps->cs_priority_active) {
|
if (ps->cs_priority_active && from_pcu) {
|
||||||
LOGP(DPAG, LOGL_NOTICE, "Dropping paging for PS, queue congested (%u)\n",
|
LOGP(DPAG, LOGL_NOTICE, "Dropping paging for PS, queue congested (%u)\n",
|
||||||
ps->num_paging);
|
ps->num_paging);
|
||||||
rate_ctr_inc2(ps->bts->ctrs, BTS_CTR_PAGING_DROP_PS);
|
rate_ctr_inc2(ps->bts->ctrs, BTS_CTR_PAGING_DROP_PS);
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include <osmocom/core/talloc.h>
|
#include <osmocom/core/talloc.h>
|
||||||
#include <osmocom/core/utils.h>
|
|
||||||
#include <osmocom/core/select.h>
|
#include <osmocom/core/select.h>
|
||||||
#include <osmocom/core/socket.h>
|
#include <osmocom/core/socket.h>
|
||||||
#include <osmocom/gsm/gsm23003.h>
|
#include <osmocom/gsm/gsm23003.h>
|
||||||
@@ -204,7 +203,7 @@ static void info_ind_fill_trx(struct gsm_pcu_if_info_trx *trx_info,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {
|
for (tn = 0; tn < 8; tn++) {
|
||||||
const struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
const struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
||||||
|
|
||||||
if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED)
|
if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED)
|
||||||
@@ -476,6 +475,12 @@ int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t sapi, uint32_t fn,
|
|||||||
LOGP(DPCU, LOGL_DEBUG, "Sending data indication: sapi=%s arfcn=%d block=%d data=%s\n",
|
LOGP(DPCU, LOGL_DEBUG, "Sending data indication: sapi=%s arfcn=%d block=%d data=%s\n",
|
||||||
sapi_string[sapi], arfcn, block_nr, osmo_hexdump(data, len));
|
sapi_string[sapi], arfcn, block_nr, osmo_hexdump(data, len));
|
||||||
|
|
||||||
|
if (lqual < bts->min_qual_norm) {
|
||||||
|
LOGP(DPCU, LOGL_DEBUG, "Link quality %"PRId16" is below threshold %d, dropping packet\n",
|
||||||
|
lqual, bts->min_qual_norm);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_IND, bts->nr);
|
msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_IND, bts->nr);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -676,7 +681,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
|
|||||||
|
|
||||||
switch (data_req->sapi) {
|
switch (data_req->sapi) {
|
||||||
case PCU_IF_SAPI_PCH:
|
case PCU_IF_SAPI_PCH:
|
||||||
paging_add_imm_ass(bts->paging_state, data_req->data, data_req->len);
|
paging_add_imm_ass(bts->paging_state, data_req->data, data_req->len, true);
|
||||||
break;
|
break;
|
||||||
case PCU_IF_SAPI_AGCH:
|
case PCU_IF_SAPI_AGCH:
|
||||||
msg = msgb_alloc(data_req->len, "pcu_agch");
|
msg = msgb_alloc(data_req->len, "pcu_agch");
|
||||||
@@ -1000,9 +1005,9 @@ static void pcu_sock_close(struct pcu_sock_state *state)
|
|||||||
|
|
||||||
bts->pcu_version[0] = '\0';
|
bts->pcu_version[0] = '\0';
|
||||||
|
|
||||||
osmo_fd_unregister(bfd);
|
|
||||||
close(bfd->fd);
|
close(bfd->fd);
|
||||||
bfd->fd = -1;
|
bfd->fd = -1;
|
||||||
|
osmo_fd_unregister(bfd);
|
||||||
|
|
||||||
/* patch SI3 to remove GPRS indicator */
|
/* patch SI3 to remove GPRS indicator */
|
||||||
regenerate_si3_restoctets(bts);
|
regenerate_si3_restoctets(bts);
|
||||||
@@ -1088,33 +1093,48 @@ close:
|
|||||||
static int pcu_sock_write(struct osmo_fd *bfd)
|
static int pcu_sock_write(struct osmo_fd *bfd)
|
||||||
{
|
{
|
||||||
struct pcu_sock_state *state = bfd->data;
|
struct pcu_sock_state *state = bfd->data;
|
||||||
struct msgb *msg;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
while ((msg = msgb_dequeue(&state->upqueue))) {
|
while (!llist_empty(&state->upqueue)) {
|
||||||
|
struct msgb *msg, *msg2;
|
||||||
|
struct gsm_pcu_if *pcu_prim;
|
||||||
|
|
||||||
|
/* peek at the beginning of the queue */
|
||||||
|
msg = llist_entry(state->upqueue.next, struct msgb, list);
|
||||||
|
pcu_prim = (struct gsm_pcu_if *)msg->data;
|
||||||
|
|
||||||
|
osmo_fd_write_disable(bfd);
|
||||||
|
|
||||||
/* bug hunter 8-): maybe someone forgot msgb_put(...) ? */
|
/* bug hunter 8-): maybe someone forgot msgb_put(...) ? */
|
||||||
OSMO_ASSERT(msgb_length(msg) > 0);
|
if (!msgb_length(msg)) {
|
||||||
|
LOGP(DPCU, LOGL_ERROR, "message type (%d) with ZERO "
|
||||||
|
"bytes!\n", pcu_prim->msg_type);
|
||||||
|
goto dontsend;
|
||||||
|
}
|
||||||
|
|
||||||
/* try to send it over the socket */
|
/* try to send it over the socket */
|
||||||
rc = write(bfd->fd, msgb_data(msg), msgb_length(msg));
|
rc = write(bfd->fd, msgb_data(msg), msgb_length(msg));
|
||||||
if (OSMO_UNLIKELY(rc == 0))
|
if (rc == 0)
|
||||||
goto close;
|
goto close;
|
||||||
if (OSMO_UNLIKELY(rc < 0)) {
|
if (rc < 0) {
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
/* Re-insert at the start of the queue, skip disabling fd WRITE */
|
osmo_fd_write_enable(bfd);
|
||||||
llist_add(&msg->list, &state->upqueue);
|
break;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
goto close;
|
goto close;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dontsend:
|
||||||
|
/* _after_ we send it, we can deueue */
|
||||||
|
msg2 = msgb_dequeue(&state->upqueue);
|
||||||
|
assert(msg == msg2);
|
||||||
msgb_free(msg);
|
msgb_free(msg);
|
||||||
}
|
}
|
||||||
osmo_fd_write_disable(bfd);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
close:
|
close:
|
||||||
msgb_free(msg);
|
|
||||||
pcu_sock_close(state);
|
pcu_sock_close(state);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1140,27 +1160,29 @@ static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags)
|
|||||||
struct osmo_fd *conn_bfd = &state->conn_bfd;
|
struct osmo_fd *conn_bfd = &state->conn_bfd;
|
||||||
struct sockaddr_un un_addr;
|
struct sockaddr_un un_addr;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
int fd;
|
int rc;
|
||||||
|
|
||||||
len = sizeof(un_addr);
|
len = sizeof(un_addr);
|
||||||
fd = accept(bfd->fd, (struct sockaddr *)&un_addr, &len);
|
rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
|
||||||
if (fd < 0) {
|
if (rc < 0) {
|
||||||
LOGP(DPCU, LOGL_ERROR, "Failed to accept a new connection\n");
|
LOGP(DPCU, LOGL_ERROR, "Failed to accept a new connection\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn_bfd->fd >= 0) {
|
if (conn_bfd->fd >= 0) {
|
||||||
LOGP(DPCU, LOGL_NOTICE, "PCU connects but we already have another active connection ?!?\n");
|
LOGP(DPCU, LOGL_NOTICE, "PCU connects but we already have "
|
||||||
|
"another active connection ?!?\n");
|
||||||
/* We already have one PCU connected, this is all we support */
|
/* We already have one PCU connected, this is all we support */
|
||||||
osmo_fd_read_disable(&state->listen_bfd);
|
state->listen_bfd.when &= ~OSMO_FD_READ;
|
||||||
close(fd);
|
close(rc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
osmo_fd_setup(conn_bfd, fd, OSMO_FD_READ, pcu_sock_cb, state, 0);
|
osmo_fd_setup(conn_bfd, rc, OSMO_FD_READ, pcu_sock_cb, state, 0);
|
||||||
|
|
||||||
if (osmo_fd_register(conn_bfd) != 0) {
|
if (osmo_fd_register(conn_bfd) != 0) {
|
||||||
LOGP(DPCU, LOGL_ERROR, "Failed to register new connection fd\n");
|
LOGP(DPCU, LOGL_ERROR, "Failed to register new connection "
|
||||||
|
"fd\n");
|
||||||
close(conn_bfd->fd);
|
close(conn_bfd->fd);
|
||||||
conn_bfd->fd = -1;
|
conn_bfd->fd = -1;
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ static const unsigned int rsl_sacch_sitypes[] = {
|
|||||||
RSL_SYSTEM_INFO_6,
|
RSL_SYSTEM_INFO_6,
|
||||||
RSL_SYSTEM_INFO_5bis,
|
RSL_SYSTEM_INFO_5bis,
|
||||||
RSL_SYSTEM_INFO_5ter,
|
RSL_SYSTEM_INFO_5ter,
|
||||||
RSL_SYSTEM_INFO_10,
|
|
||||||
RSL_EXT_MEAS_ORDER,
|
RSL_EXT_MEAS_ORDER,
|
||||||
RSL_MEAS_INFO,
|
RSL_MEAS_INFO,
|
||||||
};
|
};
|
||||||
@@ -161,14 +160,14 @@ static int rsl_handle_chan_mod_ie(struct gsm_lchan *lchan,
|
|||||||
lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
|
lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
|
||||||
break;
|
break;
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM4):
|
case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM4):
|
||||||
lchan->tch_mode = GSM48_CMODE_SPEECH_V4;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM5):
|
case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM5):
|
||||||
lchan->tch_mode = GSM48_CMODE_SPEECH_V5;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM6):
|
case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM6):
|
||||||
lchan->tch_mode = GSM48_CMODE_SPEECH_V6;
|
/* TODO: also handle RSL_CMOD_SP_{GSM4,GSM5,GSM6} */
|
||||||
break;
|
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains "
|
||||||
|
"unhandled speech coding algorithm 0x%02x\n",
|
||||||
|
cm->chan_rate);
|
||||||
|
*cause = RSL_ERR_IE_CONTENT;
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
/* If octet 4 indicates non-transparent data */
|
/* If octet 4 indicates non-transparent data */
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NT_14k5):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NT_14k5):
|
||||||
@@ -181,59 +180,35 @@ static int rsl_handle_chan_mod_ie(struct gsm_lchan *lchan,
|
|||||||
lchan->tch_mode = GSM48_CMODE_DATA_6k0;
|
lchan->tch_mode = GSM48_CMODE_DATA_6k0;
|
||||||
break;
|
break;
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NT_43k5):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NT_43k5):
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_43k5;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NT_28k8):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NT_28k8):
|
||||||
/* 28.8 kbit/s services, 29.0 kbit/s radio interface rate */
|
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_29k0;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_43k5_14k5):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_43k5_14k5):
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_43k5_14k5;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_29k0_14k5):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_29k0_14k5):
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_29k0_14k5;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_43k5_29k0):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_43k5_29k0):
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_43k5_29k0;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_14k5_43k5):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_14k5_43k5):
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_14k5_43k5;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_14k5_29k0):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_14k5_29k0):
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_14k5_29k0;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_29k0_43k5):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_29k0_43k5):
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_29k0_43k5;
|
/* TODO: also handle other non-transparent data rates */
|
||||||
break;
|
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains "
|
||||||
|
"unhandled non-transparent CSD data rate 0x%02x\n",
|
||||||
|
cm->chan_rate & 0x3f);
|
||||||
|
*cause = RSL_ERR_IE_CONTENT;
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
/* If octet 4 indicates transparent data */
|
/* If octet 4 indicates transparent data */
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_32000):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_32000):
|
||||||
/* 32.0 kbit/s services, 32.0 kbit/s radio interface rate */
|
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_32k0;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_29000):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_29000):
|
||||||
/* 29.0 kbit/s services, 29.0 kbit/s radio interface rate */
|
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_29k0;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_14400):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_14400):
|
||||||
/* 14.4 kbit/s services, 14.5 kbit/s radio interface rate */
|
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_14k5;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_9600):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_9600):
|
||||||
/* 9.6 kbit/s services, 12.0 kbit/s radio interface rate */
|
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_12k0;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_4800):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_4800):
|
||||||
/* 4.8 kbit/s services, 6.0 kbit/s radio interface rate */
|
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_6k0;
|
|
||||||
break;
|
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_2400):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_2400):
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_1200):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_1200):
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_600):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_600):
|
||||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_1200_75):
|
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_1200_75):
|
||||||
/* 2.4 kbit/s *and less* services, 3.6 kbit/s radio interface rate */
|
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains "
|
||||||
lchan->tch_mode = GSM48_CMODE_DATA_3k6;
|
"unhandled transparent CSD data rate 0x%02x\n",
|
||||||
break;
|
cm->chan_rate & 0x3f);
|
||||||
|
*cause = RSL_ERR_IE_CONTENT;
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains "
|
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains "
|
||||||
@@ -1319,7 +1294,7 @@ int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!send_rel_ack) {
|
if (!send_rel_ack) {
|
||||||
LOGPLCHAN(lchan, DRSL, LOGL_INFO, "not sending REL ACK\n");
|
LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "%s not sending REL ACK\n", gsm_lchan_name(lchan));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1410,7 +1385,7 @@ static int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause) {
|
|||||||
int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause)
|
int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause)
|
||||||
{
|
{
|
||||||
if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL) {
|
if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL) {
|
||||||
LOGPLCHAN(lchan, DRSL, LOGL_INFO, "not sending CHAN ACT %s\n",
|
LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "not sending CHAN ACT %s\n",
|
||||||
cause ? "NACK" : "ACK");
|
cause ? "NACK" : "ACK");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1677,7 +1652,7 @@ static int parse_multirate_config(struct gsm_lchan *lchan,
|
|||||||
}
|
}
|
||||||
|
|
||||||
parsed:
|
parsed:
|
||||||
amr_log_mr_conf(DRTP, LOGL_INFO, gsm_lchan_name(lchan), &lchan->tch.amr_mr);
|
amr_log_mr_conf(DRTP, LOGL_DEBUG, gsm_lchan_name(lchan), &lchan->tch.amr_mr);
|
||||||
lchan->tch.last_cmr = AMR_CMR_NONE;
|
lchan->tch.last_cmr = AMR_CMR_NONE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2727,14 +2702,12 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg)
|
|||||||
struct tlv_parsed tp;
|
struct tlv_parsed tp;
|
||||||
struct gsm_lchan *lchan = msg->lchan;
|
struct gsm_lchan *lchan = msg->lchan;
|
||||||
struct gsm_bts *bts = lchan->ts->trx->bts;
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
||||||
const uint8_t *payload_type, *speech_mode, *payload_type2, *osmux_cid, *csd_fmt;
|
const uint8_t *payload_type, *speech_mode, *payload_type2, *osmux_cid;
|
||||||
uint32_t connect_ip = 0;
|
uint32_t connect_ip = 0;
|
||||||
uint16_t connect_port = 0;
|
uint16_t connect_port = 0;
|
||||||
int rc, inc_ip_port = 0;
|
int rc, inc_ip_port = 0;
|
||||||
char *name;
|
char *name;
|
||||||
struct in_addr ia;
|
struct in_addr ia;
|
||||||
enum rsl_ipac_rtp_csd_format_d csd_fmt_d;
|
|
||||||
enum rsl_ipac_rtp_csd_format_ir csd_fmt_ir;
|
|
||||||
|
|
||||||
if (dch->c.msg_type == RSL_MT_IPAC_CRCX)
|
if (dch->c.msg_type == RSL_MT_IPAC_CRCX)
|
||||||
name = "CRCX";
|
name = "CRCX";
|
||||||
@@ -2792,17 +2765,6 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg)
|
|||||||
inc_ip_port, dch->c.msg_type);
|
inc_ip_port, dch->c.msg_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((csd_fmt = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_CSD_FMT))) {
|
|
||||||
csd_fmt_d = *csd_fmt & 0xf;
|
|
||||||
csd_fmt_ir = *csd_fmt >> 4;
|
|
||||||
LOGPC(DRSL, LOGL_DEBUG, "csd_fmt_d=%d csd_fmt_ir=%d ", csd_fmt_d, csd_fmt_ir);
|
|
||||||
if (csd_fmt_d != RSL_IPAC_RTP_CSD_TRAU_BTS) {
|
|
||||||
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC %s, csd_fmt_d=%d is not supported\n",
|
|
||||||
name, csd_fmt_d);
|
|
||||||
return tx_ipac_XXcx_nack(lchan, RSL_ERR_SERV_OPT_UNIMPL, inc_ip_port, dch->c.msg_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!osmux_cid) { /* Regular RTP */
|
if (!osmux_cid) { /* Regular RTP */
|
||||||
if (bts->osmux.use == OSMUX_USAGE_ONLY) {
|
if (bts->osmux.use == OSMUX_USAGE_ONLY) {
|
||||||
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC XXcx without Osmux CID"
|
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC XXcx without Osmux CID"
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
|
|||||||
.desc = "Frequency correction channel",
|
.desc = "Frequency correction channel",
|
||||||
|
|
||||||
/* Tx only, frequency correction bursts */
|
/* Tx only, frequency correction bursts */
|
||||||
|
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||||
.dl_fn = tx_fcch_fn,
|
.dl_fn = tx_fcch_fn,
|
||||||
},
|
},
|
||||||
[TRXC_SCH] = {
|
[TRXC_SCH] = {
|
||||||
@@ -157,6 +158,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
|
|||||||
.desc = "Synchronization channel",
|
.desc = "Synchronization channel",
|
||||||
|
|
||||||
/* Tx only, synchronization bursts */
|
/* Tx only, synchronization bursts */
|
||||||
|
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||||
.dl_fn = tx_sch_fn,
|
.dl_fn = tx_sch_fn,
|
||||||
},
|
},
|
||||||
[TRXC_BCCH] = {
|
[TRXC_BCCH] = {
|
||||||
@@ -167,6 +169,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
|
|||||||
/* Tx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4),
|
/* Tx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4),
|
||||||
* regular interleaving (3GPP TS 05.02, clause 7, table 3):
|
* regular interleaving (3GPP TS 05.02, clause 7, table 3):
|
||||||
* a L2 frame is interleaved over 4 consecutive bursts. */
|
* a L2 frame is interleaved over 4 consecutive bursts. */
|
||||||
|
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||||
.rts_fn = rts_data_fn,
|
.rts_fn = rts_data_fn,
|
||||||
.dl_fn = tx_data_fn,
|
.dl_fn = tx_data_fn,
|
||||||
},
|
},
|
||||||
@@ -176,6 +179,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
|
|||||||
.chan_nr = RSL_CHAN_RACH,
|
.chan_nr = RSL_CHAN_RACH,
|
||||||
|
|
||||||
/* Rx only, RACH convolutional coding (3GPP TS 05.03, section 4.6). */
|
/* Rx only, RACH convolutional coding (3GPP TS 05.03, section 4.6). */
|
||||||
|
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||||
.ul_fn = rx_rach_fn,
|
.ul_fn = rx_rach_fn,
|
||||||
},
|
},
|
||||||
[TRXC_CCCH] = {
|
[TRXC_CCCH] = {
|
||||||
@@ -186,6 +190,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
|
|||||||
/* Tx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4),
|
/* Tx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4),
|
||||||
* regular interleaving (3GPP TS 05.02, clause 7, table 3):
|
* regular interleaving (3GPP TS 05.02, clause 7, table 3):
|
||||||
* a L2 frame is interleaved over 4 consecutive bursts. */
|
* a L2 frame is interleaved over 4 consecutive bursts. */
|
||||||
|
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||||
.rts_fn = rts_data_fn,
|
.rts_fn = rts_data_fn,
|
||||||
.dl_fn = tx_data_fn,
|
.dl_fn = tx_data_fn,
|
||||||
},
|
},
|
||||||
@@ -570,6 +575,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
|
|||||||
.chan_nr = RSL_CHAN_OSMO_CBCH4,
|
.chan_nr = RSL_CHAN_OSMO_CBCH4,
|
||||||
|
|
||||||
/* Tx only, same as for TRXC_BCCH (xCCH), see above. */
|
/* Tx only, same as for TRXC_BCCH (xCCH), see above. */
|
||||||
|
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||||
.rts_fn = rts_data_fn,
|
.rts_fn = rts_data_fn,
|
||||||
.dl_fn = tx_data_fn,
|
.dl_fn = tx_data_fn,
|
||||||
},
|
},
|
||||||
@@ -819,7 +825,7 @@ int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn,
|
|||||||
if (tch_len)
|
if (tch_len)
|
||||||
memcpy(msg->l2h, tch, tch_len);
|
memcpy(msg->l2h, tch, tch_len);
|
||||||
|
|
||||||
LOGL1S(DL1P, LOGL_INFO, l1ts, chan, l1sap->u.data.fn, "%s Rx -> RTP: %s\n",
|
LOGL1S(DL1P, LOGL_DEBUG, l1ts, chan, l1sap->u.data.fn, "%s Rx -> RTP: %s\n",
|
||||||
gsm_lchan_name(lchan), osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
|
gsm_lchan_name(lchan), osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
|
||||||
/* forward primitive */
|
/* forward primitive */
|
||||||
l1sap_up(l1ts->ts->trx, l1sap);
|
l1sap_up(l1ts->ts->trx, l1sap);
|
||||||
@@ -1007,8 +1013,8 @@ int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pch
|
|||||||
struct l1sched_ts *l1ts = ts->priv;
|
struct l1sched_ts *l1ts = ts->priv;
|
||||||
int i = find_sched_mframe_idx(pchan, ts->nr);
|
int i = find_sched_mframe_idx(pchan, ts->nr);
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
LOGP(DL1C, LOGL_NOTICE, "%s Failed to configure multiframe (pchan=0x%02x)\n",
|
LOGP(DL1C, LOGL_NOTICE, "%s Failed to configure multiframe\n",
|
||||||
gsm_ts_name(ts), pchan);
|
gsm_ts_name(ts));
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
l1ts->mf_index = i;
|
l1ts->mf_index = i;
|
||||||
@@ -1056,52 +1062,6 @@ static void trx_sched_queue_filter(struct llist_head *q, uint8_t chan_nr, uint8_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _trx_sched_set_lchan(struct gsm_lchan *lchan,
|
|
||||||
enum trx_chan_type chan,
|
|
||||||
bool active)
|
|
||||||
{
|
|
||||||
struct l1sched_ts *l1ts = lchan->ts->priv;
|
|
||||||
struct l1sched_chan_state *chan_state;
|
|
||||||
|
|
||||||
OSMO_ASSERT(l1ts != NULL);
|
|
||||||
chan_state = &l1ts->chan_state[chan];
|
|
||||||
|
|
||||||
LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s %s\n",
|
|
||||||
(active) ? "Activating" : "Deactivating",
|
|
||||||
trx_chan_desc[chan].name);
|
|
||||||
|
|
||||||
/* free burst memory, to cleanly start with burst 0 */
|
|
||||||
if (chan_state->dl_bursts) {
|
|
||||||
talloc_free(chan_state->dl_bursts);
|
|
||||||
chan_state->dl_bursts = NULL;
|
|
||||||
}
|
|
||||||
if (chan_state->ul_bursts) {
|
|
||||||
talloc_free(chan_state->ul_bursts);
|
|
||||||
chan_state->ul_bursts = NULL;
|
|
||||||
}
|
|
||||||
if (chan_state->ul_bursts_prev) {
|
|
||||||
talloc_free(chan_state->ul_bursts_prev);
|
|
||||||
chan_state->ul_bursts_prev = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
/* Clean up everything */
|
|
||||||
memset(chan_state, 0, sizeof(*chan_state));
|
|
||||||
|
|
||||||
/* Bind to generic 'struct gsm_lchan' */
|
|
||||||
chan_state->lchan = lchan;
|
|
||||||
} else {
|
|
||||||
chan_state->ho_rach_detect = 0;
|
|
||||||
|
|
||||||
/* Remove pending Tx prims belonging to this lchan */
|
|
||||||
trx_sched_queue_filter(&l1ts->dl_prims,
|
|
||||||
trx_chan_desc[chan].chan_nr,
|
|
||||||
trx_chan_desc[chan].link_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
chan_state->active = active;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setting all logical channels given attributes to active/inactive */
|
/* setting all logical channels given attributes to active/inactive */
|
||||||
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active)
|
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active)
|
||||||
{
|
{
|
||||||
@@ -1109,6 +1069,7 @@ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_i
|
|||||||
uint8_t tn = L1SAP_CHAN2TS(chan_nr);
|
uint8_t tn = L1SAP_CHAN2TS(chan_nr);
|
||||||
uint8_t ss = l1sap_chan2ss(chan_nr);
|
uint8_t ss = l1sap_chan2ss(chan_nr);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!l1ts) {
|
if (!l1ts) {
|
||||||
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "%s lchan with uninitialized scheduler structure\n",
|
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "%s lchan with uninitialized scheduler structure\n",
|
||||||
@@ -1122,15 +1083,48 @@ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_i
|
|||||||
chan_nr &= ~RSL_CHAN_OSMO_VAMOS_MASK;
|
chan_nr &= ~RSL_CHAN_OSMO_VAMOS_MASK;
|
||||||
|
|
||||||
/* look for all matching chan_nr/link_id */
|
/* look for all matching chan_nr/link_id */
|
||||||
for (enum trx_chan_type chan = 0; chan < _TRX_CHAN_MAX; chan++) {
|
for (i = 0; i < _TRX_CHAN_MAX; i++) {
|
||||||
if (trx_chan_desc[chan].chan_nr != (chan_nr & RSL_CHAN_NR_MASK))
|
struct l1sched_chan_state *chan_state = &l1ts->chan_state[i];
|
||||||
|
|
||||||
|
if (trx_chan_desc[i].chan_nr != (chan_nr & RSL_CHAN_NR_MASK))
|
||||||
continue;
|
continue;
|
||||||
if (trx_chan_desc[chan].link_id != link_id)
|
if (trx_chan_desc[i].link_id != link_id)
|
||||||
continue;
|
continue;
|
||||||
if (l1ts->chan_state[chan].active == active)
|
if (chan_state->active == active)
|
||||||
continue;
|
continue;
|
||||||
found = true;
|
found = true;
|
||||||
_trx_sched_set_lchan(lchan, chan, active);
|
|
||||||
|
LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s %s\n",
|
||||||
|
(active) ? "Activating" : "Deactivating",
|
||||||
|
trx_chan_desc[i].name);
|
||||||
|
/* free burst memory, to cleanly start with burst 0 */
|
||||||
|
if (chan_state->dl_bursts) {
|
||||||
|
talloc_free(chan_state->dl_bursts);
|
||||||
|
chan_state->dl_bursts = NULL;
|
||||||
|
}
|
||||||
|
if (chan_state->ul_bursts) {
|
||||||
|
talloc_free(chan_state->ul_bursts);
|
||||||
|
chan_state->ul_bursts = NULL;
|
||||||
|
}
|
||||||
|
if (chan_state->ul_bursts_prev) {
|
||||||
|
talloc_free(chan_state->ul_bursts_prev);
|
||||||
|
chan_state->ul_bursts_prev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
/* Clean up everything */
|
||||||
|
memset(chan_state, 0, sizeof(*chan_state));
|
||||||
|
|
||||||
|
/* Bind to generic 'struct gsm_lchan' */
|
||||||
|
chan_state->lchan = lchan;
|
||||||
|
} else {
|
||||||
|
chan_state->ho_rach_detect = 0;
|
||||||
|
|
||||||
|
/* Remove pending Tx prims belonging to this lchan */
|
||||||
|
trx_sched_queue_filter(&l1ts->dl_prims, chan_nr, link_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
chan_state->active = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* disable handover detection (on deactivation) */
|
/* disable handover detection (on deactivation) */
|
||||||
@@ -1140,31 +1134,6 @@ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_i
|
|||||||
return found ? 0 : -EINVAL;
|
return found ? 0 : -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool active)
|
|
||||||
{
|
|
||||||
struct l1sched_ts *l1ts = lchan->ts->priv;
|
|
||||||
static const enum trx_chan_type chans[] = {
|
|
||||||
TRXC_FCCH,
|
|
||||||
TRXC_SCH,
|
|
||||||
TRXC_BCCH,
|
|
||||||
TRXC_RACH,
|
|
||||||
TRXC_CCCH,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!l1ts)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ARRAY_SIZE(chans); i++) {
|
|
||||||
enum trx_chan_type chan = chans[i];
|
|
||||||
|
|
||||||
if (l1ts->chan_state[chan].active == active)
|
|
||||||
continue;
|
|
||||||
_trx_sched_set_lchan(lchan, chan, active);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setting all logical channels given attributes to active/inactive */
|
/* setting all logical channels given attributes to active/inactive */
|
||||||
int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,
|
int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,
|
||||||
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
|
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
|
||||||
@@ -1308,7 +1277,7 @@ int _sched_rts(const struct l1sched_ts *l1ts, uint32_t fn)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* check if channel is active */
|
/* check if channel is active */
|
||||||
if (!l1ts->chan_state[chan].active)
|
if (!TRX_CHAN_IS_ACTIVE(&l1ts->chan_state[chan], chan))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* There is no burst, just for logging */
|
/* There is no burst, just for logging */
|
||||||
@@ -1365,7 +1334,7 @@ void _sched_dl_burst(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)
|
|||||||
l1cs = &l1ts->chan_state[br->chan];
|
l1cs = &l1ts->chan_state[br->chan];
|
||||||
|
|
||||||
/* check if channel is active */
|
/* check if channel is active */
|
||||||
if (!l1cs->active)
|
if (!TRX_CHAN_IS_ACTIVE(l1cs, br->chan))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Training Sequence Code and Set */
|
/* Training Sequence Code and Set */
|
||||||
@@ -1554,7 +1523,7 @@ int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi)
|
|||||||
func = trx_chan_desc[bi->chan].ul_fn;
|
func = trx_chan_desc[bi->chan].ul_fn;
|
||||||
|
|
||||||
/* check if channel is active */
|
/* check if channel is active */
|
||||||
if (!l1cs->active) {
|
if (!TRX_CHAN_IS_ACTIVE(l1cs, bi->chan)) {
|
||||||
/* handle noise measurements on dedicated and idle channels */
|
/* handle noise measurements on dedicated and idle channels */
|
||||||
if (TRX_CHAN_IS_DEDIC(bi->chan) || bi->chan == TRXC_IDLE)
|
if (TRX_CHAN_IS_DEDIC(bi->chan) || bi->chan == TRXC_IDLE)
|
||||||
trx_sched_noise_meas(l1cs, bi);
|
trx_sched_noise_meas(l1cs, bi);
|
||||||
|
|||||||
@@ -388,9 +388,9 @@ static void config_write_osmux(struct vty *vty, const char *prefix, const struct
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vty_out(vty, "%s local-ip %s%s", prefix, bts->osmux.local_addr, VTY_NEWLINE);
|
vty_out(vty, "%s local-ip %s%s", prefix, bts->osmux.local_addr, VTY_NEWLINE);
|
||||||
vty_out(vty, "%s local-port %u%s", prefix, bts->osmux.local_port, VTY_NEWLINE);
|
|
||||||
vty_out(vty, "%s batch-factor %d%s", prefix, bts->osmux.batch_factor, VTY_NEWLINE);
|
vty_out(vty, "%s batch-factor %d%s", prefix, bts->osmux.batch_factor, VTY_NEWLINE);
|
||||||
vty_out(vty, "%s batch-size %u%s", prefix, bts->osmux.batch_size, VTY_NEWLINE);
|
vty_out(vty, "%s batch-size %u%s", prefix, bts->osmux.batch_size, VTY_NEWLINE);
|
||||||
|
vty_out(vty, "%s port %u%s", prefix, bts->osmux.local_port, VTY_NEWLINE);
|
||||||
vty_out(vty, "%s dummy-padding %s%s", prefix, bts->osmux.dummy_padding ? "on" : "off", VTY_NEWLINE);
|
vty_out(vty, "%s dummy-padding %s%s", prefix, bts->osmux.dummy_padding ? "on" : "off", VTY_NEWLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,10 +440,6 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts)
|
|||||||
vty_out(vty, " gsmtap-remote-host %s%s",
|
vty_out(vty, " gsmtap-remote-host %s%s",
|
||||||
bts->gsmtap.remote_host,
|
bts->gsmtap.remote_host,
|
||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
if (bts->gsmtap.local_host != NULL)
|
|
||||||
vty_out(vty, " gsmtap-local-host %s%s",
|
|
||||||
bts->gsmtap.local_host,
|
|
||||||
VTY_NEWLINE);
|
|
||||||
for (i = 0; i < sizeof(uint32_t) * 8; i++) {
|
for (i = 0; i < sizeof(uint32_t) * 8; i++) {
|
||||||
if (bts->gsmtap.sapi_mask & ((uint32_t) 1 << i)) {
|
if (bts->gsmtap.sapi_mask & ((uint32_t) 1 << i)) {
|
||||||
sapi_buf = get_value_string_or_null(gsmtap_sapi_names, i);
|
sapi_buf = get_value_string_or_null(gsmtap_sapi_names, i);
|
||||||
@@ -2221,22 +2217,6 @@ DEFUN(cfg_bts_gsmtap_remote_host,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN(cfg_bts_gsmtap_local_host,
|
|
||||||
cfg_bts_gsmtap_local_host_cmd,
|
|
||||||
"gsmtap-local-host HOSTNAME",
|
|
||||||
"Enable local bind for GSMTAP Um logging (see also 'gsmtap-sapi')\n"
|
|
||||||
"Local IP address or hostname\n")
|
|
||||||
{
|
|
||||||
struct gsm_bts *bts = vty->index;
|
|
||||||
|
|
||||||
osmo_talloc_replace_string(bts, &bts->gsmtap.local_host, argv[0]);
|
|
||||||
|
|
||||||
if (vty->type != VTY_FILE)
|
|
||||||
vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE);
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFUN(cfg_bts_no_gsmtap_remote_host,
|
DEFUN(cfg_bts_no_gsmtap_remote_host,
|
||||||
cfg_bts_no_gsmtap_remote_host_cmd,
|
cfg_bts_no_gsmtap_remote_host_cmd,
|
||||||
"no gsmtap-remote-host",
|
"no gsmtap-remote-host",
|
||||||
@@ -2254,24 +2234,6 @@ DEFUN(cfg_bts_no_gsmtap_remote_host,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN(cfg_bts_no_gsmtap_local_host,
|
|
||||||
cfg_bts_no_gsmtap_local_host_cmd,
|
|
||||||
"no gsmtap-local-host",
|
|
||||||
NO_STR "Disable local bind for GSMTAP Um logging\n")
|
|
||||||
{
|
|
||||||
struct gsm_bts *bts = vty->index;
|
|
||||||
|
|
||||||
if (bts->gsmtap.local_host != NULL)
|
|
||||||
talloc_free(bts->gsmtap.local_host);
|
|
||||||
|
|
||||||
bts->gsmtap.local_host = NULL;
|
|
||||||
|
|
||||||
if (vty->type != VTY_FILE)
|
|
||||||
vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE);
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFUN(cfg_bts_gsmtap_sapi_all, cfg_bts_gsmtap_sapi_all_cmd,
|
DEFUN(cfg_bts_gsmtap_sapi_all, cfg_bts_gsmtap_sapi_all_cmd,
|
||||||
"gsmtap-sapi (enable-all|disable-all)",
|
"gsmtap-sapi (enable-all|disable-all)",
|
||||||
"Enable/disable sending of UL/DL messages over GSMTAP\n"
|
"Enable/disable sending of UL/DL messages over GSMTAP\n"
|
||||||
@@ -2308,7 +2270,7 @@ DEFUN(cfg_bts_gsmtap_sapi, cfg_bts_gsmtap_sapi_cmd,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN(cfg_bts_no_gsmtap_sapi, cfg_bts_no_gsmtap_sapi_cmd,
|
DEFUN(cfg_trx_no_gsmtap_sapi, cfg_bts_no_gsmtap_sapi_cmd,
|
||||||
"HIDDEN", "HIDDEN")
|
"HIDDEN", "HIDDEN")
|
||||||
{
|
{
|
||||||
struct gsm_bts *bts = vty->index;
|
struct gsm_bts *bts = vty->index;
|
||||||
@@ -2690,8 +2652,6 @@ int bts_vty_init(void *ctx)
|
|||||||
|
|
||||||
install_element(BTS_NODE, &cfg_bts_gsmtap_remote_host_cmd);
|
install_element(BTS_NODE, &cfg_bts_gsmtap_remote_host_cmd);
|
||||||
install_element(BTS_NODE, &cfg_bts_no_gsmtap_remote_host_cmd);
|
install_element(BTS_NODE, &cfg_bts_no_gsmtap_remote_host_cmd);
|
||||||
install_element(BTS_NODE, &cfg_bts_gsmtap_local_host_cmd);
|
|
||||||
install_element(BTS_NODE, &cfg_bts_no_gsmtap_local_host_cmd);
|
|
||||||
install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_all_cmd);
|
install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_all_cmd);
|
||||||
install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_cmd);
|
install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_cmd);
|
||||||
install_element(BTS_NODE, &cfg_bts_no_gsmtap_sapi_cmd);
|
install_element(BTS_NODE, &cfg_bts_no_gsmtap_sapi_cmd);
|
||||||
|
|||||||
@@ -508,6 +508,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||||||
|
|
||||||
/* create new message and fill data */
|
/* create new message and fill data */
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
msgb_pull(msg, sizeof(*l1sap));
|
||||||
/* create new message */
|
/* create new message */
|
||||||
nmsg = l1p_msgb_alloc();
|
nmsg = l1p_msgb_alloc();
|
||||||
if (!nmsg)
|
if (!nmsg)
|
||||||
@@ -516,7 +517,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||||||
rc = l1if_tch_encode(lchan,
|
rc = l1if_tch_encode(lchan,
|
||||||
l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
||||||
&l1p->u.phDataReq.msgUnitParam.u8Size,
|
&l1p->u.phDataReq.msgUnitParam.u8Size,
|
||||||
msgb_l2(msg), msgb_l2len(msg), u32Fn, use_cache,
|
msg->data, msg->len, u32Fn, use_cache,
|
||||||
l1sap->u.tch.marker);
|
l1sap->u.tch.marker);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
/* no data encoded for L1: smth will be generated below */
|
/* no data encoded for L1: smth will be generated below */
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = telnet_init_default(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR);
|
rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Error initializing telnet\n");
|
fprintf(stderr, "Error initializing telnet\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
@@ -561,6 +561,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||||||
|
|
||||||
/* create new message and fill data */
|
/* create new message and fill data */
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
msgb_pull(msg, sizeof(*l1sap));
|
||||||
/* create new message */
|
/* create new message */
|
||||||
nmsg = l1p_msgb_alloc();
|
nmsg = l1p_msgb_alloc();
|
||||||
if (!nmsg)
|
if (!nmsg)
|
||||||
@@ -569,7 +570,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||||||
rc = l1if_tch_encode(lchan,
|
rc = l1if_tch_encode(lchan,
|
||||||
l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
||||||
&l1p->u.phDataReq.msgUnitParam.u8Size,
|
&l1p->u.phDataReq.msgUnitParam.u8Size,
|
||||||
msgb_l2(msg), msgb_l2len(msg), u32Fn, use_cache,
|
msg->data, msg->len, u32Fn, use_cache,
|
||||||
l1sap->u.tch.marker);
|
l1sap->u.tch.marker);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
/* no data encoded for L1: smth will be generated below */
|
/* no data encoded for L1: smth will be generated below */
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = telnet_init_default(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR);
|
rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Error initializing telnet\n");
|
fprintf(stderr, "Error initializing telnet\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
@@ -171,12 +171,7 @@ static void mgr_gps_checkfix(struct oc2gbts_mgr_instance *mgr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GPSD_API_MAJOR_VERSION >= 9
|
|
||||||
mgr->gps.gps_fix_now = data->fix.time.tv_sec;
|
|
||||||
#else
|
|
||||||
mgr->gps.gps_fix_now = (time_t) data->fix.time;
|
mgr->gps.gps_fix_now = (time_t) data->fix.time;
|
||||||
#endif
|
|
||||||
|
|
||||||
LOGP(DCALIB, LOGL_INFO, "Got a GPS fix, satellites used: %d, timestamp: %ld\n",
|
LOGP(DCALIB, LOGL_INFO, "Got a GPS fix, satellites used: %d, timestamp: %ld\n",
|
||||||
data->satellites_used, mgr->gps.gps_fix_now);
|
data->satellites_used, mgr->gps.gps_fix_now);
|
||||||
osmo_timer_del(&mgr->gps.fix_timeout);
|
osmo_timer_del(&mgr->gps.fix_timeout);
|
||||||
|
|||||||
@@ -593,6 +593,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msgb_pull(msg, sizeof(*l1sap));
|
||||||
tOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CMD *data_req =
|
tOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CMD *data_req =
|
||||||
(tOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CMD *)
|
(tOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CMD *)
|
||||||
msgb_put(nmsg, sizeof(*data_req));
|
msgb_put(nmsg, sizeof(*data_req));
|
||||||
@@ -614,7 +615,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||||||
&data_req->Data.ulPayloadType,
|
&data_req->Data.ulPayloadType,
|
||||||
data_req->Data.abyDataContent,
|
data_req->Data.abyDataContent,
|
||||||
&data_req->Data.ulDataLength,
|
&data_req->Data.ulDataLength,
|
||||||
msgb_l2(msg), msgb_l2len(msg));
|
msg->data, msg->len);
|
||||||
|
|
||||||
mOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CMD_SWAP(data_req);
|
mOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CMD_SWAP(data_req);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
/**
|
/**
|
||||||
* EEPROM device file
|
* EEPROM device file
|
||||||
*/
|
*/
|
||||||
#define EEPROM_DEV "eeprom"
|
#define EEPROM_DEV "/sys/bus/i2c/devices/i2c-1/1-0050/eeprom"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EEPROM configuration start address
|
* EEPROM configuration start address
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ enum l1prim_type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if !defined(SUPERFEMTO_API_VERSION) || SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,1,0)
|
#if !defined(SUPERFEMTO_API_VERSION) || SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,1,0)
|
||||||
enum Superfemto_clk_src {
|
enum uperfemto_clk_src {
|
||||||
SF_CLKSRC_NONE = 0,
|
SF_CLKSRC_NONE = 0,
|
||||||
SF_CLKSRC_OCXO = 1,
|
SF_CLKSRC_OCXO = 1,
|
||||||
SF_CLKSRC_TCXO = 2,
|
SF_CLKSRC_TCXO = 2,
|
||||||
|
|||||||
@@ -505,6 +505,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||||||
|
|
||||||
/* create new message and fill data */
|
/* create new message and fill data */
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
msgb_pull(msg, sizeof(*l1sap));
|
||||||
/* create new message */
|
/* create new message */
|
||||||
nmsg = l1p_msgb_alloc();
|
nmsg = l1p_msgb_alloc();
|
||||||
if (!nmsg)
|
if (!nmsg)
|
||||||
@@ -513,7 +514,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
|||||||
rc = l1if_tch_encode(lchan,
|
rc = l1if_tch_encode(lchan,
|
||||||
l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
||||||
&l1p->u.phDataReq.msgUnitParam.u8Size,
|
&l1p->u.phDataReq.msgUnitParam.u8Size,
|
||||||
msgb_l2(msg), msgb_l2len(msg), u32Fn, use_cache,
|
msg->data, msg->len, u32Fn, use_cache,
|
||||||
l1sap->u.tch.marker);
|
l1sap->u.tch.marker);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
/* no data encoded for L1: smth will be generated below */
|
/* no data encoded for L1: smth will be generated below */
|
||||||
@@ -966,7 +967,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
|
|||||||
|
|
||||||
gsm_fn2gsmtime(&g_time, fn);
|
gsm_fn2gsmtime(&g_time, fn);
|
||||||
|
|
||||||
LOGPGT(DL1P, LOGL_INFO, &g_time, "Rx PH-DATA.ind %s (hL2 %08x): %s, " LOG_FMT_MEAS "\n",
|
DEBUGPGT(DL1P, &g_time, "Rx PH-DATA.ind %s (hL2 %08x): %s, " LOG_FMT_MEAS "\n",
|
||||||
get_value_string(femtobts_l1sapi_names, data_ind->sapi), data_ind->hLayer2,
|
get_value_string(femtobts_l1sapi_names, data_ind->sapi), data_ind->hLayer2,
|
||||||
osmo_hexdump(data_ind->msgUnitParam.u8Buffer, data_ind->msgUnitParam.u8Size),
|
osmo_hexdump(data_ind->msgUnitParam.u8Buffer, data_ind->msgUnitParam.u8Size),
|
||||||
LOG_PARAM_MEAS(&data_ind->measParam));
|
LOG_PARAM_MEAS(&data_ind->measParam));
|
||||||
@@ -980,9 +981,6 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data_ind->sapi == GsmL1_Sapi_FacchF)
|
|
||||||
LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "Rx SAPI FACCH\n");
|
|
||||||
|
|
||||||
/* fill L1SAP header */
|
/* fill L1SAP header */
|
||||||
sap_msg = l1sap_msgb_alloc(data_ind->msgUnitParam.u8Size);
|
sap_msg = l1sap_msgb_alloc(data_ind->msgUnitParam.u8Size);
|
||||||
l1sap = msgb_l1sap_prim(sap_msg);
|
l1sap = msgb_l1sap_prim(sap_msg);
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = telnet_init_default(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR);
|
rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Error initializing telnet\n");
|
fprintf(stderr, "Error initializing telnet\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
#include "sysmobts_par.h"
|
#include "sysmobts_par.h"
|
||||||
#include "eeprom.h"
|
#include "eeprom.h"
|
||||||
|
|
||||||
#define EEPROM_PATH "eeprom"
|
#define EEPROM_PATH "/sys/devices/platform/i2c_davinci.1/i2c-1/1-0050/eeprom"
|
||||||
|
|
||||||
static const struct osmo_crc8gen_code crc8_ccit = {
|
static const struct osmo_crc8gen_code crc8_ccit = {
|
||||||
.bits = 8,
|
.bits = 8,
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len
|
|||||||
{
|
{
|
||||||
struct msgb *msg;
|
struct msgb *msg;
|
||||||
uint8_t *cur;
|
uint8_t *cur;
|
||||||
bool t;
|
|
||||||
|
|
||||||
msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP");
|
msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP");
|
||||||
if (!msg)
|
if (!msg)
|
||||||
@@ -77,9 +76,8 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len
|
|||||||
|
|
||||||
cur[0] |= 0xD0;
|
cur[0] |= 0xD0;
|
||||||
#endif /* USE_L1_RTP_MODE */
|
#endif /* USE_L1_RTP_MODE */
|
||||||
t = osmo_fr_check_sid(l1_payload, payload_len);
|
|
||||||
lchan_set_marker(t, lchan);
|
lchan_set_marker(osmo_fr_check_sid(l1_payload, payload_len), lchan);
|
||||||
LOGP(DL1P, LOGL_ERROR, "FR SID:%d\n", t);
|
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
@@ -282,12 +280,11 @@ static struct msgb *l1_to_rtppayload_amr(uint8_t *l1_payload, uint8_t payload_le
|
|||||||
* Audiocode's MGW doesn't like receiving CMRs that are not
|
* Audiocode's MGW doesn't like receiving CMRs that are not
|
||||||
* the same as the previous one. This means we need to patch
|
* the same as the previous one. This means we need to patch
|
||||||
* the content here.
|
* the content here.
|
||||||
|
*/
|
||||||
if ((cur[0] & 0xF0) == 0xF0)
|
if ((cur[0] & 0xF0) == 0xF0)
|
||||||
cur[0]= lchan->tch.last_cmr << 4;
|
cur[0]= lchan->tch.last_cmr << 4;
|
||||||
else
|
else
|
||||||
lchan->tch.last_cmr = cur[0] >> 4;
|
lchan->tch.last_cmr = cur[0] >> 4;
|
||||||
*/
|
|
||||||
#else
|
#else
|
||||||
u_int8_t cmr;
|
u_int8_t cmr;
|
||||||
uint8_t ft = l1_payload[2] & 0xF;
|
uint8_t ft = l1_payload[2] & 0xF;
|
||||||
@@ -511,13 +508,12 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
|
|||||||
uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 };
|
uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 };
|
||||||
struct msgb *rmsg = NULL;
|
struct msgb *rmsg = NULL;
|
||||||
struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];
|
struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];
|
||||||
int len;
|
|
||||||
|
|
||||||
if (is_recv_only(lchan->abis_ip.speech_mode))
|
if (is_recv_only(lchan->abis_ip.speech_mode))
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
if (data_ind->msgUnitParam.u8Size < 1) {
|
if (data_ind->msgUnitParam.u8Size < 1) {
|
||||||
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "chan_nr %d Rx Payload size 0\n", chan_nr);
|
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "chan_nr %d Rx Payload size 0\n", chan_nr);
|
||||||
/* Push empty payload to upper layers */
|
/* Push empty payload to upper layers */
|
||||||
rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP");
|
rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP");
|
||||||
return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn,
|
return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn,
|
||||||
@@ -532,10 +528,6 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
|
|||||||
payload = data_ind->msgUnitParam.u8Buffer + 1;
|
payload = data_ind->msgUnitParam.u8Buffer + 1;
|
||||||
payload_len = data_ind->msgUnitParam.u8Size - 1;
|
payload_len = data_ind->msgUnitParam.u8Size - 1;
|
||||||
|
|
||||||
/* clear RTP marker if the marker has previously sent */
|
|
||||||
if (!lchan->tch.dtx.is_speech_resume)
|
|
||||||
lchan->rtp_tx_marker = false;
|
|
||||||
|
|
||||||
switch (payload_type) {
|
switch (payload_type) {
|
||||||
case GsmL1_TchPlType_Fr:
|
case GsmL1_TchPlType_Fr:
|
||||||
#if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE)
|
#if defined(L1_HAS_EFR) && defined(USE_L1_RTP_MODE)
|
||||||
@@ -552,47 +544,40 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
|
|||||||
if (lchan->type != GSM_LCHAN_TCH_H &&
|
if (lchan->type != GSM_LCHAN_TCH_H &&
|
||||||
lchan->type != GSM_LCHAN_TCH_F)
|
lchan->type != GSM_LCHAN_TCH_F)
|
||||||
goto err_payload_match;
|
goto err_payload_match;
|
||||||
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received Speech from L1 "
|
|
||||||
"(%d bytes)\n", payload_len);
|
|
||||||
break;
|
break;
|
||||||
case GsmL1_TchPlType_Amr_Onset:
|
case GsmL1_TchPlType_Amr_Onset:
|
||||||
if (lchan->type != GSM_LCHAN_TCH_H &&
|
if (lchan->type != GSM_LCHAN_TCH_H &&
|
||||||
lchan->type != GSM_LCHAN_TCH_F)
|
lchan->type != GSM_LCHAN_TCH_F)
|
||||||
goto err_payload_match;
|
goto err_payload_match;
|
||||||
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received ONSET from L1 "
|
|
||||||
"(%d bytes)\n", payload_len);
|
|
||||||
/* according to 3GPP TS 26.093 ONSET frames precede the first
|
/* according to 3GPP TS 26.093 ONSET frames precede the first
|
||||||
speech frame of a speech burst - set the marker for next RTP
|
speech frame of a speech burst - set the marker for next RTP
|
||||||
frame */
|
frame */
|
||||||
lchan->tch.dtx.is_speech_resume = true;
|
|
||||||
lchan->rtp_tx_marker = true;
|
lchan->rtp_tx_marker = true;
|
||||||
break;
|
break;
|
||||||
case GsmL1_TchPlType_Amr_SidFirstP1:
|
case GsmL1_TchPlType_Amr_SidFirstP1:
|
||||||
if (lchan->type != GSM_LCHAN_TCH_H)
|
if (lchan->type != GSM_LCHAN_TCH_H)
|
||||||
goto err_payload_match;
|
goto err_payload_match;
|
||||||
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 "
|
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 "
|
||||||
"(%d bytes)\n", payload_len);
|
"(%d bytes)\n", payload_len);
|
||||||
break;
|
break;
|
||||||
case GsmL1_TchPlType_Amr_SidFirstP2:
|
case GsmL1_TchPlType_Amr_SidFirstP2:
|
||||||
if (lchan->type != GSM_LCHAN_TCH_H)
|
if (lchan->type != GSM_LCHAN_TCH_H)
|
||||||
goto err_payload_match;
|
goto err_payload_match;
|
||||||
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 "
|
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 "
|
||||||
"(%d bytes)\n", payload_len);
|
"(%d bytes)\n", payload_len);
|
||||||
break;
|
break;
|
||||||
case GsmL1_TchPlType_Amr_SidFirstInH:
|
case GsmL1_TchPlType_Amr_SidFirstInH:
|
||||||
if (lchan->type != GSM_LCHAN_TCH_H)
|
if (lchan->type != GSM_LCHAN_TCH_H)
|
||||||
goto err_payload_match;
|
goto err_payload_match;
|
||||||
lchan->tch.dtx.is_speech_resume = true;
|
|
||||||
lchan->rtp_tx_marker = true;
|
lchan->rtp_tx_marker = true;
|
||||||
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 "
|
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 "
|
||||||
"(%d bytes)\n", payload_len);
|
"(%d bytes)\n", payload_len);
|
||||||
break;
|
break;
|
||||||
case GsmL1_TchPlType_Amr_SidUpdateInH:
|
case GsmL1_TchPlType_Amr_SidUpdateInH:
|
||||||
if (lchan->type != GSM_LCHAN_TCH_H)
|
if (lchan->type != GSM_LCHAN_TCH_H)
|
||||||
goto err_payload_match;
|
goto err_payload_match;
|
||||||
lchan->tch.dtx.is_speech_resume = true;
|
|
||||||
lchan->rtp_tx_marker = true;
|
lchan->rtp_tx_marker = true;
|
||||||
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 "
|
LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 "
|
||||||
"(%d bytes)\n", payload_len);
|
"(%d bytes)\n", payload_len);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -602,6 +587,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (payload_type) {
|
switch (payload_type) {
|
||||||
case GsmL1_TchPlType_Fr:
|
case GsmL1_TchPlType_Fr:
|
||||||
rmsg = l1_to_rtppayload_fr(payload, payload_len, lchan);
|
rmsg = l1_to_rtppayload_fr(payload, payload_len, lchan);
|
||||||
@@ -617,24 +603,12 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
|
|||||||
case GsmL1_TchPlType_Amr:
|
case GsmL1_TchPlType_Amr:
|
||||||
rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan);
|
rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan);
|
||||||
break;
|
break;
|
||||||
case GsmL1_TchPlType_Amr_Onset:
|
|
||||||
/*memcpy(sid_first+2, payload, payload_len);
|
|
||||||
len = osmo_amr_rtp_enc(sid_first, 15, AMR_SID, AMR_GOOD);
|
|
||||||
LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "ONSET resulted in length [%d]\n", len);
|
|
||||||
if (len < 0)
|
|
||||||
return 0;
|
|
||||||
len = len+2;
|
|
||||||
rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);*/
|
|
||||||
break;
|
|
||||||
case GsmL1_TchPlType_Amr_SidFirstP1:
|
case GsmL1_TchPlType_Amr_SidFirstP1:
|
||||||
rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan);
|
memcpy(sid_first, payload, payload_len);
|
||||||
lchan->rtp_tx_marker = false;
|
int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD);
|
||||||
/*memcpy(sid_first, payload, payload_len);
|
|
||||||
len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD);
|
|
||||||
LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "SID P1 resulted in length [%d]\n", len);
|
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return 0;
|
return 0;
|
||||||
rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);*/
|
rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);
|
||||||
break;
|
break;
|
||||||
/* FIXME: what about GsmL1_TchPlType_Amr_SidBad? not well documented. */
|
/* FIXME: what about GsmL1_TchPlType_Amr_SidBad? not well documented. */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -270,26 +270,11 @@ static uint8_t trx_set_ts_as_pchan(struct gsm_bts_trx_ts *ts,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return NM_NACK_RES_NOTAVAIL;
|
return NM_NACK_RES_NOTAVAIL;
|
||||||
|
|
||||||
/* activate lchans for [CBCH/]BCCH/CCCH */
|
/* activate lchan for CCCH */
|
||||||
switch (pchan) {
|
if (pchan == GSM_PCHAN_CCCH || pchan == GSM_PCHAN_CCCH_SDCCH4 ||
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH) {
|
||||||
/* using RSL_CHAN_OSMO_CBCH4 is correct here, because the scheduler
|
|
||||||
* does not distinguish between SDCCH/4+CBCH abd SDCCH/8+CBCH. */
|
|
||||||
trx_sched_set_lchan(&ts->lchan[CBCH_LCHAN],
|
|
||||||
RSL_CHAN_OSMO_CBCH4, LID_DEDIC, true);
|
|
||||||
break;
|
|
||||||
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
|
||||||
trx_sched_set_lchan(&ts->lchan[CBCH_LCHAN],
|
|
||||||
RSL_CHAN_OSMO_CBCH4, LID_DEDIC, true);
|
|
||||||
/* fall-through */
|
|
||||||
case GSM_PCHAN_CCCH_SDCCH4:
|
|
||||||
case GSM_PCHAN_CCCH:
|
|
||||||
trx_sched_set_bcch_ccch(&ts->lchan[CCCH_LCHAN], true);
|
|
||||||
ts->lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML;
|
ts->lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML;
|
||||||
lchan_set_state(&ts->lchan[CCCH_LCHAN], LCHAN_S_ACTIVE);
|
lchan_set_state(&ts->lchan[CCCH_LCHAN], LCHAN_S_ACTIVE);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
slottype = transceiver_chan_types[pchan];
|
slottype = transceiver_chan_types[pchan];
|
||||||
@@ -411,92 +396,86 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
|
|||||||
/* put data into scheduler's queue */
|
/* put data into scheduler's queue */
|
||||||
return trx_sched_tch_req(trx, l1sap);
|
return trx_sched_tch_req(trx, l1sap);
|
||||||
case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST):
|
case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST):
|
||||||
if (l1sap->u.info.type == PRIM_INFO_ACT_CIPH)
|
|
||||||
chan_nr = l1sap->u.info.u.ciph_req.chan_nr;
|
|
||||||
else /* u.act_req used by PRIM_INFO_{ACTIVATE,DEACTIVATE,MODIFY} */
|
|
||||||
chan_nr = l1sap->u.info.u.act_req.chan_nr;
|
|
||||||
lchan = get_lchan_by_chan_nr(trx, chan_nr);
|
|
||||||
if (OSMO_UNLIKELY(lchan == NULL)) {
|
|
||||||
LOGP(DL1C, LOGL_ERROR,
|
|
||||||
"Rx MPH-INFO.req (type=0x%02x) for non-existent lchan (%s)\n",
|
|
||||||
l1sap->u.info.type, rsl_chan_nr_str(chan_nr));
|
|
||||||
rc = -ENODEV;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (l1sap->u.info.type) {
|
switch (l1sap->u.info.type) {
|
||||||
case PRIM_INFO_ACT_CIPH:
|
case PRIM_INFO_ACT_CIPH:
|
||||||
|
chan_nr = l1sap->u.info.u.ciph_req.chan_nr;
|
||||||
|
lchan = get_lchan_by_chan_nr(trx, chan_nr);
|
||||||
if (l1sap->u.info.u.ciph_req.uplink)
|
if (l1sap->u.info.u.ciph_req.uplink)
|
||||||
l1if_set_ciphering(lchan, chan_nr, 0);
|
l1if_set_ciphering(lchan, chan_nr, 0);
|
||||||
if (l1sap->u.info.u.ciph_req.downlink)
|
if (l1sap->u.info.u.ciph_req.downlink)
|
||||||
l1if_set_ciphering(lchan, chan_nr, 1);
|
l1if_set_ciphering(lchan, chan_nr, 1);
|
||||||
break;
|
break;
|
||||||
case PRIM_INFO_ACTIVATE:
|
case PRIM_INFO_ACTIVATE:
|
||||||
if ((chan_nr & 0xE0) == 0x80) {
|
case PRIM_INFO_DEACTIVATE:
|
||||||
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate"
|
case PRIM_INFO_MODIFY:
|
||||||
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
chan_nr = l1sap->u.info.u.act_req.chan_nr;
|
||||||
rc = -EPERM;
|
lchan = get_lchan_by_chan_nr(trx, chan_nr);
|
||||||
|
if (l1sap->u.info.type == PRIM_INFO_ACTIVATE) {
|
||||||
|
if ((chan_nr & 0xE0) == 0x80) {
|
||||||
|
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate"
|
||||||
|
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* attempt to allocate an Error Concealment Unit instance, if available */
|
||||||
|
lchan->ecu_state = osmo_ecu_init(trx, lchan2ecu_codec(lchan));
|
||||||
|
|
||||||
|
/* activate dedicated channel */
|
||||||
|
trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true);
|
||||||
|
/* activate associated channel */
|
||||||
|
trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true);
|
||||||
|
/* set mode */
|
||||||
|
trx_sched_set_mode(lchan->ts, chan_nr,
|
||||||
|
lchan->rsl_cmode, lchan->tch_mode,
|
||||||
|
lchan->tch.amr_mr.num_modes,
|
||||||
|
lchan->tch.amr_mr.mode[0].mode,
|
||||||
|
lchan->tch.amr_mr.mode[1].mode,
|
||||||
|
lchan->tch.amr_mr.mode[2].mode,
|
||||||
|
lchan->tch.amr_mr.mode[3].mode,
|
||||||
|
amr_get_initial_mode(lchan),
|
||||||
|
(lchan->ho.active == 1));
|
||||||
|
/* set lchan active */
|
||||||
|
lchan_set_state(lchan, LCHAN_S_ACTIVE);
|
||||||
|
/* set initial ciphering */
|
||||||
|
l1if_set_ciphering(lchan, chan_nr, 0);
|
||||||
|
l1if_set_ciphering(lchan, chan_nr, 1);
|
||||||
|
if (lchan->encr.alg_id)
|
||||||
|
lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;
|
||||||
|
else
|
||||||
|
lchan->ciph_state = LCHAN_CIPH_NONE;
|
||||||
|
|
||||||
|
/* confirm */
|
||||||
|
mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_ACTIVATE, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (l1sap->u.info.type == PRIM_INFO_MODIFY) {
|
||||||
/* attempt to allocate an Error Concealment Unit instance, if available */
|
/* ECU for possibly new codec */
|
||||||
lchan->ecu_state = osmo_ecu_init(trx, lchan2ecu_codec(lchan));
|
if (lchan->ecu_state)
|
||||||
|
osmo_ecu_destroy(lchan->ecu_state);
|
||||||
/* activate dedicated channel */
|
lchan->ecu_state = osmo_ecu_init(trx, lchan2ecu_codec(lchan));
|
||||||
trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true);
|
/* change mode */
|
||||||
/* activate associated channel */
|
trx_sched_set_mode(lchan->ts, chan_nr,
|
||||||
trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true);
|
lchan->rsl_cmode, lchan->tch_mode,
|
||||||
/* set mode */
|
lchan->tch.amr_mr.num_modes,
|
||||||
trx_sched_set_mode(lchan->ts, chan_nr,
|
lchan->tch.amr_mr.mode[0].mode,
|
||||||
lchan->rsl_cmode, lchan->tch_mode,
|
lchan->tch.amr_mr.mode[1].mode,
|
||||||
lchan->tch.amr_mr.num_modes,
|
lchan->tch.amr_mr.mode[2].mode,
|
||||||
lchan->tch.amr_mr.mode[0].mode,
|
lchan->tch.amr_mr.mode[3].mode,
|
||||||
lchan->tch.amr_mr.mode[1].mode,
|
amr_get_initial_mode(lchan),
|
||||||
lchan->tch.amr_mr.mode[2].mode,
|
0);
|
||||||
lchan->tch.amr_mr.mode[3].mode,
|
/* update ciphering params */
|
||||||
amr_get_initial_mode(lchan),
|
l1if_set_ciphering(lchan, chan_nr, 0);
|
||||||
(lchan->ho.active == 1));
|
l1if_set_ciphering(lchan, chan_nr, 1);
|
||||||
/* set lchan active */
|
if (lchan->encr.alg_id)
|
||||||
lchan_set_state(lchan, LCHAN_S_ACTIVE);
|
lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;
|
||||||
/* set initial ciphering */
|
else
|
||||||
l1if_set_ciphering(lchan, chan_nr, 0);
|
lchan->ciph_state = LCHAN_CIPH_NONE;
|
||||||
l1if_set_ciphering(lchan, chan_nr, 1);
|
break;
|
||||||
if (lchan->encr.alg_id)
|
}
|
||||||
lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;
|
/* here, type == PRIM_INFO_DEACTIVATE */
|
||||||
else
|
|
||||||
lchan->ciph_state = LCHAN_CIPH_NONE;
|
|
||||||
|
|
||||||
/* confirm */
|
|
||||||
mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_ACTIVATE, 0);
|
|
||||||
break;
|
|
||||||
case PRIM_INFO_MODIFY:
|
|
||||||
/* ECU for possibly new codec */
|
|
||||||
if (lchan->ecu_state)
|
|
||||||
osmo_ecu_destroy(lchan->ecu_state);
|
|
||||||
lchan->ecu_state = osmo_ecu_init(trx, lchan2ecu_codec(lchan));
|
|
||||||
/* change mode */
|
|
||||||
trx_sched_set_mode(lchan->ts, chan_nr,
|
|
||||||
lchan->rsl_cmode, lchan->tch_mode,
|
|
||||||
lchan->tch.amr_mr.num_modes,
|
|
||||||
lchan->tch.amr_mr.mode[0].mode,
|
|
||||||
lchan->tch.amr_mr.mode[1].mode,
|
|
||||||
lchan->tch.amr_mr.mode[2].mode,
|
|
||||||
lchan->tch.amr_mr.mode[3].mode,
|
|
||||||
amr_get_initial_mode(lchan),
|
|
||||||
0);
|
|
||||||
/* update ciphering params */
|
|
||||||
l1if_set_ciphering(lchan, chan_nr, 0);
|
|
||||||
l1if_set_ciphering(lchan, chan_nr, 1);
|
|
||||||
if (lchan->encr.alg_id)
|
|
||||||
lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;
|
|
||||||
else
|
|
||||||
lchan->ciph_state = LCHAN_CIPH_NONE;
|
|
||||||
break;
|
|
||||||
case PRIM_INFO_DEACTIVATE:
|
|
||||||
if ((chan_nr & 0xE0) == 0x80) {
|
if ((chan_nr & 0xE0) == 0x80) {
|
||||||
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot deactivate"
|
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot deactivate"
|
||||||
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
||||||
rc = -EPERM;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* clear ECU state (if any) */
|
/* clear ECU state (if any) */
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ struct msgb *tch_dl_dequeue(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br
|
|||||||
if (chan_state->codec[i] == ft_codec)
|
if (chan_state->codec[i] == ft_codec)
|
||||||
ft = i;
|
ft = i;
|
||||||
}
|
}
|
||||||
if (ft_codec != 8 && ft < 0) {
|
if (ft < 0) {
|
||||||
LOGL1SB(DL1P, LOGL_ERROR, l1ts, br,
|
LOGL1SB(DL1P, LOGL_ERROR, l1ts, br,
|
||||||
"Codec (FT = %d) of RTP frame not in list\n", ft_codec);
|
"Codec (FT = %d) of RTP frame not in list\n", ft_codec);
|
||||||
goto free_bad_msg;
|
goto free_bad_msg;
|
||||||
|
|||||||
@@ -124,11 +124,6 @@ static void bts_report_interf_meas(const struct gsm_bts *bts)
|
|||||||
unsigned int tn, ln;
|
unsigned int tn, ln;
|
||||||
|
|
||||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
/* Skip pushing interf_meas for disabled TRX */
|
|
||||||
if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED ||
|
|
||||||
trx->bb_transc.mo.nm_state.operational != NM_OPSTATE_ENABLED)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {
|
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {
|
||||||
const struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
const struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
||||||
for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++)
|
for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++)
|
||||||
|
|||||||
@@ -1232,8 +1232,7 @@ void trx_if_flush(struct trx_l1h *l1h)
|
|||||||
/*! close the TRX for given handle (data + control socket) */
|
/*! close the TRX for given handle (data + control socket) */
|
||||||
void trx_if_close(struct trx_l1h *l1h)
|
void trx_if_close(struct trx_l1h *l1h)
|
||||||
{
|
{
|
||||||
LOGPPHI(l1h->phy_inst, DTRX, LOGL_NOTICE, "Closing TRXC/TRXD connections to %s\n",
|
LOGPPHI(l1h->phy_inst, DTRX, LOGL_NOTICE, "Closing TRXC/TRXD connections\n");
|
||||||
l1h->phy_inst->phy_link->u.osmotrx.remote_ip);
|
|
||||||
|
|
||||||
trx_if_flush(l1h);
|
trx_if_flush(l1h);
|
||||||
|
|
||||||
@@ -1243,7 +1242,7 @@ void trx_if_close(struct trx_l1h *l1h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*! compute UDP port number used for TRX protocol */
|
/*! compute UDP port number used for TRX protocol */
|
||||||
static uint16_t compute_port(struct phy_instance *pinst, bool remote, bool is_data)
|
static uint16_t compute_port(struct phy_instance *pinst, int remote, int is_data)
|
||||||
{
|
{
|
||||||
struct phy_link *plink = pinst->phy_link;
|
struct phy_link *plink = pinst->phy_link;
|
||||||
uint16_t inc = 1;
|
uint16_t inc = 1;
|
||||||
@@ -1264,21 +1263,21 @@ static int trx_if_open(struct trx_l1h *l1h)
|
|||||||
struct phy_link *plink = pinst->phy_link;
|
struct phy_link *plink = pinst->phy_link;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
LOGPPHI(pinst, DTRX, LOGL_NOTICE, "Opening TRXC/TRXD connections to %s\n", plink->u.osmotrx.remote_ip);
|
LOGPPHI(pinst, DTRX, LOGL_NOTICE, "Opening TRXC/TRXD connections\n");
|
||||||
|
|
||||||
/* open sockets */
|
/* open sockets */
|
||||||
rc = trx_udp_open(l1h, &l1h->trx_ofd_ctrl,
|
rc = trx_udp_open(l1h, &l1h->trx_ofd_ctrl,
|
||||||
plink->u.osmotrx.local_ip,
|
plink->u.osmotrx.local_ip,
|
||||||
compute_port(pinst, false, false),
|
compute_port(pinst, 0, 0),
|
||||||
plink->u.osmotrx.remote_ip,
|
plink->u.osmotrx.remote_ip,
|
||||||
compute_port(pinst, true, false), trx_ctrl_read_cb);
|
compute_port(pinst, 1, 0), trx_ctrl_read_cb);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
rc = trx_udp_open(l1h, &l1h->trx_ofd_data,
|
rc = trx_udp_open(l1h, &l1h->trx_ofd_data,
|
||||||
plink->u.osmotrx.local_ip,
|
plink->u.osmotrx.local_ip,
|
||||||
compute_port(pinst, false, true),
|
compute_port(pinst, 0, 1),
|
||||||
plink->u.osmotrx.remote_ip,
|
plink->u.osmotrx.remote_ip,
|
||||||
compute_port(pinst, true, true), trx_data_read_cb);
|
compute_port(pinst, 1, 1), trx_data_read_cb);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|||||||
@@ -253,11 +253,11 @@ static void update_ts_data(struct trx_l1h *l1h, struct trx_prov_ev_cfg_ts_data *
|
|||||||
l1h->config.setslot_sent[data->tn] = false;
|
l1h->config.setslot_sent[data->tn] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Whether a given TRX is fully configured */
|
/* Whether a given TRX is fully configured and can be powered on */
|
||||||
static bool trx_is_provisioned(struct trx_l1h *l1h)
|
static bool trx_is_provisioned(struct trx_l1h *l1h)
|
||||||
{
|
{
|
||||||
struct phy_instance *pinst = l1h->phy_inst;
|
struct phy_instance *pinst = l1h->phy_inst;
|
||||||
if (l1h->config.rxtune_acked && l1h->config.txtune_acked &&
|
if (l1h->config.enabled && l1h->config.rxtune_acked && l1h->config.txtune_acked &&
|
||||||
(l1h->config.bsic_acked || !pinst->phy_link->u.osmotrx.use_legacy_setbsic) &&
|
(l1h->config.bsic_acked || !pinst->phy_link->u.osmotrx.use_legacy_setbsic) &&
|
||||||
(l1h->config.tsc_acked || pinst->phy_link->u.osmotrx.use_legacy_setbsic) &&
|
(l1h->config.tsc_acked || pinst->phy_link->u.osmotrx.use_legacy_setbsic) &&
|
||||||
(l1h->config.nomtxpower_acked || l1h->config.nominal_power_set_by_vty) &&
|
(l1h->config.nomtxpower_acked || l1h->config.nominal_power_set_by_vty) &&
|
||||||
@@ -267,11 +267,6 @@ static bool trx_is_provisioned(struct trx_l1h *l1h)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Whether a given TRX is fully configured and can be powered on */
|
|
||||||
static bool trx_is_provisioned_and_enabled(struct trx_l1h *l1h)
|
|
||||||
{
|
|
||||||
return l1h->config.enabled && trx_is_provisioned(l1h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void trx_signal_ready_trx0(struct trx_l1h *l1h)
|
static void trx_signal_ready_trx0(struct trx_l1h *l1h)
|
||||||
{
|
{
|
||||||
@@ -287,7 +282,7 @@ static void trx_signal_ready_trx0(struct trx_l1h *l1h)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from TRX0 to check if other TRX are already configured so POWERON can be sent */
|
/* Called from TRX0 to check if other TRX are already configured and powered so POWERON can be sent */
|
||||||
static bool trx_other_trx0_ready(struct trx_l1h *l1h)
|
static bool trx_other_trx0_ready(struct trx_l1h *l1h)
|
||||||
{
|
{
|
||||||
struct phy_instance *pinst = l1h->phy_inst;
|
struct phy_instance *pinst = l1h->phy_inst;
|
||||||
@@ -298,7 +293,7 @@ static bool trx_other_trx0_ready(struct trx_l1h *l1h)
|
|||||||
struct trx_l1h *l1h_it = pinst_it->u.osmotrx.hdl;
|
struct trx_l1h *l1h_it = pinst_it->u.osmotrx.hdl;
|
||||||
if (l1h_it->phy_inst->num == 0)
|
if (l1h_it->phy_inst->num == 0)
|
||||||
continue;
|
continue;
|
||||||
if (!trx_is_provisioned(l1h_it))
|
if (l1h_it->provision_fi->state != TRX_PROV_ST_OPEN_POWERON)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -394,8 +389,7 @@ static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *dat
|
|||||||
uint16_t arfcn;
|
uint16_t arfcn;
|
||||||
int nominal_power;
|
int nominal_power;
|
||||||
int status;
|
int status;
|
||||||
bool waiting_other_trx;
|
bool others_ready;
|
||||||
bool was_ready = trx_is_provisioned(l1h);
|
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case TRX_PROV_EV_CLOSE:
|
case TRX_PROV_EV_CLOSE:
|
||||||
@@ -491,22 +485,22 @@ static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *dat
|
|||||||
|
|
||||||
l1if_provision_transceiver_trx(l1h);
|
l1if_provision_transceiver_trx(l1h);
|
||||||
|
|
||||||
if (l1h->phy_inst->num == 0) {
|
if (l1h->phy_inst->num == 0)
|
||||||
waiting_other_trx = !trx_other_trx0_ready(l1h);
|
others_ready = trx_other_trx0_ready(l1h);
|
||||||
} else {
|
else
|
||||||
waiting_other_trx = false; /* we don't care about others in TRX!=0 */
|
others_ready = true; /* we don't care about others in TRX!=0 */
|
||||||
/* If we just became ready for TRX0 POWERON (aka this TRX becomes provisioned), signal it to TRX0: */
|
|
||||||
if (l1h->phy_inst->num != 0 && (!was_ready && trx_is_provisioned(l1h)))
|
|
||||||
trx_signal_ready_trx0(l1h);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we gathered all data and could go forward. For TRX0, only after
|
/* if we gathered all data and could go forward. For TRX0, only after
|
||||||
* all other TRX are prepared, since it will send POWERON commad */
|
* all other TRX are prepared, since it will send POWERON commad */
|
||||||
if (trx_is_provisioned_and_enabled(l1h) && !waiting_other_trx) {
|
if (trx_is_provisioned(l1h) &&
|
||||||
if (l1h->phy_inst->num != 0)
|
(l1h->phy_inst->num != 0 || others_ready)) {
|
||||||
|
if (l1h->phy_inst->num != 0) {
|
||||||
trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_POWERON);
|
trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_POWERON);
|
||||||
else
|
/* Once we are powered on, signal TRX0 in case it was waiting for us */
|
||||||
|
trx_signal_ready_trx0(l1h);
|
||||||
|
} else {
|
||||||
trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_WAIT_POWERON_CNF);
|
trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_WAIT_POWERON_CNF);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGPFSML(fi, LOGL_INFO, "Delay poweron, wait for:%s%s%s%s%s%s%s%s\n",
|
LOGPFSML(fi, LOGL_INFO, "Delay poweron, wait for:%s%s%s%s%s%s%s%s\n",
|
||||||
l1h->config.enabled ? "" :" enable",
|
l1h->config.enabled ? "" :" enable",
|
||||||
@@ -518,7 +512,7 @@ static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *dat
|
|||||||
l1h->config.txtune_acked ? "" : " txtune-ack",
|
l1h->config.txtune_acked ? "" : " txtune-ack",
|
||||||
l1h->config.nominal_power_set_by_vty ? "" : (l1h->config.nomtxpower_acked ? "" : " nomtxpower-ack"),
|
l1h->config.nominal_power_set_by_vty ? "" : (l1h->config.nomtxpower_acked ? "" : " nomtxpower-ack"),
|
||||||
l1h->config.setformat_acked ? "" : " setformat-ack",
|
l1h->config.setformat_acked ? "" : " setformat-ack",
|
||||||
waiting_other_trx ? "" : " other-trx"
|
(l1h->phy_inst->num != 0 || others_ready) ? "" : " other-trx"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,29 +100,7 @@ static uint8_t vbts_set_trx(struct gsm_bts_trx *trx)
|
|||||||
|
|
||||||
static uint8_t vbts_set_ts(struct gsm_bts_trx_ts *ts)
|
static uint8_t vbts_set_ts(struct gsm_bts_trx_ts *ts)
|
||||||
{
|
{
|
||||||
enum gsm_phys_chan_config pchan;
|
if (trx_sched_set_pchan(ts, ts->pchan) != 0)
|
||||||
|
|
||||||
/* For dynamic timeslots, pick the pchan type that should currently be
|
|
||||||
* active. This should only be called during init, PDCH transitions
|
|
||||||
* will call trx_set_ts_as_pchan() directly. */
|
|
||||||
switch (ts->pchan) {
|
|
||||||
case GSM_PCHAN_TCH_F_PDCH:
|
|
||||||
OSMO_ASSERT((ts->flags & TS_F_PDCH_PENDING_MASK) == 0);
|
|
||||||
if (ts->flags & TS_F_PDCH_ACTIVE)
|
|
||||||
pchan = GSM_PCHAN_PDCH;
|
|
||||||
else
|
|
||||||
pchan = GSM_PCHAN_TCH_F;
|
|
||||||
break;
|
|
||||||
case GSM_PCHAN_OSMO_DYN:
|
|
||||||
OSMO_ASSERT(ts->dyn.pchan_is == ts->dyn.pchan_want);
|
|
||||||
pchan = ts->dyn.pchan_is;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pchan = ts->pchan;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trx_sched_set_pchan(ts, pchan) != 0)
|
|
||||||
return NM_NACK_RES_NOTAVAIL;
|
return NM_NACK_RES_NOTAVAIL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -187,19 +187,6 @@ nomessage:
|
|||||||
/* called by common part once OML link is established */
|
/* called by common part once OML link is established */
|
||||||
int bts_model_oml_estab(struct gsm_bts *bts)
|
int bts_model_oml_estab(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
struct phy_instance *pinst = trx_phy_instance(bts->c0);
|
|
||||||
|
|
||||||
if (vbts_sched_start(pinst->trx->bts) < 0)
|
|
||||||
return -ENOLINK;
|
|
||||||
|
|
||||||
/* Only start the scheduler for the transceiver on C0.
|
|
||||||
* If we have multiple transceivers, CCCH is always on C0
|
|
||||||
* and has to be auto active */
|
|
||||||
pinst->trx->ts[0].lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML;
|
|
||||||
|
|
||||||
/* Other TRX are activated via OML by a PRIM_INFO_MODIFY / PRIM_INFO_ACTIVATE */
|
|
||||||
lchan_set_state(&pinst->trx->ts[0].lchan[CCCH_LCHAN], LCHAN_S_ACTIVE);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +217,17 @@ int bts_model_phy_link_open(struct phy_link *plink)
|
|||||||
if (pinst->trx == NULL)
|
if (pinst->trx == NULL)
|
||||||
continue;
|
continue;
|
||||||
trx_sched_init(pinst->trx);
|
trx_sched_init(pinst->trx);
|
||||||
|
/* Only start the scheduler for the transceiver on C0.
|
||||||
|
* If we have multiple transceivers, CCCH is always on C0
|
||||||
|
* and has to be auto active */
|
||||||
|
/* Other TRX are activated via OML by a PRIM_INFO_MODIFY
|
||||||
|
* / PRIM_INFO_ACTIVATE */
|
||||||
|
if (pinst->trx == pinst->trx->bts->c0) {
|
||||||
|
vbts_sched_start(pinst->trx->bts);
|
||||||
|
/* FIXME: This is probably the wrong location to set the CCCH to active... the OML link def. needs to be reworked and fixed. */
|
||||||
|
pinst->trx->ts[0].lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML;
|
||||||
|
lchan_set_state(&pinst->trx->ts[0].lchan[CCCH_LCHAN], LCHAN_S_ACTIVE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this will automatically update the MO state of all associated TRX objects */
|
/* this will automatically update the MO state of all associated TRX objects */
|
||||||
@@ -336,6 +334,7 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
|
|||||||
{
|
{
|
||||||
struct msgb *msg = l1sap->oph.msg;
|
struct msgb *msg = l1sap->oph.msg;
|
||||||
uint8_t chan_nr;
|
uint8_t chan_nr;
|
||||||
|
uint8_t tn, ss;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct gsm_lchan *lchan;
|
struct gsm_lchan *lchan;
|
||||||
|
|
||||||
@@ -351,77 +350,77 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
|
|||||||
/* put data into scheduler's queue */
|
/* put data into scheduler's queue */
|
||||||
return trx_sched_tch_req(trx, l1sap);
|
return trx_sched_tch_req(trx, l1sap);
|
||||||
case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST):
|
case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST):
|
||||||
if (l1sap->u.info.type == PRIM_INFO_ACT_CIPH)
|
|
||||||
chan_nr = l1sap->u.info.u.ciph_req.chan_nr;
|
|
||||||
else /* u.act_req used by PRIM_INFO_{ACTIVATE,DEACTIVATE,MODIFY} */
|
|
||||||
chan_nr = l1sap->u.info.u.act_req.chan_nr;
|
|
||||||
lchan = get_lchan_by_chan_nr(trx, chan_nr);
|
|
||||||
if (OSMO_UNLIKELY(lchan == NULL)) {
|
|
||||||
LOGP(DL1C, LOGL_ERROR,
|
|
||||||
"Rx MPH-INFO.req (type=0x%02x) for non-existent lchan (%s)\n",
|
|
||||||
l1sap->u.info.type, rsl_chan_nr_str(chan_nr));
|
|
||||||
rc = -ENODEV;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (l1sap->u.info.type) {
|
switch (l1sap->u.info.type) {
|
||||||
case PRIM_INFO_ACT_CIPH:
|
case PRIM_INFO_ACT_CIPH:
|
||||||
|
chan_nr = l1sap->u.info.u.ciph_req.chan_nr;
|
||||||
|
tn = L1SAP_CHAN2TS(chan_nr);
|
||||||
|
ss = l1sap_chan2ss(chan_nr);
|
||||||
|
lchan = &trx->ts[tn].lchan[ss];
|
||||||
if (l1sap->u.info.u.ciph_req.uplink)
|
if (l1sap->u.info.u.ciph_req.uplink)
|
||||||
l1if_set_ciphering(lchan, chan_nr, 0);
|
l1if_set_ciphering(lchan, chan_nr, 0);
|
||||||
if (l1sap->u.info.u.ciph_req.downlink)
|
if (l1sap->u.info.u.ciph_req.downlink)
|
||||||
l1if_set_ciphering(lchan, chan_nr, 1);
|
l1if_set_ciphering(lchan, chan_nr, 1);
|
||||||
break;
|
break;
|
||||||
case PRIM_INFO_ACTIVATE:
|
case PRIM_INFO_ACTIVATE:
|
||||||
if ((chan_nr & 0xE0) == 0x80) {
|
case PRIM_INFO_DEACTIVATE:
|
||||||
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate"
|
case PRIM_INFO_MODIFY:
|
||||||
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
chan_nr = l1sap->u.info.u.act_req.chan_nr;
|
||||||
rc = -EPERM;
|
tn = L1SAP_CHAN2TS(chan_nr);
|
||||||
|
ss = l1sap_chan2ss(chan_nr);
|
||||||
|
lchan = &trx->ts[tn].lchan[ss];
|
||||||
|
/* we receive a channel activation request from the BSC,
|
||||||
|
* e.g. as a response to a channel req on RACH */
|
||||||
|
if (l1sap->u.info.type == PRIM_INFO_ACTIVATE) {
|
||||||
|
if ((chan_nr & 0xE0) == 0x80) {
|
||||||
|
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate"
|
||||||
|
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* activate dedicated channel */
|
||||||
|
trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true);
|
||||||
|
/* activate associated channel */
|
||||||
|
trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true);
|
||||||
|
/* set mode */
|
||||||
|
trx_sched_set_mode(lchan->ts, chan_nr,
|
||||||
|
lchan->rsl_cmode, lchan->tch_mode,
|
||||||
|
lchan->tch.amr_mr.num_modes,
|
||||||
|
lchan->tch.amr_mr.mode[0].mode,
|
||||||
|
lchan->tch.amr_mr.mode[1].mode,
|
||||||
|
lchan->tch.amr_mr.mode[2].mode,
|
||||||
|
lchan->tch.amr_mr.mode[3].mode,
|
||||||
|
amr_get_initial_mode(lchan),
|
||||||
|
(lchan->ho.active == 1));
|
||||||
|
/* set lchan active */
|
||||||
|
lchan_set_state(lchan, LCHAN_S_ACTIVE);
|
||||||
|
/* set initial ciphering */
|
||||||
|
l1if_set_ciphering(lchan, chan_nr, 0);
|
||||||
|
l1if_set_ciphering(lchan, chan_nr, 1);
|
||||||
|
if (lchan->encr.alg_id)
|
||||||
|
lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;
|
||||||
|
else
|
||||||
|
lchan->ciph_state = LCHAN_CIPH_NONE;
|
||||||
|
|
||||||
|
/* confirm */
|
||||||
|
mph_info_chan_confirm(trx, chan_nr,
|
||||||
|
PRIM_INFO_ACTIVATE, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (l1sap->u.info.type == PRIM_INFO_MODIFY) {
|
||||||
|
/* change mode */
|
||||||
|
trx_sched_set_mode(lchan->ts, chan_nr,
|
||||||
|
lchan->rsl_cmode, lchan->tch_mode,
|
||||||
|
lchan->tch.amr_mr.num_modes,
|
||||||
|
lchan->tch.amr_mr.mode[0].mode,
|
||||||
|
lchan->tch.amr_mr.mode[1].mode,
|
||||||
|
lchan->tch.amr_mr.mode[2].mode,
|
||||||
|
lchan->tch.amr_mr.mode[3].mode,
|
||||||
|
amr_get_initial_mode(lchan),
|
||||||
|
0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* activate dedicated channel */
|
|
||||||
trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true);
|
|
||||||
/* activate associated channel */
|
|
||||||
trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true);
|
|
||||||
/* set mode */
|
|
||||||
trx_sched_set_mode(lchan->ts, chan_nr,
|
|
||||||
lchan->rsl_cmode, lchan->tch_mode,
|
|
||||||
lchan->tch.amr_mr.num_modes,
|
|
||||||
lchan->tch.amr_mr.mode[0].mode,
|
|
||||||
lchan->tch.amr_mr.mode[1].mode,
|
|
||||||
lchan->tch.amr_mr.mode[2].mode,
|
|
||||||
lchan->tch.amr_mr.mode[3].mode,
|
|
||||||
amr_get_initial_mode(lchan),
|
|
||||||
(lchan->ho.active == 1));
|
|
||||||
/* set lchan active */
|
|
||||||
lchan_set_state(lchan, LCHAN_S_ACTIVE);
|
|
||||||
/* set initial ciphering */
|
|
||||||
l1if_set_ciphering(lchan, chan_nr, 0);
|
|
||||||
l1if_set_ciphering(lchan, chan_nr, 1);
|
|
||||||
if (lchan->encr.alg_id)
|
|
||||||
lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;
|
|
||||||
else
|
|
||||||
lchan->ciph_state = LCHAN_CIPH_NONE;
|
|
||||||
|
|
||||||
/* confirm */
|
|
||||||
mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_ACTIVATE, 0);
|
|
||||||
break;
|
|
||||||
case PRIM_INFO_MODIFY:
|
|
||||||
/* change mode */
|
|
||||||
trx_sched_set_mode(lchan->ts, chan_nr,
|
|
||||||
lchan->rsl_cmode, lchan->tch_mode,
|
|
||||||
lchan->tch.amr_mr.num_modes,
|
|
||||||
lchan->tch.amr_mr.mode[0].mode,
|
|
||||||
lchan->tch.amr_mr.mode[1].mode,
|
|
||||||
lchan->tch.amr_mr.mode[2].mode,
|
|
||||||
lchan->tch.amr_mr.mode[3].mode,
|
|
||||||
amr_get_initial_mode(lchan),
|
|
||||||
0);
|
|
||||||
break;
|
|
||||||
case PRIM_INFO_DEACTIVATE:
|
|
||||||
if ((chan_nr & 0xE0) == 0x80) {
|
if ((chan_nr & 0xE0) == 0x80) {
|
||||||
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot deactivate"
|
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot deactivate"
|
||||||
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
||||||
rc = -EPERM;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* deactivate associated channel */
|
/* deactivate associated channel */
|
||||||
|
|||||||
@@ -64,8 +64,6 @@ int bts_model_init(struct gsm_bts *bts)
|
|||||||
|
|
||||||
/* order alphabetically */
|
/* order alphabetically */
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH);
|
osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH);
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_EGPRS);
|
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS);
|
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS);
|
osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS);
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_AMR);
|
osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_AMR);
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR);
|
osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR);
|
||||||
|
|||||||
@@ -541,9 +541,6 @@ int vbts_sched_start(struct gsm_bts *bts)
|
|||||||
struct bts_virt_priv *bts_virt = (struct bts_virt_priv *)bts->model_priv;
|
struct bts_virt_priv *bts_virt = (struct bts_virt_priv *)bts->model_priv;
|
||||||
LOGP(DL1P, LOGL_NOTICE, "starting VBTS scheduler\n");
|
LOGP(DL1P, LOGL_NOTICE, "starting VBTS scheduler\n");
|
||||||
|
|
||||||
if (!bts_virt)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
memset(&bts_virt->fn_timer, 0, sizeof(bts_virt->fn_timer));
|
memset(&bts_virt->fn_timer, 0, sizeof(bts_virt->fn_timer));
|
||||||
bts_virt->fn_timer.cb = vbts_fn_timer_cb;
|
bts_virt->fn_timer.cb = vbts_fn_timer_cb;
|
||||||
bts_virt->fn_timer.data = bts;
|
bts_virt->fn_timer.data = bts;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
|
|||||||
@@ -251,8 +251,6 @@ OsmoBTS(bts)# list
|
|||||||
smscb queue-hysteresis <0-30>
|
smscb queue-hysteresis <0-30>
|
||||||
gsmtap-remote-host [HOSTNAME]
|
gsmtap-remote-host [HOSTNAME]
|
||||||
no gsmtap-remote-host
|
no gsmtap-remote-host
|
||||||
gsmtap-local-host HOSTNAME
|
|
||||||
no gsmtap-local-host
|
|
||||||
gsmtap-sapi (enable-all|disable-all)
|
gsmtap-sapi (enable-all|disable-all)
|
||||||
gsmtap-sapi (bcch|ccch|rach|agch|pch|sdcch|tch/f|tch/h|pacch|pdtch|ptcch|cbch|sacch)
|
gsmtap-sapi (bcch|ccch|rach|agch|pch|sdcch|tch/f|tch/h|pacch|pdtch|ptcch|cbch|sacch)
|
||||||
no gsmtap-sapi (bcch|ccch|rach|agch|pch|sdcch|tch/f|tch/h|pacch|pdtch|ptcch|cbch|sacch)
|
no gsmtap-sapi (bcch|ccch|rach|agch|pch|sdcch|tch/f|tch/h|pacch|pdtch|ptcch|cbch|sacch)
|
||||||
@@ -276,7 +274,6 @@ OsmoBTS(bts)# ?
|
|||||||
supp-meas-info Configure the RSL Supplementary Measurement Info
|
supp-meas-info Configure the RSL Supplementary Measurement Info
|
||||||
smscb SMSCB (SMS Cell Broadcast) / CBCH configuration
|
smscb SMSCB (SMS Cell Broadcast) / CBCH configuration
|
||||||
gsmtap-remote-host Enable GSMTAP Um logging (see also 'gsmtap-sapi')
|
gsmtap-remote-host Enable GSMTAP Um logging (see also 'gsmtap-sapi')
|
||||||
gsmtap-local-host Enable local bind for GSMTAP Um logging (see also 'gsmtap-sapi')
|
|
||||||
gsmtap-sapi Enable/disable sending of UL/DL messages over GSMTAP
|
gsmtap-sapi Enable/disable sending of UL/DL messages over GSMTAP
|
||||||
osmux Configure Osmux
|
osmux Configure Osmux
|
||||||
trx Select a TRX to configure
|
trx Select a TRX to configure
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ LDADD = \
|
|||||||
$(LIBOSMOTRAU_LIBS) \
|
$(LIBOSMOTRAU_LIBS) \
|
||||||
$(LIBOSMONETIF_LIBS) \
|
$(LIBOSMONETIF_LIBS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
|
|
||||||
check_PROGRAMS = paging_test
|
check_PROGRAMS = paging_test
|
||||||
EXTRA_DIST = paging_test.ok
|
EXTRA_DIST = paging_test.ok
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOCODEC_LIBS) \
|
$(LIBOSMOCODEC_LIBS) \
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOCODEC_LIBS) \
|
$(LIBOSMOCODEC_LIBS) \
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMONETIF_CFLAGS) \
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
AM_LDFLAGS = -no-install
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
|
|||||||
Reference in New Issue
Block a user