<p>pespin <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/25698">View Change</a></p><div style="white-space:pre-wrap">Approvals:
fixeria: Looks good to me, but someone else must approve
pespin: Looks good to me, approved
osmith: Looks good to me, but someone else must approve
Jenkins Builder: Verified
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Move lchan,power_control related code from gsm_data.c to their own files<br><br>We already have similar classification in osmo-bsc.<br><br>Change-Id: I1493f40d99f88a565f15d3e0943a512fb9b8719a<br>---<br>M src/common/gsm_data.c<br>M src/common/lchan.c<br>M src/common/power_control.c<br>3 files changed, 405 insertions(+), 404 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/common/gsm_data.c b/src/common/gsm_data.c</span><br><span>index 89a740d..2edeb4d 100644</span><br><span>--- a/src/common/gsm_data.c</span><br><span>+++ b/src/common/gsm_data.c</span><br><span>@@ -90,21 +90,6 @@</span><br><span> return get_value_string(gsm_chan_t_names, c);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static const struct value_string lchan_s_names[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_S_NONE, "NONE" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_S_ACT_REQ, "ACTIVATION REQUESTED" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_S_ACTIVE, "ACTIVE" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_S_REL_REQ, "RELEASE REQUESTED" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_S_REL_ERR, "RELEASE DUE ERROR" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_S_BROKEN, "BROKEN UNUSABLE" },</span><br><span style="color: hsl(0, 100%, 40%);">- { 0, NULL }</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const char *gsm_lchans_name(enum gsm_lchan_state s)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return get_value_string(lchan_s_names, s);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static char ts2str[255];</span><br><span> </span><br><span> char *gsm_ts_name(const struct gsm_bts_trx_ts *ts)</span><br><span>@@ -162,187 +147,6 @@</span><br><span> return ts2str;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void gsm_lchan_name_update(struct gsm_lchan *lchan)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- const struct gsm_bts_trx_ts *ts = lchan->ts;</span><br><span style="color: hsl(0, 100%, 40%);">- const struct gsm_bts_trx *trx = ts->trx;</span><br><span style="color: hsl(0, 100%, 40%);">- char *name;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- name = talloc_asprintf(trx, "(" GSM_TS_NAME_FMT ",ss=%u)",</span><br><span style="color: hsl(0, 100%, 40%);">- GSM_TS_NAME_ARGS(ts), lchan->nr);</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->name != NULL)</span><br><span style="color: hsl(0, 100%, 40%);">- talloc_free(lchan->name);</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->name = name;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* See Table 10.5.25 of GSM04.08 */</span><br><span style="color: hsl(0, 100%, 40%);">-static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t ts_nr, uint8_t lchan_nr)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t cbits, chan_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(pchan != GSM_PCHAN_OSMO_DYN);</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- switch (pchan) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_TCH_F:</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(lchan_nr == 0);</span><br><span style="color: hsl(0, 100%, 40%);">- cbits = ABIS_RSL_CHAN_NR_CBITS_Bm_ACCHs;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_PDCH:</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(lchan_nr == 0);</span><br><span style="color: hsl(0, 100%, 40%);">- cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_PDCH;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_TCH_H:</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(lchan_nr < 2);</span><br><span style="color: hsl(0, 100%, 40%);">- cbits = ABIS_RSL_CHAN_NR_CBITS_Lm_ACCHs(lchan_nr);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_CCCH_SDCCH4:</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_CCCH_SDCCH4_CBCH:</span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">- * As a special hack for BCCH, lchan_nr == 4 may be passed</span><br><span style="color: hsl(0, 100%, 40%);">- * here. This should never be sent in an RSL message.</span><br><span style="color: hsl(0, 100%, 40%);">- * See osmo-bts-xxx/oml.c:opstart_compl().</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan_nr == CCCH_LCHAN)</span><br><span style="color: hsl(0, 100%, 40%);">- cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;</span><br><span style="color: hsl(0, 100%, 40%);">- else {</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(lchan_nr < 4);</span><br><span style="color: hsl(0, 100%, 40%);">- cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(lchan_nr);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_SDCCH8_SACCH8C:</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(lchan_nr < 8);</span><br><span style="color: hsl(0, 100%, 40%);">- cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(lchan_nr);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_CCCH:</span><br><span style="color: hsl(0, 100%, 40%);">- cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_NONE:</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_pchan_name(pchan));</span><br><span style="color: hsl(0, 100%, 40%);">- cbits = 0x00;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- default:</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_pchan_name(pchan), (int)pchan);</span><br><span style="color: hsl(0, 100%, 40%);">- /* OSMO_ASSERT(lchan_nr == 0);</span><br><span style="color: hsl(0, 100%, 40%);">- * FIXME: On octphy and litecell, we hit above assertion (see</span><br><span style="color: hsl(0, 100%, 40%);">- * Max's comment at https://gerrit.osmocom.org/589 ); disabled</span><br><span style="color: hsl(0, 100%, 40%);">- * for BTS until this is clarified; remove the #ifdef when it</span><br><span style="color: hsl(0, 100%, 40%);">- * is fixed. Tracked in OS#2906.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-#pragma message "fix caller that passes lchan_nr != 0"</span><br><span style="color: hsl(0, 100%, 40%);">- cbits = 0x10;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- chan_nr = (cbits << 3) | (ts_nr & 0x7);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return chan_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static uint8_t _gsm_lchan2chan_nr(const struct gsm_lchan *lchan, bool rsl)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t chan_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- switch (lchan->ts->pchan) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_OSMO_DYN:</span><br><span style="color: hsl(0, 100%, 40%);">- /* Return chan_nr reflecting the current TS pchan, either a standard TCH kind, or the</span><br><span style="color: hsl(0, 100%, 40%);">- * nonstandard value reflecting PDCH for Osmocom style dyn TS. */</span><br><span style="color: hsl(0, 100%, 40%);">- chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, lchan->ts->dyn.pchan_is);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_TCH_F_PDCH:</span><br><span style="color: hsl(0, 100%, 40%);">- /* For ip.access style dyn TS, on RSL we want to use the chan_nr as if it was TCH/F.</span><br><span style="color: hsl(0, 100%, 40%);">- * We're using custom PDCH ACT and DEACT messages that use the usual chan_nr values. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (rsl)</span><br><span style="color: hsl(0, 100%, 40%);">- chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F);</span><br><span style="color: hsl(0, 100%, 40%);">- else if (~lchan->ts->flags & TS_F_PDCH_ACTIVE)</span><br><span style="color: hsl(0, 100%, 40%);">- chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F);</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_PDCH);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- default:</span><br><span style="color: hsl(0, 100%, 40%);">- chan_nr = gsm_pchan2chan_nr(lchan->ts->pchan, lchan->ts->nr, lchan->nr);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* VAMOS: if this lchan belongs to a shadow timeslot, we must reflect</span><br><span style="color: hsl(0, 100%, 40%);">- * this in the channel number. Convert it to Osmocom specific value. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->ts->vamos.is_shadow)</span><br><span style="color: hsl(0, 100%, 40%);">- chan_nr |= RSL_CHAN_OSMO_VAMOS_MASK;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return chan_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return _gsm_lchan2chan_nr(lchan, false);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t gsm_lchan2chan_nr_rsl(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return _gsm_lchan2chan_nr(lchan, true);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,</span><br><span style="color: hsl(0, 100%, 40%);">- enum gsm_phys_chan_config as_pchan)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN</span><br><span style="color: hsl(0, 100%, 40%);">- && as_pchan == GSM_PCHAN_PDCH)</span><br><span style="color: hsl(0, 100%, 40%);">- return RSL_CHAN_OSMO_PDCH | (lchan->ts->nr & ~RSL_CHAN_NR_MASK);</span><br><span style="color: hsl(0, 100%, 40%);">- return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Called by the model specific code every 104 TDMA frames (SACCH period) */</span><br><span style="color: hsl(0, 100%, 40%);">-void gsm_lchan_interf_meas_push(struct gsm_lchan *lchan, int dbm)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- const uint8_t meas_num = lchan->meas.interf_meas_num;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (meas_num >= ARRAY_SIZE(lchan->meas.interf_meas_dbm)) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Not enough room "</span><br><span style="color: hsl(0, 100%, 40%);">- "to store interference report (%ddBm)\n", dbm);</span><br><span style="color: hsl(0, 100%, 40%);">- return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->meas.interf_meas_dbm[meas_num] = dbm;</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->meas.interf_meas_num++;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Called by the higher layers every Intave * 104 TDMA frames */</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm_lchan_interf_meas_calc_band(struct gsm_lchan *lchan)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- const uint8_t meas_num = lchan->meas.interf_meas_num;</span><br><span style="color: hsl(0, 100%, 40%);">- const struct gsm_bts *bts = lchan->ts->trx->bts;</span><br><span style="color: hsl(0, 100%, 40%);">- int b, meas_avg, meas_sum = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* There must be at least one sample */</span><br><span style="color: hsl(0, 100%, 40%);">- if (meas_num == 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return -EAGAIN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Calculate the sum of all collected samples (in -x dBm) */</span><br><span style="color: hsl(0, 100%, 40%);">- while (lchan->meas.interf_meas_num) {</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t i = --lchan->meas.interf_meas_num;</span><br><span style="color: hsl(0, 100%, 40%);">- meas_sum += lchan->meas.interf_meas_dbm[i];</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Calculate the average of all collected samples */</span><br><span style="color: hsl(0, 100%, 40%);">- meas_avg = meas_sum / (int) meas_num;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Determine the band using interference boundaries from BSC */</span><br><span style="color: hsl(0, 100%, 40%);">- for (b = 0; b < ARRAY_SIZE(bts->interference.boundary); b++) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (meas_avg >= bts->interference.boundary[b])</span><br><span style="color: hsl(0, 100%, 40%);">- break; /* Current 'b' is the band value */</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPLCHAN(lchan, DL1C, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "Interference AVG: %ddBm (band %d, samples %u)\n",</span><br><span style="color: hsl(0, 100%, 40%);">- meas_avg, b, meas_num);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return b;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* determine logical channel based on TRX and channel number IE */</span><br><span> struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,</span><br><span> int *rc)</span><br><span>@@ -486,205 +290,18 @@</span><br><span> return pchan_is_tch(ts_pchan(ts));</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-const struct value_string lchan_ciph_state_names[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_CIPH_NONE, "NONE" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_CIPH_RX_REQ, "RX_REQ" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_CIPH_RX_CONF, "RX_CONF" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_CIPH_RXTX_REQ, "RXTX_REQ" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_CIPH_RX_CONF_TX_REQ, "RX_CONF_TX_REQ" },</span><br><span style="color: hsl(0, 100%, 40%);">- { LCHAN_CIPH_RXTX_CONF, "RXTX_CONF" },</span><br><span style="color: hsl(0, 100%, 40%);">- { 0, NULL }</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* determine the ECU codec constant for the codec used by given lchan */</span><br><span style="color: hsl(0, 100%, 40%);">-int lchan2ecu_codec(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- const struct gsm_bts_trx_ts *ts = lchan->ts;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- switch (lchan->tch_mode) {</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM48_CMODE_SPEECH_V1:</span><br><span style="color: hsl(0, 100%, 40%);">- if (ts_pchan(ts) == GSM_PCHAN_TCH_H)</span><br><span style="color: hsl(0, 100%, 40%);">- return OSMO_ECU_CODEC_HR;</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- return OSMO_ECU_CODEC_FR;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM48_CMODE_SPEECH_EFR:</span><br><span style="color: hsl(0, 100%, 40%);">- return OSMO_ECU_CODEC_EFR;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM48_CMODE_SPEECH_AMR:</span><br><span style="color: hsl(0, 100%, 40%);">- return OSMO_ECU_CODEC_AMR;</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (ts->pchan) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_PDCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ return true;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_TCH_F_PDCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ return (ts->flags & TS_F_PDCH_ACTIVE)</span><br><span style="color: hsl(120, 100%, 40%);">+ && !(ts->flags & TS_F_PDCH_PENDING_MASK);</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_OSMO_DYN:</span><br><span style="color: hsl(120, 100%, 40%);">+ return ts->dyn.pchan_is == GSM_PCHAN_PDCH</span><br><span style="color: hsl(120, 100%, 40%);">+ && ts->dyn.pchan_want == ts->dyn.pchan_is;</span><br><span> default:</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span> }</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Default MS/BS Power Control parameters (see 3GPP TS 45.008, table A.1) */</span><br><span style="color: hsl(0, 100%, 40%);">-const struct gsm_power_ctrl_params power_ctrl_params_def = {</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- .ctrl_interval = 1, /* Trigger loop every second SACCH block. TS 45.008 sec 4.7.1 */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Power increasing/reducing step size (optimal defaults) */</span><br><span style="color: hsl(0, 100%, 40%);">- .inc_step_size_db = 4, /* quickly increase MS/BS power */</span><br><span style="color: hsl(0, 100%, 40%);">- .red_step_size_db = 2, /* slowly decrease MS/BS power */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* RxLev measurement parameters */</span><br><span style="color: hsl(0, 100%, 40%);">- .rxlev_meas = {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Thresholds for RxLev (see 3GPP TS 45.008, A.3.2.1) */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_thresh = 32, /* L_RXLEV_XX_P (-78 dBm) */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_thresh = 38, /* U_RXLEV_XX_P (-72 dBm) */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* NOTE: only Osmocom specific EWMA is supported */</span><br><span style="color: hsl(0, 100%, 40%);">- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA,</span><br><span style="color: hsl(0, 100%, 40%);">- .ewma.alpha = 50, /* Smoothing factor 50% */</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* RxQual measurement parameters */</span><br><span style="color: hsl(0, 100%, 40%);">- .rxqual_meas = {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Thresholds for RxQual (see 3GPP TS 45.008, A.3.2.1) */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_thresh = 3, /* L_RXQUAL_XX_P (0.8% <= BER < 1.6%) */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_thresh = 0, /* U_RXQUAL_XX_P (BER < 0.2%) */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* No averaging (filtering) by default.</span><br><span style="color: hsl(0, 100%, 40%);">- * NOTE: only Osmocom specific EWMA is supported */</span><br><span style="color: hsl(0, 100%, 40%);">- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* C/I measurement parameters.</span><br><span style="color: hsl(0, 100%, 40%);">- * Target C/I retrieved from "GSM/EDGE: Evolution and Performance" Table 10.3.</span><br><span style="color: hsl(0, 100%, 40%);">- * Set lower and upper so that (lower + upper) / 2 is equal or slightly</span><br><span style="color: hsl(0, 100%, 40%);">- * above the target.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">- .ci_fr_meas = { /* FR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_thresh = 13,</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_thresh = 17,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of LOWER_CMP_N averages are lower than L_CI_FR_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of UPPER_CMP_N averages are greater than L_CI_FR_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* No averaging (filtering) by default */</span><br><span style="color: hsl(0, 100%, 40%);">- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">- .ci_hr_meas = { /* HR: Target C/I = 18 dB, Soft blocking threshold = 13 dB */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_thresh = 16,</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_thresh = 21,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of LOWER_CMP_N averages are lower than L_CI_HR_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of UPPER_CMP_N averages are greater than L_CI_HR_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* No averaging (filtering) by default */</span><br><span style="color: hsl(0, 100%, 40%);">- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">- .ci_amr_fr_meas = { /* AMR-FR: Target C/I = 9 dB, Soft blocking threshold = 4 dB */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_thresh = 7,</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_thresh = 11,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of LOWER_CMP_N averages are lower than L_CI_AMR_FR_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of UPPER_CMP_N averages are greater than L_CI_AMR_FR_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* No averaging (filtering) by default */</span><br><span style="color: hsl(0, 100%, 40%);">- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">- .ci_amr_hr_meas = { /* AMR-HR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_thresh = 13,</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_thresh = 17,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of LOWER_CMP_N averages are lower than L_CI_AMR_HR_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of UPPER_CMP_N averages are greater than L_CI_AMR_HR_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* No averaging (filtering) by default */</span><br><span style="color: hsl(0, 100%, 40%);">- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">- .ci_sdcch_meas = { /* SDCCH: Target C/I = 14 dB, Soft blocking threshold = 9 dB */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_thresh = 12,</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_thresh = 16,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of LOWER_CMP_N averages are lower than L_CI_SDCCH_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of UPPER_CMP_N averages are greater than L_CI_SDCCH_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* No averaging (filtering) by default */</span><br><span style="color: hsl(0, 100%, 40%);">- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">- .ci_gprs_meas = { /* GPRS: Target C/I = 20 dB, Soft blocking threshold = 15 dB */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_thresh = 18,</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_thresh = 24,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of LOWER_CMP_N averages are lower than L_CI_GPRS_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(0, 100%, 40%);">- * out of UPPER_CMP_N averages are greater than L_CI_GPRS_XX_P */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">- .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* No averaging (filtering) by default */</span><br><span style="color: hsl(0, 100%, 40%);">- .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(0, 100%, 40%);">- .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void power_ctrl_params_def_reset(struct gsm_power_ctrl_params *params, bool is_bs_pwr)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- *params = power_ctrl_params_def;</span><br><span style="color: hsl(0, 100%, 40%);">- if (!is_bs_pwr)</span><br><span style="color: hsl(0, 100%, 40%);">- /* Trigger loop every fourth SACCH block (1.92s). TS 45.008 sec 4.7.1: */</span><br><span style="color: hsl(0, 100%, 40%);">- params->ctrl_interval = 2;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/common/lchan.c b/src/common/lchan.c</span><br><span>index cd99be7..afcb2c3 100644</span><br><span>--- a/src/common/lchan.c</span><br><span>+++ b/src/common/lchan.c</span><br><span>@@ -24,6 +24,27 @@</span><br><span> #include <osmo-bts/lchan.h></span><br><span> #include <osmo-bts/bts.h></span><br><span> #include <osmo-bts/rsl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct value_string lchan_s_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_S_NONE, "NONE" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_S_ACT_REQ, "ACTIVATION REQUESTED" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_S_ACTIVE, "ACTIVE" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_S_REL_REQ, "RELEASE REQUESTED" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_S_REL_ERR, "RELEASE DUE ERROR" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_S_BROKEN, "BROKEN UNUSABLE" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0, NULL }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct value_string lchan_ciph_state_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_CIPH_NONE, "NONE" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_CIPH_RX_REQ, "RX_REQ" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_CIPH_RX_CONF, "RX_CONF" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_CIPH_RXTX_REQ, "RXTX_REQ" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_CIPH_RX_CONF_TX_REQ, "RX_CONF_TX_REQ" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { LCHAN_CIPH_RXTX_CONF, "RXTX_CONF" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0, NULL }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span> </span><br><span> void gsm_lchan_init(struct gsm_lchan *lchan, struct gsm_bts_trx_ts *ts, unsigned int lchan_nr)</span><br><span> {</span><br><span>@@ -36,6 +57,24 @@</span><br><span> INIT_LLIST_HEAD(&lchan->dl_tch_queue);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_lchan_name_update(struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gsm_bts_trx_ts *ts = lchan->ts;</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gsm_bts_trx *trx = ts->trx;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *name;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ name = talloc_asprintf(trx, "(" GSM_TS_NAME_FMT ",ss=%u)",</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM_TS_NAME_ARGS(ts), lchan->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->name != NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(lchan->name);</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->name = name;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const char *gsm_lchans_name(enum gsm_lchan_state s)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return get_value_string(lchan_s_names, s);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void early_rr_ia_delay_cb(void *data)</span><br><span> {</span><br><span> struct gsm_lchan *lchan = data;</span><br><span>@@ -98,18 +137,191 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)</span><br><span style="color: hsl(120, 100%, 40%);">+/* See Table 10.5.25 of GSM04.08 */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t ts_nr, uint8_t lchan_nr)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- switch (ts->pchan) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t cbits, chan_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(pchan != GSM_PCHAN_OSMO_DYN);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pchan) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_TCH_F:</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(lchan_nr == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ cbits = ABIS_RSL_CHAN_NR_CBITS_Bm_ACCHs;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> case GSM_PCHAN_PDCH:</span><br><span style="color: hsl(0, 100%, 40%);">- return true;</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_TCH_F_PDCH:</span><br><span style="color: hsl(0, 100%, 40%);">- return (ts->flags & TS_F_PDCH_ACTIVE)</span><br><span style="color: hsl(0, 100%, 40%);">- && !(ts->flags & TS_F_PDCH_PENDING_MASK);</span><br><span style="color: hsl(0, 100%, 40%);">- case GSM_PCHAN_OSMO_DYN:</span><br><span style="color: hsl(0, 100%, 40%);">- return ts->dyn.pchan_is == GSM_PCHAN_PDCH</span><br><span style="color: hsl(0, 100%, 40%);">- && ts->dyn.pchan_want == ts->dyn.pchan_is;</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(lchan_nr == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_PDCH;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_TCH_H:</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(lchan_nr < 2);</span><br><span style="color: hsl(120, 100%, 40%);">+ cbits = ABIS_RSL_CHAN_NR_CBITS_Lm_ACCHs(lchan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_CCCH_SDCCH4:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_CCCH_SDCCH4_CBCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * As a special hack for BCCH, lchan_nr == 4 may be passed</span><br><span style="color: hsl(120, 100%, 40%);">+ * here. This should never be sent in an RSL message.</span><br><span style="color: hsl(120, 100%, 40%);">+ * See osmo-bts-xxx/oml.c:opstart_compl().</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan_nr == CCCH_LCHAN)</span><br><span style="color: hsl(120, 100%, 40%);">+ cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;</span><br><span style="color: hsl(120, 100%, 40%);">+ else {</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(lchan_nr < 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(lchan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_SDCCH8_SACCH8C:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(lchan_nr < 8);</span><br><span style="color: hsl(120, 100%, 40%);">+ cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(lchan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_CCCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_NONE:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_pchan_name(pchan));</span><br><span style="color: hsl(120, 100%, 40%);">+ cbits = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> default:</span><br><span style="color: hsl(0, 100%, 40%);">- return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_pchan_name(pchan), (int)pchan);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* OSMO_ASSERT(lchan_nr == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ * FIXME: On octphy and litecell, we hit above assertion (see</span><br><span style="color: hsl(120, 100%, 40%);">+ * Max's comment at https://gerrit.osmocom.org/589 ); disabled</span><br><span style="color: hsl(120, 100%, 40%);">+ * for BTS until this is clarified; remove the #ifdef when it</span><br><span style="color: hsl(120, 100%, 40%);">+ * is fixed. Tracked in OS#2906.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma message "fix caller that passes lchan_nr != 0"</span><br><span style="color: hsl(120, 100%, 40%);">+ cbits = 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ chan_nr = (cbits << 3) | (ts_nr & 0x7);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return chan_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t _gsm_lchan2chan_nr(const struct gsm_lchan *lchan, bool rsl)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t chan_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (lchan->ts->pchan) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_OSMO_DYN:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Return chan_nr reflecting the current TS pchan, either a standard TCH kind, or the</span><br><span style="color: hsl(120, 100%, 40%);">+ * nonstandard value reflecting PDCH for Osmocom style dyn TS. */</span><br><span style="color: hsl(120, 100%, 40%);">+ chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, lchan->ts->dyn.pchan_is);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_PCHAN_TCH_F_PDCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* For ip.access style dyn TS, on RSL we want to use the chan_nr as if it was TCH/F.</span><br><span style="color: hsl(120, 100%, 40%);">+ * We're using custom PDCH ACT and DEACT messages that use the usual chan_nr values. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rsl)</span><br><span style="color: hsl(120, 100%, 40%);">+ chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F);</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (~lchan->ts->flags & TS_F_PDCH_ACTIVE)</span><br><span style="color: hsl(120, 100%, 40%);">+ chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F);</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_PDCH);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ chan_nr = gsm_pchan2chan_nr(lchan->ts->pchan, lchan->ts->nr, lchan->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* VAMOS: if this lchan belongs to a shadow timeslot, we must reflect</span><br><span style="color: hsl(120, 100%, 40%);">+ * this in the channel number. Convert it to Osmocom specific value. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->ts->vamos.is_shadow)</span><br><span style="color: hsl(120, 100%, 40%);">+ chan_nr |= RSL_CHAN_OSMO_VAMOS_MASK;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return chan_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return _gsm_lchan2chan_nr(lchan, false);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm_lchan2chan_nr_rsl(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return _gsm_lchan2chan_nr(lchan, true);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum gsm_phys_chan_config as_pchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN</span><br><span style="color: hsl(120, 100%, 40%);">+ && as_pchan == GSM_PCHAN_PDCH)</span><br><span style="color: hsl(120, 100%, 40%);">+ return RSL_CHAN_OSMO_PDCH | (lchan->ts->nr & ~RSL_CHAN_NR_MASK);</span><br><span style="color: hsl(120, 100%, 40%);">+ return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Called by the model specific code every 104 TDMA frames (SACCH period) */</span><br><span style="color: hsl(120, 100%, 40%);">+void gsm_lchan_interf_meas_push(struct gsm_lchan *lchan, int dbm)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t meas_num = lchan->meas.interf_meas_num;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (meas_num >= ARRAY_SIZE(lchan->meas.interf_meas_dbm)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Not enough room "</span><br><span style="color: hsl(120, 100%, 40%);">+ "to store interference report (%ddBm)\n", dbm);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->meas.interf_meas_dbm[meas_num] = dbm;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->meas.interf_meas_num++;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Called by the higher layers every Intave * 104 TDMA frames */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm_lchan_interf_meas_calc_band(struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t meas_num = lchan->meas.interf_meas_num;</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gsm_bts *bts = lchan->ts->trx->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ int b, meas_avg, meas_sum = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* There must be at least one sample */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (meas_num == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EAGAIN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Calculate the sum of all collected samples (in -x dBm) */</span><br><span style="color: hsl(120, 100%, 40%);">+ while (lchan->meas.interf_meas_num) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t i = --lchan->meas.interf_meas_num;</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_sum += lchan->meas.interf_meas_dbm[i];</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Calculate the average of all collected samples */</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_avg = meas_sum / (int) meas_num;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Determine the band using interference boundaries from BSC */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (b = 0; b < ARRAY_SIZE(bts->interference.boundary); b++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (meas_avg >= bts->interference.boundary[b])</span><br><span style="color: hsl(120, 100%, 40%);">+ break; /* Current 'b' is the band value */</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPLCHAN(lchan, DL1C, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Interference AVG: %ddBm (band %d, samples %u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_avg, b, meas_num);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return b;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* determine the ECU codec constant for the codec used by given lchan */</span><br><span style="color: hsl(120, 100%, 40%);">+int lchan2ecu_codec(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gsm_bts_trx_ts *ts = lchan->ts;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (lchan->tch_mode) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_CMODE_SPEECH_V1:</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ts_pchan(ts) == GSM_PCHAN_TCH_H)</span><br><span style="color: hsl(120, 100%, 40%);">+ return OSMO_ECU_CODEC_HR;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ return OSMO_ECU_CODEC_FR;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_CMODE_SPEECH_EFR:</span><br><span style="color: hsl(120, 100%, 40%);">+ return OSMO_ECU_CODEC_EFR;</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_CMODE_SPEECH_AMR:</span><br><span style="color: hsl(120, 100%, 40%);">+ return OSMO_ECU_CODEC_AMR;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span> }</span><br><span> }</span><br><span>diff --git a/src/common/power_control.c b/src/common/power_control.c</span><br><span>index 8f5ce37..a81000e 100644</span><br><span>--- a/src/common/power_control.c</span><br><span>+++ b/src/common/power_control.c</span><br><span>@@ -421,3 +421,175 @@</span><br><span> state->current = new_att;</span><br><span> return 1;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Default MS/BS Power Control parameters (see 3GPP TS 45.008, table A.1) */</span><br><span style="color: hsl(120, 100%, 40%);">+const struct gsm_power_ctrl_params power_ctrl_params_def = {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ .ctrl_interval = 1, /* Trigger loop every second SACCH block. TS 45.008 sec 4.7.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Power increasing/reducing step size (optimal defaults) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .inc_step_size_db = 4, /* quickly increase MS/BS power */</span><br><span style="color: hsl(120, 100%, 40%);">+ .red_step_size_db = 2, /* slowly decrease MS/BS power */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* RxLev measurement parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+ .rxlev_meas = {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Thresholds for RxLev (see 3GPP TS 45.008, A.3.2.1) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_thresh = 32, /* L_RXLEV_XX_P (-78 dBm) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_thresh = 38, /* U_RXLEV_XX_P (-72 dBm) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* NOTE: only Osmocom specific EWMA is supported */</span><br><span style="color: hsl(120, 100%, 40%);">+ .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA,</span><br><span style="color: hsl(120, 100%, 40%);">+ .ewma.alpha = 50, /* Smoothing factor 50% */</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* RxQual measurement parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+ .rxqual_meas = {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Thresholds for RxQual (see 3GPP TS 45.008, A.3.2.1) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_thresh = 3, /* L_RXQUAL_XX_P (0.8% <= BER < 1.6%) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_thresh = 0, /* U_RXQUAL_XX_P (BER < 0.2%) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* No averaging (filtering) by default.</span><br><span style="color: hsl(120, 100%, 40%);">+ * NOTE: only Osmocom specific EWMA is supported */</span><br><span style="color: hsl(120, 100%, 40%);">+ .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* C/I measurement parameters.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Target C/I retrieved from "GSM/EDGE: Evolution and Performance" Table 10.3.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Set lower and upper so that (lower + upper) / 2 is equal or slightly</span><br><span style="color: hsl(120, 100%, 40%);">+ * above the target.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ .ci_fr_meas = { /* FR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_thresh = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_thresh = 17,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of LOWER_CMP_N averages are lower than L_CI_FR_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of UPPER_CMP_N averages are greater than L_CI_FR_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* No averaging (filtering) by default */</span><br><span style="color: hsl(120, 100%, 40%);">+ .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ .ci_hr_meas = { /* HR: Target C/I = 18 dB, Soft blocking threshold = 13 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_thresh = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_thresh = 21,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of LOWER_CMP_N averages are lower than L_CI_HR_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of UPPER_CMP_N averages are greater than L_CI_HR_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* No averaging (filtering) by default */</span><br><span style="color: hsl(120, 100%, 40%);">+ .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ .ci_amr_fr_meas = { /* AMR-FR: Target C/I = 9 dB, Soft blocking threshold = 4 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_thresh = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_thresh = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of LOWER_CMP_N averages are lower than L_CI_AMR_FR_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of UPPER_CMP_N averages are greater than L_CI_AMR_FR_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* No averaging (filtering) by default */</span><br><span style="color: hsl(120, 100%, 40%);">+ .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ .ci_amr_hr_meas = { /* AMR-HR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_thresh = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_thresh = 17,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of LOWER_CMP_N averages are lower than L_CI_AMR_HR_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of UPPER_CMP_N averages are greater than L_CI_AMR_HR_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* No averaging (filtering) by default */</span><br><span style="color: hsl(120, 100%, 40%);">+ .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ .ci_sdcch_meas = { /* SDCCH: Target C/I = 14 dB, Soft blocking threshold = 9 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_thresh = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_thresh = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of LOWER_CMP_N averages are lower than L_CI_SDCCH_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of UPPER_CMP_N averages are greater than L_CI_SDCCH_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* No averaging (filtering) by default */</span><br><span style="color: hsl(120, 100%, 40%);">+ .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ .ci_gprs_meas = { /* GPRS: Target C/I = 20 dB, Soft blocking threshold = 15 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_thresh = 18,</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_thresh = 24,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of LOWER_CMP_N averages are lower than L_CI_GPRS_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+ * out of UPPER_CMP_N averages are greater than L_CI_GPRS_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* No averaging (filtering) by default */</span><br><span style="color: hsl(120, 100%, 40%);">+ .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+ .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void power_ctrl_params_def_reset(struct gsm_power_ctrl_params *params, bool is_bs_pwr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ *params = power_ctrl_params_def;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!is_bs_pwr)</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Trigger loop every fourth SACCH block (1.92s). TS 45.008 sec 4.7.1: */</span><br><span style="color: hsl(120, 100%, 40%);">+ params->ctrl_interval = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/25698">change 25698</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/+/25698"/><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: I1493f40d99f88a565f15d3e0943a512fb9b8719a </div>
<div style="display:none"> Gerrit-Change-Number: 25698 </div>
<div style="display:none"> Gerrit-PatchSet: 7 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>