2011-06-27 09:25:35 +00:00
|
|
|
#ifndef _GSM_DATA_H
|
|
|
|
#define _GSM_DATA_H
|
|
|
|
|
2020-06-17 15:48:16 +00:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
2011-06-27 09:25:35 +00:00
|
|
|
#include <osmocom/core/timer.h>
|
2020-06-17 15:48:16 +00:00
|
|
|
#include <osmocom/core/bitvec.h>
|
|
|
|
#include <osmocom/core/statistics.h>
|
|
|
|
#include <osmocom/core/utils.h>
|
2011-06-27 09:25:35 +00:00
|
|
|
#include <osmocom/core/linuxlist.h>
|
2020-06-17 15:48:16 +00:00
|
|
|
#include <osmocom/codec/ecu.h>
|
2011-06-27 09:25:35 +00:00
|
|
|
#include <osmocom/gsm/lapdm.h>
|
2018-02-20 23:38:05 +00:00
|
|
|
#include <osmocom/gsm/gsm23003.h>
|
2020-06-16 22:08:54 +00:00
|
|
|
#include <osmocom/gsm/gsm0502.h>
|
2020-06-17 15:48:16 +00:00
|
|
|
#include <osmocom/gsm/gsm_utils.h>
|
|
|
|
#include <osmocom/gsm/tlv.h>
|
|
|
|
#include <osmocom/gsm/rxlev_stat.h>
|
|
|
|
#include <osmocom/gsm/sysinfo.h>
|
|
|
|
#include <osmocom/gsm/meas_rep.h>
|
|
|
|
#include <osmocom/gsm/bts_features.h>
|
|
|
|
#include <osmocom/gsm/gsm48_rest_octets.h>
|
|
|
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
|
|
|
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
|
|
|
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
|
|
|
|
|
|
|
#include <osmocom/abis/e1_input.h>
|
2011-06-27 09:25:35 +00:00
|
|
|
|
|
|
|
#include <osmo-bts/paging.h>
|
New generic transmit power handling
In order to support transmit power reduction by thermal management
as well as the variety of new internal / external PA configurations
of BTSs, we need a slightly more complex system.
Also, as at high power a single dB can be quite a big difference,
we are now doing all computations in milli-dB(m), i.e. 1/10000 bel.
Ramping is now used both for up and down ramping, as that is useful in
cases where you want to gracefully shut down a cell by shrinking its
radius, gradually handing over subscribers to neighboring cells.
Furthermore, this code is becoming part of the 'common' codebase, as it
is not really specific to how sysmobts is working.
The user can specify a single aggregate value for external system
gain/attenuation. Let's say you have 1dB loss of antenna cable, so you
can put that as 'user-gain -1' into the config, which means that a
'transmit power of 20dBm' will be compensatet for that and the TRX is
instructed to output 21dBm to compensate the cable loss. Similarly,
external PAs can be described by a positive user-gain.
One of the next steps will be to communicate those values and the
nominal power capability of the specific BTS to the BSC, so the BSC will
automatically show correct signal levels in the VTY and log files.
The code includes provisions for future extensions regarding
* an external and an internal PA with calibration tables
* a thermal attenuation setting to be controlled by the site manager
2014-08-22 00:46:15 +00:00
|
|
|
#include <osmo-bts/tx_power.h>
|
2011-06-27 09:25:35 +00:00
|
|
|
|
2016-01-09 16:56:10 +00:00
|
|
|
#define GSM_FR_BITS 260
|
|
|
|
#define GSM_EFR_BITS 244
|
|
|
|
|
|
|
|
#define GSM_FR_BYTES 33 /* TS 101318 Chapter 5.1: 260 bits + 4bit sig */
|
|
|
|
#define GSM_HR_BYTES 14 /* TS 101318 Chapter 5.2: 112 bits, no sig */
|
|
|
|
#define GSM_EFR_BYTES 31 /* TS 101318 Chapter 5.3: 244 bits + 4bit sig */
|
|
|
|
|
2014-02-14 20:15:31 +00:00
|
|
|
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT 41
|
|
|
|
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE 999999
|
|
|
|
#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41
|
|
|
|
#define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91
|
|
|
|
|
2018-12-12 22:57:13 +00:00
|
|
|
#define LOGPLCHAN(lchan, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_lchan_name(lchan), ## args)
|
2020-06-18 14:56:22 +00:00
|
|
|
#define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args)
|
2018-12-12 22:57:13 +00:00
|
|
|
|
2011-06-27 09:25:35 +00:00
|
|
|
struct gsm_network {
|
2011-09-04 20:42:03 +00:00
|
|
|
struct llist_head bts_list;
|
|
|
|
unsigned int num_bts;
|
2018-02-20 23:38:05 +00:00
|
|
|
struct osmo_plmn_id plmn;
|
2012-07-08 18:50:02 +00:00
|
|
|
struct pcu_sock_state *pcu_state;
|
2011-06-27 09:25:35 +00:00
|
|
|
};
|
|
|
|
|
2012-04-19 07:35:03 +00:00
|
|
|
enum lchan_ciph_state {
|
|
|
|
LCHAN_CIPH_NONE,
|
|
|
|
LCHAN_CIPH_RX_REQ,
|
|
|
|
LCHAN_CIPH_RX_CONF,
|
2013-06-16 11:26:14 +00:00
|
|
|
LCHAN_CIPH_RXTX_REQ,
|
|
|
|
LCHAN_CIPH_RX_CONF_TX_REQ,
|
|
|
|
LCHAN_CIPH_RXTX_CONF,
|
2012-04-19 07:35:03 +00:00
|
|
|
};
|
|
|
|
|
2020-06-17 15:48:16 +00:00
|
|
|
/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1:
|
|
|
|
4-bit index is used (2#1111 = 10#15) */
|
|
|
|
#define SI2Q_MAX_NUM 16
|
|
|
|
/* length in bits (for single SI2quater message) */
|
|
|
|
#define SI2Q_MAX_LEN 160
|
|
|
|
#define SI2Q_MIN_LEN 18
|
|
|
|
|
|
|
|
/* 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 TRX_NR_TS 8
|
|
|
|
#define TS_MAX_LCHAN 8
|
|
|
|
|
|
|
|
#define MAX_VERSION_LENGTH 64
|
|
|
|
|
|
|
|
struct gsm_lchan;
|
|
|
|
struct osmo_rtp_socket;
|
|
|
|
struct pcu_sock_state;
|
|
|
|
struct smscb_msg;
|
|
|
|
|
|
|
|
/* Network Management State */
|
|
|
|
struct gsm_nm_state {
|
|
|
|
uint8_t operational;
|
|
|
|
uint8_t administrative;
|
|
|
|
uint8_t availability;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct gsm_abis_mo {
|
|
|
|
/* A-bis OML Object Class */
|
|
|
|
uint8_t obj_class;
|
|
|
|
/* is there still some procedure pending? */
|
|
|
|
uint8_t procedure_pending;
|
|
|
|
/* A-bis OML Object Instance */
|
|
|
|
struct abis_om_obj_inst obj_inst;
|
|
|
|
/* human-readable name */
|
|
|
|
const char *name;
|
|
|
|
/* NM State */
|
|
|
|
struct gsm_nm_state nm_state;
|
|
|
|
/* Attributes configured in this MO */
|
|
|
|
struct tlv_parsed *nm_attr;
|
|
|
|
/* BTS to which this MO belongs */
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define MAX_A5_KEY_LEN (128/8)
|
|
|
|
#define RSL_ENC_ALG_A5(x) (x+1)
|
|
|
|
|
|
|
|
/* state of a logical channel */
|
|
|
|
enum gsm_lchan_state {
|
|
|
|
LCHAN_S_NONE, /* channel is not active */
|
|
|
|
LCHAN_S_ACT_REQ, /* channel activation requested */
|
|
|
|
LCHAN_S_ACTIVE, /* channel is active and operational */
|
|
|
|
LCHAN_S_REL_REQ, /* channel release has been requested */
|
|
|
|
LCHAN_S_REL_ERR, /* channel is in an error state */
|
|
|
|
LCHAN_S_BROKEN, /* channel is somehow unusable */
|
|
|
|
LCHAN_S_INACTIVE, /* channel is set inactive */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define MAX_NUM_UL_MEAS 104
|
|
|
|
#define LC_UL_M_F_L1_VALID (1 << 0)
|
|
|
|
#define LC_UL_M_F_RES_VALID (1 << 1)
|
|
|
|
#define LC_UL_M_F_OSMO_EXT_VALID (1 << 2)
|
|
|
|
|
|
|
|
struct bts_ul_meas {
|
|
|
|
/* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */
|
|
|
|
uint16_t ber10k;
|
|
|
|
/* timing advance offset (in 1/256 bits) */
|
|
|
|
int16_t ta_offs_256bits;
|
|
|
|
/* C/I ratio in dB */
|
|
|
|
float c_i;
|
|
|
|
/* flags */
|
|
|
|
uint8_t is_sub:1;
|
|
|
|
/* RSSI in dBm * -1 */
|
|
|
|
uint8_t inv_rssi;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct amr_mode {
|
|
|
|
uint8_t mode;
|
|
|
|
uint8_t threshold;
|
|
|
|
uint8_t hysteresis;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct amr_multirate_conf {
|
|
|
|
uint8_t gsm48_ie[2];
|
|
|
|
struct amr_mode ms_mode[4];
|
|
|
|
struct amr_mode bts_mode[4];
|
|
|
|
uint8_t num_modes;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum lchan_csd_mode {
|
|
|
|
LCHAN_CSD_M_NT,
|
|
|
|
LCHAN_CSD_M_T_1200_75,
|
|
|
|
LCHAN_CSD_M_T_600,
|
|
|
|
LCHAN_CSD_M_T_1200,
|
|
|
|
LCHAN_CSD_M_T_2400,
|
|
|
|
LCHAN_CSD_M_T_9600,
|
|
|
|
LCHAN_CSD_M_T_14400,
|
|
|
|
LCHAN_CSD_M_T_29000,
|
|
|
|
LCHAN_CSD_M_T_32000,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* State of the SAPIs in the lchan */
|
|
|
|
enum lchan_sapi_state {
|
|
|
|
LCHAN_SAPI_S_NONE,
|
|
|
|
LCHAN_SAPI_S_REQ,
|
|
|
|
LCHAN_SAPI_S_ASSIGNED,
|
|
|
|
LCHAN_SAPI_S_REL,
|
|
|
|
LCHAN_SAPI_S_ERROR,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct gsm_lchan {
|
|
|
|
/* The TS that we're part of */
|
|
|
|
struct gsm_bts_trx_ts *ts;
|
|
|
|
/* The logical subslot number in the TS */
|
|
|
|
uint8_t nr;
|
|
|
|
/* The logical channel type */
|
|
|
|
enum gsm_chan_t type;
|
|
|
|
/* RSL channel mode */
|
|
|
|
enum rsl_cmod_spd rsl_cmode;
|
|
|
|
/* If TCH, traffic channel mode */
|
|
|
|
enum gsm48_chan_mode tch_mode;
|
|
|
|
enum lchan_csd_mode csd_mode;
|
|
|
|
/* State */
|
|
|
|
enum gsm_lchan_state state;
|
|
|
|
const char *broken_reason;
|
|
|
|
/* Encryption information */
|
|
|
|
struct {
|
|
|
|
uint8_t alg_id;
|
|
|
|
uint8_t key_len;
|
|
|
|
uint8_t key[MAX_A5_KEY_LEN];
|
|
|
|
} encr;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
uint32_t bound_ip;
|
|
|
|
uint32_t connect_ip;
|
|
|
|
uint16_t bound_port;
|
|
|
|
uint16_t connect_port;
|
|
|
|
uint16_t conn_id;
|
|
|
|
uint8_t rtp_payload;
|
|
|
|
uint8_t rtp_payload2;
|
|
|
|
uint8_t speech_mode;
|
|
|
|
struct osmo_rtp_socket *rtp_socket;
|
|
|
|
} abis_ip;
|
|
|
|
|
|
|
|
uint8_t rqd_ta;
|
|
|
|
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
/* Number of different GsmL1_Sapi_t used in osmo_bts_sysmo is 23.
|
|
|
|
* Currently we don't share these headers so this is a magic number. */
|
|
|
|
struct llist_head sapi_cmds;
|
|
|
|
uint8_t sapis_dl[23];
|
|
|
|
uint8_t sapis_ul[23];
|
|
|
|
struct lapdm_channel lapdm_ch;
|
|
|
|
struct llist_head dl_tch_queue;
|
|
|
|
struct {
|
|
|
|
/* bitmask of all SI that are present/valid in si_buf */
|
|
|
|
uint32_t valid;
|
|
|
|
/* bitmask of all SI that do not mirror the BTS-global SI values */
|
|
|
|
uint32_t overridden;
|
|
|
|
uint32_t last;
|
|
|
|
/* buffers where we put the pre-computed SI:
|
|
|
|
SI2Q_MAX_NUM is the max number of SI2quater messages (see 3GPP TS 44.018) */
|
|
|
|
sysinfo_buf_t buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
|
|
|
|
} si;
|
|
|
|
struct {
|
|
|
|
uint8_t flags;
|
|
|
|
/* RSL measurement result number, 0 at lchan_act */
|
|
|
|
uint8_t res_nr;
|
|
|
|
/* number of measurements stored in array below */
|
|
|
|
uint8_t num_ul_meas;
|
|
|
|
struct bts_ul_meas uplink[MAX_NUM_UL_MEAS];
|
|
|
|
/* last L1 header from the MS */
|
|
|
|
uint8_t l1_info[2];
|
|
|
|
struct gsm_meas_rep_unidir ul_res;
|
|
|
|
int16_t ms_toa256;
|
|
|
|
/* Frame number of the last measurement indication receceived */
|
|
|
|
uint32_t last_fn;
|
|
|
|
/* Osmocom extended measurement results, see LC_UL_M_F_EXTD_VALID */
|
|
|
|
struct {
|
|
|
|
/* minimum value of toa256 during measurement period */
|
|
|
|
int16_t toa256_min;
|
|
|
|
/* maximum value of toa256 during measurement period */
|
|
|
|
int16_t toa256_max;
|
|
|
|
/* standard deviation of toa256 value during measurement period */
|
|
|
|
uint16_t toa256_std_dev;
|
|
|
|
} ext;
|
|
|
|
} meas;
|
|
|
|
struct {
|
|
|
|
struct amr_multirate_conf amr_mr;
|
|
|
|
struct {
|
|
|
|
struct osmo_fsm_inst *dl_amr_fsm;
|
|
|
|
/* TCH cache */
|
|
|
|
uint8_t cache[20];
|
|
|
|
/* FACCH cache */
|
|
|
|
uint8_t facch[GSM_MACBLOCK_LEN];
|
|
|
|
uint8_t len;
|
|
|
|
uint32_t fn;
|
|
|
|
bool is_update;
|
|
|
|
/* set for each SID frame to detect talkspurt for codecs
|
|
|
|
without explicit ONSET event */
|
|
|
|
bool ul_sid;
|
|
|
|
/* indicates if DTXd was active during DL measurement
|
|
|
|
period */
|
|
|
|
bool dl_active;
|
|
|
|
/* last UL SPEECH resume flag */
|
|
|
|
bool is_speech_resume;
|
|
|
|
} dtx;
|
|
|
|
uint8_t last_cmr;
|
|
|
|
uint32_t last_fn;
|
|
|
|
} tch;
|
|
|
|
|
|
|
|
/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
|
|
|
|
int16_t ms_t_offs;
|
|
|
|
/* 3GPP TS 45.010 § 1.2 round trip propagation delay (in symbols) or -1 */
|
|
|
|
int16_t p_offs;
|
|
|
|
|
|
|
|
/* BTS-side ciphering state (rx only, bi-directional, ...) */
|
|
|
|
uint8_t ciph_state;
|
|
|
|
uint8_t ciph_ns;
|
|
|
|
uint8_t loopback;
|
|
|
|
struct {
|
|
|
|
uint8_t active;
|
|
|
|
uint8_t ref;
|
|
|
|
/* T3105: PHYS INF retransmission */
|
|
|
|
struct osmo_timer_list t3105;
|
|
|
|
/* counts up to Ny1 */
|
|
|
|
unsigned int phys_info_count;
|
|
|
|
} ho;
|
|
|
|
/* S counter for link loss */
|
|
|
|
int s;
|
|
|
|
/* Kind of the release/activation. E.g. RSL or PCU */
|
|
|
|
int rel_act_kind;
|
|
|
|
/* RTP header Marker bit to indicate beginning of speech after pause */
|
|
|
|
bool rtp_tx_marker;
|
|
|
|
/* power handling */
|
|
|
|
struct {
|
|
|
|
uint8_t current;
|
|
|
|
uint8_t max;
|
|
|
|
bool fixed;
|
|
|
|
} ms_power_ctrl;
|
|
|
|
|
|
|
|
/* BTS power reduction (in dB) */
|
|
|
|
uint8_t bs_power_red;
|
|
|
|
|
|
|
|
struct msgb *pending_rel_ind_msg;
|
|
|
|
|
|
|
|
/* ECU (Error Concealment Unit) state */
|
|
|
|
struct osmo_ecu_state *ecu_state;
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline uint8_t lchan_get_ta(const struct gsm_lchan *lchan)
|
|
|
|
{
|
|
|
|
return lchan->meas.l1_info[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
extern const struct value_string lchan_ciph_state_names[];
|
|
|
|
static inline const char *lchan_ciph_state_name(uint8_t state) {
|
|
|
|
return get_value_string(lchan_ciph_state_names, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
enum gsm_bts_trx_ts_flags {
|
|
|
|
TS_F_PDCH_ACTIVE = 0x1000,
|
|
|
|
TS_F_PDCH_ACT_PENDING = 0x2000,
|
|
|
|
TS_F_PDCH_DEACT_PENDING = 0x4000,
|
|
|
|
TS_F_PDCH_PENDING_MASK = 0x6000 /*<
|
|
|
|
TS_F_PDCH_ACT_PENDING | TS_F_PDCH_DEACT_PENDING */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* One Timeslot in a TRX */
|
|
|
|
struct gsm_bts_trx_ts {
|
|
|
|
struct gsm_bts_trx *trx;
|
|
|
|
/* number of this timeslot at the TRX */
|
|
|
|
uint8_t nr;
|
|
|
|
|
|
|
|
enum gsm_phys_chan_config pchan;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
enum gsm_phys_chan_config pchan_is;
|
|
|
|
enum gsm_phys_chan_config pchan_want;
|
|
|
|
struct msgb *pending_chan_activ;
|
|
|
|
} dyn;
|
|
|
|
|
|
|
|
unsigned int flags;
|
|
|
|
struct gsm_abis_mo mo;
|
|
|
|
struct tlv_parsed nm_attr;
|
|
|
|
uint8_t nm_chan_comb;
|
|
|
|
int tsc; /* -1 == use BTS TSC */
|
|
|
|
|
|
|
|
struct {
|
|
|
|
/* Parameters below are configured by VTY */
|
|
|
|
int enabled;
|
|
|
|
uint8_t maio;
|
|
|
|
uint8_t hsn;
|
|
|
|
struct bitvec arfcns;
|
|
|
|
uint8_t arfcns_data[1024/8];
|
|
|
|
/* This is the pre-computed MA for channel assignments */
|
|
|
|
struct bitvec ma;
|
|
|
|
uint8_t ma_len; /* part of ma_data that is used */
|
|
|
|
uint8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */
|
|
|
|
} hopping;
|
|
|
|
|
|
|
|
struct gsm_lchan lchan[TS_MAX_LCHAN];
|
|
|
|
};
|
|
|
|
|
|
|
|
/* One TRX in a BTS */
|
|
|
|
struct gsm_bts_trx {
|
|
|
|
/* list header in bts->trx_list */
|
|
|
|
struct llist_head list;
|
|
|
|
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
/* number of this TRX in the BTS */
|
|
|
|
uint8_t nr;
|
|
|
|
/* human readable name / description */
|
|
|
|
char *description;
|
|
|
|
/* how do we talk RSL with this TRX? */
|
|
|
|
uint8_t rsl_tei;
|
|
|
|
struct e1inp_sign_link *rsl_link;
|
|
|
|
|
|
|
|
/* Some BTS (specifically Ericsson RBS) have a per-TRX OML Link */
|
|
|
|
struct e1inp_sign_link *oml_link;
|
|
|
|
|
|
|
|
struct gsm_abis_mo mo;
|
|
|
|
struct tlv_parsed nm_attr;
|
|
|
|
struct {
|
|
|
|
struct gsm_abis_mo mo;
|
|
|
|
} bb_transc;
|
|
|
|
|
|
|
|
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 */
|
|
|
|
|
|
|
|
|
|
|
|
struct trx_power_params power_params;
|
|
|
|
bool ms_pwr_ctl_soft; /* is power control loop done by osmocom software? */
|
|
|
|
|
|
|
|
struct {
|
|
|
|
void *l1h;
|
|
|
|
} role_bts;
|
|
|
|
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
unsigned int test_state;
|
|
|
|
uint8_t test_nr;
|
|
|
|
struct rxlev_stats rxlev_stat;
|
|
|
|
} ipaccess;
|
|
|
|
};
|
|
|
|
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
|
|
|
};
|
|
|
|
|
|
|
|
#define GSM_BTS_SI2Q(bts, i) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
|
|
|
|
#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
|
|
|
|
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
|
|
|
|
#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0])
|
|
|
|
|
|
|
|
enum gsm_bts_type_variant {
|
|
|
|
BTS_UNKNOWN,
|
|
|
|
BTS_OSMO_LITECELL15,
|
|
|
|
BTS_OSMO_OC2G,
|
|
|
|
BTS_OSMO_OCTPHY,
|
|
|
|
BTS_OSMO_SYSMO,
|
|
|
|
BTS_OSMO_TRX,
|
|
|
|
BTS_OSMO_VIRTUAL,
|
|
|
|
BTS_OSMO_OMLDUMMY,
|
|
|
|
_NUM_BTS_VARIANT
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Used by OML layer for BTS Attribute reporting */
|
|
|
|
enum bts_attribute {
|
|
|
|
BTS_TYPE_VARIANT,
|
|
|
|
BTS_SUB_MODEL,
|
|
|
|
TRX_PHY_VERSION,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* BTS implementation flags (internal use, not exposed via OML) */
|
|
|
|
#define bts_internal_flag_get(bts, flag) \
|
|
|
|
((bts->flags & (typeof(bts->flags)) flag) != 0)
|
|
|
|
#define bts_internal_flag_set(bts, flag) \
|
|
|
|
bts->flags |= (typeof(bts->flags)) flag
|
|
|
|
|
|
|
|
/* TODO: add a brief description of this flag */
|
|
|
|
#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP (1 << 0)
|
|
|
|
/* When this flag is set then the measurement data is included in
|
|
|
|
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
|
|
|
|
* measurement data is passed using a separate MPH INFO MEAS IND.
|
|
|
|
* (See also ticket: OS#2977) */
|
|
|
|
#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB (1 << 1)
|
|
|
|
|
|
|
|
extern const struct value_string bts_impl_flag_desc[];
|
|
|
|
|
|
|
|
struct gsm_bts_gprs_nsvc {
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
/* data read via VTY config file, to configure the BTS
|
|
|
|
* via OML from BSC */
|
|
|
|
int id;
|
|
|
|
uint16_t nsvci;
|
|
|
|
uint16_t local_port; /* on the BTS */
|
|
|
|
uint16_t remote_port; /* on the SGSN */
|
|
|
|
uint32_t remote_ip; /* on the SGSN */
|
|
|
|
|
|
|
|
struct gsm_abis_mo mo;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum gprs_rlc_par {
|
|
|
|
RLC_T3142,
|
|
|
|
RLC_T3169,
|
|
|
|
RLC_T3191,
|
|
|
|
RLC_T3193,
|
|
|
|
RLC_T3195,
|
|
|
|
RLC_N3101,
|
|
|
|
RLC_N3103,
|
|
|
|
RLC_N3105,
|
|
|
|
CV_COUNTDOWN,
|
|
|
|
T_DL_TBF_EXT, /* ms */
|
|
|
|
T_UL_TBF_EXT, /* ms */
|
|
|
|
_NUM_RLC_PAR
|
|
|
|
};
|
|
|
|
|
|
|
|
enum gprs_cs {
|
|
|
|
GPRS_CS1,
|
|
|
|
GPRS_CS2,
|
|
|
|
GPRS_CS3,
|
|
|
|
GPRS_CS4,
|
|
|
|
GPRS_MCS1,
|
|
|
|
GPRS_MCS2,
|
|
|
|
GPRS_MCS3,
|
|
|
|
GPRS_MCS4,
|
|
|
|
GPRS_MCS5,
|
|
|
|
GPRS_MCS6,
|
|
|
|
GPRS_MCS7,
|
|
|
|
GPRS_MCS8,
|
|
|
|
GPRS_MCS9,
|
|
|
|
_NUM_GRPS_CS
|
|
|
|
};
|
|
|
|
|
|
|
|
struct gprs_rlc_cfg {
|
|
|
|
uint16_t parameter[_NUM_RLC_PAR];
|
|
|
|
struct {
|
|
|
|
uint16_t repeat_time; /* ms */
|
|
|
|
uint8_t repeat_count;
|
|
|
|
} paging;
|
|
|
|
uint32_t cs_mask; /* bitmask of gprs_cs */
|
|
|
|
uint8_t initial_cs;
|
|
|
|
uint8_t initial_mcs;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct bts_smscb_state {
|
|
|
|
struct llist_head queue; /* list of struct smscb_msg */
|
|
|
|
int queue_len;
|
|
|
|
struct rate_ctr_group *ctrs;
|
|
|
|
struct smscb_msg *cur_msg; /* current SMS-CB */
|
|
|
|
struct smscb_msg *default_msg; /* default broadcast message; NULL if none */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* The amount of time within which a sudden disconnect of a newly established
|
|
|
|
* OML connection will cause a special warning to be logged. */
|
|
|
|
#define OSMO_BTS_OML_CONN_EARLY_DISCONNECT 10 /* in seconds */
|
|
|
|
|
|
|
|
/* One BTS */
|
|
|
|
struct gsm_bts {
|
|
|
|
/* list header in net->bts_list */
|
|
|
|
struct llist_head list;
|
|
|
|
|
|
|
|
/* number of the BTS in network */
|
|
|
|
uint8_t nr;
|
|
|
|
/* human readable name / description */
|
|
|
|
char *description;
|
|
|
|
/* Cell Identity */
|
|
|
|
uint16_t cell_identity;
|
|
|
|
/* location area code of this BTS */
|
|
|
|
uint16_t location_area_code;
|
|
|
|
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
|
|
|
|
* which is used as TSC for the CCCH */
|
|
|
|
uint8_t bsic;
|
|
|
|
/* type of BTS */
|
|
|
|
enum gsm_bts_type_variant variant;
|
|
|
|
enum gsm_band band;
|
|
|
|
char version[MAX_VERSION_LENGTH];
|
|
|
|
char sub_model[MAX_VERSION_LENGTH];
|
|
|
|
|
|
|
|
/* public features of a given BTS (set/reported via OML) */
|
|
|
|
struct bitvec *features;
|
|
|
|
/* implementation flags of a given BTS (not exposed via OML) */
|
|
|
|
uint16_t flags;
|
|
|
|
|
|
|
|
/* Connected PCU version (if any) */
|
|
|
|
char pcu_version[MAX_VERSION_LENGTH];
|
|
|
|
|
|
|
|
/* maximum Tx power that the MS is permitted to use in this cell */
|
|
|
|
int ms_max_power;
|
|
|
|
|
|
|
|
/* how do we talk OML with this TRX? */
|
|
|
|
struct e1inp_sign_link *oml_link;
|
|
|
|
struct timespec oml_conn_established_timestamp;
|
|
|
|
|
|
|
|
/* Abis network management O&M handle */
|
|
|
|
struct gsm_abis_mo mo;
|
|
|
|
|
|
|
|
/* number of this BTS on given E1 link */
|
|
|
|
uint8_t bts_nr;
|
|
|
|
|
|
|
|
/* DTX features of this BTS */
|
|
|
|
bool dtxd;
|
|
|
|
|
|
|
|
/* CCCH is on C0 */
|
|
|
|
struct gsm_bts_trx *c0;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
struct gsm_abis_mo mo;
|
|
|
|
} site_mgr;
|
|
|
|
|
|
|
|
/* bitmask of all SI that are present/valid in si_buf */
|
|
|
|
uint32_t si_valid;
|
|
|
|
/* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
|
|
|
|
uint8_t si2q_index; /* distinguish individual SI2quater messages */
|
|
|
|
uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
|
|
|
|
/* buffers where we put the pre-computed SI */
|
|
|
|
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
|
|
|
|
/* offsets used while generating SI2quater */
|
|
|
|
size_t e_offset;
|
|
|
|
size_t u_offset;
|
|
|
|
/* decoded SI3 rest octets - *unmodified* as received from BSC */
|
|
|
|
struct osmo_gsm48_si_ro_info si3_ro_decoded;
|
|
|
|
/* is SI3 GPRS Indicator currently disabled due to lack of PCU connection? */
|
|
|
|
bool si3_gprs_ind_disabled;
|
|
|
|
|
|
|
|
/* ip.access Unit ID's have Site/BTS/TRX layout */
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
uint16_t site_id;
|
|
|
|
uint16_t bts_id;
|
|
|
|
uint32_t flags;
|
|
|
|
uint32_t rsl_ip;
|
|
|
|
} ip_access;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Not entirely sure how ip.access specific this is */
|
|
|
|
struct {
|
|
|
|
struct {
|
|
|
|
struct gsm_abis_mo mo;
|
|
|
|
uint16_t nsei;
|
|
|
|
uint8_t timer[7];
|
|
|
|
} nse;
|
|
|
|
struct {
|
|
|
|
struct gsm_abis_mo mo;
|
|
|
|
uint16_t bvci;
|
|
|
|
uint8_t timer[11];
|
|
|
|
struct gprs_rlc_cfg rlc_cfg;
|
|
|
|
} cell;
|
|
|
|
struct gsm_bts_gprs_nsvc nsvc[2];
|
|
|
|
uint8_t rac;
|
|
|
|
} gprs;
|
|
|
|
|
|
|
|
/* transceivers */
|
|
|
|
int num_trx;
|
|
|
|
struct llist_head trx_list;
|
|
|
|
|
|
|
|
struct rate_ctr_group *ctrs;
|
|
|
|
bool supp_meas_toa256;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
/* Interference Boundaries for OML */
|
|
|
|
int16_t boundary[6];
|
|
|
|
uint8_t intave;
|
|
|
|
} interference;
|
|
|
|
unsigned int t200_ms[7];
|
|
|
|
unsigned int t3105_ms;
|
|
|
|
struct {
|
|
|
|
uint8_t overload_period;
|
|
|
|
struct {
|
|
|
|
/* Input parameters from OML */
|
|
|
|
uint8_t load_ind_thresh; /* percent */
|
|
|
|
uint8_t load_ind_period; /* seconds */
|
|
|
|
/* Internal data */
|
|
|
|
struct osmo_timer_list timer;
|
|
|
|
unsigned int pch_total;
|
|
|
|
unsigned int pch_used;
|
|
|
|
} ccch;
|
|
|
|
struct {
|
|
|
|
/* Input parameters from OML */
|
|
|
|
int16_t busy_thresh; /* in dBm */
|
|
|
|
uint16_t averaging_slots;
|
|
|
|
/* Internal data */
|
|
|
|
unsigned int total; /* total nr */
|
|
|
|
unsigned int busy; /* above busy_thresh */
|
|
|
|
unsigned int access; /* access bursts */
|
|
|
|
} rach;
|
|
|
|
} load;
|
|
|
|
uint8_t ny1;
|
|
|
|
uint8_t max_ta;
|
|
|
|
|
|
|
|
/* AGCH queuing */
|
|
|
|
struct {
|
|
|
|
struct llist_head queue;
|
|
|
|
int length;
|
|
|
|
int max_length;
|
|
|
|
|
|
|
|
int thresh_level; /* Cleanup threshold in percent of max len */
|
|
|
|
int low_level; /* Low water mark in percent of max len */
|
|
|
|
int high_level; /* High water mark in percent of max len */
|
|
|
|
|
|
|
|
/* TODO: Use a rate counter group instead */
|
|
|
|
uint64_t dropped_msgs;
|
|
|
|
uint64_t merged_msgs;
|
|
|
|
uint64_t rejected_msgs;
|
|
|
|
uint64_t agch_msgs;
|
|
|
|
uint64_t pch_msgs;
|
|
|
|
} agch_queue;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
uint8_t *prim_notif; /* ETWS primary notification (NULL if none) */
|
|
|
|
ssize_t prim_notif_len; /* Length of prim_notif; expected 56 bytes */
|
|
|
|
uint8_t page_size;
|
|
|
|
uint8_t num_pages; /* total number of pages */
|
|
|
|
uint8_t next_page; /* next page number to be sent */
|
|
|
|
bool pni; /* Primary Notification Identifier */
|
|
|
|
} etws;
|
|
|
|
|
|
|
|
struct paging_state *paging_state;
|
|
|
|
char *bsc_oml_host;
|
|
|
|
struct llist_head oml_queue;
|
|
|
|
unsigned int rtp_jitter_buf_ms;
|
|
|
|
bool rtp_jitter_adaptive;
|
|
|
|
|
|
|
|
uint16_t rtp_port_range_start;
|
|
|
|
uint16_t rtp_port_range_end;
|
|
|
|
uint16_t rtp_port_range_next;
|
|
|
|
int rtp_ip_dscp;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
|
|
|
|
} support;
|
|
|
|
struct {
|
|
|
|
uint8_t tc4_ctr;
|
|
|
|
} si;
|
|
|
|
struct gsm_time gsm_time;
|
|
|
|
/* frame number statistics (FN in PH-RTS.ind vs. PH-DATA.ind */
|
|
|
|
struct {
|
|
|
|
int32_t min; /* minimum observed */
|
|
|
|
int32_t max; /* maximum observed */
|
|
|
|
int32_t avg256; /* accumulator */
|
|
|
|
uint32_t avg_count; /* number of samples accumulated in avg256 */
|
|
|
|
uint32_t avg_window; /* number of averages in avg_count */
|
|
|
|
} fn_stats;
|
|
|
|
/* Radio Link Timeout counter. -1 disables timeout for
|
|
|
|
* lab/measurement purpose */
|
|
|
|
int radio_link_timeout;
|
|
|
|
|
|
|
|
int ul_power_target; /* Uplink Rx power target */
|
|
|
|
|
|
|
|
/* used by the sysmoBTS to adjust band */
|
|
|
|
uint8_t auto_band;
|
|
|
|
|
|
|
|
/* State for SMSCB (Cell Broadcast) for BASIC and EXTENDED channel */
|
|
|
|
struct bts_smscb_state smscb_basic;
|
|
|
|
struct bts_smscb_state smscb_extended;
|
|
|
|
int smscb_queue_tgt_len; /* ideal/target queue length */
|
|
|
|
int smscb_queue_max_len; /* maximum queue length */
|
|
|
|
int smscb_queue_hyst; /* hysteresis for CBCH load indications */
|
|
|
|
|
|
|
|
int16_t min_qual_rach; /* minimum link quality (in centiBels) for Access Bursts */
|
|
|
|
int16_t min_qual_norm; /* minimum link quality (in centiBels) for Normal Bursts */
|
|
|
|
uint16_t max_ber10k_rach; /* Maximum permitted RACH BER in 0.01% */
|
|
|
|
|
|
|
|
struct {
|
|
|
|
char *sock_path;
|
|
|
|
} pcu;
|
|
|
|
|
2020-06-17 15:23:57 +00:00
|
|
|
struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */
|
|
|
|
struct osmo_tdef *T_defs; /* Timer defines */
|
|
|
|
|
2020-06-17 15:48:16 +00:00
|
|
|
void *model_priv; /* Allocated by bts_model, contains model specific data pointer */
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num);
|
|
|
|
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
|
|
|
|
|
|
|
|
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
|
|
|
|
struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num);
|
|
|
|
|
|
|
|
enum bts_attribute str2btsattr(const char *s);
|
|
|
|
const char *btsatttr2str(enum bts_attribute v);
|
|
|
|
|
|
|
|
enum gsm_bts_type_variant str2btsvariant(const char *arg);
|
|
|
|
const char *btsvariant2str(enum gsm_bts_type_variant v);
|
|
|
|
|
|
|
|
extern const struct value_string gsm_pchant_names[13];
|
|
|
|
extern const struct value_string gsm_pchant_descs[13];
|
|
|
|
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
|
|
|
|
enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
|
|
|
|
const char *gsm_lchant_name(enum gsm_chan_t c);
|
|
|
|
char *gsm_trx_name(const struct gsm_bts_trx *trx);
|
|
|
|
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);
|
|
|
|
char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts);
|
|
|
|
char *gsm_lchan_name_compute(const struct gsm_lchan *lchan);
|
|
|
|
const char *gsm_lchans_name(enum gsm_lchan_state s);
|
|
|
|
|
|
|
|
static inline char *gsm_lchan_name(const struct gsm_lchan *lchan)
|
|
|
|
{
|
|
|
|
return lchan->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
|
|
|
|
|
|
|
|
struct gsm_abis_mo *
|
|
|
|
gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
|
|
|
|
const struct abis_om_obj_inst *obj_inst);
|
|
|
|
|
|
|
|
struct gsm_nm_state *
|
|
|
|
gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
|
|
|
|
const struct abis_om_obj_inst *obj_inst);
|
|
|
|
void *
|
|
|
|
gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
|
|
|
|
const struct abis_om_obj_inst *obj_inst);
|
|
|
|
|
|
|
|
uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan);
|
|
|
|
uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
|
|
|
|
enum gsm_phys_chan_config as_pchan);
|
|
|
|
|
|
|
|
/* return the gsm_lchan for the CBCH (if it exists at all) */
|
|
|
|
struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
|
|
|
|
|
|
|
|
#define BSIC2BCC(bsic) ((bsic) & 0x3)
|
|
|
|
|
|
|
|
static inline uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)
|
|
|
|
{
|
|
|
|
if (ts->tsc != -1)
|
|
|
|
return ts->tsc;
|
|
|
|
else
|
|
|
|
return ts->trx->bts->bsic & 7;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
|
|
|
|
int *rc);
|
|
|
|
|
|
|
|
enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts);
|
|
|
|
uint8_t ts_subslots(struct gsm_bts_trx_ts *ts);
|
|
|
|
bool ts_is_tch(struct gsm_bts_trx_ts *ts);
|
|
|
|
const char *gsm_trx_unit_id(struct gsm_bts_trx *trx);
|
|
|
|
|
|
|
|
int lchan2ecu_codec(const struct gsm_lchan *lchan);
|
2011-06-27 09:25:35 +00:00
|
|
|
|
2012-04-16 18:07:56 +00:00
|
|
|
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state);
|
2016-07-16 22:32:07 +00:00
|
|
|
int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts,
|
|
|
|
enum gsm_phys_chan_config pchan);
|
2012-04-16 18:07:56 +00:00
|
|
|
|
2012-12-26 17:55:54 +00:00
|
|
|
/* cipher code */
|
|
|
|
#define CIPHER_A5(x) (1 << (x-1))
|
|
|
|
|
2018-03-17 11:22:40 +00:00
|
|
|
int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher);
|
2012-12-26 17:55:54 +00:00
|
|
|
|
2016-08-09 18:15:09 +00:00
|
|
|
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);
|
2012-12-26 17:55:54 +00:00
|
|
|
|
2018-01-25 17:59:42 +00:00
|
|
|
int bts_model_check_cm_mode(enum gsm_phys_chan_config pchan, enum gsm48_chan_mode cm);
|
|
|
|
|
2011-06-27 09:25:35 +00:00
|
|
|
#endif /* _GSM_DATA_H */
|