aboutsummaryrefslogtreecommitdiffstats
path: root/src/libbsc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libbsc')
-rw-r--r--src/libbsc/bsc_ctrl_commands.c87
-rw-r--r--src/libbsc/bsc_init.c7
-rw-r--r--src/libbsc/bsc_vty.c28
-rw-r--r--src/libbsc/gsm_data.c5
-rw-r--r--src/libbsc/net_init.c6
-rw-r--r--src/libbsc/pcu_sock.c5
-rw-r--r--src/libbsc/system_information.c12
7 files changed, 112 insertions, 38 deletions
diff --git a/src/libbsc/bsc_ctrl_commands.c b/src/libbsc/bsc_ctrl_commands.c
index 41d236126..64f458920 100644
--- a/src/libbsc/bsc_ctrl_commands.c
+++ b/src/libbsc/bsc_ctrl_commands.c
@@ -22,6 +22,7 @@
#include <time.h>
#include <osmocom/ctrl/control_cmd.h>
+#include <osmocom/gsm/gsm48.h>
#include <osmocom/bsc/ipaccess.h>
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/abis_nm.h>
@@ -30,8 +31,61 @@
#include <osmocom/bsc/osmo_bsc_rf.h>
#include <osmocom/bsc/bsc_msc_data.h>
-CTRL_CMD_DEFINE_RANGE(net_mnc, "mnc", struct gsm_network, network_code, 0, 999);
-CTRL_CMD_DEFINE_RANGE(net_mcc, "mcc", struct gsm_network, country_code, 1, 999);
+CTRL_CMD_DEFINE(net_mcc, "mcc");
+static int get_net_mcc(struct ctrl_cmd *cmd, void *_data)
+{
+ struct gsm_network *net = cmd->node;
+ cmd->reply = talloc_asprintf(cmd, "%s", osmo_mcc_name(net->plmn.mcc));
+ if (!cmd->reply) {
+ cmd->reply = "OOM";
+ return CTRL_CMD_ERROR;
+ }
+ return CTRL_CMD_REPLY;
+}
+static int set_net_mcc(struct ctrl_cmd *cmd, void *_data)
+{
+ struct gsm_network *net = cmd->node;
+ uint16_t mcc;
+ if (osmo_mcc_from_str(cmd->value, &mcc))
+ return -1;
+ net->plmn.mcc = mcc;
+ return get_net_mcc(cmd, _data);
+}
+static int verify_net_mcc(struct ctrl_cmd *cmd, const char *value, void *_data)
+{
+ if (osmo_mcc_from_str(value, NULL))
+ return -1;
+ return 0;
+}
+
+CTRL_CMD_DEFINE(net_mnc, "mnc");
+static int get_net_mnc(struct ctrl_cmd *cmd, void *_data)
+{
+ struct gsm_network *net = cmd->node;
+ cmd->reply = talloc_asprintf(cmd, "%s", osmo_mnc_name(net->plmn.mnc, net->plmn.mnc_3_digits));
+ if (!cmd->reply) {
+ cmd->reply = "OOM";
+ return CTRL_CMD_ERROR;
+ }
+ return CTRL_CMD_REPLY;
+}
+static int set_net_mnc(struct ctrl_cmd *cmd, void *_data)
+{
+ struct gsm_network *net = cmd->node;
+ struct osmo_plmn_id plmn = net->plmn;
+ if (osmo_mnc_from_str(cmd->value, &plmn.mnc, &plmn.mnc_3_digits)) {
+ cmd->reply = "Error while decoding MNC";
+ return CTRL_CMD_ERROR;
+ }
+ net->plmn = plmn;
+ return get_net_mnc(cmd, _data);
+}
+static int verify_net_mnc(struct ctrl_cmd *cmd, const char *value, void *_data)
+{
+ if (osmo_mnc_from_str(value, NULL, NULL))
+ return -1;
+ return 0;
+}
static int set_net_apply_config(struct ctrl_cmd *cmd, void *data)
{
@@ -64,6 +118,7 @@ CTRL_CMD_DEFINE_WO_NOVRF(net_apply_config, "apply-configuration");
static int verify_net_mcc_mnc_apply(struct ctrl_cmd *cmd, const char *value, void *d)
{
char *tmp, *saveptr, *mcc, *mnc;
+ int rc = 0;
tmp = talloc_strdup(cmd, value);
if (!tmp)
@@ -71,39 +126,45 @@ static int verify_net_mcc_mnc_apply(struct ctrl_cmd *cmd, const char *value, voi
mcc = strtok_r(tmp, ",", &saveptr);
mnc = strtok_r(NULL, ",", &saveptr);
- talloc_free(tmp);
- if (!mcc || !mnc)
- return 1;
- return 0;
+ if (osmo_mcc_from_str(mcc, NULL) || osmo_mnc_from_str(mnc, NULL, NULL))
+ rc = -1;
+
+ talloc_free(tmp);
+ return rc;
}
static int set_net_mcc_mnc_apply(struct ctrl_cmd *cmd, void *data)
{
struct gsm_network *net = cmd->node;
char *tmp, *saveptr, *mcc_str, *mnc_str;
- int mcc, mnc;
+ struct osmo_plmn_id plmn;
tmp = talloc_strdup(cmd, cmd->value);
if (!tmp)
goto oom;
-
mcc_str = strtok_r(tmp, ",", &saveptr);
mnc_str = strtok_r(NULL, ",", &saveptr);
- mcc = atoi(mcc_str);
- mnc = atoi(mnc_str);
+ if (osmo_mcc_from_str(mcc_str, &plmn.mcc)) {
+ cmd->reply = "Error while decoding MCC";
+ return CTRL_CMD_ERROR;
+ }
+
+ if (osmo_mnc_from_str(mnc_str, &plmn.mnc, &plmn.mnc_3_digits)) {
+ cmd->reply = "Error while decoding MNC";
+ return CTRL_CMD_ERROR;
+ }
talloc_free(tmp);
- if (net->network_code == mnc && net->country_code == mcc) {
+ if (!osmo_plmn_cmp(&net->plmn, &plmn)) {
cmd->reply = "Nothing changed";
return CTRL_CMD_REPLY;
}
- net->network_code = mnc;
- net->country_code = mcc;
+ net->plmn = plmn;
return set_net_apply_config(cmd, data);
diff --git a/src/libbsc/bsc_init.c b/src/libbsc/bsc_init.c
index a2f0504e1..f164533bc 100644
--- a/src/libbsc/bsc_init.c
+++ b/src/libbsc/bsc_init.c
@@ -326,9 +326,10 @@ static void bootstrap_rsl(struct gsm_bts_trx *trx)
unsigned int i;
LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
- "on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u\n",
- trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
- bsc_gsmnet->network_code, trx->bts->location_area_code,
+ "on ARFCN %u using MCC-MNC %s LAC=%u CID=%u BSIC=%u\n",
+ trx->bts->nr, trx->nr, trx->arfcn,
+ osmo_plmn_name(&bsc_gsmnet->plmn),
+ trx->bts->location_area_code,
trx->bts->cell_identity, trx->bts->bsic);
/*
diff --git a/src/libbsc/bsc_vty.c b/src/libbsc/bsc_vty.c
index 47bc51483..29a3c80a3 100644
--- a/src/libbsc/bsc_vty.c
+++ b/src/libbsc/bsc_vty.c
@@ -203,9 +203,8 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net)
struct pchan_load pl;
int i;
- vty_out(vty, "BSC is on Country Code %u, Network Code %u "
- "and has %u BTS%s", net->country_code, net->network_code,
- net->num_bts, VTY_NEWLINE);
+ vty_out(vty, "BSC is on MCC-MNC %s and has %u BTS%s",
+ osmo_plmn_name(&net->plmn), net->num_bts, VTY_NEWLINE);
vty_out(vty, "%s", VTY_NEWLINE);
vty_out(vty, " Encryption:");
for (i = 0; i < 8; i++) {
@@ -955,8 +954,9 @@ static int config_write_net(struct vty *vty)
int i;
vty_out(vty, "network%s", VTY_NEWLINE);
- vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
- vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
+ vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
+ vty_out(vty, " mobile network code %s%s",
+ osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
vty_out(vty, " encryption a5");
for (i = 0; i < 8; i++) {
if (gsmnet->a5_encryption_mask & (1 << i))
@@ -4516,8 +4516,14 @@ DEFUN(cfg_net_ncc,
"Network Country Code to use\n")
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ uint16_t mcc;
- gsmnet->country_code = atoi(argv[0]);
+ if (osmo_mcc_from_str(argv[0], &mcc)) {
+ vty_out(vty, "%% Error decoding MCC: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ gsmnet->plmn.mcc = mcc;
return CMD_SUCCESS;
}
@@ -4531,8 +4537,16 @@ DEFUN(cfg_net_mnc,
"Mobile Network Code to use\n")
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ uint16_t mnc;
+ bool mnc_3_digits;
+
+ if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
+ vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- gsmnet->network_code = atoi(argv[0]);
+ gsmnet->plmn.mnc = mnc;
+ gsmnet->plmn.mnc_3_digits = mnc_3_digits;
return CMD_SUCCESS;
}
diff --git a/src/libbsc/gsm_data.c b/src/libbsc/gsm_data.c
index d4a6a70f9..686e9c54e 100644
--- a/src/libbsc/gsm_data.c
+++ b/src/libbsc/gsm_data.c
@@ -272,8 +272,9 @@ struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_typ
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts)
{
*raid = (struct gprs_ra_id){
- .mcc = bts->network->country_code,
- .mnc = bts->network->network_code,
+ .mcc = bts->network->plmn.mcc,
+ .mnc = bts->network->plmn.mnc,
+ .mnc_3_digits = bts->network->plmn.mnc_3_digits,
.lac = bts->location_area_code,
.rac = bts->gprs.rac,
};
diff --git a/src/libbsc/net_init.c b/src/libbsc/net_init.c
index e44c335d1..d5ea5b275 100644
--- a/src/libbsc/net_init.c
+++ b/src/libbsc/net_init.c
@@ -47,8 +47,10 @@ struct gsm_network *bsc_network_init(void *ctx)
if (!net)
return NULL;
- net->country_code = 1;
- net->network_code = 1;
+ net->plmn = (struct osmo_plmn_id){
+ .mcc = 1,
+ .mnc = 1,
+ };
/* Permit a compile-time default of A5/3 and A5/1 */
net->a5_encryption_mask = (1 << 3) | (1 << 1);
diff --git a/src/libbsc/pcu_sock.c b/src/libbsc/pcu_sock.c
index 9f1c80cc2..85af59842 100644
--- a/src/libbsc/pcu_sock.c
+++ b/src/libbsc/pcu_sock.c
@@ -152,8 +152,9 @@ static int pcu_tx_info_ind(struct gsm_bts *bts)
info_ind->flags |= PCU_IF_FLAG_SYSMO;
/* RAI */
- info_ind->mcc = bts->network->country_code;
- info_ind->mnc = bts->network->network_code;
+ info_ind->mcc = bts->network->plmn.mcc;
+ info_ind->mnc = bts->network->plmn.mnc;
+ /* TODO: plmn.mnc_3_digits */
info_ind->lac = bts->location_area_code;
info_ind->rac = bts->gprs.rac;
diff --git a/src/libbsc/system_information.c b/src/libbsc/system_information.c
index 750bba427..c7c85b043 100644
--- a/src/libbsc/system_information.c
+++ b/src/libbsc/system_information.c
@@ -860,9 +860,7 @@ static int generate_si3(enum osmo_sysinfo_type t, struct gsm_bts *bts)
si3->header.system_information = GSM48_MT_RR_SYSINFO_3;
si3->cell_identity = htons(bts->cell_identity);
- gsm48_generate_lai(&si3->lai, bts->network->country_code,
- bts->network->network_code,
- bts->location_area_code);
+ gsm48_generate_lai2(&si3->lai, bts_lai(bts));
si3->control_channel_desc = bts->si_common.chan_desc;
si3->cell_options = bts->si_common.cell_options;
si3->cell_sel_par = bts->si_common.cell_sel_par;
@@ -914,9 +912,7 @@ static int generate_si4(enum osmo_sysinfo_type t, struct gsm_bts *bts)
si4->header.skip_indicator = 0;
si4->header.system_information = GSM48_MT_RR_SYSINFO_4;
- gsm48_generate_lai(&si4->lai, bts->network->country_code,
- bts->network->network_code,
- bts->location_area_code);
+ gsm48_generate_lai2(&si4->lai, bts_lai(bts));
si4->cell_sel_par = bts->si_common.cell_sel_par;
si4->rach_control = bts->si_common.rach_control;
if (acc_ramp_is_enabled(&bts->acc_ramp))
@@ -1088,9 +1084,7 @@ static int generate_si6(enum osmo_sysinfo_type t, struct gsm_bts *bts)
si6->skip_indicator = 0;
si6->system_information = GSM48_MT_RR_SYSINFO_6;
si6->cell_identity = htons(bts->cell_identity);
- gsm48_generate_lai(&si6->lai, bts->network->country_code,
- bts->network->network_code,
- bts->location_area_code);
+ gsm48_generate_lai2(&si6->lai, bts_lai(bts));
si6->cell_options = bts->si_common.cell_options;
si6->ncc_permitted = bts->si_common.ncc_permitted;
/* allow/disallow DTXu */