bsc: Select a MSC in a round-robin fashion

Select a MSC, add it to the back of the list after we have
selected it.
diff --git a/openbsc/include/openbsc/osmo_bsc.h b/openbsc/include/openbsc/osmo_bsc.h
index ffa0b57..0e904c9 100644
--- a/openbsc/include/openbsc/osmo_bsc.h
+++ b/openbsc/include/openbsc/osmo_bsc.h
@@ -32,7 +32,8 @@
 
 int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg);
 int bsc_open_connection(struct osmo_bsc_sccp_con *sccp, struct msgb *msg);
-int bsc_create_new_connection(struct gsm_subscriber_connection *conn);
+int bsc_create_new_connection(struct gsm_subscriber_connection *conn,
+			      struct osmo_msc_data *msc);
 int bsc_delete_connection(struct osmo_bsc_sccp_con *sccp);
 
 int bsc_scan_bts_msg(struct gsm_subscriber_connection *conn, struct msgb *msg);
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c
index 04305c2..8fa17e6 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_api.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c
@@ -81,6 +81,25 @@
 	queue_msg_or_return(resp);
 }
 
+static struct osmo_msc_data *find_msc(struct gsm_subscriber_connection *conn,
+				      struct msgb *msg)
+{
+	struct osmo_bsc_data *bsc;
+	struct osmo_msc_data *msc;
+
+	bsc = conn->bts->network->bsc_data;
+	llist_for_each_entry(msc, &bsc->mscs, entry) {
+		if (!msc->msc_con->is_authenticated)
+			continue;
+
+		/* force round robin by moving it to the end */
+		llist_move_tail(&msc->entry, &bsc->mscs);
+		return msc;
+	}
+
+	return NULL;
+}
+
 /*
  * Instruct to reserve data for a new connectiom, create the complete
  * layer three message, send it to open the connection.
@@ -89,13 +108,21 @@
 			uint16_t chosen_channel)
 {
 	struct msgb *resp;
+	struct osmo_msc_data *msc;
 	uint16_t network_code;
 	uint16_t country_code;
 
 	LOGP(DMSC, LOGL_INFO, "Tx MSC COMPL L3\n");
 
+	/* find the MSC link we want to use */
+	msc = find_msc(conn, msg);
+	if (!msc) {
+		LOGP(DMSC, LOGL_ERROR, "Failed to find a MSC for a connection.\n");
+		return -1;
+	}
+
 	/* allocate resource for a new connection */
-	if (bsc_create_new_connection(conn) != 0)
+	if (bsc_create_new_connection(conn, msc) != 0)
 		return BSC_API_CONN_POL_REJECT;
 
 	network_code = get_network_code_for_msc(conn->sccp_con->msc);
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
index 1410cc6..6b7256b 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
@@ -187,22 +187,19 @@
 	return 0;
 }
 
-int bsc_create_new_connection(struct gsm_subscriber_connection *conn)
+int bsc_create_new_connection(struct gsm_subscriber_connection *conn,
+			      struct osmo_msc_data *msc)
 {
 	struct gsm_network *net;
-	struct osmo_msc_data *msc;
 	struct osmo_bsc_sccp_con *bsc_con;
 	struct sccp_connection *sccp;
 
 	net = conn->bts->network;
-	msc = osmo_msc_data_find(net, 0);
-	if (!msc) {
-		LOGP(DMSC, LOGL_ERROR, "Failed to select a MSC.\n");
-		return -1;
-	}
 
+	/* This should not trigger */
 	if (!msc->msc_con->is_authenticated) {
-		LOGP(DMSC, LOGL_ERROR, "Not connected to a MSC. Not forwarding data.\n");
+		LOGP(DMSC, LOGL_ERROR,
+		     "How did this happen? MSC is not connected. Dropping.\n");
 		return -1;
 	}