From 18fa70aa3afbcb997c3ac1c1fe0e3808958533cb Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 8 Jun 2011 19:25:38 +0200 Subject: bsc: Look for CM Service Requests with emergency cause Look for emergency calls and send them to a MSC that can handle them properly. --- openbsc/include/openbsc/osmo_msc_data.h | 1 + openbsc/src/osmo-bsc/osmo_bsc_filter.c | 25 +++++++++++++++++++++++-- openbsc/src/osmo-bsc/osmo_bsc_msc.c | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) (limited to 'openbsc') 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 617a59aee..55532dbd4 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_msc.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_msc.c @@ -492,6 +492,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; } -- cgit v1.2.3