<p>fixeria has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/24612">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Report interference levels in RSL RF RESource INDication<br><br>This change implements general interference averaging logic for<br>the higher layers.  In l1sap_info_time_ind(), where we receive<br>TDMA time updates from BTS model, call rsl_tx_rf_res() for each<br>transceiver according to the interval defined by the Intave<br>parameter received from the BSC.  In rsl_tx_rf_res() perform<br>the actual averaging for each inactive logical channel, and<br>then send everything to the BSC over the A-bis/RSL.<br><br>The BTS model specific code needs to report the measurements<br>for each logical channel every 104 TDMA frames (SACCH period)<br>by calling gsm_lchan_interf_meas_push().<br><br>Change-Id: Id80fdbef087de625149755165c025c0a9563dc85<br>Related: SYS#5313, OS#1569<br>---<br>M README.md<br>M doc/manuals/abis/oml.adoc<br>M include/osmo-bts/gsm_data.h<br>M src/common/gsm_data.c<br>M src/common/l1sap.c<br>M src/common/rsl.c<br>6 files changed, 116 insertions(+), 5 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/12/24612/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/README.md b/README.md</span><br><span>index 5527ef1..51aa276 100644</span><br><span>--- a/README.md</span><br><span>+++ b/README.md</span><br><span>@@ -96,7 +96,6 @@</span><br><span>  * System Information limited to 1,2,2bis,2ter,2quater,3,4,5,6,9,13</span><br><span>  * No RATSCCH in AMR</span><br><span>  * Will reject TS 12.21 STARTING TIME in SET BTS ATTR / SET CHAN ATTR</span><br><span style="color: hsl(0, 100%, 40%);">- * No reporting of interference levels as part of TS 08.58 RF RES IND</span><br><span>  * No support of TS 08.58 MultiRate Control</span><br><span>  * No support of TS 08.58 Supported Codec Types</span><br><span>  * No support of Bter frame / ENHANCED MEASUREMENT REPORT</span><br><span>diff --git a/doc/manuals/abis/oml.adoc b/doc/manuals/abis/oml.adoc</span><br><span>index 984ab8c..b77894c 100644</span><br><span>--- a/doc/manuals/abis/oml.adoc</span><br><span>+++ b/doc/manuals/abis/oml.adoc</span><br><span>@@ -394,8 +394,8 @@</span><br><span> | 0x13 | 9.4.19 | File Version  |  | _ignored_</span><br><span> | 0x14 | 9.4.20 | GSM Time  |  | _ignored_</span><br><span> | 0x16 | 9.4.22 | HW Configuration  |  | _ignored_</span><br><span style="color: hsl(0, 100%, 40%);">-| 0x18 | 9.4.24 | Intave Parameter  | <- | _ignored_</span><br><span style="color: hsl(0, 100%, 40%);">-| 0x19 | 9.4.25 | Interference level Boundaries  | <- | _ignored_</span><br><span style="color: hsl(120, 100%, 40%);">+| 0x18 | 9.4.24 | Intave Parameter  | <- |</span><br><span style="color: hsl(120, 100%, 40%);">+| 0x19 | 9.4.25 | Interference level Boundaries  | <- |</span><br><span> | 0x1a | 9.4.26 | List of Required Attributes  |  | _ignored_</span><br><span> | 0x1c | 9.4.28 | Manufacturer Dependent State  |  | _ignored_</span><br><span> | 0x1d | 9.4.29 | Manufacturer Dependent Thresholds  |  | _ignored_</span><br><span>diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h</span><br><span>index 6ce5c3b..9bc2e5b 100644</span><br><span>--- a/include/osmo-bts/gsm_data.h</span><br><span>+++ b/include/osmo-bts/gsm_data.h</span><br><span>@@ -337,6 +337,9 @@</span><br><span>                  /* standard deviation of toa256 value during measurement period */</span><br><span>                   uint16_t toa256_std_dev;</span><br><span>             } ext;</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Interference levels reported by PHY (in -x dBm) */</span><br><span style="color: hsl(120, 100%, 40%);">+         uint8_t interf_meas_dbm[64];</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t interf_meas_num;</span><br><span>     } meas;</span><br><span>      struct {</span><br><span>             struct amr_multirate_conf amr_mr;</span><br><span>@@ -537,6 +540,9 @@</span><br><span> uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,</span><br><span>                                    enum gsm_phys_chan_config as_pchan);</span><br><span> </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%);">+int gsm_lchan_interf_meas_calc_band(struct gsm_lchan *lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define BSIC2BCC(bsic) ((bsic) & 0x07)</span><br><span> #define BTS_TSC(bts) BSIC2BCC((bts)->bsic)</span><br><span> </span><br><span>@@ -558,4 +564,16 @@</span><br><span> </span><br><span> bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool lchan_is_dcch(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (lchan->type) {</span><br><span style="color: hsl(120, 100%, 40%);">+     case GSM_LCHAN_SDCCH:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_LCHAN_TCH_F:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM_LCHAN_TCH_H:</span><br><span style="color: hsl(120, 100%, 40%);">+         return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return 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%);">+</span><br><span> #endif /* _GSM_DATA_H */</span><br><span>diff --git a/src/common/gsm_data.c b/src/common/gsm_data.c</span><br><span>index 09664e2..cf1b379 100644</span><br><span>--- a/src/common/gsm_data.c</span><br><span>+++ b/src/common/gsm_data.c</span><br><span>@@ -280,6 +280,54 @@</span><br><span>   return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr);</span><br><span> }</span><br><span> </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] = abs(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%);">+     unsigned 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 / 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: -%udBm (band %d)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+             meas_avg, b);</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> /* 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>diff --git a/src/common/l1sap.c b/src/common/l1sap.c</span><br><span>index cd2af57..33c7e2a 100644</span><br><span>--- a/src/common/l1sap.c</span><br><span>+++ b/src/common/l1sap.c</span><br><span>@@ -587,6 +587,20 @@</span><br><span>      return rach_frames_expired;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void l1sap_interf_meas_report(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    const uint32_t period = bts->interference.intave * 104;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_bts_trx *trx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (bts->interference.intave == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         return;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (bts->gsm_time.fn % period != 0)</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%);">+     llist_for_each_entry(trx, &bts->trx_list, list)</span><br><span style="color: hsl(120, 100%, 40%);">+                rsl_tx_rf_res(trx);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* time information received from bts model */</span><br><span> static int l1sap_info_time_ind(struct gsm_bts *bts,</span><br><span>                           struct osmo_phsap_prim *l1sap,</span><br><span>@@ -619,6 +633,9 @@</span><br><span>          bts->load.rach.total += calc_exprd_rach_frames(bts, fn);</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Report interference levels to the BSC */</span><br><span style="color: hsl(120, 100%, 40%);">+   l1sap_interf_meas_report(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     return 0;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/common/rsl.c b/src/common/rsl.c</span><br><span>index 516e609..565ff14 100644</span><br><span>--- a/src/common/rsl.c</span><br><span>+++ b/src/common/rsl.c</span><br><span>@@ -427,6 +427,7 @@</span><br><span> /* 8.6.1 sending RF RESOURCE INDICATION */</span><br><span> int rsl_tx_rf_res(struct gsm_bts_trx *trx)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int tn, ln;</span><br><span>         struct msgb *nmsg;</span><br><span> </span><br><span>       LOGP(DRSL, LOGL_INFO, "Tx RSL RF RESource INDication\n");</span><br><span>@@ -434,8 +435,36 @@</span><br><span>   nmsg = rsl_msgb_alloc(sizeof(struct abis_rsl_common_hdr));</span><br><span>   if (!nmsg)</span><br><span>           return -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">- // FIXME: add interference levels of TRX</span><br><span style="color: hsl(0, 100%, 40%);">-        msgb_tlv_put(nmsg, RSL_IE_RESOURCE_INFO, 0, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Add interference levels for each logical channel */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t *len = msgb_tl_put(nmsg, RSL_IE_RESOURCE_INFO);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          struct gsm_bts_trx_ts *ts = &trx->ts[tn];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        struct gsm_lchan *lchan = &ts->lchan[ln];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* We're not interested in active lchans */</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (lchan->state == LCHAN_S_ACTIVE)</span><br><span style="color: hsl(120, 100%, 40%);">+                                continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* Only for GSM_LCHAN_{SDCCH,TCH_F,TCH_H} */</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (!lchan_is_dcch(lchan))</span><br><span style="color: hsl(120, 100%, 40%);">+                            continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* Average all collected samples */</span><br><span style="color: hsl(120, 100%, 40%);">+                   int band = gsm_lchan_interf_meas_calc_band(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (band < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                              continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   msgb_v_put(nmsg, gsm_lchan2chan_nr(lchan));</span><br><span style="color: hsl(120, 100%, 40%);">+                   msgb_v_put(nmsg, (band & 0x07) << 5);</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%);">+   /* Calculate length of the V part */</span><br><span style="color: hsl(120, 100%, 40%);">+  *len = msgb_l3len(nmsg) - 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       rsl_trx_push_hdr(nmsg, RSL_MT_RF_RES_IND);</span><br><span>   nmsg->trx = trx;</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/24612">change 24612</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/+/24612"/><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: Id80fdbef087de625149755165c025c0a9563dc85 </div>
<div style="display:none"> Gerrit-Change-Number: 24612 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>