mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-bts.git
synced 2025-11-17 04:11:42 +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/*.svg
|
||||
doc/manuals/*.pdf
|
||||
doc/manuals/vty/*.pdf
|
||||
doc/manuals/*__*.png
|
||||
doc/manuals/*.check
|
||||
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 removed or changed since the last public release: c:r:0.
|
||||
#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
|
||||
|
||||
dnl checks for libraries
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.4.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.4.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 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_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 libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
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
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -27,15 +27,17 @@ BuildRequires: pkgconfig >= 0.20
|
||||
%if 0%{?suse_version}
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%endif
|
||||
BuildRequires: pkgconfig(libosmocodec) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmocoding) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmoabis) >= 1.4.0
|
||||
BuildRequires: pkgconfig(libosmotrau) >= 1.4.0
|
||||
BuildRequires: pkgconfig(libosmo-netif) >= 1.3.0
|
||||
BuildRequires: pkgconfig(libosmocodec) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmocoding) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmoabis) >= 1.3.0
|
||||
BuildRequires: pkgconfig(libosmotrau) >= 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}
|
||||
|
||||
%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
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
|
||||
8
debian/control
vendored
8
debian/control
vendored
@@ -7,12 +7,12 @@ Build-Depends: debhelper (>= 9),
|
||||
dh-autoreconf,
|
||||
autotools-dev,
|
||||
pkg-config,
|
||||
libosmocore-dev (>= 1.8.0),
|
||||
libosmo-abis-dev (>= 1.4.0),
|
||||
libosmo-netif-dev (>= 1.3.0),
|
||||
libosmocore-dev (>= 1.7.0),
|
||||
libosmo-abis-dev (>= 1.3.0),
|
||||
libosmo-netif-dev (>= 1.2.0),
|
||||
libgps-dev,
|
||||
txt2man,
|
||||
osmo-gsm-manuals-dev (>= 1.4.0)
|
||||
osmo-gsm-manuals-dev (>= 1.3.0)
|
||||
Standards-Version: 3.9.8
|
||||
Vcs-Browser: 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
|
||||
| 0x0d | RSL_SYSTEM_INFO_5bis
|
||||
| 0x0e | RSL_SYSTEM_INFO_5ter
|
||||
| 0x0f | RSL_SYSTEM_INFO_10
|
||||
| 0x47 | RSL_EXT_MEAS_ORDER
|
||||
| 0x48 | RSL_MEAS_INFO
|
||||
|===
|
||||
@@ -517,7 +516,6 @@ number*.
|
||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
||||
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
|
||||
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
||||
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
|
||||
|===
|
||||
|
||||
[[rsl_crcx_msg_ack]]
|
||||
@@ -578,7 +576,6 @@ properties of a user-plane RTP connection.
|
||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
||||
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
|
||||
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
||||
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
|
||||
|===
|
||||
|
||||
[[rsl_mdcx_msg_ack]]
|
||||
@@ -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>>
|
||||
| 0xf6 | RSL_IE_IPAC_CONN_STAT | <<RSL_IE_IPAC_CONN_STAT>>
|
||||
| 0xf8 | RSL_IE_IPAC_CONN_ID | <<RSL_IE_IPAC_CONN_ID>>
|
||||
| 0xf9 | RSL_IE_IPAC_RTP_CSD_FORMAT | <<RSL_IE_IPAC_RTP_CSD_FORMAT>>
|
||||
| 0xfc | RSL_IE_IPAC_RTP_PAYLOAD2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>>
|
||||
|===
|
||||
|
||||
@@ -1089,39 +1085,6 @@ for future use.
|
||||
| 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
|
||||
|
||||
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
|
||||
| common | bts_controlif_setup() | Initialization of Control Interface
|
||||
| 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 | main() | Installation of signal handlers
|
||||
| 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
|
||||
| common | bts_controlif_setup() | Initialization of Control Interface
|
||||
| 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 | main() | Installation of signal handlers
|
||||
| common | abis_open() | Start of the A-bis connection to BSC
|
||||
|
||||
@@ -366,7 +366,6 @@ struct gsm_bts {
|
||||
struct {
|
||||
struct gsmtap_inst *inst;
|
||||
char *remote_host;
|
||||
char *local_host;
|
||||
uint32_t sapi_mask;
|
||||
uint8_t sapi_acch;
|
||||
} gsmtap;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
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,
|
||||
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
|
||||
#define CCCH_LCHAN 4
|
||||
#define CBCH_LCHAN 2
|
||||
|
||||
#define TRX_NR_TS 8
|
||||
#define TS_MAX_LCHAN 8
|
||||
|
||||
@@ -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);
|
||||
|
||||
/* Add an IMM.ASS message to the paging queue */
|
||||
int paging_add_imm_ass(struct paging_state *ps,
|
||||
const uint8_t *data, uint8_t len);
|
||||
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
|
||||
uint8_t len, bool from_pcu);
|
||||
|
||||
/* generate paging message for given gsm time */
|
||||
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>
|
||||
|
||||
/* Whether a logical channel must be activated automatically */
|
||||
#define TRX_CHAN_FLAG_AUTO_ACTIVE (1 << 0)
|
||||
|
||||
/* FIXME: we should actually activate 'auto-active' channels */
|
||||
#define TRX_CHAN_IS_ACTIVE(state, chan) \
|
||||
(trx_chan_desc[chan].flags & TRX_CHAN_FLAG_AUTO_ACTIVE || (state)->active)
|
||||
|
||||
#define TRX_GMSK_NB_TSC(br) \
|
||||
_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
|
||||
|
||||
@@ -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 */
|
||||
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) */
|
||||
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,
|
||||
|
||||
@@ -88,12 +88,14 @@ err_index:
|
||||
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;
|
||||
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)
|
||||
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->bb_transc.mo.fi, NM_EV_RSL_UP, NULL);
|
||||
|
||||
if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED ||
|
||||
trx->bb_transc.mo.nm_state.operational == NM_OPSTATE_ENABLED) {
|
||||
rc = rsl_tx_rf_res(trx);
|
||||
if (rc < 0)
|
||||
if ((rc = rsl_tx_rf_res(trx)) < 0)
|
||||
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
|
||||
"Failed to establish RSL link (%d)", rc);
|
||||
}
|
||||
|
||||
if (trx == trx->bts->c0)
|
||||
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;
|
||||
|
||||
/* determine if this is the last block */
|
||||
block_type->lb = (block_nr + 1 == msg->num_segs);
|
||||
if (block_type->lb) {
|
||||
if (block_nr + 1 == msg->num_segs)
|
||||
block_type->lb = 1;
|
||||
else
|
||||
block_type->lb = 0;
|
||||
|
||||
if (block_nr == 4) {
|
||||
if (msg != bts_ss->default_msg) {
|
||||
DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n",
|
||||
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,
|
||||
160 samples per RTP packet,
|
||||
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);
|
||||
|
||||
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
|
||||
GSM_RTP_DURATION = 160 */
|
||||
GSM_RTP_DURATION */
|
||||
r = samples_passed + GSM_RTP_DURATION / 2;
|
||||
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:"
|
||||
" %"PRIu32" vs %d (%"PRIu32"->%"PRIu32") DIFF[%d] SAMPLES[%d]\n ",
|
||||
r, GSM_RTP_DURATION, lchan->tch.last_fn, fn, num_fn, samples_passed);
|
||||
//return r;
|
||||
}
|
||||
" %"PRIu32" vs %d (%"PRIu32"->%"PRIu32")\n",
|
||||
r, GSM_RTP_DURATION, lchan->tch.last_fn, fn);
|
||||
}
|
||||
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;
|
||||
|
||||
if (rmsg->len > 0)
|
||||
LOGPLCHAN(lchan, DL1P, LOGL_INFO, "Rx -> RTP: %s\n", osmo_hexdump(rmsg->data, rmsg->len));
|
||||
LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "Rx -> RTP: %s\n", osmo_hexdump(rmsg->data, rmsg->len));
|
||||
|
||||
rmsg->l2h = rmsg->data;
|
||||
rmsg->l1h = msgb_push(rmsg, sizeof(*l1sap));
|
||||
@@ -623,9 +615,6 @@ static void l1sap_interf_meas_report(struct gsm_bts *bts)
|
||||
return;
|
||||
|
||||
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 */
|
||||
l1sap_interf_meas_calc_avg(trx);
|
||||
/* 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 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 */
|
||||
frames_expired = GSM_TDMA_FN_SUB(info_time_ind->fn, bts->gsm_time.fn);
|
||||
@@ -1611,37 +1600,12 @@ 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
|
||||
* available is expected as empty payload. We also check if quality is
|
||||
* good enough. */
|
||||
//if (1 == 1) {
|
||||
if (!msg->len || (tch_ind->lqual_cb / 10 < bts->min_qual_norm)) {
|
||||
LOGPGT(DRTP, LOGL_NOTICE, &g_time, "Skipping RTP frame with lost payload (chan_nr=0x%02x)\n",
|
||||
chan_nr);
|
||||
if (lchan->abis_ip.osmux.use)
|
||||
lchan_osmux_skipped_frame(lchan, fn_ms_adj(fn, lchan));
|
||||
else if (lchan->abis_ip.rtp_socket)
|
||||
osmo_rtp_skipped_frame(lchan->abis_ip.rtp_socket, fn_ms_adj(fn, lchan));
|
||||
|
||||
lchan->rtp_tx_marker = true;
|
||||
lchan->tch.last_fn = fn;
|
||||
//lchan->tch.dtx.is_speech_resume = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msg->len && tch_ind->lqual_cb >= bts->min_qual_norm) {
|
||||
/* hand msg to RTP code for transmission */
|
||||
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);
|
||||
}
|
||||
@@ -1653,12 +1617,18 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap,
|
||||
return 1;
|
||||
}
|
||||
/* Only clear the marker bit once we have sent a RTP packet with it */
|
||||
//lchan->rtp_tx_marker = false;
|
||||
lchan->rtp_tx_marker = false;
|
||||
} else {
|
||||
DEBUGPGT(DRTP, &g_time, "Skipping RTP frame with lost payload (chan_nr=0x%02x)\n",
|
||||
chan_nr);
|
||||
if (lchan->abis_ip.osmux.use)
|
||||
lchan_osmux_skipped_frame(lchan, fn_ms_adj(fn, lchan));
|
||||
else if (lchan->abis_ip.rtp_socket)
|
||||
osmo_rtp_skipped_frame(lchan->abis_ip.rtp_socket, fn_ms_adj(fn, lchan));
|
||||
lchan->rtp_tx_marker = true;
|
||||
}
|
||||
|
||||
lchan->tch.last_fn = fn;
|
||||
if (lchan->tch.dtx.is_speech_resume)
|
||||
lchan->tch.dtx.is_speech_resume = false;
|
||||
|
||||
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,
|
||||
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;
|
||||
break;
|
||||
case GSM_PCHAN_NONE:
|
||||
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s not expected!\n",
|
||||
ts_nr, lchan_nr, gsm_pchan_name(pchan));
|
||||
cbits = 0x00; /* Reserved */
|
||||
LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",
|
||||
gsm_pchan_name(pchan));
|
||||
cbits = 0x00;
|
||||
break;
|
||||
default:
|
||||
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s (0x%02x) not expected!\n",
|
||||
ts_nr, lchan_nr, gsm_pchan_name(pchan), (int)pchan);
|
||||
LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",
|
||||
gsm_pchan_name(pchan), (int)pchan);
|
||||
OSMO_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -354,20 +354,21 @@ int bts_main(int argc, char **argv)
|
||||
/* TODO: move this to gsm_bts_alloc() */
|
||||
if (g_bts->gsmtap.remote_host != NULL) {
|
||||
LOGP(DLGLOBAL, LOGL_NOTICE,
|
||||
"Setting up GSMTAP Um forwarding '%s->'%s:%u'\n",
|
||||
g_bts->gsmtap.local_host, g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
|
||||
g_bts->gsmtap.inst = gsmtap_source_init2(g_bts->gsmtap.local_host, 0,
|
||||
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT, 1);
|
||||
"Setting up GSMTAP Um forwarding to '%s:%u'\n",
|
||||
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
|
||||
g_bts->gsmtap.inst = gsmtap_source_init(g_bts->gsmtap.remote_host,
|
||||
GSMTAP_UDP_PORT, 1);
|
||||
if (g_bts->gsmtap.inst == NULL) {
|
||||
fprintf(stderr, "Failed during gsmtap_source_init2()\n");
|
||||
fprintf(stderr, "Failed during gsmtap_source_init()\n");
|
||||
exit(1);
|
||||
}
|
||||
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) {
|
||||
fprintf(stderr, "Error initializing telnet\n");
|
||||
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 */
|
||||
int paging_add_imm_ass(struct paging_state *ps,
|
||||
const uint8_t *data, uint8_t len)
|
||||
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
|
||||
uint8_t len, bool from_pcu)
|
||||
{
|
||||
struct llist_head *group_q;
|
||||
struct paging_record *pr;
|
||||
@@ -277,7 +277,7 @@ int paging_add_imm_ass(struct paging_state *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",
|
||||
ps->num_paging);
|
||||
rate_ctr_inc2(ps->bts->ctrs, BTS_CTR_PAGING_DROP_PS);
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/socket.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;
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
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",
|
||||
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);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
@@ -676,7 +681,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
|
||||
|
||||
switch (data_req->sapi) {
|
||||
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;
|
||||
case PCU_IF_SAPI_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';
|
||||
|
||||
osmo_fd_unregister(bfd);
|
||||
close(bfd->fd);
|
||||
bfd->fd = -1;
|
||||
osmo_fd_unregister(bfd);
|
||||
|
||||
/* patch SI3 to remove GPRS indicator */
|
||||
regenerate_si3_restoctets(bts);
|
||||
@@ -1088,33 +1093,48 @@ close:
|
||||
static int pcu_sock_write(struct osmo_fd *bfd)
|
||||
{
|
||||
struct pcu_sock_state *state = bfd->data;
|
||||
struct msgb *msg;
|
||||
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(...) ? */
|
||||
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 */
|
||||
rc = write(bfd->fd, msgb_data(msg), msgb_length(msg));
|
||||
if (OSMO_UNLIKELY(rc == 0))
|
||||
if (rc == 0)
|
||||
goto close;
|
||||
if (OSMO_UNLIKELY(rc < 0)) {
|
||||
if (rc < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
/* Re-insert at the start of the queue, skip disabling fd WRITE */
|
||||
llist_add(&msg->list, &state->upqueue);
|
||||
return 0;
|
||||
osmo_fd_write_enable(bfd);
|
||||
break;
|
||||
}
|
||||
goto close;
|
||||
}
|
||||
|
||||
dontsend:
|
||||
/* _after_ we send it, we can deueue */
|
||||
msg2 = msgb_dequeue(&state->upqueue);
|
||||
assert(msg == msg2);
|
||||
msgb_free(msg);
|
||||
}
|
||||
osmo_fd_write_disable(bfd);
|
||||
return 0;
|
||||
|
||||
close:
|
||||
msgb_free(msg);
|
||||
pcu_sock_close(state);
|
||||
|
||||
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 sockaddr_un un_addr;
|
||||
socklen_t len;
|
||||
int fd;
|
||||
int rc;
|
||||
|
||||
len = sizeof(un_addr);
|
||||
fd = accept(bfd->fd, (struct sockaddr *)&un_addr, &len);
|
||||
if (fd < 0) {
|
||||
rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
|
||||
if (rc < 0) {
|
||||
LOGP(DPCU, LOGL_ERROR, "Failed to accept a new connection\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 */
|
||||
osmo_fd_read_disable(&state->listen_bfd);
|
||||
close(fd);
|
||||
state->listen_bfd.when &= ~OSMO_FD_READ;
|
||||
close(rc);
|
||||
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) {
|
||||
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);
|
||||
conn_bfd->fd = -1;
|
||||
return -1;
|
||||
|
||||
@@ -72,7 +72,6 @@ static const unsigned int rsl_sacch_sitypes[] = {
|
||||
RSL_SYSTEM_INFO_6,
|
||||
RSL_SYSTEM_INFO_5bis,
|
||||
RSL_SYSTEM_INFO_5ter,
|
||||
RSL_SYSTEM_INFO_10,
|
||||
RSL_EXT_MEAS_ORDER,
|
||||
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;
|
||||
break;
|
||||
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):
|
||||
lchan->tch_mode = GSM48_CMODE_SPEECH_V5;
|
||||
break;
|
||||
case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM6):
|
||||
lchan->tch_mode = GSM48_CMODE_SPEECH_V6;
|
||||
break;
|
||||
/* TODO: also handle RSL_CMOD_SP_{GSM4,GSM5,GSM6} */
|
||||
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 */
|
||||
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;
|
||||
break;
|
||||
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):
|
||||
/* 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):
|
||||
lchan->tch_mode = GSM48_CMODE_DATA_43k5_14k5;
|
||||
break;
|
||||
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):
|
||||
lchan->tch_mode = GSM48_CMODE_DATA_43k5_29k0;
|
||||
break;
|
||||
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):
|
||||
lchan->tch_mode = GSM48_CMODE_DATA_14k5_29k0;
|
||||
break;
|
||||
case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_29k0_43k5):
|
||||
lchan->tch_mode = GSM48_CMODE_DATA_29k0_43k5;
|
||||
break;
|
||||
/* TODO: also handle other non-transparent data rates */
|
||||
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 */
|
||||
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):
|
||||
/* 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):
|
||||
/* 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):
|
||||
/* 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):
|
||||
/* 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_1200):
|
||||
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):
|
||||
/* 2.4 kbit/s *and less* services, 3.6 kbit/s radio interface rate */
|
||||
lchan->tch_mode = GSM48_CMODE_DATA_3k6;
|
||||
break;
|
||||
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains "
|
||||
"unhandled transparent CSD data rate 0x%02x\n",
|
||||
cm->chan_rate & 0x3f);
|
||||
*cause = RSL_ERR_IE_CONTENT;
|
||||
return -ENOTSUP;
|
||||
|
||||
default:
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
@@ -1677,7 +1652,7 @@ static int parse_multirate_config(struct gsm_lchan *lchan,
|
||||
}
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
@@ -2727,14 +2702,12 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg)
|
||||
struct tlv_parsed tp;
|
||||
struct gsm_lchan *lchan = msg->lchan;
|
||||
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;
|
||||
uint16_t connect_port = 0;
|
||||
int rc, inc_ip_port = 0;
|
||||
char *name;
|
||||
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)
|
||||
name = "CRCX";
|
||||
@@ -2792,17 +2765,6 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg)
|
||||
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 (bts->osmux.use == OSMUX_USAGE_ONLY) {
|
||||
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",
|
||||
|
||||
/* Tx only, frequency correction bursts */
|
||||
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||
.dl_fn = tx_fcch_fn,
|
||||
},
|
||||
[TRXC_SCH] = {
|
||||
@@ -157,6 +158,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
|
||||
.desc = "Synchronization channel",
|
||||
|
||||
/* Tx only, synchronization bursts */
|
||||
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||
.dl_fn = tx_sch_fn,
|
||||
},
|
||||
[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),
|
||||
* regular interleaving (3GPP TS 05.02, clause 7, table 3):
|
||||
* a L2 frame is interleaved over 4 consecutive bursts. */
|
||||
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||
.rts_fn = rts_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,
|
||||
|
||||
/* Rx only, RACH convolutional coding (3GPP TS 05.03, section 4.6). */
|
||||
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||
.ul_fn = rx_rach_fn,
|
||||
},
|
||||
[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),
|
||||
* regular interleaving (3GPP TS 05.02, clause 7, table 3):
|
||||
* a L2 frame is interleaved over 4 consecutive bursts. */
|
||||
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||
.rts_fn = rts_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,
|
||||
|
||||
/* Tx only, same as for TRXC_BCCH (xCCH), see above. */
|
||||
.flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
|
||||
.rts_fn = rts_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)
|
||||
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)));
|
||||
/* forward primitive */
|
||||
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;
|
||||
int i = find_sched_mframe_idx(pchan, ts->nr);
|
||||
if (i < 0) {
|
||||
LOGP(DL1C, LOGL_NOTICE, "%s Failed to configure multiframe (pchan=0x%02x)\n",
|
||||
gsm_ts_name(ts), pchan);
|
||||
LOGP(DL1C, LOGL_NOTICE, "%s Failed to configure multiframe\n",
|
||||
gsm_ts_name(ts));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
l1ts->mf_index = i;
|
||||
@@ -1056,20 +1062,41 @@ 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)
|
||||
/* 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)
|
||||
{
|
||||
struct l1sched_ts *l1ts = lchan->ts->priv;
|
||||
struct l1sched_chan_state *chan_state;
|
||||
uint8_t tn = L1SAP_CHAN2TS(chan_nr);
|
||||
uint8_t ss = l1sap_chan2ss(chan_nr);
|
||||
bool found = false;
|
||||
int i;
|
||||
|
||||
OSMO_ASSERT(l1ts != NULL);
|
||||
chan_state = &l1ts->chan_state[chan];
|
||||
if (!l1ts) {
|
||||
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "%s lchan with uninitialized scheduler structure\n",
|
||||
(active) ? "Activating" : "Deactivating");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* VAMOS: convert Osmocom specific channel number to a generic one,
|
||||
* otherwise we won't match anything in trx_chan_desc[]. */
|
||||
if (lchan->ts->vamos.is_shadow)
|
||||
chan_nr &= ~RSL_CHAN_OSMO_VAMOS_MASK;
|
||||
|
||||
/* look for all matching chan_nr/link_id */
|
||||
for (i = 0; i < _TRX_CHAN_MAX; i++) {
|
||||
struct l1sched_chan_state *chan_state = &l1ts->chan_state[i];
|
||||
|
||||
if (trx_chan_desc[i].chan_nr != (chan_nr & RSL_CHAN_NR_MASK))
|
||||
continue;
|
||||
if (trx_chan_desc[i].link_id != link_id)
|
||||
continue;
|
||||
if (chan_state->active == active)
|
||||
continue;
|
||||
found = true;
|
||||
|
||||
LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s %s\n",
|
||||
(active) ? "Activating" : "Deactivating",
|
||||
trx_chan_desc[chan].name);
|
||||
|
||||
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);
|
||||
@@ -1094,45 +1121,12 @@ static void _trx_sched_set_lchan(struct gsm_lchan *lchan,
|
||||
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);
|
||||
trx_sched_queue_filter(&l1ts->dl_prims, chan_nr, link_id);
|
||||
}
|
||||
|
||||
chan_state->active = active;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
struct l1sched_ts *l1ts = lchan->ts->priv;
|
||||
uint8_t tn = L1SAP_CHAN2TS(chan_nr);
|
||||
uint8_t ss = l1sap_chan2ss(chan_nr);
|
||||
bool found = false;
|
||||
|
||||
if (!l1ts) {
|
||||
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "%s lchan with uninitialized scheduler structure\n",
|
||||
(active) ? "Activating" : "Deactivating");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* VAMOS: convert Osmocom specific channel number to a generic one,
|
||||
* otherwise we won't match anything in trx_chan_desc[]. */
|
||||
if (lchan->ts->vamos.is_shadow)
|
||||
chan_nr &= ~RSL_CHAN_OSMO_VAMOS_MASK;
|
||||
|
||||
/* look for all matching chan_nr/link_id */
|
||||
for (enum trx_chan_type chan = 0; chan < _TRX_CHAN_MAX; chan++) {
|
||||
if (trx_chan_desc[chan].chan_nr != (chan_nr & RSL_CHAN_NR_MASK))
|
||||
continue;
|
||||
if (trx_chan_desc[chan].link_id != link_id)
|
||||
continue;
|
||||
if (l1ts->chan_state[chan].active == active)
|
||||
continue;
|
||||
found = true;
|
||||
_trx_sched_set_lchan(lchan, chan, active);
|
||||
}
|
||||
|
||||
/* disable handover detection (on deactivation) */
|
||||
if (!active)
|
||||
_sched_act_rach_det(lchan->ts->trx, tn, ss, 0);
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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 */
|
||||
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,
|
||||
@@ -1308,7 +1277,7 @@ int _sched_rts(const struct l1sched_ts *l1ts, uint32_t fn)
|
||||
return 0;
|
||||
|
||||
/* check if channel is active */
|
||||
if (!l1ts->chan_state[chan].active)
|
||||
if (!TRX_CHAN_IS_ACTIVE(&l1ts->chan_state[chan], chan))
|
||||
return -EINVAL;
|
||||
|
||||
/* 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];
|
||||
|
||||
/* check if channel is active */
|
||||
if (!l1cs->active)
|
||||
if (!TRX_CHAN_IS_ACTIVE(l1cs, br->chan))
|
||||
return;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* check if channel is active */
|
||||
if (!l1cs->active) {
|
||||
if (!TRX_CHAN_IS_ACTIVE(l1cs, bi->chan)) {
|
||||
/* handle noise measurements on dedicated and idle channels */
|
||||
if (TRX_CHAN_IS_DEDIC(bi->chan) || bi->chan == TRXC_IDLE)
|
||||
trx_sched_noise_meas(l1cs, bi);
|
||||
|
||||
@@ -388,9 +388,9 @@ static void config_write_osmux(struct vty *vty, const char *prefix, const struct
|
||||
break;
|
||||
}
|
||||
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-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);
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
bts->gsmtap.remote_host,
|
||||
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++) {
|
||||
if (bts->gsmtap.sapi_mask & ((uint32_t) 1 << 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;
|
||||
}
|
||||
|
||||
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,
|
||||
cfg_bts_no_gsmtap_remote_host_cmd,
|
||||
"no gsmtap-remote-host",
|
||||
@@ -2254,24 +2234,6 @@ DEFUN(cfg_bts_no_gsmtap_remote_host,
|
||||
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,
|
||||
"gsmtap-sapi (enable-all|disable-all)",
|
||||
"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;
|
||||
}
|
||||
|
||||
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")
|
||||
{
|
||||
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_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_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 */
|
||||
if (msg) {
|
||||
msgb_pull(msg, sizeof(*l1sap));
|
||||
/* create new message */
|
||||
nmsg = l1p_msgb_alloc();
|
||||
if (!nmsg)
|
||||
@@ -516,7 +517,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
||||
rc = l1if_tch_encode(lchan,
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
||||
&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);
|
||||
if (rc < 0) {
|
||||
/* no data encoded for L1: smth will be generated below */
|
||||
|
||||
@@ -319,7 +319,7 @@ int main(int argc, char **argv)
|
||||
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) {
|
||||
fprintf(stderr, "Error initializing telnet\n");
|
||||
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 */
|
||||
if (msg) {
|
||||
msgb_pull(msg, sizeof(*l1sap));
|
||||
/* create new message */
|
||||
nmsg = l1p_msgb_alloc();
|
||||
if (!nmsg)
|
||||
@@ -569,7 +570,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
||||
rc = l1if_tch_encode(lchan,
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
||||
&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);
|
||||
if (rc < 0) {
|
||||
/* no data encoded for L1: smth will be generated below */
|
||||
|
||||
@@ -306,7 +306,7 @@ int main(int argc, char **argv)
|
||||
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) {
|
||||
fprintf(stderr, "Error initializing telnet\n");
|
||||
exit(1);
|
||||
|
||||
@@ -171,12 +171,7 @@ static void mgr_gps_checkfix(struct oc2gbts_mgr_instance *mgr)
|
||||
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;
|
||||
#endif
|
||||
|
||||
LOGP(DCALIB, LOGL_INFO, "Got a GPS fix, satellites used: %d, timestamp: %ld\n",
|
||||
data->satellites_used, mgr->gps.gps_fix_now);
|
||||
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;
|
||||
}
|
||||
|
||||
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 *)
|
||||
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.abyDataContent,
|
||||
&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);
|
||||
} else {
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
/**
|
||||
* EEPROM device file
|
||||
*/
|
||||
#define EEPROM_DEV "eeprom"
|
||||
#define EEPROM_DEV "/sys/bus/i2c/devices/i2c-1/1-0050/eeprom"
|
||||
|
||||
/**
|
||||
* EEPROM configuration start address
|
||||
|
||||
@@ -56,7 +56,7 @@ enum l1prim_type {
|
||||
};
|
||||
|
||||
#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_OCXO = 1,
|
||||
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 */
|
||||
if (msg) {
|
||||
msgb_pull(msg, sizeof(*l1sap));
|
||||
/* create new message */
|
||||
nmsg = l1p_msgb_alloc();
|
||||
if (!nmsg)
|
||||
@@ -513,7 +514,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg,
|
||||
rc = l1if_tch_encode(lchan,
|
||||
l1p->u.phDataReq.msgUnitParam.u8Buffer,
|
||||
&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);
|
||||
if (rc < 0) {
|
||||
/* 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);
|
||||
|
||||
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,
|
||||
osmo_hexdump(data_ind->msgUnitParam.u8Buffer, data_ind->msgUnitParam.u8Size),
|
||||
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;
|
||||
}
|
||||
|
||||
if (data_ind->sapi == GsmL1_Sapi_FacchF)
|
||||
LOGPFN(DL1P, LOGL_INFO, data_ind->u32Fn, "Rx SAPI FACCH\n");
|
||||
|
||||
/* fill L1SAP header */
|
||||
sap_msg = l1sap_msgb_alloc(data_ind->msgUnitParam.u8Size);
|
||||
l1sap = msgb_l1sap_prim(sap_msg);
|
||||
|
||||
@@ -288,7 +288,7 @@ int main(int argc, char **argv)
|
||||
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) {
|
||||
fprintf(stderr, "Error initializing telnet\n");
|
||||
exit(1);
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "sysmobts_par.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 = {
|
||||
.bits = 8,
|
||||
|
||||
@@ -56,7 +56,6 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len
|
||||
{
|
||||
struct msgb *msg;
|
||||
uint8_t *cur;
|
||||
bool t;
|
||||
|
||||
msg = msgb_alloc_headroom(1024, 128, "L1P-to-RTP");
|
||||
if (!msg)
|
||||
@@ -77,9 +76,8 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len
|
||||
|
||||
cur[0] |= 0xD0;
|
||||
#endif /* USE_L1_RTP_MODE */
|
||||
t = osmo_fr_check_sid(l1_payload, payload_len);
|
||||
lchan_set_marker(t, lchan);
|
||||
LOGP(DL1P, LOGL_ERROR, "FR SID:%d\n", t);
|
||||
|
||||
lchan_set_marker(osmo_fr_check_sid(l1_payload, payload_len), lchan);
|
||||
|
||||
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
|
||||
* the same as the previous one. This means we need to patch
|
||||
* the content here.
|
||||
|
||||
*/
|
||||
if ((cur[0] & 0xF0) == 0xF0)
|
||||
cur[0]= lchan->tch.last_cmr << 4;
|
||||
else
|
||||
lchan->tch.last_cmr = cur[0] >> 4;
|
||||
*/
|
||||
#else
|
||||
u_int8_t cmr;
|
||||
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 };
|
||||
struct msgb *rmsg = NULL;
|
||||
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))
|
||||
return -EAGAIN;
|
||||
|
||||
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 */
|
||||
rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP");
|
||||
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_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) {
|
||||
case GsmL1_TchPlType_Fr:
|
||||
#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 &&
|
||||
lchan->type != GSM_LCHAN_TCH_F)
|
||||
goto err_payload_match;
|
||||
LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "DTX: received Speech from L1 "
|
||||
"(%d bytes)\n", payload_len);
|
||||
break;
|
||||
case GsmL1_TchPlType_Amr_Onset:
|
||||
if (lchan->type != GSM_LCHAN_TCH_H &&
|
||||
lchan->type != GSM_LCHAN_TCH_F)
|
||||
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
|
||||
speech frame of a speech burst - set the marker for next RTP
|
||||
frame */
|
||||
lchan->tch.dtx.is_speech_resume = true;
|
||||
lchan->rtp_tx_marker = true;
|
||||
break;
|
||||
case GsmL1_TchPlType_Amr_SidFirstP1:
|
||||
if (lchan->type != GSM_LCHAN_TCH_H)
|
||||
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);
|
||||
break;
|
||||
case GsmL1_TchPlType_Amr_SidFirstP2:
|
||||
if (lchan->type != GSM_LCHAN_TCH_H)
|
||||
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);
|
||||
break;
|
||||
case GsmL1_TchPlType_Amr_SidFirstInH:
|
||||
if (lchan->type != GSM_LCHAN_TCH_H)
|
||||
goto err_payload_match;
|
||||
lchan->tch.dtx.is_speech_resume = 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);
|
||||
break;
|
||||
case GsmL1_TchPlType_Amr_SidUpdateInH:
|
||||
if (lchan->type != GSM_LCHAN_TCH_H)
|
||||
goto err_payload_match;
|
||||
lchan->tch.dtx.is_speech_resume = 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);
|
||||
break;
|
||||
default:
|
||||
@@ -602,6 +587,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch (payload_type) {
|
||||
case GsmL1_TchPlType_Fr:
|
||||
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:
|
||||
rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan);
|
||||
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:
|
||||
rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan);
|
||||
lchan->rtp_tx_marker = false;
|
||||
/*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);
|
||||
memcpy(sid_first, payload, payload_len);
|
||||
int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD);
|
||||
if (len < 0)
|
||||
return 0;
|
||||
rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);*/
|
||||
rmsg = l1_to_rtppayload_amr(sid_first, len, lchan);
|
||||
break;
|
||||
/* 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)
|
||||
return NM_NACK_RES_NOTAVAIL;
|
||||
|
||||
/* activate lchans for [CBCH/]BCCH/CCCH */
|
||||
switch (pchan) {
|
||||
case GSM_PCHAN_SDCCH8_SACCH8C_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);
|
||||
/* activate lchan for CCCH */
|
||||
if (pchan == GSM_PCHAN_CCCH || pchan == GSM_PCHAN_CCCH_SDCCH4 ||
|
||||
pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH) {
|
||||
ts->lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML;
|
||||
lchan_set_state(&ts->lchan[CCCH_LCHAN], LCHAN_S_ACTIVE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
slottype = transceiver_chan_types[pchan];
|
||||
@@ -411,31 +396,24 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
|
||||
/* put data into scheduler's queue */
|
||||
return trx_sched_tch_req(trx, l1sap);
|
||||
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) {
|
||||
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)
|
||||
l1if_set_ciphering(lchan, chan_nr, 0);
|
||||
if (l1sap->u.info.u.ciph_req.downlink)
|
||||
l1if_set_ciphering(lchan, chan_nr, 1);
|
||||
break;
|
||||
case PRIM_INFO_ACTIVATE:
|
||||
case PRIM_INFO_DEACTIVATE:
|
||||
case PRIM_INFO_MODIFY:
|
||||
chan_nr = l1sap->u.info.u.act_req.chan_nr;
|
||||
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));
|
||||
rc = -EPERM;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -469,7 +447,8 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
|
||||
/* confirm */
|
||||
mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_ACTIVATE, 0);
|
||||
break;
|
||||
case PRIM_INFO_MODIFY:
|
||||
}
|
||||
if (l1sap->u.info.type == PRIM_INFO_MODIFY) {
|
||||
/* ECU for possibly new codec */
|
||||
if (lchan->ecu_state)
|
||||
osmo_ecu_destroy(lchan->ecu_state);
|
||||
@@ -492,11 +471,11 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
|
||||
else
|
||||
lchan->ciph_state = LCHAN_CIPH_NONE;
|
||||
break;
|
||||
case PRIM_INFO_DEACTIVATE:
|
||||
}
|
||||
/* here, type == PRIM_INFO_DEACTIVATE */
|
||||
if ((chan_nr & 0xE0) == 0x80) {
|
||||
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot deactivate"
|
||||
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
||||
rc = -EPERM;
|
||||
break;
|
||||
}
|
||||
/* 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)
|
||||
ft = i;
|
||||
}
|
||||
if (ft_codec != 8 && ft < 0) {
|
||||
if (ft < 0) {
|
||||
LOGL1SB(DL1P, LOGL_ERROR, l1ts, br,
|
||||
"Codec (FT = %d) of RTP frame not in list\n", ft_codec);
|
||||
goto free_bad_msg;
|
||||
|
||||
@@ -124,11 +124,6 @@ static void bts_report_interf_meas(const struct gsm_bts *bts)
|
||||
unsigned int tn, ln;
|
||||
|
||||
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++) {
|
||||
const struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
||||
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) */
|
||||
void trx_if_close(struct trx_l1h *l1h)
|
||||
{
|
||||
LOGPPHI(l1h->phy_inst, DTRX, LOGL_NOTICE, "Closing TRXC/TRXD connections to %s\n",
|
||||
l1h->phy_inst->phy_link->u.osmotrx.remote_ip);
|
||||
LOGPPHI(l1h->phy_inst, DTRX, LOGL_NOTICE, "Closing TRXC/TRXD connections\n");
|
||||
|
||||
trx_if_flush(l1h);
|
||||
|
||||
@@ -1243,7 +1242,7 @@ void trx_if_close(struct trx_l1h *l1h)
|
||||
}
|
||||
|
||||
/*! 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;
|
||||
uint16_t inc = 1;
|
||||
@@ -1264,21 +1263,21 @@ static int trx_if_open(struct trx_l1h *l1h)
|
||||
struct phy_link *plink = pinst->phy_link;
|
||||
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 */
|
||||
rc = trx_udp_open(l1h, &l1h->trx_ofd_ctrl,
|
||||
plink->u.osmotrx.local_ip,
|
||||
compute_port(pinst, false, false),
|
||||
compute_port(pinst, 0, 0),
|
||||
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)
|
||||
return rc;
|
||||
rc = trx_udp_open(l1h, &l1h->trx_ofd_data,
|
||||
plink->u.osmotrx.local_ip,
|
||||
compute_port(pinst, false, true),
|
||||
compute_port(pinst, 0, 1),
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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.tsc_acked || pinst->phy_link->u.osmotrx.use_legacy_setbsic) &&
|
||||
(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;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
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;
|
||||
if (l1h_it->phy_inst->num == 0)
|
||||
continue;
|
||||
if (!trx_is_provisioned(l1h_it))
|
||||
if (l1h_it->provision_fi->state != TRX_PROV_ST_OPEN_POWERON)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -394,8 +389,7 @@ static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *dat
|
||||
uint16_t arfcn;
|
||||
int nominal_power;
|
||||
int status;
|
||||
bool waiting_other_trx;
|
||||
bool was_ready = trx_is_provisioned(l1h);
|
||||
bool others_ready;
|
||||
|
||||
switch (event) {
|
||||
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);
|
||||
|
||||
if (l1h->phy_inst->num == 0) {
|
||||
waiting_other_trx = !trx_other_trx0_ready(l1h);
|
||||
} else {
|
||||
waiting_other_trx = false; /* 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 (l1h->phy_inst->num == 0)
|
||||
others_ready = trx_other_trx0_ready(l1h);
|
||||
else
|
||||
others_ready = true; /* we don't care about others in TRX!=0 */
|
||||
|
||||
/* if we gathered all data and could go forward. For TRX0, only after
|
||||
* all other TRX are prepared, since it will send POWERON commad */
|
||||
if (trx_is_provisioned_and_enabled(l1h) && !waiting_other_trx) {
|
||||
if (l1h->phy_inst->num != 0)
|
||||
if (trx_is_provisioned(l1h) &&
|
||||
(l1h->phy_inst->num != 0 || others_ready)) {
|
||||
if (l1h->phy_inst->num != 0) {
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
LOGPFSML(fi, LOGL_INFO, "Delay poweron, wait for:%s%s%s%s%s%s%s%s\n",
|
||||
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.nominal_power_set_by_vty ? "" : (l1h->config.nomtxpower_acked ? "" : " nomtxpower-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)
|
||||
{
|
||||
enum gsm_phys_chan_config pchan;
|
||||
|
||||
/* 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)
|
||||
if (trx_sched_set_pchan(ts, ts->pchan) != 0)
|
||||
return NM_NACK_RES_NOTAVAIL;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -187,19 +187,6 @@ nomessage:
|
||||
/* called by common part once OML link is established */
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -230,6 +217,17 @@ int bts_model_phy_link_open(struct phy_link *plink)
|
||||
if (pinst->trx == NULL)
|
||||
continue;
|
||||
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 */
|
||||
@@ -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;
|
||||
uint8_t chan_nr;
|
||||
uint8_t tn, ss;
|
||||
int rc = 0;
|
||||
struct gsm_lchan *lchan;
|
||||
|
||||
@@ -351,31 +350,30 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
|
||||
/* put data into scheduler's queue */
|
||||
return trx_sched_tch_req(trx, l1sap);
|
||||
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) {
|
||||
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)
|
||||
l1if_set_ciphering(lchan, chan_nr, 0);
|
||||
if (l1sap->u.info.u.ciph_req.downlink)
|
||||
l1if_set_ciphering(lchan, chan_nr, 1);
|
||||
break;
|
||||
case PRIM_INFO_ACTIVATE:
|
||||
case PRIM_INFO_DEACTIVATE:
|
||||
case PRIM_INFO_MODIFY:
|
||||
chan_nr = l1sap->u.info.u.act_req.chan_nr;
|
||||
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));
|
||||
rc = -EPERM;
|
||||
break;
|
||||
}
|
||||
/* activate dedicated channel */
|
||||
@@ -403,9 +401,11 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
|
||||
lchan->ciph_state = LCHAN_CIPH_NONE;
|
||||
|
||||
/* confirm */
|
||||
mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_ACTIVATE, 0);
|
||||
mph_info_chan_confirm(trx, chan_nr,
|
||||
PRIM_INFO_ACTIVATE, 0);
|
||||
break;
|
||||
case PRIM_INFO_MODIFY:
|
||||
}
|
||||
if (l1sap->u.info.type == PRIM_INFO_MODIFY) {
|
||||
/* change mode */
|
||||
trx_sched_set_mode(lchan->ts, chan_nr,
|
||||
lchan->rsl_cmode, lchan->tch_mode,
|
||||
@@ -417,11 +417,10 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
|
||||
amr_get_initial_mode(lchan),
|
||||
0);
|
||||
break;
|
||||
case PRIM_INFO_DEACTIVATE:
|
||||
}
|
||||
if ((chan_nr & 0xE0) == 0x80) {
|
||||
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot deactivate"
|
||||
" channel %s\n", rsl_chan_nr_str(chan_nr));
|
||||
rc = -EPERM;
|
||||
break;
|
||||
}
|
||||
/* deactivate associated channel */
|
||||
|
||||
@@ -64,8 +64,6 @@ int bts_model_init(struct gsm_bts *bts)
|
||||
|
||||
/* order alphabetically */
|
||||
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_SPEECH_F_AMR);
|
||||
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;
|
||||
LOGP(DL1P, LOGL_NOTICE, "starting VBTS scheduler\n");
|
||||
|
||||
if (!bts_virt)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&bts_virt->fn_timer, 0, sizeof(bts_virt->fn_timer));
|
||||
bts_virt->fn_timer.cb = vbts_fn_timer_cb;
|
||||
bts_virt->fn_timer.data = bts;
|
||||
|
||||
@@ -9,7 +9,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
|
||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
|
||||
@@ -9,7 +9,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
|
||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
|
||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
|
||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
|
||||
@@ -251,8 +251,6 @@ OsmoBTS(bts)# list
|
||||
smscb queue-hysteresis <0-30>
|
||||
gsmtap-remote-host [HOSTNAME]
|
||||
no gsmtap-remote-host
|
||||
gsmtap-local-host HOSTNAME
|
||||
no gsmtap-local-host
|
||||
gsmtap-sapi (enable-all|disable-all)
|
||||
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
|
||||
smscb SMSCB (SMS Cell Broadcast) / CBCH configuration
|
||||
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
|
||||
osmux Configure Osmux
|
||||
trx Select a TRX to configure
|
||||
|
||||
@@ -18,7 +18,6 @@ LDADD = \
|
||||
$(LIBOSMOTRAU_LIBS) \
|
||||
$(LIBOSMONETIF_LIBS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
|
||||
check_PROGRAMS = paging_test
|
||||
EXTRA_DIST = paging_test.ok
|
||||
|
||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOCODEC_LIBS) \
|
||||
|
||||
@@ -14,7 +14,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOCODEC_LIBS) \
|
||||
|
||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
|
||||
@@ -8,7 +8,6 @@ AM_CFLAGS = \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMONETIF_CFLAGS) \
|
||||
$(NULL)
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
|
||||
Reference in New Issue
Block a user