This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Neels Hofmeyr gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/6668 implement support for 3-digit MNC with leading zeros Add 3-digit flags and use the new RAI and LAI API from libosmocore throughout the code base to be able to handle an MNC < 100 that has three digits (leading zeros). Depends: Id2240f7f518494c9df6c8bda52c0d5092f90f221 (libosmocore), Ib7176b1d65a03b76f41f94bc9d3293a8a07d24c6 (libosmocore) Change-Id: I8e722103344186fde118b26d8353db95a4581daa --- M include/osmocom/bsc/bsc_msc_data.h M include/osmocom/bsc/gsm_data.h M src/libbsc/bsc_ctrl_commands.c M src/libbsc/bsc_init.c M src/libbsc/bsc_vty.c M src/libbsc/system_information.c M src/osmo-bsc/osmo_bsc_api.c M src/osmo-bsc/osmo_bsc_bssap.c M src/osmo-bsc/osmo_bsc_ctrl.c M src/osmo-bsc/osmo_bsc_filter.c M src/osmo-bsc/osmo_bsc_msc.c M src/osmo-bsc/osmo_bsc_vty.c M tests/bssap/bssap_test.err 13 files changed, 124 insertions(+), 65 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/68/6668/1 diff --git a/include/osmocom/bsc/bsc_msc_data.h b/include/osmocom/bsc/bsc_msc_data.h index a3e0106..cbda10d 100644 --- a/include/osmocom/bsc/bsc_msc_data.h +++ b/include/osmocom/bsc/bsc_msc_data.h @@ -78,8 +78,9 @@ struct osmo_timer_list pong_timer; int advanced_ping; struct bsc_msc_connection *msc_con; - int core_mnc; - int core_mcc; + uint16_t core_mcc; + uint16_t core_mnc; + bool core_mnc_3_digits; int core_lac; int core_ci; int rtp_base; diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h index a8d7a0b..8fc0901 100644 --- a/include/osmocom/bsc/gsm_data.h +++ b/include/osmocom/bsc/gsm_data.h @@ -13,6 +13,7 @@ #include <osmocom/core/stats.h> #include <osmocom/core/stat_item.h> #include <osmocom/gsm/protocol/gsm_08_08.h> +#include <osmocom/gsm/gsm48.h> #include <osmocom/crypt/auth.h> @@ -1195,6 +1196,8 @@ /* global parameters */ uint16_t country_code; uint16_t network_code; + bool network_code_3_digits; + /* bit-mask of permitted encryption algorithms. LSB=A5/0, MSB=A5/7 */ uint8_t a5_encryption_mask; int neci; @@ -1270,6 +1273,11 @@ } mgw; }; +static inline const char *gsmnet_mcc_mnc_name(struct gsm_network *net) +{ + return osmo_mcc_mnc_name2(net->country_code, net->network_code, net->network_code_3_digits); +} + extern void talloc_ctx_init(void *ctx_root); int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type); diff --git a/src/libbsc/bsc_ctrl_commands.c b/src/libbsc/bsc_ctrl_commands.c index 41d2361..cac3ba9 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> @@ -75,6 +76,10 @@ if (!mcc || !mnc) return 1; + + if (gsm48_mnc_from_str(mnc, NULL, NULL)) + return 1; + return 0; } @@ -82,7 +87,8 @@ { struct gsm_network *net = cmd->node; char *tmp, *saveptr, *mcc_str, *mnc_str; - int mcc, mnc; + uint16_t mcc, mnc; + bool mnc_3_digits; tmp = talloc_strdup(cmd, cmd->value); if (!tmp) @@ -93,16 +99,22 @@ mnc_str = strtok_r(NULL, ",", &saveptr); mcc = atoi(mcc_str); - mnc = atoi(mnc_str); + if (gsm48_mnc_from_str(mnc_str, &mnc, &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 (!gsm48_mnc_cmp(net->network_code, net->network_code_3_digits, + mnc, mnc_3_digits) + && net->country_code == mcc) { cmd->reply = "Nothing changed"; return CTRL_CMD_REPLY; } net->network_code = mnc; + net->network_code_3_digits = mnc_3_digits; net->country_code = mcc; return set_net_apply_config(cmd, data); diff --git a/src/libbsc/bsc_init.c b/src/libbsc/bsc_init.c index 2b1d53b..04a8ef5 100644 --- a/src/libbsc/bsc_init.c +++ b/src/libbsc/bsc_init.c @@ -326,9 +326,10 @@ 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, + gsmnet_mcc_mnc_name(bsc_gsmnet), + trx->bts->location_area_code, trx->bts->cell_identity, trx->bts->bsic); if (trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE) { diff --git a/src/libbsc/bsc_vty.c b/src/libbsc/bsc_vty.c index 36c849d..1f13606 100644 --- a/src/libbsc/bsc_vty.c +++ b/src/libbsc/bsc_vty.c @@ -194,9 +194,8 @@ 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", + gsmnet_mcc_mnc_name(net), net->num_bts, VTY_NEWLINE); vty_out(vty, "%s", VTY_NEWLINE); vty_out(vty, " Encryption:"); for (i = 0; i < 8; i++) { @@ -925,8 +924,9 @@ 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->country_code), VTY_NEWLINE); + vty_out(vty, " mobile network code %s%s", + osmo_mnc_name(gsmnet->network_code, gsmnet->network_code_3_digits), VTY_NEWLINE); vty_out(vty, " encryption a5"); for (i = 0; i < 8; i++) { if (gsmnet->a5_encryption_mask & (1 << i)) @@ -4413,8 +4413,16 @@ "Mobile Network Code to use\n") { struct gsm_network *gsmnet = gsmnet_from_vty(vty); + uint16_t mnc; + bool mnc_3_digits; - gsmnet->network_code = atoi(argv[0]); + if (gsm48_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 = mnc; + gsmnet->network_code_3_digits = mnc_3_digits; return CMD_SUCCESS; } diff --git a/src/libbsc/system_information.c b/src/libbsc/system_information.c index a04959d..6c575b3 100644 --- a/src/libbsc/system_information.c +++ b/src/libbsc/system_information.c @@ -853,9 +853,9 @@ 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->network->country_code, + bts->network->network_code, bts->network->network_code_3_digits, + bts->location_area_code); 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; @@ -905,9 +905,9 @@ 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->network->country_code, + bts->network->network_code, bts->network->network_code_3_digits, + bts->location_area_code); si4->cell_sel_par = bts->si_common.cell_sel_par; si4->rach_control = bts->si_common.rach_control; @@ -1077,9 +1077,9 @@ 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->network->country_code, + bts->network->network_code, bts->network->network_code_3_digits, + bts->location_area_code); si6->cell_options = bts->si_common.cell_options; si6->ncc_permitted = bts->si_common.ncc_permitted; /* allow/disallow DTXu */ diff --git a/src/osmo-bsc/osmo_bsc_api.c b/src/osmo-bsc/osmo_bsc_api.c index 465832c..0ca7083 100644 --- a/src/osmo-bsc/osmo_bsc_api.c +++ b/src/osmo-bsc/osmo_bsc_api.c @@ -54,16 +54,24 @@ static int complete_layer3(struct gsm_subscriber_connection *conn, struct msgb *msg, struct bsc_msc_data *msc); -static uint16_t get_network_code_for_msc(struct bsc_msc_data *msc) +static void get_network_code_for_msc(struct bsc_msc_data *msc, uint16_t *mnc, bool *mnc_3_digits) { - if (msc->core_mnc != -1) - return msc->core_mnc; - return msc->network->network_code; + if (msc->core_mnc != GSM_MCC_MNC_INVALID) { + if (mnc) + *mnc = msc->core_mnc; + if (mnc_3_digits) + *mnc_3_digits = msc->core_mnc_3_digits; + return; + } + if (mnc) + *mnc = msc->network->network_code; + if (mnc_3_digits) + *mnc_3_digits = msc->network->network_code_3_digits; } static uint16_t get_country_code_for_msc(struct bsc_msc_data *msc) { - if (msc->core_mcc != -1) + if (msc->core_mcc != GSM_MCC_MNC_INVALID) return msc->core_mcc; return msc->network->country_code; } @@ -242,8 +250,9 @@ char *imsi = NULL; struct timeval tv; struct msgb *resp; - uint16_t network_code; - uint16_t country_code; + uint16_t mnc; + bool mnc_3_digits; + uint16_t mcc; uint16_t lac; uint16_t ci; enum bsc_con ret; @@ -285,14 +294,14 @@ /* check return value, if failed check msg for and send USSD */ - network_code = get_network_code_for_msc(conn->sccp.msc); - country_code = get_country_code_for_msc(conn->sccp.msc); + get_network_code_for_msc(conn->sccp.msc, &mnc, &mnc_3_digits); + mcc = get_country_code_for_msc(conn->sccp.msc); lac = get_lac_for_msc(conn->sccp.msc, conn_get_bts(conn)); ci = get_ci_for_msc(conn->sccp.msc, conn_get_bts(conn)); bsc_scan_bts_msg(conn, msg); - resp = gsm0808_create_layer3(msg, network_code, country_code, lac, ci); + resp = gsm0808_create_layer3_aoip2(msg, mnc, mnc_3_digits, mcc, lac, ci, NULL); if (!resp) { LOGP(DMSC, LOGL_DEBUG, "Failed to create layer3 message.\n"); osmo_bsc_sigtran_del_conn(conn); diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index 156ebd3..d1c17f3 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -263,14 +263,14 @@ /* Decode 5-byte LAI list element data (see TS 08.08 3.2.2.27) into MCC/MNC/LAC. * Return 0 if successful, negative on error. */ static int -decode_lai(const uint8_t *data, uint16_t *mcc, uint16_t *mnc, uint16_t *lac) +decode_lai(const uint8_t *data, uint16_t *mcc, uint16_t *mnc, bool *mnc_3_digits, uint16_t *lac) { struct gsm48_loc_area_id lai; /* Copy data to stack to prevent unaligned access in gsm48_decode_lai(). */ memcpy(&lai, data, sizeof(lai)); /* don't byte swap yet */ - return gsm48_decode_lai(&lai, mcc, mnc, lac) != 0 ? -1 : 0; + return gsm48_decode_lai2(&lai, mcc, mnc, mnc_3_digits, lac) ? -1 : 0; } static void @@ -291,8 +291,9 @@ int i = 0; while (remain >= sizeof(struct gsm48_loc_area_id) + sizeof(ci)) { uint16_t mcc, mnc, lac, *ci_be; + bool mnc_3_digits; size_t lai_offset = 1 + i * (sizeof(struct gsm48_loc_area_id) + sizeof(ci)); - if (decode_lai(&data[lai_offset], &mcc, &mnc, &lac) != 0) { + if (decode_lai(&data[lai_offset], &mcc, &mnc, &mnc_3_digits, &lac)) { LOGP(DMSC, LOGL_ERROR, "Paging IMSI %s: Invalid LAI in Cell Identifier List " "for BSS (0x%x), paging entire BSS anyway (%s)\n", mi_string, CELL_IDENT_BSS, osmo_hexdump(data, data_length)); @@ -301,7 +302,9 @@ } ci_be = (uint16_t *)(&data[lai_offset + sizeof(struct gsm48_loc_area_id)]); ci = osmo_load16be(ci_be); - if (mcc == msc->network->country_code && mnc == msc->network->network_code) { + if (mcc == msc->network->country_code + && !gsm48_mnc_cmp(msc->network->network_code, msc->network->network_code_3_digits, + mnc, mnc_3_digits)) { int paged = 0; struct gsm_bts *bts; llist_for_each_entry(bts, &msc->network->bts_list, list) { @@ -318,9 +321,10 @@ mi_string, lac, ci); } } else { - LOGP(DMSC, LOGL_DEBUG, "Paging IMSI %s: MCC/MNC in Cell Identifier List " - "(%d/%d) do not match our network (%d/%d)\n", mi_string, mcc, mnc, - msc->network->country_code, msc->network->network_code); + LOGP(DMSC, LOGL_DEBUG, "Paging IMSI %s: MCC-MNC in Cell Identifier List " + "(%s) do not match our network (%s)\n", + mi_string, osmo_mcc_mnc_name(mcc, mnc, mnc_3_digits), + gsmnet_mcc_mnc_name(msc->network)); } remain -= sizeof(struct gsm48_loc_area_id) + sizeof(ci); i++; @@ -390,14 +394,18 @@ int i = 0; while (remain >= sizeof(struct gsm48_loc_area_id)) { uint16_t mcc, mnc, lac; - if (decode_lai(&data[1 + i * sizeof(struct gsm48_loc_area_id)], &mcc, &mnc, &lac) != 0) { + bool mnc_3_digits; + if (decode_lai(&data[1 + i * sizeof(struct gsm48_loc_area_id)], &mcc, &mnc, + &mnc_3_digits, &lac)) { LOGP(DMSC, LOGL_ERROR, "Paging IMSI %s: Invalid LAI in Cell Identifier List " "for BSS (0x%x), paging entire BSS anyway (%s)\n", mi_string, CELL_IDENT_BSS, osmo_hexdump(data, data_length)); page_all_bts(msc, tmsi, mi_string, chan_needed); return; } - if (mcc == msc->network->country_code && mnc == msc->network->network_code) { + if (mcc == msc->network->country_code + && !gsm48_mnc_cmp(msc->network->network_code, msc->network->network_code_3_digits, + mnc, mnc_3_digits)) { int paged = 0; struct gsm_bts *bts; llist_for_each_entry(bts, &msc->network->bts_list, list) { @@ -412,9 +420,10 @@ mi_string, lac); } } else { - LOGP(DMSC, LOGL_DEBUG, "Paging IMSI %s: MCC/MNC in Cell Identifier List " - "(%d/%d) do not match our network (%d/%d)\n", mi_string, mcc, mnc, - msc->network->country_code, msc->network->network_code); + LOGP(DMSC, LOGL_DEBUG, "Paging IMSI %s: MCC-MNC in Cell Identifier List " + "(%s) do not match our network (%s)\n", + mi_string, osmo_mcc_mnc_name(mcc, mnc, mnc_3_digits), + gsmnet_mcc_mnc_name(msc->network)); } remain -= sizeof(struct gsm48_loc_area_id); i++; diff --git a/src/osmo-bsc/osmo_bsc_ctrl.c b/src/osmo-bsc/osmo_bsc_ctrl.c index 6092f23..9455226 100644 --- a/src/osmo-bsc/osmo_bsc_ctrl.c +++ b/src/osmo-bsc/osmo_bsc_ctrl.c @@ -207,10 +207,11 @@ policy = osmo_bsc_rf_get_policy_name(osmo_bsc_rf_get_policy_by_bts(bts)); cmd->reply = talloc_asprintf_append(cmd->reply, - ",%s,%s,%s,%d,%d", + ",%s,%s,%s,%s,%s", oper, admin, policy, - bts->network->country_code, - bts->network->network_code); + osmo_mcc_name(bts->network->country_code), + osmo_mnc_name(bts->network->network_code, + bts->network->network_code_3_digits)); osmo_bsc_send_trap(cmd, msc_con); talloc_free(cmd); diff --git a/src/osmo-bsc/osmo_bsc_filter.c b/src/osmo-bsc/osmo_bsc_filter.c index c1f3e80..bd0bd1d 100644 --- a/src/osmo-bsc/osmo_bsc_filter.c +++ b/src/osmo-bsc/osmo_bsc_filter.c @@ -49,8 +49,8 @@ gh = msgb_l3(msg); lu = (struct gsm48_loc_upd_req *) gh->data; - gsm48_generate_lai(&lai, net->country_code, net->network_code, - bts->location_area_code); + gsm48_generate_lai2(&lai, net->country_code, net->network_code, net->network_code_3_digits, + bts->location_area_code); if (memcmp(&lai, &lu->lai, sizeof(lai)) != 0) { LOGP(DMSC, LOGL_DEBUG, "Marking con for welcome USSD.\n"); @@ -315,9 +315,9 @@ static int has_core_identity(struct bsc_msc_data *msc) { - if (msc->core_mnc != -1) + if (msc->core_mnc != GSM_MCC_MNC_INVALID) return 1; - if (msc->core_mcc != -1) + if (msc->core_mcc != GSM_MCC_MNC_INVALID) return 1; if (msc->core_lac != -1) return 1; @@ -361,9 +361,9 @@ if (msgb_l3len(msg) >= sizeof(*gh) + sizeof(*lai)) { /* overwrite LAI in the message */ lai = (struct gsm48_loc_area_id *) &gh->data[0]; - gsm48_generate_lai(lai, net->country_code, - net->network_code, - bts->location_area_code); + gsm48_generate_lai2(lai, net->country_code, + net->network_code, net->network_code_3_digits, + bts->location_area_code); } } diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c index 46be2e6..61f1018 100644 --- a/src/osmo-bsc/osmo_bsc_msc.c +++ b/src/osmo-bsc/osmo_bsc_msc.c @@ -581,8 +581,9 @@ INIT_LLIST_HEAD(&msc_data->dests); msc_data->ping_timeout = 20; msc_data->pong_timeout = 5; - msc_data->core_mnc = -1; - msc_data->core_mcc = -1; + msc_data->core_mnc = GSM_MCC_MNC_INVALID; + msc_data->core_mnc_3_digits = false; + msc_data->core_mcc = GSM_MCC_MNC_INVALID; msc_data->core_ci = -1; msc_data->core_lac = -1; msc_data->rtp_base = 4000; diff --git a/src/osmo-bsc/osmo_bsc_vty.c b/src/osmo-bsc/osmo_bsc_vty.c index e173b4a..7b967c7 100644 --- a/src/osmo-bsc/osmo_bsc_vty.c +++ b/src/osmo-bsc/osmo_bsc_vty.c @@ -27,6 +27,7 @@ #include <osmocom/bsc/bsc_msg_filter.h> #include <osmocom/core/talloc.h> +#include <osmocom/gsm/gsm48.h> #include <osmocom/vty/logging.h> #include <osmocom/mgcp_client/mgcp_client.h> @@ -107,12 +108,12 @@ struct bsc_msc_dest *dest; vty_out(vty, "msc %d%s", msc->nr, VTY_NEWLINE); - if (msc->core_mnc != -1) - vty_out(vty, " core-mobile-network-code %d%s", - msc->core_mnc, VTY_NEWLINE); - if (msc->core_mcc != -1) - vty_out(vty, " core-mobile-country-code %d%s", - msc->core_mcc, VTY_NEWLINE); + if (msc->core_mnc != GSM_MCC_MNC_INVALID) + vty_out(vty, " core-mobile-network-code %s%s", + osmo_mnc_name(msc->core_mnc, msc->core_mnc_3_digits), VTY_NEWLINE); + if (msc->core_mcc != GSM_MCC_MNC_INVALID) + vty_out(vty, " core-mobile-country-code %s%s", + osmo_mcc_name(msc->core_mcc), VTY_NEWLINE); if (msc->core_lac != -1) vty_out(vty, " core-location-area-code %d%s", msc->core_lac, VTY_NEWLINE); @@ -236,7 +237,15 @@ "Use this network code for the core network\n" "MNC value\n") { struct bsc_msc_data *data = bsc_msc_data(vty); - data->core_mnc = atoi(argv[0]); + uint16_t mnc; + bool mnc_3_digits; + + if (gsm48_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) { + vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + data->core_mnc = mnc; + data->core_mnc_3_digits = mnc_3_digits; return CMD_SUCCESS; } diff --git a/tests/bssap/bssap_test.err b/tests/bssap/bssap_test.err index 18bfbca..8ae3b22 100644 --- a/tests/bssap/bssap_test.err +++ b/tests/bssap/bssap_test.err @@ -16,7 +16,7 @@ 2: DMSC Rx MSC UDT: 00 19 52 08 08 59 51 20 69 00 07 43 94 09 04 01 08 44 60 1a 06 04 15 f5 49 00 65 DMSC Rx MSC UDT BSSMAP PAGING -DMSC Paging IMSI 515029600703449: MCC/MNC in Cell Identifier List (515/94) do not match our network (1/1) +DMSC Paging IMSI 515029600703449: MCC-MNC in Cell Identifier List (515-94) do not match our network (001-01) bsc_handle_udt() returned 0 3: -- To view, visit https://gerrit.osmocom.org/6668 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8e722103344186fde118b26d8353db95a4581daa Gerrit-PatchSet: 1 Gerrit-Project: osmo-bsc Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>