bsc: Create a osmo_bsc_data and embed osmo_msc_data

We want to have multiple MSCs but we also have some data
that is only present on a per BSC basis. Right now the
MSC data is not allocated with talloc, so we have some
change in the talloc contexts.
This commit is contained in:
Holger Hans Peter Freyther 2011-08-15 15:53:00 +02:00
parent 4d31900e2d
commit 8ec4952557
14 changed files with 108 additions and 87 deletions

View File

@ -285,7 +285,7 @@ struct gsm_network {
int pag_any_tch;
/* MSC data in case we are a true BSC */
struct osmo_msc_data *msc_data;
struct osmo_bsc_data *bsc_data;
/* subscriber related features */
int keep_subscr;

View File

@ -19,7 +19,8 @@
#include <osmocom/abis/e1_input.h>
struct osmo_msc_data;
struct osmo_bsc_data;
struct osmo_bsc_sccp_con;
struct gsm_sms_queue;

View File

@ -57,20 +57,30 @@ struct osmo_msc_data {
/* destinations */
struct llist_head dests;
/* ussd welcome text */
char *ussd_welcome_txt;
/* mgcp agent */
struct osmo_wqueue mgcp_agent;
};
/*
* Per BSC data.
*/
struct osmo_bsc_data {
struct gsm_network *network;
/* msc configuration */
struct osmo_msc_data msc;
/* rf ctl related bits */
char *mid_call_txt;
int mid_call_timeout;
char *rf_ctrl_name;
struct osmo_bsc_rf *rf_ctrl;
/* ussd welcome text */
char *ussd_welcome_txt;
};
int osmo_bsc_msc_init(struct gsm_network *network);
int osmo_bsc_sccp_init(struct gsm_network *gsmnet);
int msc_queue_write(struct bsc_msc_connection *conn, struct msgb *msg, int proto);

View File

@ -197,9 +197,9 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net)
dump_pchan_load_vty(vty, " ", &pl);
/* show rf */
if (net->msc_data && net->msc_data->rf_ctrl)
if (net->bsc_data && net->bsc_data->rf_ctrl)
vty_out(vty, " Last RF Command: %s%s",
net->msc_data->rf_ctrl->last_state_command,
net->bsc_data->rf_ctrl->last_state_command,
VTY_NEWLINE);
}

View File

@ -79,14 +79,14 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
if (!net)
return NULL;
net->msc_data = talloc_zero(net, struct osmo_msc_data);
if (!net->msc_data) {
net->bsc_data = talloc_zero(net, struct osmo_bsc_data);
if (!net->bsc_data) {
talloc_free(net);
return NULL;
}
/* Init back pointer */
net->msc_data->network = net;
net->bsc_data->network = net;
net->country_code = country_code;
net->network_code = network_code;
@ -141,12 +141,13 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
net->mncc_recv = mncc_recv;
INIT_LLIST_HEAD(&net->msc_data->dests);
net->msc_data->ping_timeout = 20;
net->msc_data->pong_timeout = 5;
net->msc_data->core_ncc = -1;
net->msc_data->core_mcc = -1;
net->msc_data->rtp_base = 4000;
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);

View File

@ -1,5 +1,5 @@
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves
/* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@ -47,15 +47,15 @@
static uint16_t get_network_code_for_msc(struct gsm_network *net)
{
if (net->msc_data->core_ncc != -1)
return net->msc_data->core_ncc;
if (net->bsc_data->msc.core_ncc != -1)
return net->bsc_data->msc.core_ncc;
return net->network_code;
}
static uint16_t get_country_code_for_msc(struct gsm_network *net)
{
if (net->msc_data->core_mcc != -1)
return net->msc_data->core_mcc;
if (net->bsc_data->msc.core_mcc != -1)
return net->bsc_data->msc.core_mcc;
return net->country_code;
}

View File

@ -1,6 +1,6 @@
/* GSM 08.08 BSSMAP handling */
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves
/* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@ -296,6 +296,7 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
struct msgb *msg, unsigned int length)
{
struct msgb *resp;
struct osmo_msc_data *msc;
struct gsm_network *network;
struct tlv_parsed tp;
uint8_t *data;
@ -357,11 +358,12 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
* the correct value.
*/
full_rate = 0;
msc = &network->bsc_data->msc;
for (supported = 0;
chan_mode == GSM48_CMODE_SIGN && supported < network->msc_data->audio_length;
chan_mode == GSM48_CMODE_SIGN && supported < msc->audio_length;
++supported) {
int perm_val = audio_support_to_gsm88(network->msc_data->audio_support[supported]);
int perm_val = audio_support_to_gsm88(msc->audio_support[supported]);
for (i = 2; i < TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE); ++i) {
if ((data[i] & 0x7f) == perm_val) {
chan_mode = gsm88_to_chan_mode(perm_val);
@ -380,8 +382,7 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
/* map it to a MGCP Endpoint and a RTP port */
port = mgcp_timeslot_to_endpoint(multiplex, timeslot);
conn->rtp_port = rtp_calculate_port(port,
network->msc_data->rtp_base);
conn->rtp_port = rtp_calculate_port(port, msc->rtp_base);
return gsm0808_assign_req(conn->conn, chan_mode, full_rate);

View File

@ -1,5 +1,5 @@
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves
/* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@ -125,10 +125,10 @@ static void send_welcome_ussd(struct gsm_subscriber_connection *conn)
struct gsm_network *net;
net = conn->bts->network;
if (!net->msc_data->ussd_welcome_txt)
if (!net->bsc_data->msc.ussd_welcome_txt)
return;
gsm0480_send_ussdNotify(conn, 1, net->msc_data->ussd_welcome_txt);
gsm0480_send_ussdNotify(conn, 1, net->bsc_data->msc.ussd_welcome_txt);
gsm0480_send_releaseComplete(conn);
}
@ -152,8 +152,8 @@ int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
net = conn->bts->network;
if (mtype == GSM48_MT_MM_LOC_UPD_ACCEPT) {
if (net->msc_data->core_ncc != -1 ||
net->msc_data->core_mcc != -1) {
if (net->bsc_data->msc.core_ncc != -1 ||
net->bsc_data->msc.core_mcc != -1) {
if (msgb_l3len(msg) >= sizeof(*gh) + sizeof(*lai)) {
lai = (struct gsm48_loc_area_id *) &gh->data[0];
gsm48_generate_lai(lai, net->country_code,

View File

@ -26,9 +26,9 @@
int bsc_grace_allow_new_connection(struct gsm_network *network)
{
if (!network->msc_data->rf_ctrl)
if (!network->bsc_data->rf_ctrl)
return 1;
return network->msc_data->rf_ctrl->policy == S_RF_ON;
return network->bsc_data->rf_ctrl->policy == S_RF_ON;
}
static int handle_sub(struct gsm_lchan *lchan, const char *text)
@ -68,7 +68,7 @@ static int handle_grace(struct gsm_network *network)
struct gsm_bts *bts;
struct gsm_bts_trx *trx;
if (!network->msc_data->mid_call_txt)
if (!network->bsc_data->mid_call_txt)
return 0;
llist_for_each_entry(bts, &network->bts_list, list) {
@ -77,7 +77,7 @@ static int handle_grace(struct gsm_network *network)
struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
for (lchan_nr = 0; lchan_nr < TS_MAX_LCHAN; ++lchan_nr) {
handle_sub(&ts->lchan[lchan_nr],
network->msc_data->mid_call_txt);
network->bsc_data->mid_call_txt);
}
}
}

View File

@ -161,13 +161,13 @@ static void signal_handler(int signal)
talloc_report_full(tall_bsc_ctx, stderr);
break;
case SIGUSR2:
if (!bsc_gsmnet->msc_data)
if (!bsc_gsmnet->bsc_data)
return;
if (!bsc_gsmnet->msc_data->msc_con)
if (!bsc_gsmnet->bsc_data->msc.msc_con)
return;
if (!bsc_gsmnet->msc_data->msc_con->is_connected)
if (!bsc_gsmnet->bsc_data->msc.msc_con->is_connected)
return;
bsc_msc_lost(bsc_gsmnet->msc_data->msc_con);
bsc_msc_lost(bsc_gsmnet->bsc_data->msc.msc_con);
break;
default:
break;
@ -391,7 +391,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 *data;
struct osmo_bsc_data *data;
int rc;
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
@ -430,7 +430,7 @@ int main(int argc, char **argv)
ctrl_cmd_install(CTRL_NODE_NET, &cmd_net_rf_lock);
ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_rf_lock);
data = bsc_gsmnet->msc_data;
data = bsc_gsmnet->bsc_data;
if (rf_ctrl)
bsc_replace_string(data, &data->rf_ctrl_name, rf_ctrl);

View File

@ -431,7 +431,7 @@ static void send_id_get_response(struct osmo_msc_data *data, int fd)
int osmo_bsc_msc_init(struct gsm_network *network)
{
struct osmo_msc_data *data = network->msc_data;
struct osmo_msc_data *data = &network->bsc_data->msc;
if (mgcp_create_port(data) != 0)
return -1;

View File

@ -160,9 +160,9 @@ static int enter_grace(struct osmo_bsc_rf *rf)
{
rf->grace_timeout.cb = grace_timeout;
rf->grace_timeout.data = rf;
osmo_timer_schedule(&rf->grace_timeout, rf->gsm_network->msc_data->mid_call_timeout, 0);
osmo_timer_schedule(&rf->grace_timeout, rf->gsm_network->bsc_data->mid_call_timeout, 0);
LOGP(DLINP, LOGL_NOTICE, "Going to switch RF off in %d seconds.\n",
rf->gsm_network->msc_data->mid_call_timeout);
rf->gsm_network->bsc_data->mid_call_timeout);
send_signal(rf, S_RF_GRACE);
return 0;

View File

@ -1,7 +1,7 @@
/* Interaction with the SCCP subsystem */
/*
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves
* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@ -141,7 +141,7 @@ static void msc_sccp_write_ipa(struct sccp_connection *conn, struct msgb *msg,
void *global_ctx, void *ctx)
{
struct gsm_network *net = (struct gsm_network *) global_ctx;
msc_queue_write(net->msc_data->msc_con, msg, IPAC_PROTO_SCCP);
msc_queue_write(net->bsc_data->msc.msc_con, msg, IPAC_PROTO_SCCP);
}
static int msc_sccp_accept(struct sccp_connection *connection, void *data)
@ -153,7 +153,7 @@ static int msc_sccp_accept(struct sccp_connection *connection, void *data)
static int msc_sccp_read(struct msgb *msgb, unsigned int length, void *data)
{
struct gsm_network *net = (struct gsm_network *) data;
return bsc_handle_udt(net, net->msc_data->msc_con, msgb, length);
return bsc_handle_udt(net, net->bsc_data->msc.msc_con, msgb, length);
}
int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
@ -186,7 +186,7 @@ int bsc_create_new_connection(struct gsm_subscriber_connection *conn)
struct sccp_connection *sccp;
net = conn->bts->network;
if (!net->msc_data->msc_con->is_authenticated) {
if (!net->bsc_data->msc.msc_con->is_authenticated) {
LOGP(DMSC, LOGL_ERROR, "Not connected to a MSC. Not forwarding data.\n");
return -1;
}
@ -223,7 +223,7 @@ int bsc_create_new_connection(struct gsm_subscriber_connection *conn)
INIT_LLIST_HEAD(&bsc_con->sccp_queue);
bsc_con->sccp = sccp;
bsc_con->msc_con = net->msc_data->msc_con;
bsc_con->msc_con = net->bsc_data->msc.msc_con;
bsc_con->conn = conn;
llist_add_tail(&bsc_con->entry, &active_connections);
conn->sccp_con = bsc_con;

View File

@ -29,9 +29,14 @@
extern struct gsm_network *bsc_gsmnet;
static struct osmo_bsc_data *osmo_bsc_data(struct vty *vty)
{
return bsc_gsmnet->bsc_data;
}
static struct osmo_msc_data *osmo_msc_data(struct vty *vty)
{
return bsc_gsmnet->msc_data;
return &bsc_gsmnet->bsc_data->msc;
}
static struct cmd_node msc_node = {
@ -52,50 +57,52 @@ DEFUN(cfg_net_msc, cfg_net_msc_cmd,
static int config_write_msc(struct vty *vty)
{
struct bsc_msc_dest *dest;
struct osmo_msc_data *data = osmo_msc_data(vty);
struct osmo_bsc_data *bsc = osmo_bsc_data(vty);
struct osmo_msc_data *msc = &bsc->msc;
vty_out(vty, "msc%s", VTY_NEWLINE);
if (data->bsc_token)
vty_out(vty, " token %s%s", data->bsc_token, VTY_NEWLINE);
if (data->core_ncc != -1)
if (msc->bsc_token)
vty_out(vty, " token %s%s", msc->bsc_token, VTY_NEWLINE);
if (msc->core_ncc != -1)
vty_out(vty, " core-mobile-network-code %d%s",
data->core_ncc, VTY_NEWLINE);
if (data->core_mcc != -1)
msc->core_ncc, VTY_NEWLINE);
if (msc->core_mcc != -1)
vty_out(vty, " core-mobile-country-code %d%s",
data->core_mcc, VTY_NEWLINE);
vty_out(vty, " ip.access rtp-base %d%s", data->rtp_base, VTY_NEWLINE);
vty_out(vty, " timeout-ping %d%s", data->ping_timeout, VTY_NEWLINE);
vty_out(vty, " timeout-pong %d%s", data->pong_timeout, VTY_NEWLINE);
if (data->mid_call_txt)
vty_out(vty, " mid-call-text %s%s", data->mid_call_txt, VTY_NEWLINE);
vty_out(vty, " mid-call-timeout %d%s", data->mid_call_timeout, VTY_NEWLINE);
if (data->ussd_welcome_txt)
vty_out(vty, " bsc-welcome-text %s%s", data->ussd_welcome_txt, VTY_NEWLINE);
if (data->rf_ctrl_name)
vty_out(vty, " bsc-rf-socket %s%s",
data->rf_ctrl_name, VTY_NEWLINE);
msc->core_mcc, VTY_NEWLINE);
vty_out(vty, " ip.access rtp-base %d%s", msc->rtp_base, VTY_NEWLINE);
vty_out(vty, " timeout-ping %d%s", msc->ping_timeout, VTY_NEWLINE);
vty_out(vty, " timeout-pong %d%s", msc->pong_timeout, VTY_NEWLINE);
if (msc->ussd_welcome_txt)
vty_out(vty, " bsc-welcome-text %s%s", msc->ussd_welcome_txt, VTY_NEWLINE);
if (data->audio_length != 0) {
if (msc->audio_length != 0) {
int i;
vty_out(vty, " codec-list ");
for (i = 0; i < data->audio_length; ++i) {
for (i = 0; i < msc->audio_length; ++i) {
if (i != 0)
vty_out(vty, ", ");
if (data->audio_support[i]->hr)
vty_out(vty, "hr%.1u", data->audio_support[i]->ver);
if (msc->audio_support[i]->hr)
vty_out(vty, "hr%.1u", msc->audio_support[i]->ver);
else
vty_out(vty, "fr%.1u", data->audio_support[i]->ver);
vty_out(vty, "fr%.1u", msc->audio_support[i]->ver);
}
vty_out(vty, "%s", VTY_NEWLINE);
}
llist_for_each_entry(dest, &data->dests, list)
llist_for_each_entry(dest, &msc->dests, list)
vty_out(vty, " dest %s %d %d%s", dest->ip, dest->port,
dest->dscp, VTY_NEWLINE);
if (bsc->mid_call_txt)
vty_out(vty, " mid-call-text %s%s", bsc->mid_call_txt, VTY_NEWLINE);
vty_out(vty, " mid-call-timeout %d%s", bsc->mid_call_timeout, VTY_NEWLINE);
if (bsc->rf_ctrl_name)
vty_out(vty, " bsc-rf-socket %s%s",
bsc->rf_ctrl_name, VTY_NEWLINE);
return CMD_SUCCESS;
}
@ -106,7 +113,7 @@ DEFUN(cfg_net_bsc_token,
{
struct osmo_msc_data *data = osmo_msc_data(vty);
bsc_replace_string(data, &data->bsc_token, argv[0]);
bsc_replace_string(osmo_bsc_data(vty), &data->bsc_token, argv[0]);
return CMD_SUCCESS;
}
@ -163,7 +170,7 @@ DEFUN(cfg_net_bsc_codec_list,
/* create a new array */
data->audio_support =
talloc_zero_array(data, struct gsm_audio_support *, argc);
talloc_zero_array(osmo_bsc_data(vty), struct gsm_audio_support *, argc);
data->audio_length = argc;
for (i = 0; i < argc; ++i) {
@ -211,13 +218,13 @@ DEFUN(cfg_net_msc_dest,
struct bsc_msc_dest *dest;
struct osmo_msc_data *data = osmo_msc_data(vty);
dest = talloc_zero(data, struct bsc_msc_dest);
dest = talloc_zero(osmo_bsc_data(vty), struct bsc_msc_dest);
if (!dest) {
vty_out(vty, "%%Failed to create structure.%s", VTY_NEWLINE);
return CMD_WARNING;
}
dest->ip = talloc_strdup(data, argv[0]);
dest->ip = talloc_strdup(dest, argv[0]);
if (!dest->ip) {
vty_out(vty, "%%Failed to copy dest ip.%s", VTY_NEWLINE);
talloc_free(dest);
@ -279,7 +286,7 @@ DEFUN(cfg_net_msc_mid_call_text,
"mid-call-text .TEXT",
"Set the USSD notifcation to be send.\n" "Text to be sent\n")
{
struct osmo_msc_data *data = osmo_msc_data(vty);
struct osmo_bsc_data *data = osmo_bsc_data(vty);
char *txt = argv_concat(argv, argc, 0);
if (!txt)
return CMD_WARNING;
@ -294,7 +301,7 @@ DEFUN(cfg_net_msc_mid_call_timeout,
"mid-call-timeout NR",
"Switch from Grace to Off in NR seconds.\n" "Timeout in seconds\n")
{
struct osmo_msc_data *data = osmo_msc_data(vty);
struct osmo_bsc_data *data = osmo_bsc_data(vty);
data->mid_call_timeout = atoi(argv[0]);
return CMD_SUCCESS;
}
@ -309,7 +316,7 @@ DEFUN(cfg_net_msc_welcome_ussd,
if (!str)
return CMD_WARNING;
bsc_replace_string(data, &data->ussd_welcome_txt, str);
bsc_replace_string(osmo_bsc_data(vty), &data->ussd_welcome_txt, str);
talloc_free(str);
return CMD_SUCCESS;
}
@ -319,7 +326,7 @@ DEFUN(cfg_net_rf_socket,
"bsc-rf-socket PATH",
"Set the filename for the RF control interface.\n" "RF Control path\n")
{
struct osmo_msc_data *data = osmo_msc_data(vty);
struct osmo_bsc_data *data = osmo_bsc_data(vty);
bsc_replace_string(data, &data->rf_ctrl_name, argv[0]);
return CMD_SUCCESS;
@ -348,9 +355,10 @@ int bsc_vty_init_extra(void)
install_element(MSC_NODE, &cfg_net_msc_no_dest_cmd);
install_element(MSC_NODE, &cfg_net_msc_ping_time_cmd);
install_element(MSC_NODE, &cfg_net_msc_pong_time_cmd);
install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd);
install_element(MSC_NODE, &cfg_net_msc_mid_call_text_cmd);
install_element(MSC_NODE, &cfg_net_msc_mid_call_timeout_cmd);
install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd);
install_element(MSC_NODE, &cfg_net_rf_socket_cmd);
install_element_ve(&show_statistics_cmd);