#ifndef _GSM_DATA_H #define _GSM_DATA_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 */ #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 #define LOGPLCHAN(lchan, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_lchan_name(lchan), ## args) #define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args) struct gsm_network { struct llist_head bts_list; unsigned int num_bts; struct osmo_plmn_id plmn; struct pcu_sock_state *pcu_state; }; enum lchan_ciph_state { LCHAN_CIPH_NONE, LCHAN_CIPH_RX_REQ, LCHAN_CIPH_RX_CONF, LCHAN_CIPH_RXTX_REQ, LCHAN_CIPH_RX_CONF_TX_REQ, LCHAN_CIPH_RXTX_CONF, }; /* 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; struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */ struct osmo_tdef *T_defs; /* Timer defines */ 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); void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state); int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pchan); /* cipher code */ #define CIPHER_A5(x) (1 << (x-1)) int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher); bool ts_is_pdch(const struct gsm_bts_trx_ts *ts); int bts_model_check_cm_mode(enum gsm_phys_chan_config pchan, enum gsm48_chan_mode cm); #endif /* _GSM_DATA_H */