summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-06-08 19:25:38 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-08-25 23:17:36 +0200
commit735c714a74c542318fde061ba5c9459b02f320c0 (patch)
tree260350d39cd30010ba2b18872cfdf837d7c3d38d
parent935eac12aa36ed1a351d5c50a6f216b0a8d3a544 (diff)
bsc: Look for CM Service Requests with emergency cause
Look for emergency calls and send them to a MSC that can handle them properly.
-rw-r--r--openbsc/include/openbsc/osmo_msc_data.h1
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_filter.c25
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_msc.c1
3 files changed, 25 insertions, 2 deletions
diff --git a/openbsc/include/openbsc/osmo_msc_data.h b/openbsc/include/openbsc/osmo_msc_data.h
index 9edf880..0bda662 100644
--- a/openbsc/include/openbsc/osmo_msc_data.h
+++ b/openbsc/include/openbsc/osmo_msc_data.h
@@ -46,6 +46,7 @@ struct osmo_msc_data {
/* Back pointer */
struct gsm_network *network;
+ int allow_emerg;
int type;
/* Connection data */
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_filter.c b/openbsc/src/osmo-bsc/osmo_bsc_filter.c
index 3bc2dfd..fa7f2d9 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_filter.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_filter.c
@@ -106,6 +106,21 @@ static int handle_page_resp(struct gsm_subscriber_connection *conn, struct msgb
subscr_put(subscr);
return 0;
}
+
+static int is_cm_service_for_emerg(struct msgb *msg)
+{
+ struct gsm48_service_request *cm;
+ struct gsm48_hdr *gh = msgb_l3(msg);
+
+ if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*cm)) {
+ LOGP(DMSC, LOGL_ERROR, "CM ServiceRequest does not fit.\n");
+ return 0;
+ }
+
+ cm = (struct gsm48_service_request *) &gh->data[0];
+ return cm->cm_service_type == GSM48_CMSERV_EMERGENCY;
+}
+
struct osmo_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn,
struct msgb *msg)
{
@@ -115,6 +130,7 @@ struct osmo_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn,
struct osmo_bsc_data *bsc;
struct osmo_msc_data *msc, *pag_msc;
struct gsm_subscriber *subscr;
+ int is_emerg = 0;
bsc = conn->bts->network->bsc_data;
@@ -135,14 +151,19 @@ struct osmo_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn,
*/
if (pdisc == GSM48_PDISC_RR && mtype == GSM48_MT_RR_PAG_RESP)
goto paging;
- else
+ else if (pdisc == GSM48_PDISC_MM && mtype == GSM48_MT_MM_CM_SERV_REQ) {
+ is_emerg = is_cm_service_for_emerg(msg);
+ goto round_robin;
+ } else
goto round_robin;
round_robin:
llist_for_each_entry(msc, &bsc->mscs, entry) {
if (!msc->msc_con->is_authenticated)
continue;
- if (msc->type != MSC_CON_TYPE_NORMAL)
+ if (!is_emerg && msc->type != MSC_CON_TYPE_NORMAL)
+ continue;
+ if (is_emerg && !msc->allow_emerg)
continue;
/* force round robin by moving it to the end */
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_msc.c b/openbsc/src/osmo-bsc/osmo_bsc_msc.c
index 31cbfb2..40d8366 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_msc.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_msc.c
@@ -489,6 +489,7 @@ struct osmo_msc_data *osmo_msc_data_alloc(struct gsm_network *net, int nr)
msc_data->rtp_base = 4000;
msc_data->nr = nr;
+ msc_data->allow_emerg = 1;
return msc_data;
}