<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>