diff options
-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/bsc_vty.c | 1 | ||||
-rw-r--r-- | openbsc/src/gsm_04_08_utils.c | 31 | ||||
-rw-r--r-- | openbsc/src/gsm_data.c | 2 | ||||
-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 aa070eb0a..15ac1b3fa 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -29,8 +29,9 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg); int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id); int gsm0408_new_conn(struct gsm_subscriber_connection *conn); -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_subscriber_connection *conn); int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, u_int8_t *rand, int key_seq); diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index fe021e945..d97dc4f9e 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -713,6 +713,8 @@ struct gsm_network { /* enable the DTXu and DTXd for this network */ int dtx_enabled; + enum gsm_chan_t ctype_by_chreq[16]; + int msc_prio; }; diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 4827dd0e9..047c76808 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -1188,8 +1188,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 44cef0aea..71e4aed37 100644 --- a/openbsc/src/bs11_config.c +++ b/openbsc/src/bs11_config.c @@ -872,3 +872,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/bsc_vty.c b/openbsc/src/bsc_vty.c index f56440ec1..d9c248f32 100644 --- a/openbsc/src/bsc_vty.c +++ b/openbsc/src/bsc_vty.c @@ -1129,6 +1129,7 @@ DEFUN(cfg_net_neci, struct gsm_network *gsmnet = gsmnet_from_vty(vty); gsmnet->neci = atoi(argv[0]); + gsm_net_update_ctype(gsmnet); return CMD_SUCCESS; } diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c index 72de3b421..bb0174612 100644 --- a/openbsc/src/gsm_04_08_utils.c +++ b/openbsc/src/gsm_04_08_utils.c @@ -132,13 +132,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 { @@ -150,13 +173,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 f71527d06..29b6d0722 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -305,6 +305,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); + return net; } diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 759001c57..32c71683a 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -76,6 +76,7 @@ int main(int argc, char** argv) void nm_state_event() {} void input_event() {} void sms_alloc() {} +void gsm_net_update_ctype(struct gsm_network *network) {} struct tlv_definition nm_att_tlvdef; |