From 2aa0b45cc03ab8c91fabdaf585cb8b17c3f26c2c Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 7 Jan 2010 03:17:01 +0100 Subject: [bssap] Allow to use a different country code too * Be able to have a country code in the air but use a different country code when talking to the core network. * Now both country and network code can be different on air and on the MSC communication. --- openbsc/include/openbsc/gsm_data.h | 1 + openbsc/src/bssap.c | 43 ++++++++++++++++++++++++-------------- openbsc/src/gsm_data.c | 1 + openbsc/src/vty_interface.c | 13 ++++++++++++ 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index c34d4af10..7d5e50277 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -595,6 +595,7 @@ struct gsm_network { } rrlp; /* a hack for On Waves. It must be signed */ + u_int32_t core_country_code; u_int32_t core_network_code; }; diff --git a/openbsc/src/bssap.c b/openbsc/src/bssap.c index 8c02658da..94e55a6c5 100644 --- a/openbsc/src/bssap.c +++ b/openbsc/src/bssap.c @@ -63,6 +63,19 @@ static const struct tlv_definition bss_att_tlvdef = { }, }; +static int get_network_code_for_msc(struct gsm_network *net) +{ + if (net->core_network_code > 0) + return net->core_network_code; + return net->network_code; +} + +static int get_country_code_for_msc(struct gsm_network *net) +{ + if (net->core_country_code > 0) + return net->core_country_code; + return net->country_code; +} static int bssmap_paging_cb(unsigned int hooknum, unsigned int event, struct msgb *msg, void *data, void *param) { @@ -556,15 +569,17 @@ int dtap_rcvmsg(struct gsm_lchan *lchan, struct msgb *msg, unsigned int length) * LAI for the Location Update Accept packet and maybe more * as well. */ - if (gsm48->trx->bts->network->core_network_code > 0 && - msgb_l3len(gsm48) >= sizeof(struct gsm48_loc_area_id) + 1) { - struct gsm48_hdr *gh = (struct gsm48_hdr *)gsm48->l3h; - if (gh->msg_type == GSM48_MT_MM_LOC_UPD_ACCEPT) { - struct gsm_network *net = gsm48->trx->bts->network; - struct gsm48_loc_area_id *lai = (struct gsm48_loc_area_id *) &gh->data[0]; - gsm0408_generate_lai(lai, net->country_code, - net->network_code, - gsm48->trx->bts->location_area_code); + if (gsm48->trx->bts->network->core_network_code > 0 || + gsm48->trx->bts->network->core_country_code > 0) { + if (msgb_l3len(gsm48) >= sizeof(struct gsm48_loc_area_id) + 1) { + struct gsm48_hdr *gh = (struct gsm48_hdr *)gsm48->l3h; + if (gh->msg_type == GSM48_MT_MM_LOC_UPD_ACCEPT) { + struct gsm_network *net = gsm48->trx->bts->network; + struct gsm48_loc_area_id *lai = (struct gsm48_loc_area_id *) &gh->data[0]; + gsm0408_generate_lai(lai, get_country_code_for_msc(net), + get_network_code_for_msc(net), + gsm48->trx->bts->location_area_code); + } } } @@ -580,18 +595,14 @@ struct msgb *bssmap_create_layer3(struct msgb *msg_l3) struct msgb* msg; struct gsm48_loc_area_id *lai; struct gsm_bts *bts = msg_l3->lchan->ts->trx->bts; - int network_code = bts->network->network_code; + int network_code = get_network_code_for_msc(bts->network); + int country_code = get_country_code_for_msc(bts->network); msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "bssmap cmpl l3"); if (!msg) return NULL; - /* check if we need to overwrite the network code */ - if (bts->network->core_network_code > 0) - network_code = bts->network->core_network_code; - - /* create the bssmap header */ msg->l3h = msgb_put(msg, 2); msg->l3h[0] = 0x0; @@ -607,7 +618,7 @@ struct msgb *bssmap_create_layer3(struct msgb *msg_l3) data[2] = CELL_IDENT_WHOLE_GLOBAL; lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai)); - gsm0408_generate_lai(lai, bts->network->country_code, + gsm0408_generate_lai(lai, country_code, network_code, bts->location_area_code); ci = (u_int16_t *) msgb_put(msg, 2); diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index 43bf92b32..18a3ac2c2 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -224,6 +224,7 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c net->mncc_recv = mncc_recv; + net->core_country_code = -1; net->core_network_code = -1; return net; diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index 78636aa7e..e53e7c6f9 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -294,6 +294,8 @@ static int config_write_net(struct vty *vty) { vty_out(vty, "network%s", VTY_NEWLINE); vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE); + if (gsmnet->core_country_code > 0) + vty_out(vty, " core network country code %u%s", gsmnet->core_country_code, VTY_NEWLINE); vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE); if (gsmnet->core_network_code > 0) vty_out(vty, " core mobile network code %u%s", gsmnet->core_network_code, VTY_NEWLINE); @@ -845,6 +847,16 @@ DEFUN(cfg_net_ncc, return CMD_SUCCESS; } +DEFUN(cfg_core_net_ncc, + cfg_core_net_ncc_cmd, + "core network country code <1-999>", + "Set the GSM country code to be used in the MSC connection") +{ + gsmnet->core_country_code = atoi(argv[0]); + + return CMD_SUCCESS; +} + DEFUN(cfg_net_mnc, cfg_net_mnc_cmd, "mobile network code <1-999>", @@ -1596,6 +1608,7 @@ int bsc_vty_init(struct gsm_network *net) install_node(&net_node, config_write_net); install_default(GSMNET_NODE); install_element(GSMNET_NODE, &cfg_net_ncc_cmd); + install_element(GSMNET_NODE, &cfg_core_net_ncc_cmd); install_element(GSMNET_NODE, &cfg_net_mnc_cmd); install_element(GSMNET_NODE, &cfg_core_net_mnc_cmd); install_element(GSMNET_NODE, &cfg_net_name_short_cmd); -- cgit v1.2.3