summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-06-07 11:40:20 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-05-02 19:24:29 +0200
commitedc63caa074ee07cc0bb15b2aa822ad73c8bbbf7 (patch)
tree38188c5add7ebce03e4b92c259a37c2bcdffb682
parent02b48652a59b41bb6a8c38f9e0b15cd8e8c0c617 (diff)
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.
-rw-r--r--openbsc/include/openbsc/osmo_bsc.h3
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_api.c29
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_sccp.c13
3 files changed, 35 insertions, 10 deletions
diff --git a/openbsc/include/openbsc/osmo_bsc.h b/openbsc/include/openbsc/osmo_bsc.h
index ffa0b5747..0e904c987 100644
--- a/openbsc/include/openbsc/osmo_bsc.h
+++ b/openbsc/include/openbsc/osmo_bsc.h
@@ -32,7 +32,8 @@ struct bsc_api *osmo_bsc_api();
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 03949cfbc..2d2b804f4 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_api.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c
@@ -81,6 +81,25 @@ static void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn,
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 @@ static int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg
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 46ffd5760..6d1127ac3 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_sccp.c
@@ -187,22 +187,19 @@ int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
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;
}