aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gsm_04_08.h5
-rw-r--r--openbsc/include/openbsc/gsm_data.h2
-rw-r--r--openbsc/src/abis_rsl.c4
-rw-r--r--openbsc/src/bs11_config.c5
-rw-r--r--openbsc/src/bsc_vty.c1
-rw-r--r--openbsc/src/gsm_04_08_utils.c31
-rw-r--r--openbsc/src/gsm_data.c2
-rw-r--r--openbsc/tests/channel/channel_test.c1
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;