Compare commits

..

1 Commits

Author SHA1 Message Date
Daniel Willmann
08f337abec shutdown_fsm: Add power_ramp_force() to jump straight to the tgt power
Both power_ramp_start() and power_ramp_force() are now small macros
around _power_ramp_start()

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

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

Change-Id: Ida1d7bbf094958b9142af306dbf84206729a609e
Related: SYS#6237
2022-12-20 15:21:46 +01:00
66 changed files with 417 additions and 755 deletions

1
.gitignore vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

BIN
eeprom

Binary file not shown.

View File

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

View File

@@ -27,8 +27,8 @@ struct gsm_bts_trx {
uint16_t arfcn;
int nominal_power; /* in dBm */
unsigned int max_power_red; /* in actual dB */
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
uint8_t ta_ctrl_interval; /* 1 step is 2 SACCH periods */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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)
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 ((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);

View File

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

View File

@@ -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,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
* 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",
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) {
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);
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 (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;
if (lchan->tch.dtx.is_speech_resume)
lchan->tch.dtx.is_speech_resume = false;
return 0;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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,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 */
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 ss = l1sap_chan2ss(chan_nr);
bool found = false;
int i;
if (!l1ts) {
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;
/* 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))
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[chan].link_id != link_id)
if (trx_chan_desc[i].link_id != link_id)
continue;
if (l1ts->chan_state[chan].active == active)
if (chan_state->active == active)
continue;
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) */
@@ -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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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,92 +396,86 @@ 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:
if ((chan_nr & 0xE0) == 0x80) {
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate"
" channel %s\n", rsl_chan_nr_str(chan_nr));
rc = -EPERM;
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));
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;
}
/* 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;
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 (l1sap->u.info.type == 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;
}
/* 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) */

View File

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

View File

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

View File

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

View File

@@ -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"
);
}
}

View File

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

View File

@@ -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,77 +350,77 @@ 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:
if ((chan_nr & 0xE0) == 0x80) {
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate"
" channel %s\n", rsl_chan_nr_str(chan_nr));
rc = -EPERM;
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));
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;
}
/* 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) {
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot deactivate"
" channel %s\n", rsl_chan_nr_str(chan_nr));
rc = -EPERM;
break;
}
/* deactivate associated channel */

View File

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

View File

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

View File

@@ -9,7 +9,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \

View File

@@ -8,7 +8,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \

View File

@@ -9,7 +9,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \

View File

@@ -8,7 +8,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \

View File

@@ -8,7 +8,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \

View File

@@ -8,7 +8,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \

View File

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

View File

@@ -18,7 +18,6 @@ LDADD = \
$(LIBOSMOTRAU_LIBS) \
$(LIBOSMONETIF_LIBS) \
$(NULL)
AM_LDFLAGS = -no-install
check_PROGRAMS = paging_test
EXTRA_DIST = paging_test.ok

View File

@@ -8,7 +8,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOCODEC_LIBS) \

View File

@@ -14,7 +14,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOCODEC_LIBS) \

View File

@@ -8,7 +8,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \

View File

@@ -8,7 +8,6 @@ AM_CFLAGS = \
$(LIBOSMOTRAU_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
AM_LDFLAGS = -no-install
LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \