aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-03-25 04:58:08 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-03-25 04:58:08 +0100
commitaebea482f54a97deaca8688c79af3809a756240c (patch)
treeee1df27e820e16e8eb4f2fefca05cb136777486a /openbsc
parent12f20d369c6bba0dfe61e433c14d220b9c43febd (diff)
channel request: Store the to be assigned channel type in the GSM Network
Store the mapping from request to channel type in the GSM Network struct as there is some policy involved with handling the request. E.g. in a half rate network we don't want emergy calls to be getting a TCH/F, or we want to have a different policy for early/late assignment of phone calls. Update the table when creating the network and when the neci is changed.
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/gsm_04_08_utils.c31
-rw-r--r--openbsc/src/gsm_data.c2
-rw-r--r--openbsc/src/vty_interface.c1
-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 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;