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.
This commit is contained in:
Holger Hans Peter Freyther 2011-06-07 11:40:20 +02:00
parent 6545f7c6b7
commit 4084e87af9
3 changed files with 35 additions and 10 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
}