aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-01-05 13:57:45 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-01-05 13:57:45 +0100
commit893ea65f381acc877f852e48894f4575904b7cf9 (patch)
tree77b795c436019640d0cf33583d37337b2f7e7900
parent64b811f11321a13138ec48edcd6cafae23fcc7ed (diff)
[bsc_msc_ip] Turn the MNC hack into a config option
* Make it possible to have a different MNC in the RSL traffic than in the core network. * Introduce the "core network code NUMBER" variable. If it is set this network code will be used in traffic with the MSC. * Use the core_network_code number when sending a packet to the MSC * Regenerate the LAI (this is where I could have a bug) when sending packets to the BTS. * Add size checks. This is not tested, I might got something wrong.
-rw-r--r--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/src/bssap.c25
-rw-r--r--openbsc/src/gsm_data.c2
-rw-r--r--openbsc/src/vty_interface.c13
4 files changed, 37 insertions, 6 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 4e1977e3..c34d4af1 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -593,6 +593,9 @@ struct gsm_network {
struct {
enum rrlp_mode mode;
} rrlp;
+
+ /* a hack for On Waves. It must be signed */
+ u_int32_t core_network_code;
};
#define SMS_HDR_SIZE 128
diff --git a/openbsc/src/bssap.c b/openbsc/src/bssap.c
index 6071b5dc..8c02658d 100644
--- a/openbsc/src/bssap.c
+++ b/openbsc/src/bssap.c
@@ -552,12 +552,20 @@ int dtap_rcvmsg(struct gsm_lchan *lchan, struct msgb *msg, unsigned int length)
memcpy(data, msg->l3h + sizeof(*header), length - sizeof(*header));
/*
- * patch LAI entries...
+ * This is coming from the network. We need to regenerate the
+ * LAI for the Location Update Accept packet and maybe more
+ * as well.
*/
- struct gsm48_hdr *gh = (struct gsm48_hdr *)gsm48->l3h;
- if (gh->msg_type == GSM48_MT_MM_LOC_UPD_ACCEPT) {
- if (gh->data[2] == 0x80)
- gh->data[2] = 0x08;
+ 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);
+ }
}
bts_queue_send(gsm48, header->link_id);
@@ -572,12 +580,17 @@ 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;
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);
@@ -595,7 +608,7 @@ struct msgb *bssmap_create_layer3(struct msgb *msg_l3)
lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
gsm0408_generate_lai(lai, bts->network->country_code,
- /*bts->network->network_code - 1*/ 8, bts->location_area_code);
+ network_code, bts->location_area_code);
ci = (u_int16_t *) msgb_put(msg, 2);
*ci = htons(bts->cell_identity);
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index 12f439be..43bf92b3 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -224,6 +224,8 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c
net->mncc_recv = mncc_recv;
+ net->core_network_code = -1;
+
return net;
}
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index 58204776..78636aa7 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -295,6 +295,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);
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);
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);
@@ -853,6 +855,16 @@ DEFUN(cfg_net_mnc,
return CMD_SUCCESS;
}
+DEFUN(cfg_core_net_mnc,
+ cfg_core_net_mnc_cmd,
+ "core mobile network code <1-999>",
+ "Set the GSM mobile network code to be used in the MSC connection")
+{
+ gsmnet->core_network_code = atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_net_name_short,
cfg_net_name_short_cmd,
"short name NAME",
@@ -1585,6 +1597,7 @@ int bsc_vty_init(struct gsm_network *net)
install_default(GSMNET_NODE);
install_element(GSMNET_NODE, &cfg_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);
install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
install_element(GSMNET_NODE, &cfg_net_auth_policy_cmd);