bsc: Prepare to have multiple MSC connections

We now have a list of MSCs but in the code we will
try to access the MSC with the nr 0.
This commit is contained in:
Holger Hans Peter Freyther 2011-06-04 19:58:26 +02:00
parent 44e5dad3e2
commit 20fea24515
6 changed files with 90 additions and 26 deletions

View File

@ -1,8 +1,8 @@
/*
* Data for the true BSC
*
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010 by On-Waves
* (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@ -36,6 +36,8 @@ struct gsm_audio_support {
};
struct osmo_msc_data {
struct llist_head entry;
/* Back pointer */
struct gsm_network *network;
@ -62,6 +64,8 @@ struct osmo_msc_data {
/* mgcp agent */
struct osmo_wqueue mgcp_agent;
int nr;
};
/*
@ -71,7 +75,7 @@ struct osmo_bsc_data {
struct gsm_network *network;
/* msc configuration */
struct osmo_msc_data msc;
struct llist_head mscs;
/* rf ctl related bits */
char *mid_call_txt;
@ -87,4 +91,8 @@ int msc_queue_write(struct bsc_msc_connection *conn, struct msgb *msg, int proto
int osmo_bsc_audio_init(struct gsm_network *network);
struct osmo_msc_data *osmo_msc_data_find(struct gsm_network *, int);
struct osmo_msc_data *osmo_msc_data_alloc(struct gsm_network *, int);
#endif

View File

@ -87,6 +87,7 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
/* Init back pointer */
net->bsc_data->network = net;
INIT_LLIST_HEAD(&net->bsc_data->mscs);
net->country_code = country_code;
net->network_code = network_code;
@ -141,14 +142,6 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
net->mncc_recv = mncc_recv;
INIT_LLIST_HEAD(&net->bsc_data->msc.dests);
net->bsc_data->msc.ping_timeout = 20;
net->bsc_data->msc.pong_timeout = 5;
net->bsc_data->msc.core_ncc = -1;
net->bsc_data->msc.core_mcc = -1;
net->bsc_data->msc.rtp_base = 4000;
net->bsc_data->msc.network = net;
gsm_net_update_ctype(net);
return net;

View File

@ -144,6 +144,8 @@ static struct vty_app_info vty_info = {
extern int bsc_shutdown_net(struct gsm_network *net);
static void signal_handler(int signal)
{
struct osmo_msc_data *msc;
fprintf(stdout, "signal %u received\n", signal);
switch (signal) {
@ -163,11 +165,8 @@ static void signal_handler(int signal)
case SIGUSR2:
if (!bsc_gsmnet->bsc_data)
return;
if (!bsc_gsmnet->bsc_data->msc.msc_con)
return;
if (!bsc_gsmnet->bsc_data->msc.msc_con->is_connected)
return;
bsc_msc_lost(bsc_gsmnet->bsc_data->msc.msc_con);
llist_for_each_entry(msc, &bsc_gsmnet->bsc_data->mscs, entry)
bsc_msc_lost(msc->msc_con);
break;
default:
break;
@ -391,6 +390,7 @@ static int verify_net_rf_lock(struct ctrl_cmd *cmd, const char *value, void *dat
int main(int argc, char **argv)
{
struct osmo_msc_data *msc;
struct osmo_bsc_data *data;
int rc;
@ -443,11 +443,14 @@ int main(int argc, char **argv)
}
}
if (osmo_bsc_msc_init(&bsc_gsmnet->bsc_data->msc) != 0) {
LOGP(DNAT, LOGL_ERROR, "Failed to start up. Exiting.\n");
exit(1);
llist_for_each_entry(msc, &bsc_gsmnet->bsc_data->mscs, entry) {
if (osmo_bsc_msc_init(msc) != 0) {
LOGP(DNAT, LOGL_ERROR, "Failed to start up. Exiting.\n");
exit(1);
}
}
if (osmo_bsc_sccp_init(bsc_gsmnet) != 0) {
LOGP(DNM, LOGL_ERROR, "Failed to register SCCP.\n");
exit(1);

View File

@ -455,3 +455,43 @@ int osmo_bsc_msc_init(struct osmo_msc_data *data)
return 0;
}
struct osmo_msc_data *osmo_msc_data_find(struct gsm_network *net, int nr)
{
struct osmo_msc_data *msc_data;
llist_for_each_entry(msc_data, &net->bsc_data->mscs, entry)
if (msc_data->nr == nr)
return msc_data;
return NULL;
}
struct osmo_msc_data *osmo_msc_data_alloc(struct gsm_network *net, int nr)
{
struct osmo_msc_data *msc_data;
/* check if there is already one */
msc_data = osmo_msc_data_find(net, nr);
if (msc_data)
return msc_data;
msc_data = talloc_zero(net, struct osmo_msc_data);
if (!msc_data)
return NULL;
llist_add_tail(&msc_data->entry, &net->bsc_data->mscs);
/* Init back pointer */
msc_data->network = net;
INIT_LLIST_HEAD(&msc_data->dests);
msc_data->ping_timeout = 20;
msc_data->pong_timeout = 5;
msc_data->core_ncc = -1;
msc_data->core_mcc = -1;
msc_data->rtp_base = 4000;
msc_data->nr = nr;
return msc_data;
}

View File

@ -195,7 +195,12 @@ int bsc_create_new_connection(struct gsm_subscriber_connection *conn)
struct sccp_connection *sccp;
net = conn->bts->network;
msc = &net->bsc_data->msc;
msc = osmo_msc_data_find(net, 0);
if (!msc) {
LOGP(DMSC, LOGL_ERROR, "Failed to select a MSC.\n");
return -1;
}
if (!msc->msc_con->is_authenticated) {
LOGP(DMSC, LOGL_ERROR, "Not connected to a MSC. Not forwarding data.\n");
return -1;

View File

@ -36,7 +36,7 @@ static struct osmo_bsc_data *osmo_bsc_data(struct vty *vty)
static struct osmo_msc_data *osmo_msc_data(struct vty *vty)
{
return &bsc_gsmnet->bsc_data->msc;
return osmo_msc_data_find(bsc_gsmnet, (int) vty->index);
}
static struct cmd_node msc_node = {
@ -48,17 +48,23 @@ static struct cmd_node msc_node = {
DEFUN(cfg_net_msc, cfg_net_msc_cmd,
"msc", "Configure MSC details")
{
vty->index = bsc_gsmnet;
vty->node = MSC_NODE;
int index = 0;
struct osmo_msc_data *msc;
msc = osmo_msc_data_alloc(bsc_gsmnet, index);
if (!msc) {
vty_out(vty, "%%Failed to allocate MSC data.%s", VTY_NEWLINE);
return CMD_WARNING;
}
vty->index = (void *) index;
vty->node = MSC_NODE;
return CMD_SUCCESS;
}
static int config_write_msc(struct vty *vty)
static void write_msc(struct vty *vty, struct osmo_msc_data *msc)
{
struct bsc_msc_dest *dest;
struct osmo_bsc_data *bsc = osmo_bsc_data(vty);
struct osmo_msc_data *msc = &bsc->msc;
vty_out(vty, "msc%s", VTY_NEWLINE);
if (msc->bsc_token)
@ -95,6 +101,15 @@ static int config_write_msc(struct vty *vty)
llist_for_each_entry(dest, &msc->dests, list)
vty_out(vty, " dest %s %d %d%s", dest->ip, dest->port,
dest->dscp, VTY_NEWLINE);
}
static int config_write_msc(struct vty *vty)
{
struct osmo_msc_data *msc;
struct osmo_bsc_data *bsc = osmo_bsc_data(vty);
llist_for_each_entry(msc, &bsc->mscs, entry)
write_msc(vty, msc);
if (bsc->mid_call_txt)
vty_out(vty, " mid-call-text %s%s", bsc->mid_call_txt, VTY_NEWLINE);