aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-03-22 19:25:58 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-04-11 20:45:32 +0200
commitedafdc14f3cf0b9714932bce3faf2751f370663d (patch)
tree34d1d26eddb3ea03d7585e370c26bc4805fdf703 /openbsc
parent54fc3a13183e4d5956c8c17b74caf7ef21febe0a (diff)
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.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/iu_cs.h3
-rw-r--r--openbsc/src/libmsc/iu_cs.c36
-rw-r--r--openbsc/src/osmo-cscn/cscn_main.c2
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 <openbsc/gsm_subscriber.h>
/* 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,