<p>dexter has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/19793">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">abis_rsl: prioritize emergency calls over regular calls<br><br>when an emergency call arrives while all TCH are busy, the BSC should<br>pick an arbitrary (preferably the longest lasting) call / lchan and<br>release it in favor of the incoming emergancy call.<br><br>The release of the existing call is a process that can not be done<br>synchronously while the ChanRQD is handled sonce multiple messages are<br>exchanged between BTS and MSC and multiple FSMs need to do their work.<br><br>To be able to release one lchan while handling a ChanRQD a queue is<br>implemented in which the incomming channel requests are collected. The<br>queue is checked regulary for incoming requests. If one of the requests<br>is for an emergency call and if all channels are busy one channel is<br>picked and released. It is also made sure that the incoming emergency<br>call directly gets the TCH that was just released.<br><br>Change-Id: If8651265928797dbda9f528b544931dcfa4a0b36<br>Related: OS#4549<br>---<br>M include/osmocom/bsc/abis_rsl.h<br>M include/osmocom/bsc/bts.h<br>M include/osmocom/bsc/lchan_fsm.h<br>M include/osmocom/bsc/lchan_select.h<br>M src/ipaccess/ipaccess-config.c<br>M src/ipaccess/ipaccess-proxy.c<br>M src/osmo-bsc/abis_rsl.c<br>M src/osmo-bsc/bts.c<br>M src/osmo-bsc/lchan_fsm.c<br>M src/osmo-bsc/lchan_select.c<br>M src/utils/bs11_config.c<br>M src/utils/meas_json.c<br>M tests/abis/abis_test.c<br>M tests/acc/acc_test.c<br>M tests/bsc/bsc_test.c<br>M tests/gsm0408/gsm0408_test.c<br>M tests/nanobts_omlattr/nanobts_omlattr_test.c<br>17 files changed, 271 insertions(+), 47 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/93/19793/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/abis_rsl.h b/include/osmocom/bsc/abis_rsl.h</span><br><span>index 2611a3d..146c636 100644</span><br><span>--- a/include/osmocom/bsc/abis_rsl.h</span><br><span>+++ b/include/osmocom/bsc/abis_rsl.h</span><br><span>@@ -118,5 +118,7 @@</span><br><span> </span><br><span> int rsl_tx_rf_chan_release(struct gsm_lchan *lchan);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif /* RSL_MT_H */</span><br><span> </span><br><span>diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h</span><br><span>index 16053a3..693fb80 100644</span><br><span>--- a/include/osmocom/bsc/bts.h</span><br><span>+++ b/include/osmocom/bsc/bts.h</span><br><span>@@ -495,6 +495,8 @@</span><br><span>       struct osmo_timer_list etws_timer;      /* when to stop ETWS PN */</span><br><span> </span><br><span>       struct llist_head oml_fail_rep;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct llist_head chan_rqd_queue;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_timer_list chan_rqd_queue_timer;</span><br><span> };</span><br><span> </span><br><span> #define GSM_BTS_SI2Q(bts, i)   (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])</span><br><span>diff --git a/include/osmocom/bsc/lchan_fsm.h b/include/osmocom/bsc/lchan_fsm.h</span><br><span>index e5b3707..8dc228b 100644</span><br><span>--- a/include/osmocom/bsc/lchan_fsm.h</span><br><span>+++ b/include/osmocom/bsc/lchan_fsm.h</span><br><span>@@ -75,3 +75,5 @@</span><br><span> void lchan_forget_conn(struct gsm_lchan *lchan);</span><br><span> </span><br><span> void lchan_set_last_error(struct gsm_lchan *lchan, const char *fmt, ...);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void lchan_fsm_skip_error(struct gsm_lchan *lchan);</span><br><span>diff --git a/include/osmocom/bsc/lchan_select.h b/include/osmocom/bsc/lchan_select.h</span><br><span>index 865181b..7a828d9 100644</span><br><span>--- a/include/osmocom/bsc/lchan_select.h</span><br><span>+++ b/include/osmocom/bsc/lchan_select.h</span><br><span>@@ -4,3 +4,4 @@</span><br><span> struct gsm_lchan *lchan_select_by_type(struct gsm_bts *bts, enum gsm_chan_t type);</span><br><span> struct gsm_lchan *lchan_select_by_chan_mode(struct gsm_bts *bts,</span><br><span>                                           enum gsm48_chan_mode chan_mode, enum channel_rate chan_rate);</span><br><span style="color: hsl(120, 100%, 40%);">+bool lchan_select_avail(struct gsm_bts *bts, enum gsm_chan_t type);</span><br><span>diff --git a/src/ipaccess/ipaccess-config.c b/src/ipaccess/ipaccess-config.c</span><br><span>index c9264d7..be5f6a8 100644</span><br><span>--- a/src/ipaccess/ipaccess-config.c</span><br><span>+++ b/src/ipaccess/ipaccess-config.c</span><br><span>@@ -1142,3 +1142,4 @@</span><br><span> int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)</span><br><span> { return 0; }</span><br><span> int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts) { return 0; }</span><br><span>diff --git a/src/ipaccess/ipaccess-proxy.c b/src/ipaccess/ipaccess-proxy.c</span><br><span>index d5dd8d4..fec866a 100644</span><br><span>--- a/src/ipaccess/ipaccess-proxy.c</span><br><span>+++ b/src/ipaccess/ipaccess-proxy.c</span><br><span>@@ -1260,3 +1260,4 @@</span><br><span> int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)</span><br><span> { return 0; }</span><br><span> int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts) { return 0; }</span><br><span>diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c</span><br><span>index 42f3a42..64c4af5 100644</span><br><span>--- a/src/osmo-bsc/abis_rsl.c</span><br><span>+++ b/src/osmo-bsc/abis_rsl.c</span><br><span>@@ -1322,77 +1322,219 @@</span><br><span>         return rsl_send_imm_ass_rej(bts, rqd_ref, wait_ind);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct chan_rqd {</span><br><span style="color: hsl(120, 100%, 40%);">+      struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm48_req_ref ref;</span><br><span style="color: hsl(120, 100%, 40%);">+     enum gsm_chreq_reason_t reason;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t ta;</span><br><span style="color: hsl(120, 100%, 40%);">+   bool relasing;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm_lchan *lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Handle packet channel rach requests */</span><br><span style="color: hsl(0, 100%, 40%);">-static int rsl_rx_pchan_rqd(struct msgb *msg, struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+static int rsl_rx_pchan_rqd(struct chan_rqd *rqd)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gsm48_req_ref *rqd_ref;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-      rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t ra = rqd_ref->ra;</span><br><span>         uint8_t t1, t2, t3;</span><br><span>  uint32_t fn;</span><br><span>         uint8_t rqd_ta;</span><br><span>      uint8_t is_11bit;</span><br><span> </span><br><span>        /* Process rach request and forward contained information to PCU */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ra == 0x7F) {</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rqd->ref.ra == 0x7F) {</span><br><span>                is_11bit = 1;</span><br><span> </span><br><span>            /* FIXME: Also handle 11 bit rach requests */</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGP(DRSL, LOGL_ERROR, "BTS %d eleven bit access burst not supported yet!\n",bts->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DRSL, LOGL_ERROR, "BTS %d eleven bit access burst not supported yet!\n",rqd->bts->nr);</span><br><span>          return -EINVAL;</span><br><span>      } else {</span><br><span>             is_11bit = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-           t1 = rqd_ref->t1;</span><br><span style="color: hsl(0, 100%, 40%);">-            t2 = rqd_ref->t2;</span><br><span style="color: hsl(0, 100%, 40%);">-            t3 = rqd_ref->t3_low | (rqd_ref->t3_high << 3);</span><br><span style="color: hsl(120, 100%, 40%);">+           t1 = rqd->ref.t1;</span><br><span style="color: hsl(120, 100%, 40%);">+          t2 = rqd->ref.t2;</span><br><span style="color: hsl(120, 100%, 40%);">+          t3 = rqd->ref.t3_low | (rqd->ref.t3_high << 3);</span><br><span>          fn = (51 * ((t3-t2) % 26) + t3 + 51 * 26 * t1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];</span><br><span style="color: hsl(120, 100%, 40%);">+            rqd_ta = rqd->ta;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return pcu_tx_rach_ind(bts, rqd_ta, ra, fn, is_11bit,</span><br><span style="color: hsl(120, 100%, 40%);">+ return pcu_tx_rach_ind(rqd->bts, rqd_ta, rqd->ref.ra, fn, is_11bit,</span><br><span>                           GSM_L1_BURST_TYPE_ACCESS_0);</span><br><span> }</span><br><span> </span><br><span> /* MS has requested a channel on the RACH */</span><br><span> static int rsl_rx_chan_rqd(struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       struct lchan_activate_info info;</span><br><span>     struct e1inp_sign_link *sign_link = msg->dst;</span><br><span>     struct gsm_bts *bts = sign_link->trx->bts;</span><br><span>     struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gsm48_req_ref *rqd_ref;</span><br><span style="color: hsl(0, 100%, 40%);">-  enum gsm_chan_t lctype;</span><br><span style="color: hsl(0, 100%, 40%);">- enum gsm_chreq_reason_t chreq_reason;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gsm_lchan *lchan;</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t rqd_ta;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct chan_rqd *rqd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       rqd = talloc_zero(bts, struct chan_rqd);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(rqd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   rqd->bts = bts;</span><br><span> </span><br><span>       /* parse request reference to be used in immediate assign */</span><br><span style="color: hsl(0, 100%, 40%);">-    if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE)</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rqd_hdr->data[0] != RSL_IE_REQ_REFERENCE) {</span><br><span style="color: hsl(120, 100%, 40%);">+            talloc_free(rqd);</span><br><span>            return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     memcpy(&rqd->ref, &rqd_hdr->data[1], sizeof(rqd->ref));</span><br><span> </span><br><span>         /* parse access delay and use as TA */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY)</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rqd_hdr->data[sizeof(struct gsm48_req_ref)+1] != RSL_IE_ACCESS_DELAY) {</span><br><span style="color: hsl(120, 100%, 40%);">+                talloc_free(rqd);</span><br><span>            return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     rqd->ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];</span><br><span> </span><br><span>   /* Determine channel request cause code */</span><br><span style="color: hsl(0, 100%, 40%);">-      chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);</span><br><span style="color: hsl(120, 100%, 40%);">+ rqd->reason = get_reason_by_chreq(rqd->ref.ra, bts->network->neci);</span><br><span>      LOG_BTS(bts, DRSL, LOGL_INFO, "CHAN RQD: reason: %s (ra=0x%02x, neci=0x%02x, chreq_reason=0x%02x)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-         get_value_string(gsm_chreq_descs, chreq_reason), rqd_ref->ra, bts->network->neci, chreq_reason);</span><br><span style="color: hsl(120, 100%, 40%);">+             get_value_string(gsm_chreq_descs, rqd->reason), rqd->ref.ra, bts->network->neci, rqd->reason);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       rate_ctr_inc(&bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Enqueue request */</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_add_tail(&rqd->list, &bts->chan_rqd_queue);</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</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%);">+/* Find any busy TCH/H or TCH/F lchan, prefer established and old lchans */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct gsm_lchan *get_any_lchan(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int trx_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+   int ts_nr;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_bts_trx *trx;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_bts_trx_ts *ts;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_lchan *lchan_est = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_lchan *lchan_any = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_lchan *lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {</span><br><span style="color: hsl(120, 100%, 40%);">+             trx = gsm_bts_trx_num(bts, trx_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+           for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      ts = &trx->ts[ts_nr];</span><br><span style="color: hsl(120, 100%, 40%);">+                  ts_for_each_lchan(lchan, ts) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                 if (bts->chan_alloc_reverse) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                             if (lchan->fi->state == LCHAN_ST_ESTABLISHED)</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   lchan_est = lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+                                            else</span><br><span style="color: hsl(120, 100%, 40%);">+                                                  lchan_any = lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+                                    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                              if (lchan->fi->state == LCHAN_ST_ESTABLISHED) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                 if (!lchan_est)</span><br><span style="color: hsl(120, 100%, 40%);">+                                                               lchan_est = lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+                                            } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      if (!lchan_any)</span><br><span style="color: hsl(120, 100%, 40%);">+                                                               lchan_any = lchan;</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%);">+                     }</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%);">+   if (lchan_est)</span><br><span style="color: hsl(120, 100%, 40%);">+                return lchan_est;</span><br><span style="color: hsl(120, 100%, 40%);">+     else if (lchan_any)</span><br><span style="color: hsl(120, 100%, 40%);">+           return lchan_any;</span><br><span style="color: hsl(120, 100%, 40%);">+     return 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%);">+/* Ensure that an incoming emergency call gets priority, if all voice channels</span><br><span style="color: hsl(120, 100%, 40%);">+ * are busy, terminate one regular call */</span><br><span style="color: hsl(120, 100%, 40%);">+static int handle_emergency_call(struct chan_rqd *rqd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      /* If the request is not about an emergency call, we may exit early,</span><br><span style="color: hsl(120, 100%, 40%);">+   * without doing anything. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if(rqd->reason != GSM_CHREQ_REASON_EMERG)</span><br><span style="color: hsl(120, 100%, 40%);">+              return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* First check the situation on the BTS, if we still have TCH/H or</span><br><span style="color: hsl(120, 100%, 40%);">+     * TCH/F resources available, then not action is required. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan_select_avail(rqd->bts, GSM_LCHAN_TCH_F)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOG_BTS(rqd->bts, DRSL, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                       "CHAN RQD/EMERGENCY-PRIORITY: at least one TCH/F is (now) available!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (lchan_select_avail(rqd->bts, GSM_LCHAN_TCH_H)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOG_BTS(rqd->bts, DRSL, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                       "CHAN RQD/EMERGENCY-PRIORITY: at least one TCH/H is (now) available!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return 0;</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%);">+   if (!rqd->relasing) {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Pick any busy TCH/F or TCH/H lchan and inititate a channel</span><br><span style="color: hsl(120, 100%, 40%);">+          * release to make room for the incoming emergency call */</span><br><span style="color: hsl(120, 100%, 40%);">+            rqd->lchan = get_any_lchan(rqd->bts);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!rqd->lchan) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* It can not happen that we first find out that there</span><br><span style="color: hsl(120, 100%, 40%);">+                         * is no TCH/H or TCH/F available and at the same time</span><br><span style="color: hsl(120, 100%, 40%);">+                         * we ware unable to find any busy TCH/H or TCH/F. In</span><br><span style="color: hsl(120, 100%, 40%);">+                  * this case, the BTS probably does not have any</span><br><span style="color: hsl(120, 100%, 40%);">+                       * voice channels configured? */</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOG_BTS(rqd->bts, DRSL, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                               "CHAN RQD/EMERGENCY-PRIORITY: no TCH/H or TCH/F available - check VTY config!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                  return 0;</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%);">+           LOG_BTS(rqd->bts, DRSL, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                       "CHAN RQD/EMERGENCY-PRIORITY: inducing termination of lchan %s (state:%s) in favor of incoming EMERGENCY CALL!\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  gsm_lchan_name(rqd->lchan), osmo_fsm_inst_state_name(rqd->lchan->fi));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             lchan_release(rqd->lchan, !!(rqd->lchan->conn), true, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+            rqd->relasing = true;</span><br><span style="color: hsl(120, 100%, 40%);">+      } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!rqd->lchan->fi) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOG_BTS(rqd->bts, DRSL, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                                "CHAN RQD/EMERGENCY-PRIORITY: lchan %s has lost its FSM - skipping!\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                             gsm_lchan_name(rqd->lchan));</span><br><span style="color: hsl(120, 100%, 40%);">+                       return 0;</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%);">+           LOG_BTS(rqd->bts, DRSL, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                       "CHAN RQD/EMERGENCY-PRIORITY: still terminating lchan %s (state:%s) in favor of incoming EMERGENCY CALL!\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                        gsm_lchan_name(rqd->lchan), osmo_fsm_inst_state_name(rqd->lchan->fi));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             /* If the channel was released in error (not established), the</span><br><span style="color: hsl(120, 100%, 40%);">+                 * lchan FSM automatically blocks the LCHAN for a short time.</span><br><span style="color: hsl(120, 100%, 40%);">+          * This is not acceptable in an emergency situation, so we skip</span><br><span style="color: hsl(120, 100%, 40%);">+                * this waiting period. */</span><br><span style="color: hsl(120, 100%, 40%);">+            if (rqd->lchan->fi->state == LCHAN_ST_WAIT_AFTER_ERROR)</span><br><span style="color: hsl(120, 100%, 40%);">+                      lchan_fsm_skip_error(rqd->lchan);</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%);">+   return -1;</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%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct lchan_activate_info info;</span><br><span style="color: hsl(120, 100%, 40%);">+      enum gsm_chan_t lctype;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_lchan *lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct llist_head *lh_rqd;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct chan_rqd *rqd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (llist_empty(&bts->chan_rqd_queue)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     lh_rqd = bts->chan_rqd_queue.next;</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!lh_rqd)</span><br><span style="color: hsl(120, 100%, 40%);">+           return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     rqd = llist_entry(lh_rqd, struct chan_rqd, list);</span><br><span> </span><br><span>        /* Handle PDCH related rach requests (in case of BSC-co-located-PCU */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (chreq_reason == GSM_CHREQ_REASON_PDCH)</span><br><span style="color: hsl(0, 100%, 40%);">-              return rsl_rx_pchan_rqd(msg, bts);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rqd->reason == GSM_CHREQ_REASON_PDCH)</span><br><span style="color: hsl(120, 100%, 40%);">+          return rsl_rx_pchan_rqd(rqd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Ensure that emergency calls will get priority over regular calls */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (handle_emergency_call(rqd) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return 0;</span><br><span> </span><br><span>        /* determine channel type (SDCCH/TCH_F/TCH_H) based on</span><br><span>        * request reference RA */</span><br><span style="color: hsl(0, 100%, 40%);">-      lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   rate_ctr_inc(&bts->bts_ctrs->ctr[BTS_CTR_CHREQ_TOTAL]);</span><br><span style="color: hsl(120, 100%, 40%);">+     lctype = get_ctype_by_chreq(bts->network, rqd->ref.ra);</span><br><span> </span><br><span>    /* check availability / allocate channel</span><br><span>      *</span><br><span>@@ -1402,30 +1544,45 @@</span><br><span>          * - If there is still no channel available, try a TCH/F.</span><br><span>     *</span><br><span>    */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (chreq_reason == GSM_CHREQ_REASON_EMERG) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rqd->reason == GSM_CHREQ_REASON_EMERG) {</span><br><span>              if (bts->si_common.rach_control.t2 & 0x4) {</span><br><span>                   LOG_BTS(bts, DRSL, LOGL_NOTICE, "CHAN RQD: MS attempts EMERGENCY CALL although EMERGENCY CALLS "</span><br><span>                           "are not allowed in sysinfo (spec violation by MS!)\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                      rsl_tx_imm_ass_rej(bts, rqd_ref);</span><br><span style="color: hsl(120, 100%, 40%);">+                     rsl_tx_imm_ass_rej(bts, &rqd->ref);</span><br><span style="color: hsl(120, 100%, 40%);">+                    llist_del(lh_rqd);</span><br><span style="color: hsl(120, 100%, 40%);">+                    talloc_free(rqd);</span><br><span>                    return -EINVAL;</span><br><span>              }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       lchan = lchan_select_by_type(bts, GSM_LCHAN_SDCCH);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan = lchan_select_by_type(bts, GSM_LCHAN_TCH_F);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If an emergency call is incoming, the preemption logic already</span><br><span style="color: hsl(120, 100%, 40%);">+      * has made sure that there is at least one TCH/F or TCH/H available,</span><br><span style="color: hsl(120, 100%, 40%);">+  * so we refrain from assigning an SDCCH first, assigning the TCH</span><br><span style="color: hsl(120, 100%, 40%);">+      * dirrectly is faster and safer in this case */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rqd->reason == GSM_CHREQ_REASON_EMERG)</span><br><span style="color: hsl(120, 100%, 40%);">+         lchan = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+          lchan = lchan_select_by_type(bts, GSM_LCHAN_SDCCH);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        if (!lchan) {</span><br><span>                LOG_BTS(bts, DRSL, LOGL_NOTICE, "CHAN RQD: no resources for %s 0x%x, retrying with %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     gsm_lchant_name(GSM_LCHAN_SDCCH), rqd_ref->ra, gsm_lchant_name(GSM_LCHAN_TCH_H));</span><br><span style="color: hsl(120, 100%, 40%);">+                  gsm_lchant_name(GSM_LCHAN_SDCCH), rqd->ref.ra, gsm_lchant_name(GSM_LCHAN_TCH_H));</span><br><span>                 lchan = lchan_select_by_type(bts, GSM_LCHAN_TCH_H);</span><br><span>  }</span><br><span>    if (!lchan) {</span><br><span>                LOG_BTS(bts, DRSL, LOGL_NOTICE, "CHAN RQD: no resources for %s 0x%x, retrying with %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     gsm_lchant_name(GSM_LCHAN_SDCCH), rqd_ref->ra, gsm_lchant_name(GSM_LCHAN_TCH_F));</span><br><span style="color: hsl(120, 100%, 40%);">+                  gsm_lchant_name(GSM_LCHAN_SDCCH), rqd->ref.ra, gsm_lchant_name(GSM_LCHAN_TCH_F));</span><br><span>                 lchan = lchan_select_by_type(bts, GSM_LCHAN_TCH_F);</span><br><span>  }</span><br><span>    if (!lchan) {</span><br><span>                LOG_BTS(bts, DRSL, LOGL_NOTICE, "CHAN RQD: no resources for %s 0x%x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       gsm_lchant_name(lctype), rqd_ref->ra);</span><br><span style="color: hsl(120, 100%, 40%);">+                     gsm_lchant_name(lctype), rqd->ref.ra);</span><br><span>            rate_ctr_inc(&bts->bts_ctrs->ctr[BTS_CTR_CHREQ_NO_CHANNEL]);</span><br><span style="color: hsl(0, 100%, 40%);">-          rsl_tx_imm_ass_rej(bts, rqd_ref);</span><br><span style="color: hsl(120, 100%, 40%);">+             rsl_tx_imm_ass_rej(bts, &rqd->ref);</span><br><span style="color: hsl(120, 100%, 40%);">+            llist_del(lh_rqd);</span><br><span style="color: hsl(120, 100%, 40%);">+            talloc_free(rqd);</span><br><span>            return 0;</span><br><span>    }</span><br><span> </span><br><span>@@ -1433,17 +1590,19 @@</span><br><span>      lchan->rqd_ref = talloc_zero(bts, struct gsm48_req_ref);</span><br><span>  OSMO_ASSERT(lchan->rqd_ref);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     *(lchan->rqd_ref) = *rqd_ref;</span><br><span style="color: hsl(0, 100%, 40%);">-        lchan->rqd_ta = rqd_ta;</span><br><span style="color: hsl(120, 100%, 40%);">+    *(lchan->rqd_ref) = rqd->ref;</span><br><span style="color: hsl(120, 100%, 40%);">+   lchan->rqd_ta = rqd->ta;</span><br><span> </span><br><span>   LOG_LCHAN(lchan, LOGL_DEBUG, "MS: Channel Request: reason=%s ra=0x%02x ta=%d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                gsm_chreq_name(chreq_reason), rqd_ref->ra, rqd_ta);</span><br><span style="color: hsl(120, 100%, 40%);">+                gsm_chreq_name(rqd->reason), rqd->ref.ra, rqd->ta);</span><br><span>       info = (struct lchan_activate_info){</span><br><span>                 .activ_for = FOR_MS_CHANNEL_REQUEST,</span><br><span>                 .chan_mode = GSM48_CMODE_SIGN,</span><br><span>       };</span><br><span> </span><br><span>       lchan_activate(lchan, &info);</span><br><span style="color: hsl(120, 100%, 40%);">+     llist_del(lh_rqd);</span><br><span style="color: hsl(120, 100%, 40%);">+    talloc_free(rqd);</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c</span><br><span>index 4318b7e..ff85267 100644</span><br><span>--- a/src/osmo-bsc/bts.c</span><br><span>+++ b/src/osmo-bsc/bts.c</span><br><span>@@ -23,6 +23,7 @@</span><br><span> #include <osmocom/bsc/gsm_data.h></span><br><span> #include <osmocom/bsc/bts.h></span><br><span> #include <osmocom/bsc/debug.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/abis_rsl.h></span><br><span> </span><br><span> const struct value_string bts_attribute_names[] = {</span><br><span>     OSMO_VALUE_STRING(BTS_TYPE_VARIANT),</span><br><span>@@ -31,6 +32,14 @@</span><br><span>    { 0, NULL }</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* timer call-back to poll CHAN RQD queue */</span><br><span style="color: hsl(120, 100%, 40%);">+static void chan_rqd_poll_cb(void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_bts *bts = (struct gsm_bts *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+ abis_rsl_chan_rqd_queue_poll(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_timer_schedule(&bts->chan_rqd_queue_timer, 0, 100000);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> enum bts_attribute str2btsattr(const char *s)</span><br><span> {</span><br><span>        return get_string_value(bts_attribute_names, s);</span><br><span>@@ -319,6 +328,11 @@</span><br><span>      INIT_LLIST_HEAD(&bts->loc_list);</span><br><span>      INIT_LLIST_HEAD(&bts->local_neighbors);</span><br><span>       INIT_LLIST_HEAD(&bts->oml_fail_rep);</span><br><span style="color: hsl(120, 100%, 40%);">+   INIT_LLIST_HEAD(&bts->chan_rqd_queue);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Start CHAN RQD queue */</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_timer_setup(&bts->chan_rqd_queue_timer, chan_rqd_poll_cb, bts);</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_timer_schedule(&bts->chan_rqd_queue_timer, 0, 0);</span><br><span> </span><br><span>    /* Enable all codecs by default. These get reset to a more fine grained selection IF a</span><br><span>        * 'codec-support' config appears in the config file (see bsc_vty.c). */</span><br><span>diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c</span><br><span>index db72651..ea4a115 100644</span><br><span>--- a/src/osmo-bsc/lchan_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_fsm.c</span><br><span>@@ -1479,6 +1479,13 @@</span><br><span>       }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void lchan_fsm_skip_error(struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_fsm_inst *fi = lchan->fi;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (fi->state == LCHAN_ST_WAIT_AFTER_ERROR)</span><br><span style="color: hsl(120, 100%, 40%);">+                lchan_fsm_state_chg(LCHAN_ST_UNUSED);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int lchan_fsm_timer_cb(struct osmo_fsm_inst *fi)</span><br><span> {</span><br><span>   struct gsm_lchan *lchan = lchan_fi_lchan(fi);</span><br><span>diff --git a/src/osmo-bsc/lchan_select.c b/src/osmo-bsc/lchan_select.c</span><br><span>index d2dba1b..6f73fbc 100644</span><br><span>--- a/src/osmo-bsc/lchan_select.c</span><br><span>+++ b/src/osmo-bsc/lchan_select.c</span><br><span>@@ -162,16 +162,11 @@</span><br><span>       return lchan_select_by_type(bts, type);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Return a matching lchan from a specific BTS that is currently available. The next logical step is</span><br><span style="color: hsl(0, 100%, 40%);">- * lchan_activate() on it, which would possibly cause dynamic timeslot pchan switching, taken care of by</span><br><span style="color: hsl(0, 100%, 40%);">- * the lchan and timeslot FSMs. */</span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_lchan *lchan_select_by_type(struct gsm_bts *bts, enum gsm_chan_t type)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct gsm_lchan *_get_lchan_by_type(struct gsm_bts *bts, enum gsm_chan_t type)</span><br><span> {</span><br><span>         struct gsm_lchan *lchan = NULL;</span><br><span>      enum gsm_phys_chan_config first, first_cbch, second, second_cbch;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOG_BTS(bts, DRLL, LOGL_DEBUG, "lchan_select_by_type(%s)\n", gsm_lchant_name(type));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>       switch (type) {</span><br><span>      case GSM_LCHAN_SDCCH:</span><br><span>                if (bts->chan_alloc_reverse) {</span><br><span>@@ -231,6 +226,20 @@</span><br><span>             LOG_BTS(bts, DRLL, LOGL_ERROR, "Unknown gsm_chan_t %u\n", type);</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ return lchan;</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%);">+/* Return a matching lchan from a specific BTS that is currently available. The next logical step is</span><br><span style="color: hsl(120, 100%, 40%);">+ * lchan_activate() on it, which would possibly cause dynamic timeslot pchan switching, taken care of by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the lchan and timeslot FSMs. */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_lchan *lchan_select_by_type(struct gsm_bts *bts, enum gsm_chan_t type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm_lchan *lchan = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     LOG_BTS(bts, DRLL, LOGL_DEBUG, "lchan_select_by_type(%s)\n", gsm_lchant_name(type));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      lchan = _get_lchan_by_type(bts, type);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     if (lchan) {</span><br><span>                 lchan->type = type;</span><br><span>               LOG_LCHAN(lchan, LOGL_INFO, "Selected\n");</span><br><span>@@ -240,3 +249,18 @@</span><br><span> </span><br><span>      return lchan;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Look through the available BTS resources and tell if a desired channel type would be available */</span><br><span style="color: hsl(120, 100%, 40%);">+bool lchan_select_avail(struct gsm_bts *bts, enum gsm_chan_t type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gsm_lchan *lchan = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     LOG_BTS(bts, DRLL, LOGL_DEBUG, "lchan_select_avail(%s)\n", gsm_lchant_name(type));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan = _get_lchan_by_type(bts, type);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+            return true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return false;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/utils/bs11_config.c b/src/utils/bs11_config.c</span><br><span>index c279179..db804d5 100644</span><br><span>--- a/src/utils/bs11_config.c</span><br><span>+++ b/src/utils/bs11_config.c</span><br><span>@@ -995,3 +995,4 @@</span><br><span> int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)</span><br><span> { return 0; }</span><br><span> int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts) { return 0; }</span><br><span>diff --git a/src/utils/meas_json.c b/src/utils/meas_json.c</span><br><span>index b44a300..6c9d438 100644</span><br><span>--- a/src/utils/meas_json.c</span><br><span>+++ b/src/utils/meas_json.c</span><br><span>@@ -210,3 +210,4 @@</span><br><span> int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)</span><br><span> { return 0; }</span><br><span> int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts) { return 0; }</span><br><span>diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c</span><br><span>index 9d26edd..e87564e 100644</span><br><span>--- a/tests/abis/abis_test.c</span><br><span>+++ b/tests/abis/abis_test.c</span><br><span>@@ -196,3 +196,4 @@</span><br><span> int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)</span><br><span> { return 0; }</span><br><span> int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts) { return 0; }</span><br><span>diff --git a/tests/acc/acc_test.c b/tests/acc/acc_test.c</span><br><span>index 72d3212..e92972d 100644</span><br><span>--- a/tests/acc/acc_test.c</span><br><span>+++ b/tests/acc/acc_test.c</span><br><span>@@ -65,6 +65,8 @@</span><br><span>             osmo_timer_del(&bts->acc_mgr.rotate_timer);</span><br><span>   if (osmo_timer_pending(&bts->acc_ramp.step_timer))</span><br><span>            osmo_timer_del(&bts->acc_ramp.step_timer);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (osmo_timer_pending(&bts->chan_rqd_queue_timer))</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_timer_del(&bts->chan_rqd_queue_timer);</span><br><span>   /* no need to llist_del(&bts->list), we never registered the bts there. */</span><br><span>    talloc_free(bts);</span><br><span>    fprintf(stderr, "BTS deallocated OK in %s()\n", msg);</span><br><span>@@ -531,3 +533,4 @@</span><br><span> int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)</span><br><span> { return 0; }</span><br><span> int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts) { return 0; }</span><br><span>diff --git a/tests/bsc/bsc_test.c b/tests/bsc/bsc_test.c</span><br><span>index dd2b1bb..e387c37 100644</span><br><span>--- a/tests/bsc/bsc_test.c</span><br><span>+++ b/tests/bsc/bsc_test.c</span><br><span>@@ -245,3 +245,4 @@</span><br><span> int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)</span><br><span> { return 0; }</span><br><span> int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts) { return 0; }</span><br><span>diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c</span><br><span>index 35531f8..18ee788 100644</span><br><span>--- a/tests/gsm0408/gsm0408_test.c</span><br><span>+++ b/tests/gsm0408/gsm0408_test.c</span><br><span>@@ -142,6 +142,8 @@</span><br><span>      rate_ctr_group_free(bts->bts_ctrs);</span><br><span>       if (osmo_timer_pending(&bts->acc_mgr.rotate_timer))</span><br><span>           osmo_timer_del(&bts->acc_mgr.rotate_timer);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (osmo_timer_pending(&bts->chan_rqd_queue_timer))</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_timer_del(&bts->chan_rqd_queue_timer);</span><br><span>   /* no need to llist_del(&bts->list), we never registered the bts there. */</span><br><span>    talloc_free(bts);</span><br><span>    printf("BTS deallocated OK in %s()\n", msg);</span><br><span>@@ -976,3 +978,4 @@</span><br><span> int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type, const uint8_t *data, int len) { return 0; }</span><br><span> int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)</span><br><span> { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts) { return 0; }</span><br><span>diff --git a/tests/nanobts_omlattr/nanobts_omlattr_test.c b/tests/nanobts_omlattr/nanobts_omlattr_test.c</span><br><span>index ea98409..975c280 100644</span><br><span>--- a/tests/nanobts_omlattr/nanobts_omlattr_test.c</span><br><span>+++ b/tests/nanobts_omlattr/nanobts_omlattr_test.c</span><br><span>@@ -325,3 +325,4 @@</span><br><span> int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len)</span><br><span> { return 0; }</span><br><span> int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type si_type) { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+int abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts) { return 0; }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/19793">change 19793</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-bsc/+/19793"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: If8651265928797dbda9f528b544931dcfa4a0b36 </div>
<div style="display:none"> Gerrit-Change-Number: 19793 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>