aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libbsc
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-03-21 14:45:13 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2018-03-22 05:23:11 +0100
commit408856088bcf376f5317803fd8d1747f8b920054 (patch)
tree9266e5698859483ef5b359f4d6f2e3e7cdd4f109 /openbsc/src/libbsc
parent8469818e33ef81e9f707a0c4dd13d7b91ecf83f5 (diff)
backport support for 3-digit MNC with leading zerosneels/mnc3
Backport the patches with the following change-ids: osmo-bsc.git: I5b097dbb6329f284e3b4914a744d5c3ad628f715 I8e722103344186fde118b26d8353db95a4581daa I78f30aef7aa224b2e9db54c3a844d8f520b3aee0 I38ac98a4d25159cfd4f686efbfbaf8f00625a6d8 osmo-iuh.git: I29ebcddd45fe3079f8883589a83cc7216a535475 Also apply change of ipac_bcch_info.cgi to struct osmo_cell_global_id in src/ipaccess/network_listen.c, a change that appears to not have been necessary in the new split repositories. Related: OS#3010 Change-Id: Ibf50fd7e1ca5472d0a38fcb87c68227d6de44f42
Diffstat (limited to 'openbsc/src/libbsc')
-rw-r--r--openbsc/src/libbsc/abis_nm.c30
-rw-r--r--openbsc/src/libbsc/bsc_ctrl_commands.c88
-rw-r--r--openbsc/src/libbsc/bsc_init.c7
-rw-r--r--openbsc/src/libbsc/bsc_vty.c10
-rw-r--r--openbsc/src/libbsc/pcu_sock.c5
-rw-r--r--openbsc/src/libbsc/system_information.c12
6 files changed, 100 insertions, 52 deletions
diff --git a/openbsc/src/libbsc/abis_nm.c b/openbsc/src/libbsc/abis_nm.c
index f24f6bf91..8eadfa8d7 100644
--- a/openbsc/src/libbsc/abis_nm.c
+++ b/openbsc/src/libbsc/abis_nm.c
@@ -2785,10 +2785,12 @@ int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, uint8_t obj_class,
void abis_nm_ipaccess_cgi(uint8_t *buf, struct gsm_bts *bts)
{
- /* we simply reuse the GSM48 function and overwrite the RAC
- * with the Cell ID */
- gsm48_ra_id_by_bts(buf, bts);
- *((uint16_t *)(buf + 5)) = htons(bts->cell_identity);
+ struct gsm48_ra_id *_buf = (struct gsm48_ra_id*)buf;
+ uint16_t ci = htons(bts->cell_identity);
+ /* we simply reuse the GSM48 function and write the Cell ID over the position where the RAC
+ * starts */
+ gsm48_ra_id_by_bts(_buf, bts);
+ memcpy(&_buf->rac, &ci, sizeof(ci));
}
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, bool locked, const char *reason)
@@ -2822,23 +2824,11 @@ const char *ipacc_testres_name(uint8_t res)
return get_value_string(ipacc_testres_names, res);
}
-void ipac_parse_cgi(struct cell_global_id *cid, const uint8_t *buf)
+void ipac_parse_cgi(struct osmo_cell_global_id *cid, const uint8_t *buf)
{
- cid->mcc = (buf[0] & 0xf) * 100;
- cid->mcc += (buf[0] >> 4) * 10;
- cid->mcc += (buf[1] & 0xf) * 1;
-
- if (buf[1] >> 4 == 0xf) {
- cid->mnc = (buf[2] & 0xf) * 10;
- cid->mnc += (buf[2] >> 4) * 1;
- } else {
- cid->mnc = (buf[2] & 0xf) * 100;
- cid->mnc += (buf[2] >> 4) * 10;
- cid->mnc += (buf[1] >> 4) * 1;
- }
-
- cid->lac = ntohs(*((uint16_t *)&buf[3]));
- cid->ci = ntohs(*((uint16_t *)&buf[5]));
+ osmo_plmn_from_bcd(buf, &cid->lai.plmn);
+ cid->lai.lac = ntohs(*((uint16_t *)&buf[3]));
+ cid->cell_identity = ntohs(*((uint16_t *)&buf[5]));
}
/* parse BCCH information IEI from wire format to struct ipac_bcch_info */
diff --git a/openbsc/src/libbsc/bsc_ctrl_commands.c b/openbsc/src/libbsc/bsc_ctrl_commands.c
index 641fe2bf6..8b8685ab8 100644
--- a/openbsc/src/libbsc/bsc_ctrl_commands.c
+++ b/openbsc/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 <openbsc/ipaccess.h>
#include <openbsc/gsm_data.h>
#include <openbsc/abis_nm.h>
@@ -65,8 +66,62 @@ static int verify_vty_description_string(struct ctrl_cmd *cmd,
return 0;
}
-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;
+}
+
CTRL_CMD_VTY_STRING(net_short_name, "short-name", struct gsm_network, name_short);
CTRL_CMD_VTY_STRING(net_long_name, "long-name", struct gsm_network, name_long);
@@ -101,6 +156,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)
@@ -108,39 +164,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/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c
index 0f732d758..9389c4342 100644
--- a/openbsc/src/libbsc/bsc_init.c
+++ b/openbsc/src/libbsc/bsc_init.c
@@ -305,9 +305,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/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 5340e11dd..f78247bda 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -164,9 +164,8 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net)
{
struct pchan_load pl;
- 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, " Long network name: '%s'%s",
net->name_long, VTY_NEWLINE);
vty_out(vty, " Short network name: '%s'%s",
@@ -840,8 +839,9 @@ static int config_write_net(struct vty *vty)
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
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, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE);
diff --git a/openbsc/src/libbsc/pcu_sock.c b/openbsc/src/libbsc/pcu_sock.c
index 98e12fad4..e2066ba3e 100644
--- a/openbsc/src/libbsc/pcu_sock.c
+++ b/openbsc/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;
+ info_ind->mnc_3_digits = bts->network->plmn.mnc_3_digits;
info_ind->lac = bts->location_area_code;
info_ind->rac = bts->gprs.rac;
diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c
index 57921455a..a6226a4d1 100644
--- a/openbsc/src/libbsc/system_information.c
+++ b/openbsc/src/libbsc/system_information.c
@@ -841,9 +841,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;
@@ -895,9 +893,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))
@@ -1069,9 +1065,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 */