aboutsummaryrefslogtreecommitdiffstats
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>2012-05-02 19:24:29 +0200
commitd3d79fb9cdd7efacab5301ea27ec94352c68fb56 (patch)
treebafa99fff612702ab43352353055e7cc7754f1cf
parent389fb6bb125bbb75b4349a6012b8d99c4c129a96 (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 9edf880cf..0bda66225 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 3bc2dfd7f..fa7f2d928 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 31cbfb2a5..40d8366ca 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;
}