<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/25442">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">MS Power Control Loop: Feed UL C/I from correct measurement period<br><br>As per 3GPP TS 45.008 sec 4.2, the ms_pwr received in L1 SACCH Header is<br>the value used over previous measurement period. Hence, we need to feed<br>the algo with the measurements taken over that same period.<br><br>Related: SYS#4917<br>Change-Id: I13c0014fdd73f823ae5b1256c35bfa7d97cfa334<br>---<br>M include/osmo-bts/gsm_data.h<br>M src/common/l1sap.c<br>M src/common/measurement.c<br>M tests/meas/meas_testcases.h<br>4 files changed, 51 insertions(+), 27 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/42/25442/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h</span><br><span>index 8a5974e..9fe68d6 100644</span><br><span>--- a/include/osmo-bts/gsm_data.h</span><br><span>+++ b/include/osmo-bts/gsm_data.h</span><br><span>@@ -105,8 +105,8 @@</span><br><span> uint16_t ber10k;</span><br><span> /* timing advance offset (in 1/256 bits) */</span><br><span> int16_t ta_offs_256bits;</span><br><span style="color: hsl(0, 100%, 40%);">- /* C/I ratio in dB */</span><br><span style="color: hsl(0, 100%, 40%);">- float c_i;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* C/I ratio in cB */</span><br><span style="color: hsl(120, 100%, 40%);">+ int16_t c_i;</span><br><span> /* flags */</span><br><span> uint8_t is_sub:1;</span><br><span> /* RSSI in dBm * -1 */</span><br><span>@@ -341,6 +341,8 @@</span><br><span> struct rsl_l1_info l1_info;</span><br><span> struct gsm_meas_rep_unidir ul_res;</span><br><span> int16_t ms_toa256;</span><br><span style="color: hsl(120, 100%, 40%);">+ int16_t ul_ci_cb_full;</span><br><span style="color: hsl(120, 100%, 40%);">+ int16_t ul_ci_cb_sub;</span><br><span> /* Frame number of the last measurement indication receceived */</span><br><span> uint32_t last_fn;</span><br><span> /* Osmocom extended measurement results, see LC_UL_M_F_EXTD_VALID */</span><br><span>diff --git a/src/common/l1sap.c b/src/common/l1sap.c</span><br><span>index a641dab..40e818d 100644</span><br><span>--- a/src/common/l1sap.c</span><br><span>+++ b/src/common/l1sap.c</span><br><span>@@ -681,6 +681,7 @@</span><br><span> uint8_t is_sub;</span><br><span> int16_t ta_offs_256bits;</span><br><span> uint16_t ber10k;</span><br><span style="color: hsl(120, 100%, 40%);">+ int16_t ci_cb;</span><br><span> const char *ind_name;</span><br><span> </span><br><span> switch (ind_type) {</span><br><span>@@ -693,6 +694,7 @@</span><br><span> is_sub = info_meas_ind->is_sub;</span><br><span> ta_offs_256bits = info_meas_ind->ta_offs_256bits;</span><br><span> ber10k = info_meas_ind->ber10k;</span><br><span style="color: hsl(120, 100%, 40%);">+ ci_cb = info_meas_ind->c_i_cb;</span><br><span> ind_name = "MPH INFO";</span><br><span> break;</span><br><span> case PRIM_TCH:</span><br><span>@@ -705,6 +707,7 @@</span><br><span> is_sub = ph_tch_ind->is_sub;</span><br><span> ta_offs_256bits = ph_tch_ind->ta_offs_256bits;</span><br><span> ber10k = ph_tch_ind->ber10k;</span><br><span style="color: hsl(120, 100%, 40%);">+ ci_cb = ph_tch_ind->lqual_cb;</span><br><span> ind_name = "TCH";</span><br><span> break;</span><br><span> case PRIM_PH_DATA:</span><br><span>@@ -717,6 +720,7 @@</span><br><span> is_sub = ph_data_ind->is_sub;</span><br><span> ta_offs_256bits = ph_data_ind->ta_offs_256bits;</span><br><span> ber10k = ph_data_ind->ber10k;</span><br><span style="color: hsl(120, 100%, 40%);">+ ci_cb = ph_data_ind->lqual_cb;</span><br><span> ind_name = "DATA";</span><br><span> break;</span><br><span> default:</span><br><span>@@ -732,9 +736,9 @@</span><br><span> }</span><br><span> </span><br><span> DEBUGPFN(DL1P, fn,</span><br><span style="color: hsl(0, 100%, 40%);">- "%s %s meas ind, ta_offs_256bits=%d, ber10k=%d, inv_rssi=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ "%s %s meas ind, ta_offs_256bits=%d, ber10k=%d, inv_rssi=%u, C/I=%d cB\n",</span><br><span> gsm_lchan_name(lchan), ind_name, ta_offs_256bits, ber10k,</span><br><span style="color: hsl(0, 100%, 40%);">- inv_rssi);</span><br><span style="color: hsl(120, 100%, 40%);">+ inv_rssi, ci_cb);</span><br><span> </span><br><span> /* in the GPRS case we are not interested in measurement</span><br><span> * processing. The PCU will take care of it */</span><br><span>@@ -744,6 +748,7 @@</span><br><span> memset(&ulm, 0, sizeof(ulm));</span><br><span> ulm.ta_offs_256bits = ta_offs_256bits;</span><br><span> ulm.ber10k = ber10k;</span><br><span style="color: hsl(120, 100%, 40%);">+ ulm.c_i = ci_cb;</span><br><span> ulm.inv_rssi = inv_rssi;</span><br><span> ulm.is_sub = is_sub;</span><br><span> </span><br><span>@@ -1526,11 +1531,11 @@</span><br><span> uint8_t chan_nr, link_id;</span><br><span> uint8_t tn;</span><br><span> uint32_t fn;</span><br><span style="color: hsl(0, 100%, 40%);">- int8_t rssi;</span><br><span> enum osmo_ph_pres_info_type pr_info = data_ind->pdch_presence_info;</span><br><span> struct gsm_sacch_l1_hdr *l1_hdr;</span><br><span style="color: hsl(120, 100%, 40%);">+ int8_t ul_rssi;</span><br><span style="color: hsl(120, 100%, 40%);">+ int16_t ul_ci_cb;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- rssi = data_ind->rssi;</span><br><span> chan_nr = data_ind->chan_nr;</span><br><span> link_id = data_ind->link_id;</span><br><span> fn = data_ind->fn;</span><br><span>@@ -1578,7 +1583,7 @@</span><br><span> </span><br><span> /* PDTCH / PACCH frame handling */</span><br><span> pcu_tx_data_ind(&trx->ts[tn], PCU_IF_SAPI_PDTCH, fn, trx->arfcn,</span><br><span style="color: hsl(0, 100%, 40%);">- L1SAP_FN2MACBLOCK(fn), data, len, rssi, data_ind->ber10k,</span><br><span style="color: hsl(120, 100%, 40%);">+ L1SAP_FN2MACBLOCK(fn), data, len, data_ind->rssi, data_ind->ber10k,</span><br><span> data_ind->ta_offs_256bits/64, data_ind->lqual_cb);</span><br><span> return 0;</span><br><span> }</span><br><span>@@ -1606,7 +1611,15 @@</span><br><span> </span><br><span> radio_link_timeout(lchan, true);</span><br><span> lchan_ms_ta_ctrl(lchan, lchan->ta_ctrl.current, lchan->meas.ms_toa256);</span><br><span style="color: hsl(0, 100%, 40%);">- lchan_ms_pwr_ctrl(lchan, lchan->ms_power_ctrl.current, data_ind->rssi, data_ind->lqual_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If DTx is active on Downlink, use the '-SUB', otherwise '-FULL': */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->tch.dtx.dl_active) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ul_rssi = rxlev2dbm(lchan->meas.ul_res.sub.rx_lev);</span><br><span style="color: hsl(120, 100%, 40%);">+ ul_ci_cb = lchan->meas.ul_ci_cb_full;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ul_rssi = rxlev2dbm(lchan->meas.ul_res.full.rx_lev);</span><br><span style="color: hsl(120, 100%, 40%);">+ ul_ci_cb = lchan->meas.ul_ci_cb_sub;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan_ms_pwr_ctrl(lchan, lchan->ms_power_ctrl.current, ul_rssi, ul_ci_cb);</span><br><span> }</span><br><span> return -EINVAL;</span><br><span> }</span><br><span>@@ -1616,7 +1629,6 @@</span><br><span> handover_frame(lchan);</span><br><span> </span><br><span> if (L1SAP_IS_LINK_SACCH(link_id)) {</span><br><span style="color: hsl(0, 100%, 40%);">- int8_t ul_rssi;</span><br><span> radio_link_timeout(lchan, false);</span><br><span> le = &lchan->lapdm_ch.lapdm_acch;</span><br><span> /* save the SACCH L1 header in the lchan struct for RSL MEAS RES */</span><br><span>@@ -1644,16 +1656,15 @@</span><br><span> * feed the Control Loop with the measurements for the same</span><br><span> * period (the previous one), which is stored in lchan->meas(.ul_res): */</span><br><span> lchan_ms_ta_ctrl(lchan, l1_hdr->ta, lchan->meas.ms_toa256);</span><br><span style="color: hsl(0, 100%, 40%);">- /* FIXME: lchan_ms_pwr_ctrl() is currently being passed data_ind->lqual_cb, which is wrong because:</span><br><span style="color: hsl(0, 100%, 40%);">- * 1- It contains measurement data for 1 SACCH block only, not the average over the entire period</span><br><span style="color: hsl(0, 100%, 40%);">- * 2- It contains measurement data for *current* meas period, not *previous* one.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span> /* If DTx is active on Downlink, use the '-SUB', otherwise '-FULL': */</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->tch.dtx.dl_active)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->tch.dtx.dl_active) {</span><br><span> ul_rssi = rxlev2dbm(lchan->meas.ul_res.sub.rx_lev);</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(120, 100%, 40%);">+ ul_ci_cb = lchan->meas.ul_ci_cb_full;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span> ul_rssi = rxlev2dbm(lchan->meas.ul_res.full.rx_lev);</span><br><span style="color: hsl(0, 100%, 40%);">- lchan_ms_pwr_ctrl(lchan, l1_hdr->ms_pwr, ul_rssi, data_ind->lqual_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+ ul_ci_cb = lchan->meas.ul_ci_cb_sub;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan_ms_pwr_ctrl(lchan, l1_hdr->ms_pwr, ul_rssi, ul_ci_cb);</span><br><span> lchan_bs_pwr_ctrl(lchan, (const struct gsm48_hdr *) &data[5]);</span><br><span> } else</span><br><span> le = &lchan->lapdm_ch.lapdm_dcch;</span><br><span>diff --git a/src/common/measurement.c b/src/common/measurement.c</span><br><span>index a4cc668..a1c91a9 100644</span><br><span>--- a/src/common/measurement.c</span><br><span>+++ b/src/common/measurement.c</span><br><span>@@ -341,7 +341,7 @@</span><br><span> if (!ulm->is_sub)</span><br><span> dest->is_sub = ts45008_83_is_sub(lchan, fn);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- 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",</span><br><span style="color: hsl(120, 100%, 40%);">+ 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",</span><br><span> gsm_lchan_name(lchan), ulm->ber10k, ulm->ta_offs_256bits,</span><br><span> ulm->c_i, dest->is_sub, ulm->inv_rssi, lchan->meas.num_ul_meas,</span><br><span> fn_mod);</span><br><span>@@ -555,8 +555,10 @@</span><br><span> struct gsm_meas_rep_unidir *mru;</span><br><span> uint32_t ber_full_sum = 0;</span><br><span> uint32_t irssi_full_sum = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int32_t ci_full_sum = 0;</span><br><span> uint32_t ber_sub_sum = 0;</span><br><span> uint32_t irssi_sub_sum = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int32_t ci_sub_sum = 0;</span><br><span> int32_t ta256b_sum = 0;</span><br><span> unsigned int num_meas_sub = 0;</span><br><span> unsigned int num_meas_sub_actual = 0;</span><br><span>@@ -624,11 +626,13 @@</span><br><span> m = &lchan->meas.uplink[i + num_ul_meas_excess];</span><br><span> if (m->is_sub) {</span><br><span> irssi_sub_sum += m->inv_rssi;</span><br><span style="color: hsl(120, 100%, 40%);">+ ci_sub_sum += m->c_i;</span><br><span> num_meas_sub_actual++;</span><br><span> is_sub = true;</span><br><span> }</span><br><span> irssi_full_sum += m->inv_rssi;</span><br><span> ta256b_sum += m->ta_offs_256bits;</span><br><span style="color: hsl(120, 100%, 40%);">+ ci_full_sum += m->c_i;</span><br><span> </span><br><span> num_ul_meas_actual++;</span><br><span> } else {</span><br><span>@@ -697,27 +701,32 @@</span><br><span> else</span><br><span> irssi_full_sum = irssi_full_sum / num_ul_meas_actual;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (!num_ul_meas_actual)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!num_ul_meas_actual) {</span><br><span> ta256b_sum = lchan->meas.ms_toa256;</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(120, 100%, 40%);">+ ci_full_sum = lchan->meas.ul_ci_cb_full;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span> ta256b_sum = ta256b_sum / (signed)num_ul_meas_actual;</span><br><span style="color: hsl(120, 100%, 40%);">+ ci_full_sum = ci_full_sum / (signed)num_ul_meas_actual;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span> if (!num_meas_sub)</span><br><span> ber_sub_sum = MEASUREMENT_DUMMY_BER;</span><br><span> else</span><br><span> ber_sub_sum = ber_sub_sum / num_meas_sub;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (!num_meas_sub_actual)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!num_meas_sub_actual) {</span><br><span> irssi_sub_sum = MEASUREMENT_DUMMY_IRSSI;</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(120, 100%, 40%);">+ ci_sub_sum = lchan->meas.ul_ci_cb_sub;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span> irssi_sub_sum = irssi_sub_sum / num_meas_sub_actual;</span><br><span style="color: hsl(120, 100%, 40%);">+ ci_sub_sum = ci_sub_sum / (signed)num_meas_sub_actual;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span> LOGPLCHAN(lchan, DMEAS, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">- "Computed TA256(% 4d) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), "</span><br><span style="color: hsl(0, 100%, 40%);">- "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm)\n",</span><br><span style="color: hsl(0, 100%, 40%);">- ta256b_sum, ber_full_sum / 100, ber_full_sum % 100,</span><br><span style="color: hsl(0, 100%, 40%);">- irssi_full_sum, ber_sub_sum / 100, ber_sub_sum % 100,</span><br><span style="color: hsl(0, 100%, 40%);">- irssi_sub_sum);</span><br><span style="color: hsl(120, 100%, 40%);">+ "Computed TA256(% 4d), BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), C/I-FULL(% 4d cB), "</span><br><span style="color: hsl(120, 100%, 40%);">+ "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm), C/I-SUB(% 4d cB)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ta256b_sum, ber_full_sum / 100, ber_full_sum % 100, irssi_full_sum, ci_full_sum,</span><br><span style="color: hsl(120, 100%, 40%);">+ ber_sub_sum / 100, ber_sub_sum % 100, irssi_sub_sum, ci_sub_sum);</span><br><span> </span><br><span> /* store results */</span><br><span> mru = &lchan->meas.ul_res;</span><br><span>@@ -726,6 +735,8 @@</span><br><span> mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum);</span><br><span> mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_sum);</span><br><span> lchan->meas.ms_toa256 = ta256b_sum;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->meas.ul_ci_cb_full = ci_full_sum;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->meas.ul_ci_cb_sub = ci_sub_sum;</span><br><span> </span><br><span> LOGPLCHAN(lchan, DMEAS, LOGL_INFO,</span><br><span> "UL MEAS RXLEV_FULL(%u), RXLEV_SUB(%u), RXQUAL_FULL(%u), RXQUAL_SUB(%u), "</span><br><span>diff --git a/tests/meas/meas_testcases.h b/tests/meas/meas_testcases.h</span><br><span>index d7eee5c..90f0f85 100644</span><br><span>--- a/tests/meas/meas_testcases.h</span><br><span>+++ b/tests/meas/meas_testcases.h</span><br><span>@@ -1,5 +1,5 @@</span><br><span> #define ULM(ber, ta, sub, neg_rssi) \</span><br><span style="color: hsl(0, 100%, 40%);">- { .ber10k = (ber), .ta_offs_256bits = (ta), .c_i = 1.0, .is_sub = sub, .inv_rssi = (neg_rssi) }</span><br><span style="color: hsl(120, 100%, 40%);">+ { .ber10k = (ber), .ta_offs_256bits = (ta), .c_i = 10, .is_sub = sub, .inv_rssi = (neg_rssi) }</span><br><span> </span><br><span> struct meas_testcase {</span><br><span> const char *name;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/25442">change 25442</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-bts/+/25442"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-bts </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I13c0014fdd73f823ae5b1256c35bfa7d97cfa334 </div>
<div style="display:none"> Gerrit-Change-Number: 25442 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>