diff options
Diffstat (limited to 'src/common/gsm_data.c')
-rw-r--r-- | src/common/gsm_data.c | 405 |
1 files changed, 11 insertions, 394 deletions
diff --git a/src/common/gsm_data.c b/src/common/gsm_data.c index 89a740dd..2edeb4dc 100644 --- a/src/common/gsm_data.c +++ b/src/common/gsm_data.c @@ -90,21 +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_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) @@ -162,187 +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; -} - -static uint8_t _gsm_lchan2chan_nr(const struct gsm_lchan *lchan, bool rsl) -{ - 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, on RSL we 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. */ - if (rsl) - chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F); - else if (~lchan->ts->flags & TS_F_PDCH_ACTIVE) - chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F); - else - chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_PDCH); - 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_lchan2chan_nr(const struct gsm_lchan *lchan) -{ - return _gsm_lchan2chan_nr(lchan, false); -} - -uint8_t gsm_lchan2chan_nr_rsl(const struct gsm_lchan *lchan) -{ - return _gsm_lchan2chan_nr(lchan, true); -} - -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) @@ -486,205 +290,18 @@ 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 = { - - .ctrl_interval = 1, /* Trigger loop every second SACCH block. TS 45.008 sec 4.7.1 */ - - /* 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%) */ - - /* No averaging (filtering) by default. - * NOTE: only Osmocom specific EWMA is supported */ - .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, - }, - - /* C/I measurement parameters. - * Target C/I retrieved from "GSM/EDGE: Evolution and Performance" Table 10.3. - * Set lower and upper so that (lower + upper) / 2 is equal or slightly - * above the target. - */ - .ci_fr_meas = { /* FR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */ - .lower_thresh = 13, - .upper_thresh = 17, - - /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages - * out of LOWER_CMP_N averages are lower than L_CI_FR_XX_P */ - .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages - * out of UPPER_CMP_N averages are greater than L_CI_FR_XX_P */ - .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - - /* No averaging (filtering) by default */ - .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, - - /* Hreqave: the period over which an average is produced */ - .h_reqave = 4, /* TODO: investigate a reasonable default value */ - /* Hreqt: the number of averaged results maintained */ - .h_reqt = 6, /* TODO: investigate a reasonable default value */ - }, - .ci_hr_meas = { /* HR: Target C/I = 18 dB, Soft blocking threshold = 13 dB */ - .lower_thresh = 16, - .upper_thresh = 21, - - /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages - * out of LOWER_CMP_N averages are lower than L_CI_HR_XX_P */ - .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages - * out of UPPER_CMP_N averages are greater than L_CI_HR_XX_P */ - .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - - /* No averaging (filtering) by default */ - .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, - - /* Hreqave: the period over which an average is produced */ - .h_reqave = 4, /* TODO: investigate a reasonable default value */ - /* Hreqt: the number of averaged results maintained */ - .h_reqt = 6, /* TODO: investigate a reasonable default value */ - }, - .ci_amr_fr_meas = { /* AMR-FR: Target C/I = 9 dB, Soft blocking threshold = 4 dB */ - .lower_thresh = 7, - .upper_thresh = 11, - - /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages - * out of LOWER_CMP_N averages are lower than L_CI_AMR_FR_XX_P */ - .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages - * out of UPPER_CMP_N averages are greater than L_CI_AMR_FR_XX_P */ - .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - - /* No averaging (filtering) by default */ - .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, - - /* Hreqave: the period over which an average is produced */ - .h_reqave = 4, /* TODO: investigate a reasonable default value */ - /* Hreqt: the number of averaged results maintained */ - .h_reqt = 6, /* TODO: investigate a reasonable default value */ - }, - .ci_amr_hr_meas = { /* AMR-HR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */ - .lower_thresh = 13, - .upper_thresh = 17, - - /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages - * out of LOWER_CMP_N averages are lower than L_CI_AMR_HR_XX_P */ - .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages - * out of UPPER_CMP_N averages are greater than L_CI_AMR_HR_XX_P */ - .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - - /* No averaging (filtering) by default */ - .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, - - /* Hreqave: the period over which an average is produced */ - .h_reqave = 4, /* TODO: investigate a reasonable default value */ - /* Hreqt: the number of averaged results maintained */ - .h_reqt = 6, /* TODO: investigate a reasonable default value */ - }, - .ci_sdcch_meas = { /* SDCCH: Target C/I = 14 dB, Soft blocking threshold = 9 dB */ - .lower_thresh = 12, - .upper_thresh = 16, - - /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages - * out of LOWER_CMP_N averages are lower than L_CI_SDCCH_XX_P */ - .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages - * out of UPPER_CMP_N averages are greater than L_CI_SDCCH_XX_P */ - .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - - /* No averaging (filtering) by default */ - .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, - - /* Hreqave: the period over which an average is produced */ - .h_reqave = 4, /* TODO: investigate a reasonable default value */ - /* Hreqt: the number of averaged results maintained */ - .h_reqt = 6, /* TODO: investigate a reasonable default value */ - }, - .ci_gprs_meas = { /* GPRS: Target C/I = 20 dB, Soft blocking threshold = 15 dB */ - .lower_thresh = 18, - .upper_thresh = 24, - - /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages - * out of LOWER_CMP_N averages are lower than L_CI_GPRS_XX_P */ - .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ - /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages - * out of UPPER_CMP_N averages are greater than L_CI_GPRS_XX_P */ - .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ - - /* No averaging (filtering) by default */ - .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, - - /* Hreqave: the period over which an average is produced */ - .h_reqave = 4, /* TODO: investigate a reasonable default value */ - /* Hreqt: the number of averaged results maintained */ - .h_reqt = 6, /* TODO: investigate a reasonable default value */ - }, -}; - -void power_ctrl_params_def_reset(struct gsm_power_ctrl_params *params, bool is_bs_pwr) -{ - *params = power_ctrl_params_def; - if (!is_bs_pwr) - /* Trigger loop every fourth SACCH block (1.92s). TS 45.008 sec 4.7.1: */ - params->ctrl_interval = 2; -} |