aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/gsm_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/gsm_data.c')
-rw-r--r--src/common/gsm_data.c259
1 files changed, 25 insertions, 234 deletions
diff --git a/src/common/gsm_data.c b/src/common/gsm_data.c
index 36a57115..44469589 100644
--- a/src/common/gsm_data.c
+++ b/src/common/gsm_data.c
@@ -40,6 +40,12 @@
#include <osmo-bts/bts_trx.h>
#include <osmo-bts/logging.h>
+struct osmo_tdef_group bts_tdef_groups[] = {
+ { .name = "bts", .tdefs = bts_T_defs, .desc = "BTS process timers" },
+ { .name = "abis", .tdefs = abis_T_defs, .desc = "Abis (RSL) related timers" },
+ {}
+};
+
const struct value_string gsm_pchant_names[13] = {
{ GSM_PCHAN_NONE, "NONE" },
{ GSM_PCHAN_CCCH, "CCCH" },
@@ -84,22 +90,6 @@ const char *gsm_lchant_name(enum gsm_chan_t c)
return get_value_string(gsm_chan_t_names, c);
}
-static const struct value_string lchan_s_names[] = {
- { LCHAN_S_NONE, "NONE" },
- { LCHAN_S_ACT_REQ, "ACTIVATION REQUESTED" },
- { LCHAN_S_ACTIVE, "ACTIVE" },
- { LCHAN_S_INACTIVE, "INACTIVE" },
- { LCHAN_S_REL_REQ, "RELEASE REQUESTED" },
- { LCHAN_S_REL_ERR, "RELEASE DUE ERROR" },
- { LCHAN_S_BROKEN, "BROKEN UNUSABLE" },
- { 0, NULL }
-};
-
-const char *gsm_lchans_name(enum gsm_lchan_state s)
-{
- return get_value_string(lchan_s_names, s);
-}
-
static char ts2str[255];
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts)
@@ -157,172 +147,6 @@ char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts)
return ts2str;
}
-void gsm_lchan_name_update(struct gsm_lchan *lchan)
-{
- const struct gsm_bts_trx_ts *ts = lchan->ts;
- const struct gsm_bts_trx *trx = ts->trx;
- char *name;
-
- name = talloc_asprintf(trx, "(" GSM_TS_NAME_FMT ",ss=%u)",
- GSM_TS_NAME_ARGS(ts), lchan->nr);
- if (lchan->name != NULL)
- talloc_free(lchan->name);
- lchan->name = name;
-}
-
-/* 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)
-{
- uint8_t cbits, chan_nr;
-
- OSMO_ASSERT(pchan != GSM_PCHAN_OSMO_DYN);
- OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH);
-
- switch (pchan) {
- case GSM_PCHAN_TCH_F:
- OSMO_ASSERT(lchan_nr == 0);
- cbits = ABIS_RSL_CHAN_NR_CBITS_Bm_ACCHs;
- break;
- case GSM_PCHAN_PDCH:
- OSMO_ASSERT(lchan_nr == 0);
- cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_PDCH;
- break;
- case GSM_PCHAN_TCH_H:
- OSMO_ASSERT(lchan_nr < 2);
- cbits = ABIS_RSL_CHAN_NR_CBITS_Lm_ACCHs(lchan_nr);
- break;
- case GSM_PCHAN_CCCH_SDCCH4:
- case GSM_PCHAN_CCCH_SDCCH4_CBCH:
- /*
- * As a special hack for BCCH, lchan_nr == 4 may be passed
- * here. This should never be sent in an RSL message.
- * See osmo-bts-xxx/oml.c:opstart_compl().
- */
- if (lchan_nr == CCCH_LCHAN)
- cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
- else {
- OSMO_ASSERT(lchan_nr < 4);
- cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(lchan_nr);
- }
- break;
- case GSM_PCHAN_SDCCH8_SACCH8C:
- case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
- OSMO_ASSERT(lchan_nr < 8);
- cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(lchan_nr);
- break;
- case GSM_PCHAN_CCCH:
- cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
- break;
- case GSM_PCHAN_NONE:
- LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",
- gsm_pchan_name(pchan));
- cbits = 0x00;
- break;
- default:
- LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",
- gsm_pchan_name(pchan), (int)pchan);
- /* OSMO_ASSERT(lchan_nr == 0);
- * FIXME: On octphy and litecell, we hit above assertion (see
- * Max's comment at https://gerrit.osmocom.org/589 ); disabled
- * for BTS until this is clarified; remove the #ifdef when it
- * is fixed. Tracked in OS#2906.
- */
-#pragma message "fix caller that passes lchan_nr != 0"
- cbits = 0x10;
- break;
- }
-
- chan_nr = (cbits << 3) | (ts_nr & 0x7);
-
- return chan_nr;
-}
-
-uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)
-{
- uint8_t chan_nr;
-
- switch (lchan->ts->pchan) {
- case GSM_PCHAN_OSMO_DYN:
- /* Return chan_nr reflecting the current TS pchan, either a standard TCH kind, or the
- * nonstandard value reflecting PDCH for Osmocom style dyn TS. */
- chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, lchan->ts->dyn.pchan_is);
- break;
- case GSM_PCHAN_TCH_F_PDCH:
- /* For ip.access style dyn TS, we always want to use the chan_nr as if it was TCH/F.
- * We're using custom PDCH ACT and DEACT messages that use the usual chan_nr values. */
- chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F);
- break;
- default:
- chan_nr = gsm_pchan2chan_nr(lchan->ts->pchan, lchan->ts->nr, lchan->nr);
- break;
- }
-
- /* VAMOS: if this lchan belongs to a shadow timeslot, we must reflect
- * this in the channel number. Convert it to Osmocom specific value. */
- if (lchan->ts->vamos.is_shadow)
- chan_nr |= RSL_CHAN_OSMO_VAMOS_MASK;
-
- return chan_nr;
-}
-
-uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
- enum gsm_phys_chan_config as_pchan)
-{
- if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN
- && as_pchan == GSM_PCHAN_PDCH)
- return RSL_CHAN_OSMO_PDCH | (lchan->ts->nr & ~RSL_CHAN_NR_MASK);
- return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr);
-}
-
-/* Called by the model specific code every 104 TDMA frames (SACCH period) */
-void gsm_lchan_interf_meas_push(struct gsm_lchan *lchan, int dbm)
-{
- const uint8_t meas_num = lchan->meas.interf_meas_num;
-
- if (meas_num >= ARRAY_SIZE(lchan->meas.interf_meas_dbm)) {
- LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Not enough room "
- "to store interference report (%ddBm)\n", dbm);
- return;
- }
-
- lchan->meas.interf_meas_dbm[meas_num] = dbm;
- lchan->meas.interf_meas_num++;
-}
-
-/* Called by the higher layers every Intave * 104 TDMA frames */
-int gsm_lchan_interf_meas_calc_band(struct gsm_lchan *lchan)
-{
- const uint8_t meas_num = lchan->meas.interf_meas_num;
- const struct gsm_bts *bts = lchan->ts->trx->bts;
- int b, meas_avg, meas_sum = 0;
-
- /* There must be at least one sample */
- if (meas_num == 0)
- return -EAGAIN;
-
- /* Calculate the sum of all collected samples (in -x dBm) */
- while (lchan->meas.interf_meas_num) {
- uint8_t i = --lchan->meas.interf_meas_num;
- meas_sum += lchan->meas.interf_meas_dbm[i];
- }
-
- /* Calculate the average of all collected samples */
- meas_avg = meas_sum / (int) meas_num;
-
- /* Determine the band using interference boundaries from BSC */
- for (b = 0; b < ARRAY_SIZE(bts->interference.boundary); b++) {
- if (meas_avg >= bts->interference.boundary[b])
- break; /* Current 'b' is the band value */
- }
-
- LOGPLCHAN(lchan, DL1C, LOGL_DEBUG,
- "Interference AVG: %ddBm (band %d, samples %u)\n",
- meas_avg, b, meas_num);
-
- return b;
-}
-
/* determine logical channel based on TRX and channel number IE */
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
int *rc)
@@ -466,61 +290,28 @@ bool ts_is_tch(const struct gsm_bts_trx_ts *ts)
return pchan_is_tch(ts_pchan(ts));
}
-const struct value_string lchan_ciph_state_names[] = {
- { LCHAN_CIPH_NONE, "NONE" },
- { LCHAN_CIPH_RX_REQ, "RX_REQ" },
- { LCHAN_CIPH_RX_CONF, "RX_CONF" },
- { LCHAN_CIPH_RXTX_REQ, "RXTX_REQ" },
- { LCHAN_CIPH_RX_CONF_TX_REQ, "RX_CONF_TX_REQ" },
- { LCHAN_CIPH_RXTX_CONF, "RXTX_CONF" },
- { 0, NULL }
-};
-
-/* determine the ECU codec constant for the codec used by given lchan */
-int lchan2ecu_codec(const struct gsm_lchan *lchan)
+bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)
{
- const struct gsm_bts_trx_ts *ts = lchan->ts;
-
- switch (lchan->tch_mode) {
- case GSM48_CMODE_SPEECH_V1:
- if (ts_pchan(ts) == GSM_PCHAN_TCH_H)
- return OSMO_ECU_CODEC_HR;
- else
- return OSMO_ECU_CODEC_FR;
- break;
- case GSM48_CMODE_SPEECH_EFR:
- return OSMO_ECU_CODEC_EFR;
- case GSM48_CMODE_SPEECH_AMR:
- return OSMO_ECU_CODEC_AMR;
+ switch (ts->pchan) {
+ case GSM_PCHAN_PDCH:
+ return true;
+ case GSM_PCHAN_TCH_F_PDCH:
+ return (ts->flags & TS_F_PDCH_ACTIVE)
+ && !(ts->flags & TS_F_PDCH_PENDING_MASK);
+ case GSM_PCHAN_OSMO_DYN:
+ return ts->dyn.pchan_is == GSM_PCHAN_PDCH
+ && ts->dyn.pchan_want == ts->dyn.pchan_is;
default:
- return -1;
+ return false;
}
}
-/* Default MS/BS Power Control parameters (see 3GPP TS 45.008, table A.1) */
-const struct gsm_power_ctrl_params power_ctrl_params_def = {
- /* Power increasing/reducing step size (optimal defaults) */
- .inc_step_size_db = 4, /* quickly increase MS/BS power */
- .red_step_size_db = 2, /* slowly decrease MS/BS power */
-
- /* RxLev measurement parameters */
- .rxlev_meas = {
- /* Thresholds for RxLev (see 3GPP TS 45.008, A.3.2.1) */
- .lower_thresh = 32, /* L_RXLEV_XX_P (-78 dBm) */
- .upper_thresh = 38, /* U_RXLEV_XX_P (-72 dBm) */
-
- /* NOTE: only Osmocom specific EWMA is supported */
- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA,
- .ewma.alpha = 50, /* Smoothing factor 50% */
- },
-
- /* RxQual measurement parameters */
- .rxqual_meas = {
- /* Thresholds for RxQual (see 3GPP TS 45.008, A.3.2.1) */
- .lower_thresh = 3, /* L_RXQUAL_XX_P (0.8% <= BER < 1.6%) */
- .upper_thresh = 0, /* U_RXQUAL_XX_P (BER < 0.2%) */
+void gsm_ts_release(struct gsm_bts_trx_ts *ts)
+{
+ unsigned int ln;
- /* FIXME: RxQual averaging is not yet implemented */
- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,
- },
-};
+ for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) {
+ struct gsm_lchan *lchan = &ts->lchan[ln];
+ gsm_lchan_release(lchan, LCHAN_REL_ACT_OML);
+ }
+}