fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/27758 )
Change subject: osmo-bts-trx: use C/I in the AMR link adaptation loop ......................................................................
osmo-bts-trx: use C/I in the AMR link adaptation loop
Change-Id: Ide84bf864f56020c0265cfb9731615d4f7bad7f5 Related: SYS#5917, OS#4984 --- M include/osmo-bts/scheduler.h M src/common/scheduler.c M src/osmo-bts-trx/amr_loop.c M src/osmo-bts-trx/amr_loop.h M src/osmo-bts-trx/sched_lchan_tchf.c M src/osmo-bts-trx/sched_lchan_tchh.c 6 files changed, 48 insertions(+), 49 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/58/27758/1
diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h index e39315f..eab904c 100644 --- a/include/osmo-bts/scheduler.h +++ b/include/osmo-bts/scheduler.h @@ -114,8 +114,8 @@ /* AMR */ uint8_t codec[4]; /* 4 possible codecs for amr */ int codecs; /* number of possible codecs */ - float ber_sum; /* sum of bit error rates */ - int ber_num; /* number of bit error rates */ + int lqual_cb_sum; /* sum of link quality samples (in cB) */ + int lqual_cb_num; /* number of link quality samples */ uint8_t ul_ft; /* current uplink FT index */ uint8_t dl_ft; /* current downlink FT index */ uint8_t ul_cmr; /* current uplink CMR index */ diff --git a/src/common/scheduler.c b/src/common/scheduler.c index 96189ef..8ec9ccf 100644 --- a/src/common/scheduler.c +++ b/src/common/scheduler.c @@ -1185,8 +1185,8 @@ chan_state->dl_ft = initial_id; chan_state->ul_cmr = initial_id; chan_state->dl_cmr = initial_id; - chan_state->ber_sum = 0; - chan_state->ber_num = 0; + chan_state->lqual_cb_sum = 0; + chan_state->lqual_cb_num = 0; } rc = 0; } diff --git a/src/osmo-bts-trx/amr_loop.c b/src/osmo-bts-trx/amr_loop.c index afb9c37..1d40bb5 100644 --- a/src/osmo-bts-trx/amr_loop.c +++ b/src/osmo-bts-trx/amr_loop.c @@ -32,16 +32,11 @@ #include "amr_loop.h"
void trx_loop_amr_input(struct l1sched_chan_state *chan_state, - int n_errors, int n_bits_total) + const struct l1sched_meas_set *meas_set) { - struct gsm_lchan *lchan = chan_state->lchan; - float ber; - - /* calculate BER (Bit Error Ratio) */ - if (n_bits_total == 0) - ber = 1.0; /* 100% BER */ - else - ber = (float) n_errors / (float) n_bits_total; + const struct gsm_lchan *lchan = chan_state->lchan; + const struct amr_multirate_conf *cfg = &lchan->tch.amr_mr; + int lqual_cb = meas_set->ci_cb; /* cB (centibel) */
/* check if loop is enabled */ if (!chan_state->amr_loop) @@ -53,46 +48,49 @@
/* count bit errors */ if (lchan->type == GSM_LCHAN_TCH_H) { - chan_state->ber_num += 2; - chan_state->ber_sum += (ber + ber); + chan_state->lqual_cb_num += 2; + chan_state->lqual_cb_sum += (lqual_cb + lqual_cb); } else { - chan_state->ber_num++; - chan_state->ber_sum += ber; + chan_state->lqual_cb_num++; + chan_state->lqual_cb_sum += lqual_cb; }
/* count frames */ - if (chan_state->ber_num < 48) + if (chan_state->lqual_cb_num < 48) return;
- /* calculate average (reuse ber variable) */ - ber = chan_state->ber_sum / chan_state->ber_num; + /* calculate average (reuse lqual_cb variable) */ + lqual_cb = chan_state->lqual_cb_sum / chan_state->lqual_cb_num;
- /* reset bit errors */ - chan_state->ber_num = 0; - chan_state->ber_sum = 0; + LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "AVG link quality (C/I) is %d cB, " + "codec mode=%d\n", lqual_cb, chan_state->ul_ft);
- LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Current bit error rate (BER) %.6f " - "codec id %d\n", ber, chan_state->ul_ft); + /* reset the link quality measurements */ + chan_state->lqual_cb_num = 0; + chan_state->lqual_cb_sum = 0;
- /* degrade */ if (chan_state->dl_cmr > 0) { - /* degrade, if ber is above threshold FIXME: C/I */ - if (ber > - lchan->tch.amr_mr.bts_mode[chan_state->dl_cmr-1].threshold) { - LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Degrading due to BER %.6f " - "from codec id %d to %d\n", ber, chan_state->dl_cmr, - chan_state->dl_cmr - 1); + const int thresh_lower_cb = cfg->bts_mode[chan_state->dl_cmr - 1].threshold / 2 * 10; + + /* Degrade if the link quality is below THR_MX_Dn(i - 1) */ + if (lqual_cb < thresh_lower_cb) { + LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Degrading AMR codec mode: " + "%d -> %d due to link quality %d cB < THR_MX_Dn=%d cB\n", + chan_state->dl_cmr, chan_state->dl_cmr - 1, + lqual_cb, thresh_lower_cb); chan_state->dl_cmr--; } } else if (chan_state->dl_cmr < chan_state->codecs - 1) { - /* degrade, if ber is above threshold FIXME: C/I*/ - if (ber < - lchan->tch.amr_mr.bts_mode[chan_state->dl_cmr].threshold - - lchan->tch.amr_mr.bts_mode[chan_state->dl_cmr].hysteresis) { - LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Upgrading due to BER %.6f " - "from codec id %d to %d\n", ber, chan_state->dl_cmr, - chan_state->dl_cmr + 1); - chan_state->dl_cmr++; + const int thresh_upper_cb = cfg->bts_mode[chan_state->dl_cmr].threshold / 2 * 10 + + cfg->bts_mode[chan_state->dl_cmr].hysteresis / 2 * 10; + + /* Upgrade if the link quality is above THR_MX_Up(i) */ + if (lqual_cb > thresh_upper_cb) { + LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Upgrading AMR codec mode: " + "%d -> %d due to link quality %d cB > THR_MX_Up=%d cB\n", + chan_state->dl_cmr, chan_state->dl_cmr + 1, + lqual_cb, thresh_upper_cb); + chan_state->dl_cmr--; } } } @@ -107,9 +105,9 @@ if (!chan_state->amr_loop && loop) { chan_state->amr_loop = 1;
- /* reset bit errors */ - chan_state->ber_num = 0; - chan_state->ber_sum = 0; + /* reset the link quality measurements */ + chan_state->lqual_cb_num = 0; + chan_state->lqual_cb_sum = 0;
return; } diff --git a/src/osmo-bts-trx/amr_loop.h b/src/osmo-bts-trx/amr_loop.h index 85f73fd..efff76c 100644 --- a/src/osmo-bts-trx/amr_loop.h +++ b/src/osmo-bts-trx/amr_loop.h @@ -11,6 +11,6 @@ */
void trx_loop_amr_input(struct l1sched_chan_state *chan_state, - int n_errors, int n_bits_total); + const struct l1sched_meas_set *meas_set);
void trx_loop_amr_set(struct l1sched_chan_state *chan_state, int loop); diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c index 8ca0961..fb19dd2 100644 --- a/src/osmo-bts-trx/sched_lchan_tchf.c +++ b/src/osmo-bts-trx/sched_lchan_tchf.c @@ -197,8 +197,6 @@ break; }
- if (rc) - trx_loop_amr_input(chan_state, n_errors, n_bits_total); /* only good speech frames get rtp header */ if (rc != GSM_MACBLOCK_LEN && rc >= 4) { if (chan_state->amr_last_dtx == AMR_OTHER) { @@ -225,6 +223,9 @@ /* meas_avg.fn now contains TDMA frame number of the first burst */ fn_begin = meas_avg.fn;
+ if (tch_mode == GSM48_CMODE_SPEECH_AMR) + trx_loop_amr_input(chan_state, &meas_avg); + /* Check if the frame is bad */ if (rc < 0) { LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Received bad data (%u/%u)\n", diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c index e3ce600..1b4aa40 100644 --- a/src/osmo-bts-trx/sched_lchan_tchh.c +++ b/src/osmo-bts-trx/sched_lchan_tchh.c @@ -233,9 +233,6 @@ break; }
- if (rc) - trx_loop_amr_input(chan_state, n_errors, n_bits_total); - /* only good speech frames get rtp header */ if (rc != GSM_MACBLOCK_LEN && rc >= 4) { if (chan_state->amr_last_dtx == AMR_OTHER) { @@ -264,6 +261,9 @@ /* meas_avg.fn now contains TDMA frame number of the first burst */ fn_begin = meas_avg.fn;
+ if (tch_mode == GSM48_CMODE_SPEECH_AMR) + trx_loop_amr_input(chan_state, &meas_avg); + /* Check if the frame is bad */ if (rc < 0) { LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Received bad data (%u/%u)\n",