aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2018-08-24 23:40:59 +0200
committerHarald Welte <laforge@gnumonks.org>2018-09-09 15:40:58 +0000
commitd9a1cd994ced629589fbf75bc59490c5fc0d1a43 (patch)
tree3862062d3de8be91952296dfa2eb1d7b96bb6701
parent02d99db08b13589e1417c3448a07747f8805ba88 (diff)
CBCH: Implement CBCH support for osmo-bts-{trx,virtual}
This patch adds scheduler support for the channel combinations that substitute SDCCH index 2 for a CBCH in either a SDCCH/8 or SDCCH/4. Change-Id: Icc15603079a1709ec094f400a9bcf0008211890f Closes: OS#1617
-rw-r--r--README.md1
-rw-r--r--include/osmo-bts/scheduler.h1
-rw-r--r--src/common/scheduler.c3
-rw-r--r--src/common/scheduler_mframe.c218
-rw-r--r--src/osmo-bts-trx/main.c1
-rw-r--r--src/osmo-bts-virtual/main.c1
6 files changed, 223 insertions, 2 deletions
diff --git a/README.md b/README.md
index 43c27b26..38b4bd9f 100644
--- a/README.md
+++ b/README.md
@@ -124,4 +124,3 @@ osmo-bts-trx
* TCH/F_PDCH cannel not working as voice (https://osmocom.org/issues/1865)
* No BER value delivered to OsmoPCU (https://osmocom.org/issues/1855)
* No 11bit RACH support (https://osmocom.org/issues/1854)
- * No CBCH support (https://osmocom.org/issues/1617)
diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h
index 3fe7978c..32d6e917 100644
--- a/include/osmo-bts/scheduler.h
+++ b/include/osmo-bts/scheduler.h
@@ -47,6 +47,7 @@ enum trx_chan_type {
TRXC_SACCH8_7,
TRXC_PDTCH,
TRXC_PTCCH,
+ TRXC_CBCH,
_TRX_CHAN_MAX
};
diff --git a/src/common/scheduler.c b/src/common/scheduler.c
index 5c250e4d..8a6c0078 100644
--- a/src/common/scheduler.c
+++ b/src/common/scheduler.c
@@ -116,6 +116,7 @@ const ubit_t _sched_sch_train[64] = {
*/
const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
+ /* is_pdch chan_type chan_nr link_id name rts_fn dl_fn ul_fn auto_active */
{ 0, TRXC_IDLE, 0, LID_DEDIC, "IDLE", NULL, tx_idle_fn, NULL, 1 },
{ 0, TRXC_FCCH, 0, LID_DEDIC, "FCCH", NULL, tx_fcch_fn, NULL, 1 },
{ 0, TRXC_SCH, 0, LID_DEDIC, "SCH", NULL, tx_sch_fn, NULL, 1 },
@@ -154,6 +155,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
{ 0, TRXC_SACCH8_7, 0x78, LID_SACCH, "SACCH/8(7)", rts_data_fn, tx_data_fn, rx_data_fn, 0 },
{ 1, TRXC_PDTCH, 0xc0, LID_DEDIC, "PDTCH", rts_data_fn, tx_pdtch_fn, rx_pdtch_fn, 0 },
{ 1, TRXC_PTCCH, 0xc0, LID_DEDIC, "PTCCH", rts_data_fn, tx_data_fn, rx_data_fn, 0 },
+ { 0, TRXC_CBCH, 0xc8, LID_DEDIC, "CBCH", rts_data_fn, tx_data_fn, NULL, 1 },
};
const struct value_string trx_chan_type_names[] = {
@@ -195,6 +197,7 @@ const struct value_string trx_chan_type_names[] = {
OSMO_VALUE_STRING(TRXC_SACCH8_7),
OSMO_VALUE_STRING(TRXC_PDTCH),
OSMO_VALUE_STRING(TRXC_PTCCH),
+ OSMO_VALUE_STRING(TRXC_CBCH),
OSMO_VALUE_STRING(_TRX_CHAN_MAX),
{ 0, NULL }
};
diff --git a/src/common/scheduler_mframe.c b/src/common/scheduler_mframe.c
index ab0b5b63..b78ffa85 100644
--- a/src/common/scheduler_mframe.c
+++ b/src/common/scheduler_mframe.c
@@ -2,7 +2,7 @@
/* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
* (C) 2015 by Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
- * (C) 2015-2017 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2015-2018 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
@@ -170,6 +170,113 @@ static const struct trx_sched_frame frame_bcch_sdcch4[102] = {
{ TRXC_IDLE, 0, TRXC_SDCCH4_2, 3 },
};
+static const struct trx_sched_frame frame_bcch_sdcch4_cbch[102] = {
+/* dl_chan dl_bid ul_chan ul_bid */
+ { TRXC_FCCH, 0, TRXC_SDCCH4_3, 0 },
+ { TRXC_SCH, 0, TRXC_SDCCH4_3, 1 },
+ { TRXC_BCCH, 0, TRXC_SDCCH4_3, 2 },
+ { TRXC_BCCH, 1, TRXC_SDCCH4_3, 3 },
+ { TRXC_BCCH, 2, TRXC_RACH, 0 },
+ { TRXC_BCCH, 3, TRXC_RACH, 0 },
+ { TRXC_CCCH, 0, TRXC_IDLE, 0 },
+ { TRXC_CCCH, 1, TRXC_IDLE, 1 },
+ { TRXC_CCCH, 2, TRXC_IDLE, 2 },
+ { TRXC_CCCH, 3, TRXC_IDLE, 3 },
+ { TRXC_FCCH, 0, TRXC_SACCH4_3, 0 },
+ { TRXC_SCH, 0, TRXC_SACCH4_3, 1 },
+ { TRXC_CCCH, 0, TRXC_SACCH4_3, 2 },
+ { TRXC_CCCH, 1, TRXC_SACCH4_3, 3 },
+ { TRXC_CCCH, 2, TRXC_RACH, 0 },
+ { TRXC_CCCH, 3, TRXC_RACH, 0 },
+ { TRXC_CCCH, 0, TRXC_RACH, 0 },
+ { TRXC_CCCH, 1, TRXC_RACH, 0 },
+ { TRXC_CCCH, 2, TRXC_RACH, 0 },
+ { TRXC_CCCH, 3, TRXC_RACH, 0 },
+ { TRXC_FCCH, 0, TRXC_RACH, 0 },
+ { TRXC_SCH, 0, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_0, 0, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_0, 1, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_0, 2, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_0, 3, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_1, 0, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_1, 1, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_1, 2, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_1, 3, TRXC_RACH, 0 },
+ { TRXC_FCCH, 0, TRXC_RACH, 0 },
+ { TRXC_SCH, 0, TRXC_RACH, 0 },
+ { TRXC_CBCH, 0, TRXC_RACH, 0 },
+ { TRXC_CBCH, 1, TRXC_RACH, 0 },
+ { TRXC_CBCH, 2, TRXC_RACH, 0 },
+ { TRXC_CBCH, 3, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_3, 0, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_3, 1, TRXC_SDCCH4_0, 0 },
+ { TRXC_SDCCH4_3, 2, TRXC_SDCCH4_0, 1 },
+ { TRXC_SDCCH4_3, 3, TRXC_SDCCH4_0, 2 },
+ { TRXC_FCCH, 0, TRXC_SDCCH4_0, 3 },
+ { TRXC_SCH, 0, TRXC_SDCCH4_1, 0 },
+ { TRXC_SACCH4_0, 0, TRXC_SDCCH4_1, 1 },
+ { TRXC_SACCH4_0, 1, TRXC_SDCCH4_1, 2 },
+ { TRXC_SACCH4_0, 2, TRXC_SDCCH4_1, 3 },
+ { TRXC_SACCH4_0, 3, TRXC_RACH, 0 },
+ { TRXC_SACCH4_1, 0, TRXC_RACH, 0 },
+ { TRXC_SACCH4_1, 1, TRXC_RACH, 0 },
+ { TRXC_SACCH4_1, 2, TRXC_RACH, 1 },
+ { TRXC_SACCH4_1, 3, TRXC_RACH, 2 },
+ { TRXC_IDLE, 0, TRXC_RACH, 3 },
+
+ { TRXC_FCCH, 0, TRXC_SDCCH4_3, 0 },
+ { TRXC_SCH, 0, TRXC_SDCCH4_3, 1 },
+ { TRXC_BCCH, 0, TRXC_SDCCH4_3, 2 },
+ { TRXC_BCCH, 1, TRXC_SDCCH4_3, 3 },
+ { TRXC_BCCH, 2, TRXC_RACH, 0 },
+ { TRXC_BCCH, 3, TRXC_RACH, 0 },
+ { TRXC_CCCH, 0, TRXC_SACCH4_0, 0 },
+ { TRXC_CCCH, 1, TRXC_SACCH4_0, 1 },
+ { TRXC_CCCH, 2, TRXC_SACCH4_0, 2 },
+ { TRXC_CCCH, 3, TRXC_SACCH4_0, 3 },
+ { TRXC_FCCH, 0, TRXC_SACCH4_1, 0 },
+ { TRXC_SCH, 0, TRXC_SACCH4_1, 1 },
+ { TRXC_CCCH, 0, TRXC_SACCH4_1, 2 },
+ { TRXC_CCCH, 1, TRXC_SACCH4_1, 3 },
+ { TRXC_CCCH, 2, TRXC_RACH, 0 },
+ { TRXC_CCCH, 3, TRXC_RACH, 0 },
+ { TRXC_CCCH, 0, TRXC_RACH, 0 },
+ { TRXC_CCCH, 1, TRXC_RACH, 0 },
+ { TRXC_CCCH, 2, TRXC_RACH, 0 },
+ { TRXC_CCCH, 3, TRXC_RACH, 0 },
+ { TRXC_FCCH, 0, TRXC_RACH, 0 },
+ { TRXC_SCH, 0, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_0, 0, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_0, 1, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_0, 2, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_0, 3, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_1, 0, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_1, 1, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_1, 2, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_1, 3, TRXC_RACH, 0 },
+ { TRXC_FCCH, 0, TRXC_RACH, 0 },
+ { TRXC_SCH, 0, TRXC_RACH, 0 },
+ { TRXC_CBCH, 0, TRXC_RACH, 0 },
+ { TRXC_CBCH, 1, TRXC_RACH, 0 },
+ { TRXC_CBCH, 2, TRXC_RACH, 0 },
+ { TRXC_CBCH, 3, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_3, 0, TRXC_RACH, 0 },
+ { TRXC_SDCCH4_3, 1, TRXC_SDCCH4_0, 0 },
+ { TRXC_SDCCH4_3, 2, TRXC_SDCCH4_0, 1 },
+ { TRXC_SDCCH4_3, 3, TRXC_SDCCH4_0, 2 },
+ { TRXC_FCCH, 0, TRXC_SDCCH4_0, 3 },
+ { TRXC_SCH, 0, TRXC_SDCCH4_1, 0 },
+ { TRXC_IDLE, 0, TRXC_SDCCH4_1, 1 },
+ { TRXC_IDLE, 1, TRXC_SDCCH4_1, 2 },
+ { TRXC_IDLE, 2, TRXC_SDCCH4_1, 3 },
+ { TRXC_IDLE, 3, TRXC_RACH, 0 },
+ { TRXC_SACCH4_3, 0, TRXC_RACH, 0 },
+ { TRXC_SACCH4_3, 1, TRXC_RACH, 0 },
+ { TRXC_SACCH4_3, 2, TRXC_RACH, 1 },
+ { TRXC_SACCH4_3, 3, TRXC_RACH, 2 },
+ { TRXC_IDLE, 0, TRXC_SDCCH4_2, 3 },
+};
+
static const struct trx_sched_frame frame_sdcch8[102] = {
/* dl_chan dl_bid ul_chan ul_bid */
{ TRXC_SDCCH8_0, 0, TRXC_SACCH8_5, 0 },
@@ -277,6 +384,113 @@ static const struct trx_sched_frame frame_sdcch8[102] = {
{ TRXC_IDLE, 0, TRXC_SACCH8_4, 3 },
};
+static const struct trx_sched_frame frame_sdcch8_cbch[102] = {
+/* dl_chan dl_bid ul_chan ul_bid */
+ { TRXC_SDCCH8_0, 0, TRXC_SACCH8_5, 0 },
+ { TRXC_SDCCH8_0, 1, TRXC_SACCH8_5, 1 },
+ { TRXC_SDCCH8_0, 2, TRXC_SACCH8_5, 2 },
+ { TRXC_SDCCH8_0, 3, TRXC_SACCH8_5, 3 },
+ { TRXC_SDCCH8_1, 0, TRXC_SACCH8_6, 0 },
+ { TRXC_SDCCH8_1, 1, TRXC_SACCH8_6, 1 },
+ { TRXC_SDCCH8_1, 2, TRXC_SACCH8_6, 2 },
+ { TRXC_SDCCH8_1, 3, TRXC_SACCH8_6, 3 },
+ { TRXC_CBCH, 0, TRXC_SACCH8_7, 0 },
+ { TRXC_CBCH, 1, TRXC_SACCH8_7, 1 },
+ { TRXC_CBCH, 2, TRXC_SACCH8_7, 2 },
+ { TRXC_CBCH, 3, TRXC_SACCH8_7, 3 },
+ { TRXC_SDCCH8_3, 0, TRXC_IDLE, 0 },
+ { TRXC_SDCCH8_3, 1, TRXC_IDLE, 0 },
+ { TRXC_SDCCH8_3, 2, TRXC_IDLE, 0 },
+ { TRXC_SDCCH8_3, 3, TRXC_SDCCH8_0, 0 },
+ { TRXC_SDCCH8_4, 0, TRXC_SDCCH8_0, 1 },
+ { TRXC_SDCCH8_4, 1, TRXC_SDCCH8_0, 2 },
+ { TRXC_SDCCH8_4, 2, TRXC_SDCCH8_0, 3 },
+ { TRXC_SDCCH8_4, 3, TRXC_SDCCH8_1, 0 },
+ { TRXC_SDCCH8_5, 0, TRXC_SDCCH8_1, 1 },
+ { TRXC_SDCCH8_5, 1, TRXC_SDCCH8_1, 2 },
+ { TRXC_SDCCH8_5, 2, TRXC_SDCCH8_1, 3 },
+ { TRXC_SDCCH8_5, 3, TRXC_IDLE, 0 },
+ { TRXC_SDCCH8_6, 0, TRXC_IDLE, 1 },
+ { TRXC_SDCCH8_6, 1, TRXC_IDLE, 2 },
+ { TRXC_SDCCH8_6, 2, TRXC_IDLE, 3 },
+ { TRXC_SDCCH8_6, 3, TRXC_SDCCH8_3, 0 },
+ { TRXC_SDCCH8_7, 0, TRXC_SDCCH8_3, 1 },
+ { TRXC_SDCCH8_7, 1, TRXC_SDCCH8_3, 2 },
+ { TRXC_SDCCH8_7, 2, TRXC_SDCCH8_3, 3 },
+ { TRXC_SDCCH8_7, 3, TRXC_SDCCH8_4, 0 },
+ { TRXC_SACCH8_0, 0, TRXC_SDCCH8_4, 1 },
+ { TRXC_SACCH8_0, 1, TRXC_SDCCH8_4, 2 },
+ { TRXC_SACCH8_0, 2, TRXC_SDCCH8_4, 3 },
+ { TRXC_SACCH8_0, 3, TRXC_SDCCH8_5, 0 },
+ { TRXC_SACCH8_1, 0, TRXC_SDCCH8_5, 1 },
+ { TRXC_SACCH8_1, 1, TRXC_SDCCH8_5, 2 },
+ { TRXC_SACCH8_1, 2, TRXC_SDCCH8_5, 3 },
+ { TRXC_SACCH8_1, 3, TRXC_SDCCH8_6, 0 },
+ { TRXC_IDLE, 0, TRXC_SDCCH8_6, 1 },
+ { TRXC_IDLE, 1, TRXC_SDCCH8_6, 2 },
+ { TRXC_IDLE, 2, TRXC_SDCCH8_6, 3 },
+ { TRXC_IDLE, 3, TRXC_SDCCH8_7, 0 },
+ { TRXC_SACCH8_3, 0, TRXC_SDCCH8_7, 1 },
+ { TRXC_SACCH8_3, 1, TRXC_SDCCH8_7, 2 },
+ { TRXC_SACCH8_3, 2, TRXC_SDCCH8_7, 3 },
+ { TRXC_SACCH8_3, 3, TRXC_SACCH8_0, 0 },
+ { TRXC_IDLE, 0, TRXC_SACCH8_0, 1 },
+ { TRXC_IDLE, 0, TRXC_SACCH8_0, 2 },
+ { TRXC_IDLE, 0, TRXC_SACCH8_0, 3 },
+
+ { TRXC_SDCCH8_0, 0, TRXC_SACCH8_1, 0 },
+ { TRXC_SDCCH8_0, 1, TRXC_SACCH8_1, 1 },
+ { TRXC_SDCCH8_0, 2, TRXC_SACCH8_1, 2 },
+ { TRXC_SDCCH8_0, 3, TRXC_SACCH8_1, 3 },
+ { TRXC_SDCCH8_1, 0, TRXC_IDLE, 0 },
+ { TRXC_SDCCH8_1, 1, TRXC_IDLE, 1 },
+ { TRXC_SDCCH8_1, 2, TRXC_IDLE, 2 },
+ { TRXC_SDCCH8_1, 3, TRXC_IDLE, 3 },
+ { TRXC_CBCH, 0, TRXC_SACCH8_3, 0 },
+ { TRXC_CBCH, 1, TRXC_SACCH8_3, 1 },
+ { TRXC_CBCH, 2, TRXC_SACCH8_3, 2 },
+ { TRXC_CBCH, 3, TRXC_SACCH8_3, 3 },
+ { TRXC_SDCCH8_3, 0, TRXC_IDLE, 0 },
+ { TRXC_SDCCH8_3, 1, TRXC_IDLE, 0 },
+ { TRXC_SDCCH8_3, 2, TRXC_IDLE, 0 },
+ { TRXC_SDCCH8_3, 3, TRXC_SDCCH8_0, 0 },
+ { TRXC_SDCCH8_4, 0, TRXC_SDCCH8_0, 1 },
+ { TRXC_SDCCH8_4, 1, TRXC_SDCCH8_0, 2 },
+ { TRXC_SDCCH8_4, 2, TRXC_SDCCH8_0, 3 },
+ { TRXC_SDCCH8_4, 3, TRXC_SDCCH8_1, 0 },
+ { TRXC_SDCCH8_5, 0, TRXC_SDCCH8_1, 1 },
+ { TRXC_SDCCH8_5, 1, TRXC_SDCCH8_1, 2 },
+ { TRXC_SDCCH8_5, 2, TRXC_SDCCH8_1, 3 },
+ { TRXC_SDCCH8_5, 3, TRXC_IDLE, 0 },
+ { TRXC_SDCCH8_6, 0, TRXC_IDLE, 1 },
+ { TRXC_SDCCH8_6, 1, TRXC_IDLE, 2 },
+ { TRXC_SDCCH8_6, 2, TRXC_IDLE, 3 },
+ { TRXC_SDCCH8_6, 3, TRXC_SDCCH8_3, 0 },
+ { TRXC_SDCCH8_7, 0, TRXC_SDCCH8_3, 1 },
+ { TRXC_SDCCH8_7, 1, TRXC_SDCCH8_3, 2 },
+ { TRXC_SDCCH8_7, 2, TRXC_SDCCH8_3, 3 },
+ { TRXC_SDCCH8_7, 3, TRXC_SDCCH8_4, 0 },
+ { TRXC_SACCH8_4, 0, TRXC_SDCCH8_4, 1 },
+ { TRXC_SACCH8_4, 1, TRXC_SDCCH8_4, 2 },
+ { TRXC_SACCH8_4, 2, TRXC_SDCCH8_4, 3 },
+ { TRXC_SACCH8_4, 3, TRXC_SDCCH8_5, 0 },
+ { TRXC_SACCH8_5, 0, TRXC_SDCCH8_5, 1 },
+ { TRXC_SACCH8_5, 1, TRXC_SDCCH8_5, 2 },
+ { TRXC_SACCH8_5, 2, TRXC_SDCCH8_5, 3 },
+ { TRXC_SACCH8_5, 3, TRXC_SDCCH8_6, 0 },
+ { TRXC_SACCH8_6, 0, TRXC_SDCCH8_6, 1 },
+ { TRXC_SACCH8_6, 1, TRXC_SDCCH8_6, 2 },
+ { TRXC_SACCH8_6, 2, TRXC_SDCCH8_6, 3 },
+ { TRXC_SACCH8_6, 3, TRXC_SDCCH8_7, 0 },
+ { TRXC_SACCH8_7, 0, TRXC_SDCCH8_7, 1 },
+ { TRXC_SACCH8_7, 1, TRXC_SDCCH8_7, 2 },
+ { TRXC_SACCH8_7, 2, TRXC_SDCCH8_7, 3 },
+ { TRXC_SACCH8_7, 3, TRXC_SACCH8_4, 0 },
+ { TRXC_IDLE, 0, TRXC_SACCH8_4, 1 },
+ { TRXC_IDLE, 0, TRXC_SACCH8_4, 2 },
+ { TRXC_IDLE, 0, TRXC_SACCH8_4, 3 },
+};
+
static const struct trx_sched_frame frame_tchf_ts0[104] = {
/* dl_chan dl_bid ul_chan ul_bid */
{ TRXC_TCHF, 0, TRXC_TCHF, 0 }, { TRXC_TCHF, 1, TRXC_TCHF, 1 }, { TRXC_TCHF, 2, TRXC_TCHF, 2 }, { TRXC_TCHF, 3, TRXC_TCHF, 3 },
@@ -749,7 +963,9 @@ const struct trx_sched_multiframe trx_sched_multiframes[] = {
{ GSM_PCHAN_NONE, 0xff, 0, NULL, "NONE"},
{ GSM_PCHAN_CCCH, 0xff, 51, frame_bcch, "BCCH+CCCH" },
{ GSM_PCHAN_CCCH_SDCCH4, 0xff, 102, frame_bcch_sdcch4, "BCCH+CCCH+SDCCH/4+SACCH/4" },
+ { GSM_PCHAN_CCCH_SDCCH4_CBCH, 0xff, 102, frame_bcch_sdcch4_cbch, "BCCH+CCCH+SDCCH/4+SACCH/4+CBCH" },
{ GSM_PCHAN_SDCCH8_SACCH8C, 0xff, 102, frame_sdcch8, "SDCCH/8+SACCH/8" },
+ { GSM_PCHAN_SDCCH8_SACCH8C_CBCH,0xff, 102, frame_sdcch8_cbch, "SDCCH/8+SACCH/8+CBCH" },
{ GSM_PCHAN_TCH_F, 0x01, 104, frame_tchf_ts0, "TCH/F+SACCH" },
{ GSM_PCHAN_TCH_F, 0x02, 104, frame_tchf_ts1, "TCH/F+SACCH" },
{ GSM_PCHAN_TCH_F, 0x04, 104, frame_tchf_ts2, "TCH/F+SACCH" },
diff --git a/src/osmo-bts-trx/main.c b/src/osmo-bts-trx/main.c
index 3b82e42b..61610f73 100644
--- a/src/osmo-bts-trx/main.c
+++ b/src/osmo-bts-trx/main.c
@@ -111,6 +111,7 @@ int bts_model_init(struct gsm_bts *bts)
gsm_bts_set_feature(bts, BTS_FEAT_SPEECH_F_EFR);
gsm_bts_set_feature(bts, BTS_FEAT_SPEECH_F_AMR);
gsm_bts_set_feature(bts, BTS_FEAT_SPEECH_H_AMR);
+ gsm_bts_set_feature(bts, BTS_FEAT_CBCH);
bts_model_vty_init(bts);
diff --git a/src/osmo-bts-virtual/main.c b/src/osmo-bts-virtual/main.c
index 81fb9581..b66a3ff9 100644
--- a/src/osmo-bts-virtual/main.c
+++ b/src/osmo-bts-virtual/main.c
@@ -65,6 +65,7 @@ int bts_model_init(struct gsm_bts *bts)
gsm_bts_set_feature(bts, BTS_FEAT_SPEECH_F_EFR);
gsm_bts_set_feature(bts, BTS_FEAT_SPEECH_F_AMR);
gsm_bts_set_feature(bts, BTS_FEAT_SPEECH_H_AMR);
+ gsm_bts_set_feature(bts, BTS_FEAT_CBCH);
bts_model_vty_init(bts);