bsc: Allow to use different LAC/CI for the core-network
We need to use different LAC/CI towards the core network. It is a bit problematic as LAC/CI is a per BTS attribute so this feature only works if a BSC manages everything in the same LAC. Related: SYS#1398
This commit is contained in:
parent
7cce1d301a
commit
32dd2f3f9b
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Data for the true BSC
|
* Data for the true BSC
|
||||||
*
|
*
|
||||||
* (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
|
* (C) 2010-2015 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||||
* (C) 2010-2011 by On-Waves
|
* (C) 2010-2015 by On-Waves
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -67,6 +67,8 @@ struct osmo_msc_data {
|
||||||
struct bsc_msc_connection *msc_con;
|
struct bsc_msc_connection *msc_con;
|
||||||
int core_ncc;
|
int core_ncc;
|
||||||
int core_mcc;
|
int core_mcc;
|
||||||
|
int core_lac;
|
||||||
|
int core_ci;
|
||||||
int rtp_base;
|
int rtp_base;
|
||||||
|
|
||||||
/* audio codecs */
|
/* audio codecs */
|
||||||
|
|
|
@ -65,6 +65,21 @@ static uint16_t get_country_code_for_msc(struct osmo_msc_data *msc)
|
||||||
return msc->network->country_code;
|
return msc->network->country_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t get_lac_for_msc(struct osmo_msc_data *msc, struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
if (msc->core_lac != -1)
|
||||||
|
return msc->core_lac;
|
||||||
|
return bts->location_area_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t get_ci_for_msc(struct osmo_msc_data *msc, struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
if (msc->core_ci != -1)
|
||||||
|
return msc->core_ci;
|
||||||
|
return bts->cell_identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci)
|
static void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci)
|
||||||
{
|
{
|
||||||
struct msgb *resp;
|
struct msgb *resp;
|
||||||
|
@ -161,6 +176,8 @@ static int complete_layer3(struct gsm_subscriber_connection *conn,
|
||||||
struct msgb *resp;
|
struct msgb *resp;
|
||||||
uint16_t network_code;
|
uint16_t network_code;
|
||||||
uint16_t country_code;
|
uint16_t country_code;
|
||||||
|
uint16_t lac;
|
||||||
|
uint16_t ci;
|
||||||
enum bsc_con ret;
|
enum bsc_con ret;
|
||||||
int send_ping = msc->advanced_ping;
|
int send_ping = msc->advanced_ping;
|
||||||
|
|
||||||
|
@ -189,11 +206,11 @@ static int complete_layer3(struct gsm_subscriber_connection *conn,
|
||||||
|
|
||||||
network_code = get_network_code_for_msc(conn->sccp_con->msc);
|
network_code = get_network_code_for_msc(conn->sccp_con->msc);
|
||||||
country_code = get_country_code_for_msc(conn->sccp_con->msc);
|
country_code = get_country_code_for_msc(conn->sccp_con->msc);
|
||||||
|
lac = get_lac_for_msc(conn->sccp_con->msc, conn->bts);
|
||||||
|
ci = get_ci_for_msc(conn->sccp_con->msc, conn->bts);
|
||||||
|
|
||||||
bsc_scan_bts_msg(conn, msg);
|
bsc_scan_bts_msg(conn, msg);
|
||||||
resp = gsm0808_create_layer3(msg, network_code, country_code,
|
resp = gsm0808_create_layer3(msg, network_code, country_code, lac, ci);
|
||||||
conn->bts->location_area_code,
|
|
||||||
conn->bts->cell_identity);
|
|
||||||
if (!resp) {
|
if (!resp) {
|
||||||
LOGP(DMSC, LOGL_DEBUG, "Failed to create layer3 message.\n");
|
LOGP(DMSC, LOGL_DEBUG, "Failed to create layer3 message.\n");
|
||||||
sccp_connection_free(conn->sccp_con->sccp);
|
sccp_connection_free(conn->sccp_con->sccp);
|
||||||
|
|
|
@ -311,6 +311,19 @@ static int bsc_patch_mm_info(struct gsm_subscriber_connection *conn,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int has_core_identity(struct osmo_msc_data *msc)
|
||||||
|
{
|
||||||
|
if (msc->core_ncc != -1)
|
||||||
|
return 1;
|
||||||
|
if (msc->core_mcc != -1)
|
||||||
|
return 1;
|
||||||
|
if (msc->core_lac != -1)
|
||||||
|
return 1;
|
||||||
|
if (msc->core_ci != -1)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Messages coming back from the MSC.
|
* Messages coming back from the MSC.
|
||||||
*/
|
*/
|
||||||
|
@ -336,7 +349,7 @@ int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
||||||
msc = conn->sccp_con->msc;
|
msc = conn->sccp_con->msc;
|
||||||
|
|
||||||
if (mtype == GSM48_MT_MM_LOC_UPD_ACCEPT) {
|
if (mtype == GSM48_MT_MM_LOC_UPD_ACCEPT) {
|
||||||
if (msc->core_ncc != -1 || msc->core_mcc != -1) {
|
if (has_core_identity(msc)) {
|
||||||
if (msgb_l3len(msg) >= sizeof(*gh) + sizeof(*lai)) {
|
if (msgb_l3len(msg) >= sizeof(*gh) + sizeof(*lai)) {
|
||||||
lai = (struct gsm48_loc_area_id *) &gh->data[0];
|
lai = (struct gsm48_loc_area_id *) &gh->data[0];
|
||||||
gsm48_generate_lai(lai, net->country_code,
|
gsm48_generate_lai(lai, net->country_code,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Handle the connection to the MSC. This include ping/timeout/reconnect
|
* Handle the connection to the MSC. This include ping/timeout/reconnect
|
||||||
* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||||
* (C) 2009-2014 by Holger Hans Peter Freyther <zecke@selfish.org>
|
* (C) 2009-2015 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||||
* (C) 2009-2014 by On-Waves
|
* (C) 2009-2015 by On-Waves
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -524,6 +524,8 @@ struct osmo_msc_data *osmo_msc_data_alloc(struct gsm_network *net, int nr)
|
||||||
msc_data->pong_timeout = 5;
|
msc_data->pong_timeout = 5;
|
||||||
msc_data->core_ncc = -1;
|
msc_data->core_ncc = -1;
|
||||||
msc_data->core_mcc = -1;
|
msc_data->core_mcc = -1;
|
||||||
|
msc_data->core_ci = -1;
|
||||||
|
msc_data->core_lac = -1;
|
||||||
msc_data->rtp_base = 4000;
|
msc_data->rtp_base = 4000;
|
||||||
|
|
||||||
msc_data->nr = nr;
|
msc_data->nr = nr;
|
||||||
|
|
|
@ -112,6 +112,12 @@ static void write_msc(struct vty *vty, struct osmo_msc_data *msc)
|
||||||
if (msc->core_mcc != -1)
|
if (msc->core_mcc != -1)
|
||||||
vty_out(vty, " core-mobile-country-code %d%s",
|
vty_out(vty, " core-mobile-country-code %d%s",
|
||||||
msc->core_mcc, VTY_NEWLINE);
|
msc->core_mcc, VTY_NEWLINE);
|
||||||
|
if (msc->core_lac != -1)
|
||||||
|
vty_out(vty, " core-location-area-code %d%s",
|
||||||
|
msc->core_lac, VTY_NEWLINE);
|
||||||
|
if (msc->core_ci != -1)
|
||||||
|
vty_out(vty, " core-cell-identity %d%s",
|
||||||
|
msc->core_ci, VTY_NEWLINE);
|
||||||
vty_out(vty, " ip.access rtp-base %d%s", msc->rtp_base, VTY_NEWLINE);
|
vty_out(vty, " ip.access rtp-base %d%s", msc->rtp_base, VTY_NEWLINE);
|
||||||
|
|
||||||
if (msc->ping_timeout == -1)
|
if (msc->ping_timeout == -1)
|
||||||
|
@ -239,6 +245,26 @@ DEFUN(cfg_net_bsc_mcc,
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN(cfg_net_bsc_lac,
|
||||||
|
cfg_net_bsc_lac_cmd,
|
||||||
|
"core-location-area-code <0-65535>",
|
||||||
|
"Use this location area code for the core network\n" "LAC value\n")
|
||||||
|
{
|
||||||
|
struct osmo_msc_data *data = osmo_msc_data(vty);
|
||||||
|
data->core_lac = atoi(argv[0]);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN(cfg_net_bsc_ci,
|
||||||
|
cfg_net_bsc_ci_cmd,
|
||||||
|
"core-cell-identity <0-65535>",
|
||||||
|
"Use this cell identity for the core network\n" "CI value\n")
|
||||||
|
{
|
||||||
|
struct osmo_msc_data *data = osmo_msc_data(vty);
|
||||||
|
data->core_ci = atoi(argv[0]);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN(cfg_net_bsc_rtp_base,
|
DEFUN(cfg_net_bsc_rtp_base,
|
||||||
cfg_net_bsc_rtp_base_cmd,
|
cfg_net_bsc_rtp_base_cmd,
|
||||||
"ip.access rtp-base <1-65000>",
|
"ip.access rtp-base <1-65000>",
|
||||||
|
@ -785,6 +811,8 @@ int bsc_vty_init_extra(void)
|
||||||
install_element(MSC_NODE, &cfg_net_bsc_token_cmd);
|
install_element(MSC_NODE, &cfg_net_bsc_token_cmd);
|
||||||
install_element(MSC_NODE, &cfg_net_bsc_ncc_cmd);
|
install_element(MSC_NODE, &cfg_net_bsc_ncc_cmd);
|
||||||
install_element(MSC_NODE, &cfg_net_bsc_mcc_cmd);
|
install_element(MSC_NODE, &cfg_net_bsc_mcc_cmd);
|
||||||
|
install_element(MSC_NODE, &cfg_net_bsc_lac_cmd);
|
||||||
|
install_element(MSC_NODE, &cfg_net_bsc_ci_cmd);
|
||||||
install_element(MSC_NODE, &cfg_net_bsc_rtp_base_cmd);
|
install_element(MSC_NODE, &cfg_net_bsc_rtp_base_cmd);
|
||||||
install_element(MSC_NODE, &cfg_net_bsc_codec_list_cmd);
|
install_element(MSC_NODE, &cfg_net_bsc_codec_list_cmd);
|
||||||
install_element(MSC_NODE, &cfg_net_msc_dest_cmd);
|
install_element(MSC_NODE, &cfg_net_msc_dest_cmd);
|
||||||
|
|
|
@ -495,6 +495,21 @@ class TestVTYBSC(TestVTYGenericBSC):
|
||||||
self.assert_(res.find(" timeout-pong 14") > 0)
|
self.assert_(res.find(" timeout-pong 14") > 0)
|
||||||
self.assert_(res.find(" timeout-ping advanced") > 0)
|
self.assert_(res.find(" timeout-ping advanced") > 0)
|
||||||
|
|
||||||
|
def testMscDataCoreLACCI(self):
|
||||||
|
self.vty.enable()
|
||||||
|
res = self.vty.command("show running-config")
|
||||||
|
self.assertEquals(res.find("core-location-area-code"), -1)
|
||||||
|
self.assertEquals(res.find("core-cell-identity"), -1)
|
||||||
|
|
||||||
|
self.vty.command("configure terminal")
|
||||||
|
self.vty.command("msc 0")
|
||||||
|
self.vty.command("core-location-area-code 666")
|
||||||
|
self.vty.command("core-cell-identity 333")
|
||||||
|
|
||||||
|
res = self.vty.command("show running-config")
|
||||||
|
self.assert_(res.find("core-location-area-code 666") > 0)
|
||||||
|
self.assert_(res.find("core-cell-identity 333") > 0)
|
||||||
|
|
||||||
class TestVTYNAT(TestVTYGenericBSC):
|
class TestVTYNAT(TestVTYGenericBSC):
|
||||||
|
|
||||||
def vty_command(self):
|
def vty_command(self):
|
||||||
|
|
Loading…
Reference in New Issue