aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmo-bts/gsm_data.h6
-rw-r--r--src/common/l1sap.c39
-rw-r--r--src/common/measurement.c31
-rw-r--r--tests/meas/meas_testcases.h2
4 files changed, 51 insertions, 27 deletions
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h
index e2a1ae96..08694266 100644
--- a/include/osmo-bts/gsm_data.h
+++ b/include/osmo-bts/gsm_data.h
@@ -105,8 +105,8 @@ struct bts_ul_meas {
uint16_t ber10k;
/* timing advance offset (in 1/256 bits) */
int16_t ta_offs_256bits;
- /* C/I ratio in dB */
- float c_i;
+ /* C/I ratio in cB */
+ int16_t c_i;
/* flags */
uint8_t is_sub:1;
/* RSSI in dBm * -1 */
@@ -339,6 +339,8 @@ struct gsm_lchan {
struct rsl_l1_info l1_info;
struct gsm_meas_rep_unidir ul_res;
int16_t ms_toa256;
+ int16_t ul_ci_cb_full;
+ int16_t ul_ci_cb_sub;
/* Frame number of the last measurement indication receceived */
uint32_t last_fn;
/* Osmocom extended measurement results, see LC_UL_M_F_EXTD_VALID */
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index a641dab1..40e818d2 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -681,6 +681,7 @@ static void process_l1sap_meas_data(struct gsm_bts_trx *trx,
uint8_t is_sub;
int16_t ta_offs_256bits;
uint16_t ber10k;
+ int16_t ci_cb;
const char *ind_name;
switch (ind_type) {
@@ -693,6 +694,7 @@ static void process_l1sap_meas_data(struct gsm_bts_trx *trx,
is_sub = info_meas_ind->is_sub;
ta_offs_256bits = info_meas_ind->ta_offs_256bits;
ber10k = info_meas_ind->ber10k;
+ ci_cb = info_meas_ind->c_i_cb;
ind_name = "MPH INFO";
break;
case PRIM_TCH:
@@ -705,6 +707,7 @@ static void process_l1sap_meas_data(struct gsm_bts_trx *trx,
is_sub = ph_tch_ind->is_sub;
ta_offs_256bits = ph_tch_ind->ta_offs_256bits;
ber10k = ph_tch_ind->ber10k;
+ ci_cb = ph_tch_ind->lqual_cb;
ind_name = "TCH";
break;
case PRIM_PH_DATA:
@@ -717,6 +720,7 @@ static void process_l1sap_meas_data(struct gsm_bts_trx *trx,
is_sub = ph_data_ind->is_sub;
ta_offs_256bits = ph_data_ind->ta_offs_256bits;
ber10k = ph_data_ind->ber10k;
+ ci_cb = ph_data_ind->lqual_cb;
ind_name = "DATA";
break;
default:
@@ -732,9 +736,9 @@ static void process_l1sap_meas_data(struct gsm_bts_trx *trx,
}
DEBUGPFN(DL1P, fn,
- "%s %s meas ind, ta_offs_256bits=%d, ber10k=%d, inv_rssi=%u\n",
+ "%s %s meas ind, ta_offs_256bits=%d, ber10k=%d, inv_rssi=%u, C/I=%d cB\n",
gsm_lchan_name(lchan), ind_name, ta_offs_256bits, ber10k,
- inv_rssi);
+ inv_rssi, ci_cb);
/* in the GPRS case we are not interested in measurement
* processing. The PCU will take care of it */
@@ -744,6 +748,7 @@ static void process_l1sap_meas_data(struct gsm_bts_trx *trx,
memset(&ulm, 0, sizeof(ulm));
ulm.ta_offs_256bits = ta_offs_256bits;
ulm.ber10k = ber10k;
+ ulm.c_i = ci_cb;
ulm.inv_rssi = inv_rssi;
ulm.is_sub = is_sub;
@@ -1526,11 +1531,11 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
uint8_t chan_nr, link_id;
uint8_t tn;
uint32_t fn;
- int8_t rssi;
enum osmo_ph_pres_info_type pr_info = data_ind->pdch_presence_info;
struct gsm_sacch_l1_hdr *l1_hdr;
+ int8_t ul_rssi;
+ int16_t ul_ci_cb;
- rssi = data_ind->rssi;
chan_nr = data_ind->chan_nr;
link_id = data_ind->link_id;
fn = data_ind->fn;
@@ -1578,7 +1583,7 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
/* PDTCH / PACCH frame handling */
pcu_tx_data_ind(&trx->ts[tn], PCU_IF_SAPI_PDTCH, fn, trx->arfcn,
- L1SAP_FN2MACBLOCK(fn), data, len, rssi, data_ind->ber10k,
+ L1SAP_FN2MACBLOCK(fn), data, len, data_ind->rssi, data_ind->ber10k,
data_ind->ta_offs_256bits/64, data_ind->lqual_cb);
return 0;
}
@@ -1606,7 +1611,15 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
radio_link_timeout(lchan, true);
lchan_ms_ta_ctrl(lchan, lchan->ta_ctrl.current, lchan->meas.ms_toa256);
- lchan_ms_pwr_ctrl(lchan, lchan->ms_power_ctrl.current, data_ind->rssi, data_ind->lqual_cb);
+ /* If DTx is active on Downlink, use the '-SUB', otherwise '-FULL': */
+ if (lchan->tch.dtx.dl_active) {
+ ul_rssi = rxlev2dbm(lchan->meas.ul_res.sub.rx_lev);
+ ul_ci_cb = lchan->meas.ul_ci_cb_full;
+ } else {
+ ul_rssi = rxlev2dbm(lchan->meas.ul_res.full.rx_lev);
+ ul_ci_cb = lchan->meas.ul_ci_cb_sub;
+ }
+ lchan_ms_pwr_ctrl(lchan, lchan->ms_power_ctrl.current, ul_rssi, ul_ci_cb);
}
return -EINVAL;
}
@@ -1616,7 +1629,6 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
handover_frame(lchan);
if (L1SAP_IS_LINK_SACCH(link_id)) {
- int8_t ul_rssi;
radio_link_timeout(lchan, false);
le = &lchan->lapdm_ch.lapdm_acch;
/* save the SACCH L1 header in the lchan struct for RSL MEAS RES */
@@ -1644,16 +1656,15 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
* feed the Control Loop with the measurements for the same
* period (the previous one), which is stored in lchan->meas(.ul_res): */
lchan_ms_ta_ctrl(lchan, l1_hdr->ta, lchan->meas.ms_toa256);
- /* FIXME: lchan_ms_pwr_ctrl() is currently being passed data_ind->lqual_cb, which is wrong because:
- * 1- It contains measurement data for 1 SACCH block only, not the average over the entire period
- * 2- It contains measurement data for *current* meas period, not *previous* one.
- */
/* If DTx is active on Downlink, use the '-SUB', otherwise '-FULL': */
- if (lchan->tch.dtx.dl_active)
+ if (lchan->tch.dtx.dl_active) {
ul_rssi = rxlev2dbm(lchan->meas.ul_res.sub.rx_lev);
- else
+ ul_ci_cb = lchan->meas.ul_ci_cb_full;
+ } else {
ul_rssi = rxlev2dbm(lchan->meas.ul_res.full.rx_lev);
- lchan_ms_pwr_ctrl(lchan, l1_hdr->ms_pwr, ul_rssi, data_ind->lqual_cb);
+ ul_ci_cb = lchan->meas.ul_ci_cb_sub;
+ }
+ lchan_ms_pwr_ctrl(lchan, l1_hdr->ms_pwr, ul_rssi, ul_ci_cb);
lchan_bs_pwr_ctrl(lchan, (const struct gsm48_hdr *) &data[5]);
} else
le = &lchan->lapdm_ch.lapdm_dcch;
diff --git a/src/common/measurement.c b/src/common/measurement.c
index a4cc6686..a1c91a9d 100644
--- a/src/common/measurement.c
+++ b/src/common/measurement.c
@@ -341,7 +341,7 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan,
if (!ulm->is_sub)
dest->is_sub = ts45008_83_is_sub(lchan, fn);
- DEBUGPFN(DMEAS, fn, "%s adding measurement (ber10k=%u, ta_offs=%d, ci=%0.2f, is_sub=%u, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
+ DEBUGPFN(DMEAS, fn, "%s adding measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, is_sub=%u, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
gsm_lchan_name(lchan), ulm->ber10k, ulm->ta_offs_256bits,
ulm->c_i, dest->is_sub, ulm->inv_rssi, lchan->meas.num_ul_meas,
fn_mod);
@@ -555,8 +555,10 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
struct gsm_meas_rep_unidir *mru;
uint32_t ber_full_sum = 0;
uint32_t irssi_full_sum = 0;
+ int32_t ci_full_sum = 0;
uint32_t ber_sub_sum = 0;
uint32_t irssi_sub_sum = 0;
+ int32_t ci_sub_sum = 0;
int32_t ta256b_sum = 0;
unsigned int num_meas_sub = 0;
unsigned int num_meas_sub_actual = 0;
@@ -624,11 +626,13 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
m = &lchan->meas.uplink[i + num_ul_meas_excess];
if (m->is_sub) {
irssi_sub_sum += m->inv_rssi;
+ ci_sub_sum += m->c_i;
num_meas_sub_actual++;
is_sub = true;
}
irssi_full_sum += m->inv_rssi;
ta256b_sum += m->ta_offs_256bits;
+ ci_full_sum += m->c_i;
num_ul_meas_actual++;
} else {
@@ -697,27 +701,32 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
else
irssi_full_sum = irssi_full_sum / num_ul_meas_actual;
- if (!num_ul_meas_actual)
+ if (!num_ul_meas_actual) {
ta256b_sum = lchan->meas.ms_toa256;
- else
+ ci_full_sum = lchan->meas.ul_ci_cb_full;
+ } else {
ta256b_sum = ta256b_sum / (signed)num_ul_meas_actual;
+ ci_full_sum = ci_full_sum / (signed)num_ul_meas_actual;
+ }
if (!num_meas_sub)
ber_sub_sum = MEASUREMENT_DUMMY_BER;
else
ber_sub_sum = ber_sub_sum / num_meas_sub;
- if (!num_meas_sub_actual)
+ if (!num_meas_sub_actual) {
irssi_sub_sum = MEASUREMENT_DUMMY_IRSSI;
- else
+ ci_sub_sum = lchan->meas.ul_ci_cb_sub;
+ } else {
irssi_sub_sum = irssi_sub_sum / num_meas_sub_actual;
+ ci_sub_sum = ci_sub_sum / (signed)num_meas_sub_actual;
+ }
LOGPLCHAN(lchan, DMEAS, LOGL_INFO,
- "Computed TA256(% 4d) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), "
- "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm)\n",
- ta256b_sum, ber_full_sum / 100, ber_full_sum % 100,
- irssi_full_sum, ber_sub_sum / 100, ber_sub_sum % 100,
- irssi_sub_sum);
+ "Computed TA256(% 4d), BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), C/I-FULL(% 4d cB), "
+ "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm), C/I-SUB(% 4d cB)\n",
+ ta256b_sum, ber_full_sum / 100, ber_full_sum % 100, irssi_full_sum, ci_full_sum,
+ ber_sub_sum / 100, ber_sub_sum % 100, irssi_sub_sum, ci_sub_sum);
/* store results */
mru = &lchan->meas.ul_res;
@@ -726,6 +735,8 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum);
mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_sum);
lchan->meas.ms_toa256 = ta256b_sum;
+ lchan->meas.ul_ci_cb_full = ci_full_sum;
+ lchan->meas.ul_ci_cb_sub = ci_sub_sum;
LOGPLCHAN(lchan, DMEAS, LOGL_INFO,
"UL MEAS RXLEV_FULL(%u), RXLEV_SUB(%u), RXQUAL_FULL(%u), RXQUAL_SUB(%u), "
diff --git a/tests/meas/meas_testcases.h b/tests/meas/meas_testcases.h
index d7eee5c3..90f0f850 100644
--- a/tests/meas/meas_testcases.h
+++ b/tests/meas/meas_testcases.h
@@ -1,5 +1,5 @@
#define ULM(ber, ta, sub, neg_rssi) \
- { .ber10k = (ber), .ta_offs_256bits = (ta), .c_i = 1.0, .is_sub = sub, .inv_rssi = (neg_rssi) }
+ { .ber10k = (ber), .ta_offs_256bits = (ta), .c_i = 10, .is_sub = sub, .inv_rssi = (neg_rssi) }
struct meas_testcase {
const char *name;