diff options
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/include/openbsc/gsm_04_08.h | 5 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_data.h | 2 | ||||
-rw-r--r-- | openbsc/src/abis_rsl.c | 4 | ||||
-rw-r--r-- | openbsc/src/bs11_config.c | 5 | ||||
-rw-r--r-- | openbsc/src/gsm_04_08_utils.c | 31 | ||||
-rw-r--r-- | openbsc/src/gsm_data.c | 2 | ||||
-rw-r--r-- | openbsc/src/vty_interface.c | 1 | ||||
-rw-r--r-- | openbsc/tests/channel/channel_test.c | 1 |
8 files changed, 43 insertions, 8 deletions
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index c4018cd11..602658331 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -16,8 +16,9 @@ struct gsm_trans; void gsm0408_allow_everyone(int allow); int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id); -enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci); -enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci); +enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *bts, u_int8_t ra); +enum gsm_chreq_reason_t get_reason_by_chreq(u_int8_t ra, int neci); +void gsm_net_update_ctype(struct gsm_network *net); int gsm48_tx_mm_info(struct gsm_lchan *lchan); int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand, int key_seq); diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 5b70d1db6..c8fee474b 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -624,6 +624,8 @@ struct gsm_network { enum rrlp_mode mode; } rrlp; + enum gsm_chan_t ctype_by_chreq[16]; + /* a hack for On Waves. It must be signed */ int32_t core_country_code; int32_t core_network_code; diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 446e081ca..b0f4b6e1a 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -1104,8 +1104,8 @@ static int rsl_rx_chan_rqd(struct msgb *msg) /* determine channel type (SDCCH/TCH_F/TCH_H) based on * request reference RA */ - lctype = get_ctype_by_chreq(bts, rqd_ref->ra, bts->network->neci); - chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra, bts->network->neci); + lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra); + chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci); counter_inc(bts->network->stats.chreq.total); diff --git a/openbsc/src/bs11_config.c b/openbsc/src/bs11_config.c index 80f9ba956..de426aa9c 100644 --- a/openbsc/src/bs11_config.c +++ b/openbsc/src/bs11_config.c @@ -870,3 +870,8 @@ int main(int argc, char **argv) exit(0); } + +/* dummy to be able to compile */ +void gsm_net_update_ctype(struct gsm_network *net) +{ +} diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c index 68f34f409..ad1040b3b 100644 --- a/openbsc/src/gsm_04_08_utils.c +++ b/openbsc/src/gsm_04_08_utils.c @@ -164,13 +164,36 @@ static const enum gsm_chreq_reason_t reason_by_chreq[] = { [CHREQ_T_RESERVED_IGNORE] = GSM_CHREQ_REASON_OTHER, }; -enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci) +/* verify that the two tables match */ +static_assert(sizeof(ctype_by_chreq) == + sizeof(((struct gsm_network *) NULL)->ctype_by_chreq), assert_size); + +/* + * Update channel types for request based on policy. E.g. in the + * case of a TCH/H network/bsc use TCH/H for the emergency calls, + * for early assignment assign a SDCCH and some other options. + */ +void gsm_net_update_ctype(struct gsm_network *network) +{ + /* copy over the data */ + memcpy(network->ctype_by_chreq, ctype_by_chreq, sizeof(ctype_by_chreq)); + + /* + * Use TCH/H for emergency calls when this cell allows TCH/H. Maybe it + * is better to iterate over the BTS/TRX and check if no TCH/F is available + * and then set it to TCH/H. + */ + if (network->neci) + network->ctype_by_chreq[CHREQ_T_EMERG_CALL] = GSM_LCHAN_TCH_H; +} + +enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *network, u_int8_t ra) { int i; int length; const struct chreq *chreq; - if (neci) { + if (network->neci) { chreq = chreq_type_neci1; length = ARRAY_SIZE(chreq_type_neci1); } else { @@ -182,13 +205,13 @@ enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci) for (i = 0; i < length; i++) { const struct chreq *chr = &chreq[i]; if ((ra & chr->mask) == chr->val) - return ctype_by_chreq[chr->type]; + return network->ctype_by_chreq[chr->type]; } LOGP(DRR, LOGL_ERROR, "Unknown CHANNEL REQUEST RQD 0x%02x\n", ra); return GSM_LCHAN_SDCCH; } -enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci) +enum gsm_chreq_reason_t get_reason_by_chreq(u_int8_t ra, int neci) { int i; int length; diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index c4d0431a3..5efebc208 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -296,6 +296,8 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c net->mncc_recv = mncc_recv; + gsm_net_update_ctype(net); + net->core_country_code = -1; net->core_network_code = -1; net->rtp_base_port = 4000; diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index 09b95cac1..a5ed0d21a 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -1265,6 +1265,7 @@ DEFUN(cfg_net_neci, "Set if NECI of cell selection is to be set") { gsmnet->neci = atoi(argv[0]); + gsm_net_update_ctype(gsmnet); return CMD_SUCCESS; } diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 4c57a75c6..96f13cbbd 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -77,6 +77,7 @@ void nm_state_event() {} void input_event() {} void sms_alloc() {} void _lchan_release() {} +void gsm_net_update_ctype(struct gsm_network *network) {} struct tlv_definition nm_att_tlvdef; |