Before sending mm info message to ms: - extract mcc and mnc from imsi - try to find virtual network with the same mcc and mnc - if virtual network was found, use long and short network names of this virtual network for subscriber - if virtual network was not found, use long and short network names of main network for subscriber --- openbsc/include/openbsc/gsm_data.h | 16 ++++ openbsc/include/openbsc/vty.h | 1 + openbsc/src/libbsc/bsc_vty.c | 156 +++++++++++++++++++++++++++++++++++++ openbsc/src/libbsc/net_init.c | 1 + openbsc/src/libcommon/common_vty.c | 9 +++ openbsc/src/libcommon/gsm_data.c | 42 ++++++++++ openbsc/src/libmsc/gsm_04_08.c | 45 +++++++++-- 7 files changed, 262 insertions(+), 8 deletions(-)
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 6d7aba3..9a52254 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -248,6 +248,9 @@ struct gsm_network { unsigned int num_bts; struct llist_head bts_list;
+ unsigned int num_virt_net; + struct llist_head virt_net_list; + /* timer values */ int T3101; int T3103; @@ -293,6 +296,16 @@ struct gsm_network { struct ctrl_handle *ctrl; };
+struct gsm_virt_network { + struct llist_head list; + uint8_t nr; + struct gsm_network *network; + uint16_t country_code; + uint16_t network_code; + char *name_long; + char *name_short; +}; + struct osmo_esme;
enum gsm_sms_source_id { @@ -435,6 +448,9 @@ int gsm_bts_model_register(struct gsm_bts_model *model); struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan); void subscr_con_free(struct gsm_subscriber_connection *conn);
+struct gsm_virt_network *gsm_virt_net_alloc_register(struct gsm_network *net); +struct gsm_virt_network *gsm_virt_net_num(struct gsm_network *net, int num); + struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type, uint8_t bsic); diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h index bc30e23..2848702 100644 --- a/openbsc/include/openbsc/vty.h +++ b/openbsc/include/openbsc/vty.h @@ -17,6 +17,7 @@ extern struct cmd_element cfg_no_description_cmd;
enum bsc_vty_node { GSMNET_NODE = _LAST_OSMOVTY_NODE + 1, + VIRT_NET_NODE, BTS_NODE, TRX_NODE, TS_NODE, diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 29f2501..b414395 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -112,6 +112,12 @@ struct cmd_node net_node = { 1, };
+struct cmd_node virt_net_node = { + VIRT_NET_NODE, + "%s(config-net-virt)# ", + 1, +}; + struct cmd_node bts_node = { BTS_NODE, "%s(config-net-bts)# ", @@ -343,6 +349,42 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]", return CMD_SUCCESS; }
+static void virt_net_dump_vty(struct vty *vty, struct gsm_virt_network *virt_net) +{ + vty_out(vty, "Virtual network %u%s", virt_net->nr, VTY_NEWLINE); + vty_out(vty, " Country Code %u, Network Code %u%s", + virt_net->country_code, virt_net->network_code, VTY_NEWLINE); + vty_out(vty, " Long network name: '%s'%s", + virt_net->name_long, VTY_NEWLINE); + vty_out(vty, " Short network name: '%s'%s", + virt_net->name_short, VTY_NEWLINE); +} + +DEFUN(show_virt_net, show_virt_net_cmd, "show virtual-network [<0-255>]", + SHOW_STR "Display information about a virtual network\n" + "Virtual network number") +{ + struct gsm_network *net = gsmnet_from_vty(vty); + int virt_net_nr; + + if (argc != 0) { + /* use the virtual network number that the user has specified */ + virt_net_nr = atoi(argv[0]); + if (virt_net_nr >= net->num_virt_net) { + vty_out(vty, "%% can't find virtual network '%s'%s", argv[0], + VTY_NEWLINE); + return CMD_WARNING; + } + virt_net_dump_vty(vty, gsm_virt_net_num(net, virt_net_nr)); + return CMD_SUCCESS; + } + /* print all virtual networks */ + for (virt_net_nr = 0; virt_net_nr < net->num_virt_net; virt_net_nr++) + virt_net_dump_vty(vty, gsm_virt_net_num(net, virt_net_nr)); + + return CMD_SUCCESS; +} + /* utility functions */ static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line, const char *ts, const char *ss) @@ -743,6 +785,26 @@ static int config_write_bts(struct vty *v) return CMD_SUCCESS; }
+static void config_write_virt_net_single(struct vty *vty, struct gsm_virt_network *virt_net) +{ + vty_out(vty, " virtual-network %u%s", virt_net->nr, VTY_NEWLINE); + vty_out(vty, " network country code %u%s", virt_net->country_code, VTY_NEWLINE); + vty_out(vty, " mobile network code %u%s", virt_net->network_code, VTY_NEWLINE); + vty_out(vty, " short name %s%s", virt_net->name_short, VTY_NEWLINE); + vty_out(vty, " long name %s%s", virt_net->name_long, VTY_NEWLINE); +} + +static int config_write_virt_net(struct vty *v) +{ + struct gsm_network *gsmnet = gsmnet_from_vty(v); + struct gsm_virt_network *virt_net; + + llist_for_each_entry(virt_net, &gsmnet->virt_net_list, list) + config_write_virt_net_single(v, virt_net); + + return CMD_SUCCESS; +} + static int config_write_net(struct vty *vty) { struct gsm_network *gsmnet = gsmnet_from_vty(vty); @@ -1612,6 +1674,91 @@ DEFUN(cfg_net_subscr_keep, return CMD_SUCCESS; }
+DEFUN(cfg_virt_net, + cfg_virt_net_cmd, + "virtual-network <0-255>", + "Select a virtual network to configure\n" + "Virtual-network Number\n") +{ + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + int virt_net_nr = atoi(argv[0]); + struct gsm_virt_network *virt_net; + + if (virt_net_nr > gsmnet->num_virt_net) { + vty_out(vty, "%% The next unused Virtual-network number is %u%s", + gsmnet->num_virt_net, VTY_NEWLINE); + return CMD_WARNING; + } else if (virt_net_nr == gsmnet->num_virt_net) { + /* allocate a new one */ + virt_net = gsm_virt_net_alloc_register(gsmnet); + } else + virt_net = gsm_virt_net_num(gsmnet, virt_net_nr); + + if (!virt_net) { + vty_out(vty, "%% Unable to allocate Virtual-network %u%s", + gsmnet->num_virt_net, VTY_NEWLINE); + return CMD_WARNING; + } + + vty->index = virt_net; + vty->index_sub = NULL; + vty->node = VIRT_NET_NODE; + + return CMD_SUCCESS; +} + +DEFUN(cfg_virt_net_ncc, + cfg_virt_net_ncc_cmd, + "network country code <1-999>", + "Set the GSM network country code\n" + "Country commands\n" + CODE_CMD_STR + "Network Country Code to use\n") +{ + struct gsm_virt_network *virt_net = vty->index; + + virt_net->country_code = atoi(argv[0]); + + return CMD_SUCCESS; +} + +DEFUN(cfg_virt_net_mnc, + cfg_virt_net_mnc_cmd, + "mobile network code <0-999>", + "Set the GSM mobile network code\n" + "Network Commands\n" + CODE_CMD_STR + "Mobile Network Code to use\n") +{ + struct gsm_virt_network *virt_net = vty->index; + + virt_net->network_code = atoi(argv[0]); + + return CMD_SUCCESS; +} + +DEFUN(cfg_virt_net_name_short, + cfg_virt_net_name_short_cmd, + "short name NAME", + "Set the short GSM network name\n" NAME_CMD_STR NAME_STR) +{ + struct gsm_virt_network *virt_net = vty->index; + + bsc_replace_string(virt_net->network, &virt_net->name_short, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_virt_net_name_long, + cfg_virt_net_name_long_cmd, + "long name NAME", + "Set the long GSM network name\n" NAME_CMD_STR NAME_STR) +{ + struct gsm_virt_network *virt_net = vty->index; + + bsc_replace_string(virt_net->network, &virt_net->name_long, argv[0]); + return CMD_SUCCESS; +} + /* per-BTS configuration */ DEFUN(cfg_bts, cfg_bts_cmd, @@ -3763,6 +3910,7 @@ int bsc_vty_init(const struct log_info *cat)
install_element_ve(&show_net_cmd); + install_element_ve(&show_virt_net_cmd); install_element_ve(&show_bts_cmd); install_element_ve(&show_trx_cmd); install_element_ve(&show_ts_cmd); @@ -3811,6 +3959,14 @@ int bsc_vty_init(const struct log_info *cat) install_element(GSMNET_NODE, &cfg_net_subscr_keep_cmd); install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
+ install_element(GSMNET_NODE, &cfg_virt_net_cmd); + install_node(&virt_net_node, config_write_virt_net); + vty_install_default(VIRT_NET_NODE); + install_element(VIRT_NET_NODE, &cfg_virt_net_ncc_cmd); + install_element(VIRT_NET_NODE, &cfg_virt_net_mnc_cmd); + install_element(VIRT_NET_NODE, &cfg_virt_net_name_short_cmd); + install_element(VIRT_NET_NODE, &cfg_virt_net_name_long_cmd); + install_element(GSMNET_NODE, &cfg_bts_cmd); install_node(&bts_node, config_write_bts); vty_install_default(BTS_NODE); diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index 568a0b8..1fe9f3e 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -71,6 +71,7 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod INIT_LLIST_HEAD(&net->trans_list); INIT_LLIST_HEAD(&net->upqueue); INIT_LLIST_HEAD(&net->bts_list); + INIT_LLIST_HEAD(&net->virt_net_list);
net->stats.chreq.total = osmo_counter_alloc("net.chreq.total"); net->stats.chreq.no_channel = osmo_counter_alloc("net.chreq.no_channel"); diff --git a/openbsc/src/libcommon/common_vty.c b/openbsc/src/libcommon/common_vty.c index a0674f0..c3434f1 100644 --- a/openbsc/src/libcommon/common_vty.c +++ b/openbsc/src/libcommon/common_vty.c @@ -42,6 +42,15 @@ int bsc_vty_go_parent(struct vty *vty) vty->node = CONFIG_NODE; vty->index = NULL; break; + case VIRT_NET_NODE: + vty->node = GSMNET_NODE; + { + /* set vty->index correctly ! */ + struct gsm_virt_network *virt_net = vty->index; + vty->index = virt_net->network; + vty->index_sub = NULL; + } + break; case BTS_NODE: vty->node = GSMNET_NODE; { diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 16035ed..5076a3e 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -192,6 +192,48 @@ const char *rrlp_mode_name(enum rrlp_mode mode) return get_value_string(rrlp_mode_names, mode); }
+struct gsm_virt_network *gsm_virt_net_alloc(void *ctx) +{ + struct gsm_virt_network *virt_net = talloc_zero(ctx, struct gsm_virt_network); + if (!virt_net) + return NULL; + return virt_net; +} + +struct gsm_virt_network *gsm_virt_net_alloc_register(struct gsm_network *net) +{ + struct gsm_virt_network *virt_net; + + virt_net = gsm_virt_net_alloc(net); + if (!virt_net) + return NULL; + + virt_net->nr = net->num_virt_net++; + virt_net->network = net; + virt_net->country_code = 1; + virt_net->network_code = 1; + virt_net->name_short = talloc_strdup(net, "OpenBSC"); + virt_net->name_long = talloc_strdup(net, "OpenBSC"); + + llist_add_tail(&virt_net->list, &net->virt_net_list); + return virt_net; +} + +struct gsm_virt_network *gsm_virt_net_num(struct gsm_network *net, int num) +{ + struct gsm_virt_network *virt_net; + + if (num >= net->num_virt_net) + return NULL; + + llist_for_each_entry(virt_net, &net->virt_net_list, list) { + if (virt_net->nr == num) + return virt_net; + } + + return NULL; +} + static const struct value_string bts_gprs_mode_names[] = { { BTS_GPRS_NONE, "none" }, { BTS_GPRS_GPRS, "gprs" }, diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 1524ec4..db03d0e 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -702,6 +702,15 @@ static uint8_t bcdify(uint8_t value) return ret; }
+static void mcc_mnc_from_imsi(char* imsi, uint16_t* mcc, uint16_t* mnc) +{ + char mcc_str[4]; + char mnc_str[3]; + strncpy(mcc_str, imsi, 3); + strncpy(mnc_str, imsi + 3, 2); + *mcc = atoi(mcc_str); + *mnc = atoi(mnc_str); +}
/* Section 9.2.15a */ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) @@ -719,13 +728,33 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) int tzunits; int dst = 0;
+ uint16_t imsi_mcc; + uint16_t imsi_mnc; + char *name_long = net->name_long; + char *name_short = net->name_short; + int virt_net_nr; + msg->lchan = conn->lchan;
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->proto_discr = GSM48_PDISC_MM; gh->msg_type = GSM48_MT_MM_INFO;
- if (net->name_long) { + if (net->num_virt_net) { + mcc_mnc_from_imsi(conn->subscr->imsi, &imsi_mcc, &imsi_mnc); + for (virt_net_nr = 0; virt_net_nr < net->num_virt_net; virt_net_nr++) { + struct gsm_virt_network* virt_net = gsm_virt_net_num(net, virt_net_nr); + if (virt_net && + (virt_net->country_code == imsi_mcc) && + (virt_net->network_code == imsi_mnc)) { + name_long = virt_net->name_long; + name_short = virt_net->name_short; + break; + } + } + } + + if (name_long) { #if 0 name_len = strlen(net->name_long); /* 10.5.3.5a */ @@ -741,8 +770,8 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) /* FIXME: Use Cell Broadcast, not UCS-2, since * UCS-2 is only supported by later revisions of the spec */ #endif - name_len = (strlen(net->name_long)*7)/8; - name_pad = (8 - strlen(net->name_long)*7)%8; + name_len = (strlen(name_long)*7)/8; + name_pad = (8 - strlen(name_long)*7)%8; if (name_pad > 0) name_len++; /* 10.5.3.5a */ @@ -752,11 +781,11 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) ptr8[2] = 0x80 | name_pad; /* Cell Broadcast DCS, no CI */
ptr8 = msgb_put(msg, name_len); - gsm_7bit_encode_n(ptr8, name_len, net->name_long, NULL); + gsm_7bit_encode_n(ptr8, name_len, name_long, NULL);
}
- if (net->name_short) { + if (name_short) { #if 0 name_len = strlen(net->name_short); /* 10.5.3.5a */ @@ -769,8 +798,8 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) for (i = 0; i < name_len; i++) ptr16[i] = htons(net->name_short[i]); #endif - name_len = (strlen(net->name_short)*7)/8; - name_pad = (8 - strlen(net->name_short)*7)%8; + name_len = (strlen(name_short)*7)/8; + name_pad = (8 - strlen(name_short)*7)%8; if (name_pad > 0) name_len++; /* 10.5.3.5a */ @@ -780,7 +809,7 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) ptr8[2] = 0x80 | name_pad; /* Cell Broadcast DCS, no CI */
ptr8 = msgb_put(msg, name_len); - gsm_7bit_encode_n(ptr8, name_len, net->name_short, NULL); + gsm_7bit_encode_n(ptr8, name_len, name_short, NULL);
}
--- openbsc/tests/vty_test_runner.py | 52 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index ecf5204..ec90167 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -133,6 +133,9 @@ class TestVTYGenericBSC(TestVTYBase): self.assertTrue(self.vty.verify("network",[''])) self.assertEquals(self.vty.node(), 'config-net') self.checkForEndAndExit() + self.assertTrue(self.vty.verify("virtual-network 0",[''])) + self.assertEquals(self.vty.node(), 'config-net-virt') + self.checkForEndAndExit() self.assertTrue(self.vty.verify("bts 0",[''])) self.assertEquals(self.vty.node(), 'config-net-bts') self.checkForEndAndExit() @@ -154,6 +157,12 @@ class TestVTYGenericBSC(TestVTYBase): self.assertEquals(self.vty.node(), 'config-net-bts') self.assertTrue(self.vty.verify("exit",[''])) self.assertEquals(self.vty.node(), 'config-net') + self.assertTrue(self.vty.verify("virtual-network 1",[''])) + self.assertEquals(self.vty.node(), 'config-net-virt') + self.checkForEndAndExit() + self.vty.command("write terminal") + self.assertTrue(self.vty.verify("exit",[''])) + self.assertEquals(self.vty.node(), 'config-net') self.assertTrue(self.vty.verify("exit",[''])) self.assertEquals(self.vty.node(), 'config') self.assertTrue(self.vty.verify("exit",[''])) @@ -307,6 +316,48 @@ class TestVTYNITB(TestVTYGenericBSC): if classNum != 10: self.assertEquals(res.find("rach access-control-class " + str(classNum) + " barred"), -1)
+ def testVirtualNetworks(self): + self.vty.enable() + self.vty.command("configure terminal") + self.vty.command("network") + self.vty.command("virtual-network 0") + + # Test invalid input + self.vty.verify("network country code 0", ['% Unknown command.']) + self.vty.verify("network country code 1000", ['% Unknown command.']) + self.vty.verify("network country code 1234", ['% Unknown command.']) + self.vty.verify("mobile network code 0", ['% Unknown command.']) + self.vty.verify("mobile network code 1000", ['% Unknown command.']) + self.vty.verify("mobile network code 1234", ['% Unknown command.']) + self.vty.verify("mobile network code 1234", ['% Unknown command.']) + self.vty.verify("short name Test Net", ['% Unknown command.']) + self.vty.verify("long name Test Network", ['% Unknown command.']) + + # Set virtual-networks + self.vty.verify("network country code 2", ['']) + self.vty.verify("mobile network code 2", ['']) + self.vty.verify("short name TestNet2", ['']) + self.vty.verify("long name TestNetwork2", ['']) + self.vty.verify("exit",['']) + self.vty.command("virtual-network 1") + self.vty.verify("network country code 3", ['']) + self.vty.verify("mobile network code 3", ['']) + self.vty.verify("short name TestNet3", ['']) + self.vty.verify("long name TestNetwork3", ['']) + + # Verify settings + res = self.vty.command("write terminal") + self.assert_(res.find('virtual-network 0') > 0) + self.assert_(res.find('network country code 2') > 0) + self.assert_(res.find('mobile network code 2') > 0) + self.assert_(res.find('short name TestNet2') > 0) + self.assert_(res.find('long name TestNetwork2') > 0) + self.assert_(res.find('virtual-network 1') > 0) + self.assert_(res.find('network country code 3') > 0) + self.assert_(res.find('mobile network code 3') > 0) + self.assert_(res.find('short name TestNet3') > 0) + self.assert_(res.find('long name TestNetwork3') > 0) + def testSubscriberCreateDeleteTwice(self): """ OS#1657 indicates that there might be an issue creating the @@ -342,7 +393,6 @@ class TestVTYNITB(TestVTYGenericBSC): res = self.vty.command('show subscriber imsi '+imsi) self.assert_(res != '% No subscriber found for imsi '+imsi)
- def testSubscriberCreateDelete(self): self.vty.enable()
On 12 Apr 2016, at 06:48, Ivan Kluchnikov kluchnikovi@gmail.com wrote:
Dear Ivan,
can you please give a general introduction of that feature? Describe when one would want to use it. Why it is not a regexp for the IMSI but actually only the country code and network code? How you intend to deal with two or three digit network code?
kind regards
holger
Hi Holger,
Thank you for patch review.
can you please give a general introduction of that feature? Describe when
one would want to use it.
The basic idea is to support roaming-based network sharing. So subscribers of different operators can roam seamlessly in our network. For that purpose we should be able to check a subscriber's IMSI to identify the virtual network the IMSI belongs to. On the first stage to achieve seamless roaming we should be able to set network name for each supported virtual network. In future we plan to add more configuration parameters for virtual network: - auth policy (which could solve http://projects.osmocom.org/issues/1647) - location updating reject cause (useful for real deployments) May be you also have any ideas which parameters could be added to virtual network node?
Why it is not a regexp for the IMSI but actually only the country code and
network code? How you intend to deal with two or three digit network code?
Yes, I agree that the current implementation is not enough flexible and it is a good idea to use imsi-prefix instead of mcc and mnc, also it will fix the issue with 3 digit mnc. Do you think it makes sense? But I am not sure that I understand the idea of using regexp for the IMSI, could you please clarify for which cases it could be useful?
On 13 Apr 2016, at 05:18, Ivan Kluchnikov Ivan.Kluchnikov@fairwaves.ru wrote:
Hi Holger,
Hi Ivan,
Yes, I agree that the current implementation is not enough flexible and it is a good idea to use imsi-prefix instead of mcc and mnc, also it will fix the issue with 3 digit mnc.
yes? But how do you intend to fix it? The current structure will not be enough
Do you think it makes sense? But I am not sure that I understand the idea of using regexp for the IMSI, could you please clarify for which cases it could be useful?
I understand you want to fill a short-term gap but I don't think it is the right approach to "roaming" at all. At the end of classic roaming one will:
* Get a yes/no if it is allowed to roam * Get subscriber data (MSISDN, ...) * The subscribed services (allowed to do telephony)
Right now the code is just about sending different network names. that seems very different from roaming?
holger
Holger,
Yes, I agree that the current implementation is not enough flexible and it is a good idea to use imsi-prefix instead of mcc and mnc, also it will fix the issue with 3 digit mnc.
yes? But how do you intend to fix it? The current structure will not be enough
It requires changes in the code, but what I meant, we can have it as an option later - whether you want to specify mcc/mnc separately or as a prefix/regex. Btw, I think we can treat mcc/mnc as strings for virtual networks instead of integers to solve the 2/3 digit mnc issue.
Do you think it makes sense? But I am not sure that I understand the idea of using regexp for the
IMSI, could you please clarify for which cases it could be useful?
I understand you want to fill a short-term gap but I don't think it is the right approach to "roaming" at all. At the end of classic roaming one will:
* Get a yes/no if it is allowed to roam * Get subscriber data (MSISDN, ...) * The subscribed services (allowed to do telephony)Right now the code is just about sending different network names. that seems very different from roaming?
Just for clarification, it is not about classic roaming, but about roaming-based network sharing concept which is described in TS 123 251 Network sharing; Architecture and functional description. It is also includes 4.2.3.2 Behaviour of non-supporting UEs (GERAN, UTRAN) "It is recommended for the network and the UE to support the Network Identity part of the Network Identity and Time Zone feature for providing the UE with the name of the serving PLMN operator."
Regarding classic roaming, we have implemented remote protocol for LU (and also for SMS and USSD) based on gsup protocol and this protocol allows to update and manage the subscriber list, which includes: * Get a yes/no if it is allowed to roam * Get subscriber data (MSISDN, ...) Calls are handled through MNCC/SIP in case of roaming scenario and does not require any changes. This code in our fairwaves/sup-* branches, but it is not ready for merging now, I hope we will be able to cleanup this code soon.
2016-04-13 13:39 GMT+03:00 Holger Freyther holger@freyther.de:
On 13 Apr 2016, at 05:18, Ivan Kluchnikov Ivan.Kluchnikov@fairwaves.ru
wrote:
Hi Holger,
Hi Ivan,
Yes, I agree that the current implementation is not enough flexible and
it is a good idea to use imsi-prefix instead of mcc and mnc, also it will fix the issue with 3 digit mnc.
yes? But how do you intend to fix it? The current structure will not be enough
Do you think it makes sense? But I am not sure that I understand the idea of using regexp for the
IMSI, could you please clarify for which cases it could be useful?
I understand you want to fill a short-term gap but I don't think it is the right approach to "roaming" at all. At the end of classic roaming one will:
* Get a yes/no if it is allowed to roam * Get subscriber data (MSISDN, ...) * The subscribed services (allowed to do telephony)Right now the code is just about sending different network names. that seems very different from roaming?
holger