From edafdc14f3cf0b9714932bce3faf2751f370663d Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Tue, 22 Mar 2016 19:25:58 +0100 Subject: cscn: record and use LAC on incoming InitialUE msg Add lac argument to gsm0408_rcvmsg_iucs(), to record the LAC in newly allocated gsm_subscriber_connections. In effect, fix the LAC sent to UE during Location Updating Accept message. Before, 0 was stored as LAC and sent to the UE, regardless of the actual LAC in use. --- openbsc/include/openbsc/iu_cs.h | 3 ++- openbsc/src/libmsc/iu_cs.c | 36 ++++++++++++++++++++++++++++++------ openbsc/src/osmo-cscn/cscn_main.c | 2 +- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/openbsc/include/openbsc/iu_cs.h b/openbsc/include/openbsc/iu_cs.h index f165c9b58..fb61a5cf1 100644 --- a/openbsc/include/openbsc/iu_cs.h +++ b/openbsc/include/openbsc/iu_cs.h @@ -1,6 +1,7 @@ #pragma once -int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg); +int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg, + uint16_t *lac); struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network, struct ue_conn_ctx *ue); diff --git a/openbsc/src/libmsc/iu_cs.c b/openbsc/src/libmsc/iu_cs.c index 946d89ad5..863a67893 100644 --- a/openbsc/src/libmsc/iu_cs.c +++ b/openbsc/src/libmsc/iu_cs.c @@ -9,13 +9,14 @@ #include /* For A-interface see libbsc/bsc_api.c subscr_con_allocate() */ -struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *network, - struct ue_conn_ctx *ue) +static struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *network, + struct ue_conn_ctx *ue, + uint16_t lac) { struct gsm_subscriber_connection *conn; - DEBUGP(DIUCS, "Allocating IuCS subscriber conn: link_id %p, conn_id %" PRIx32 "\n", - ue->link, ue->conn_id); + DEBUGP(DIUCS, "Allocating IuCS subscriber conn: lac %d, link_id %p, conn_id %" PRIx32 "\n", + lac, ue->link, ue->conn_id); conn = talloc_zero(network, struct gsm_subscriber_connection); if (!conn) @@ -24,6 +25,7 @@ struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *ne conn->network = network; conn->via_iface = IFACE_IU; conn->iu.ue_ctx = ue; + conn->lac = lac; llist_add_tail(&conn->entry, &network->subscr_conns); return conn; @@ -101,7 +103,8 @@ struct gsm_subscriber_connection *subscr_conn_lookup_iu( * sent the msg. * * For A-interface see libbsc/bsc_api.c gsm0408_rcvmsg(). */ -int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg) +int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg, + uint16_t *lac) { int rc; struct ue_conn_ctx *ue_ctx; @@ -113,6 +116,19 @@ int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg) * search? */ conn = subscr_conn_lookup_iu(network, ue_ctx); + if (conn && lac && (conn->lac != *lac)) { + LOGP(DIUCS, LOGL_ERROR, "IuCS subscriber has changed LAC" + " within the same connection, discarding connection:" + " %s from LAC %d to %d\n", + subscr_name(conn->subscr), conn->lac, *lac); + /* Deallocate conn with previous LAC */ + msc_subscr_con_free(conn); + /* At this point we could be tolerant and allocate a new + * connection, but changing the LAC within the same connection + * is shifty. Rather cancel everything. */ + return -1; + } + if (conn) { /* if we already have a connection, handle DTAP. gsm0408_dispatch() is aka msc_dtap() */ @@ -128,7 +144,15 @@ int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg) } else { /* allocate a new connection */ - conn = subscr_conn_allocate_iu(network, ue_ctx); + if (!lac) { + LOGP(DIUCS, LOGL_ERROR, "New IuCS subscriber" + " but no LAC available. Expecting an InitialUE" + " message containing a LAI IE." + " Dropping connection.\n"); + return -1; + } + + conn = subscr_conn_allocate_iu(network, ue_ctx, *lac); if (!conn) abort(); diff --git a/openbsc/src/osmo-cscn/cscn_main.c b/openbsc/src/osmo-cscn/cscn_main.c index 2b1b505a6..50f7ddbbb 100644 --- a/openbsc/src/osmo-cscn/cscn_main.c +++ b/openbsc/src/osmo-cscn/cscn_main.c @@ -321,7 +321,7 @@ static int rcvmsg_iu_cs(struct msgb *msg, struct gprs_ra_id *ra_id, /* FIXME gpr { DEBUGP(DIUCS, "got Iu-CS message: %s\n", osmo_hexdump(msg->data, msg->len)); - return gsm0408_rcvmsg_iucs(cscn_network, msg); + return gsm0408_rcvmsg_iucs(cscn_network, msg, ra_id? &ra_id->lac : NULL); } static int rx_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, -- cgit v1.2.3