aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-09-06 09:36:02 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-09-06 09:36:02 +0800
commit78891078fec12099122d474db6c974cd98cc11b5 (patch)
tree6fa31b8bad88c6a92db19c379f0110710a2ffeb0
parent5a3a61d88f1231af5dba96050cbc27270765ef23 (diff)
chan: 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.
-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;