SPN,PLMN ,MCC,MNC名词 解释:
遇到一个SIM字串显示的问题,此前一直认为SIM显示字串就是网络运营商,即对应PLMN(MCC,MNC)的名称,但实际并非如此简单,分析解决的过程如下:
问题描述:
放入4G sim卡,搜索显示的网络名称为英文CMCC,并非所期望的“中国移动“或”中国移动3G“字样。
问题分析:
1,第一反应,怀疑字串错误,或者4G的PLMN对应的TXT名不正确,查看代码以及TRACE后确认对应的PLMN及TXT正常;
2,从调用TXT字串处向上层逻辑查看,调用的逻辑从上至下依次为
OutputIdleWinNetworkName -> MMIPHONE_GetSimAndServiceString -> MMIPHONE_GenPLMNDisplay -> MMIPHONE_GetNetWorkNameId
并和正常显示字串的trace对比,发现异常出现在无法调用到MMIPHONE_GenPLMNDisplay,因此查看MMIPHONE_GetSimAndServiceString函数的实现,发现这里判断SPN及OPN的状态,这是新名词,我并不熟悉,求教度娘,解释如下:
OPN 是指此SIM卡的提供商名称;
SPN 服务提供商名称;
PLMN 当前注册的网络提供商名称;
OPN和SPN都是提前预置在SIM卡中的;网络提供商和服务提供商可能不是同一个企业,所以有时需要单独显示SPN。
至此,猜测这里显示的是OPN或SPN字串,而非一般所认知的PLMN字串,检查MMIPHONE_GetSimAndServiceString函数中获取的OPN及SPN的显示标志及获取的字串,证实了猜测,故障所报的英文CMCC字串正是SPN字串,这里的逻辑是:检查SIM中OPN及SPN状态,若无需获取或获取不到字串,则调用MMIPHONE_GenPLMNDisplay根据PLMN表获取网络运营商名称,即,字串的显示是存在优先级关系的,代码示例如下:
MMI_STRING_T aci_string = {0};
MMI_STRING_T opn_string = {0};
MMI_STRING_T spn_string = {0};
wchar aci[MAX_ACI_INFO_LEN + 1] = {0};
wchar opn[MAX_ONSHORTFORM_LEN + 1] = {0};
wchar spn[MN_SPN_ID_NUM_LEN + 1] = {0};
//get aci string
if(g_service_status[dual_sys].is_add_ci)
{
aci_string.wstr_ptr = (wchar *)aci;
GetAciString(&g_service_status[dual_sys], &aci_string, MAX_ACI_INFO_LEN);
}
//get opn string
if (g_service_status[dual_sys].is_opn_need)
{
opn_string.wstr_ptr = (wchar *)opn;
GetOpnString(&g_service_status[dual_sys], &opn_string, MAX_ONSHORTFORM_LEN);
}
//get spn string
if (g_service_status[dual_sys].is_spn_need)
{
spn_string.wstr_ptr = (wchar *)spn;
GetSpnString(&g_service_status[dual_sys], &spn_string, MN_SPN_ID_NUM_LEN);
}
CatAciOpnSpnString(&aci_string, &opn_string, &spn_string, network_str_ptr);
if (0 == network_str_ptr->wstr_len)
{
network_str_ptr->wstr_len = MMIPHONE_MAX_OPER_NAME_LEN;
MMIPHONE_GenPLMNDisplay(
MMIAPIGET_SpecSim_TDOrGsm(dual_sys),
&g_service_status[dual_sys].plmn,
network_str_ptr->wstr_ptr,
&network_str_ptr->wstr_len,
FALSE);
}
由此想到的,目前正在推广虚拟运营商,根据一则新闻报道的数据:
”上海有12家虚拟运营商备案,包括京东通信、苏宁互联等在内,工信部已经为这些虚拟运营商发放了客服号码,他们的客服电话也与电信运营商相似,是以100开头的五位数号码。尽管虚拟运营商已经陆续开始发放专属的170号段,但整体还是处于用户体验、内部网络测试时期,每家虚拟运营商大约仅有约1000名体验者,预计到2014年10月,才会大面积正式商用“。
手机上对运营商名字的显示完全可以做为一个运营商的品牌宣传手段。特别是虚拟运营商,并不希望出现合作伙伴,同时也是竞争对手的名字。在这种情况下,手机是如何决定显示哪些内容,需要一个标准,查询资料,根据TS 22.101,手机在显示运营商信息时,一共有三个选择,优先级从高到低排列(如下TS 22.101介绍为转载):
1. (U)SIM卡中存放的PLMN和PNN内容。具体显示哪个内容根据SPN文件设置以及当前登陆网络决定。
2. 网络下发MM中的数据
3. ME制造时预置的PLMN以及对应的显示名称
事实上,还有第四种显示方式,就是直接显示MCC+MNC。例如中国移动前几年刚启用460 02的时候,很多手机不能识别,就直接把这个组合显示出来。
注:手机在注册的时候,网络下发给手机的MM信息(Miscellaneous Messages):
Full name for network
Short name for network
Local time zone
Universal time and local time zone
LSA Identity
Network Daylight Saving Time
(U)SIM相关文件的作用如下
1. EF_6F46_SPN
b1=0: 当注册PLMN为HPLMN或者EF_SPDI所存PLMN时,不显示PNN
b1=1: 当注册PLMN为HPLMN或者EF_SPDI所存PLMN时,显示PNN
b2=0: 当注册PLMN既不是HPLMN也不是EF_SPDI所存PLMN时,显示SPN
b2=1: 当注册PLMN既不是HPLMN也不是EF_SPDI所存PLMN时,显示SPN
其他:RFU
前提:根据ETSI规范,
在HPLMN时,默认需要显示SPN;
在VPLMN时,默认需要显示PNN
2. EF_6FCD_SPDI
此文件中存放的PLMN手机进行显示时,等效视为HPLMN
3. EF_6FC5_PNN
用于存放Full Name和Short Name以替换手机内存所存或者网络下发的对应值。
4. EF_6FC6_OPL
如果卡内不存在此文件,则以6FC5的第一条记录替换HPLMN或者EPLMN的内容。
如果此文件存在,则以Byte 1-7指示PLMN, Byte 8指示对应的Full Name/Short Name。
其他
新增两个文件EF_6FDE_SPNI和EF_6FDF_PNNI,可以支持图标显示。
实用举例
Q: 如果有一个虚拟运营商,它在自己的国家X省使用自己的网络(MCC=123,MNC=01),在其他地方租用别的运营商的网络。在Y省租用MNOY(MCC=123,MNC=02)的网络,在Z省租用MNOZ的网络(MCC=123,MNC=03)。它要求在XY省只显示MVNO A,在Z省显示MVNO A和MVNO A+,漫游出国的时候显示MVNO A和漫游伙伴的名字。请问,我们在USIM卡中应该如何设置(假设手机能够完美的支持SPDI和PNN的要求)?
A:
1. 将SPN的第一个字节设置为00
2. 将PLMN Y(MCC=123, MNC=02)放入EF_6FCD_SPDI文件
3. 在EF_6FC5_PNN中存入MVNO A+
4. 将PLMN Z(MCC=123, MNC = 03)放入EF_6FC6_OPL,并指向PNN文件的对应记录
参考规范:
ETSI TS 124.008 V7.4.0
ETSI TS 122.101 V9.11.0
ETSI TS 131.102 V10.3.0
当然,这里OPN或SPN的获取,并不只能从sim ef文件中获取,也有可能,比如Android智能机,获取的方式是不同的,存放在\system\etc下的spn-conf.xml文件中,打开spn-conf.xml可以看到如下代码:
<?xml version="1.0" encoding="utf-8"?>
<spnOverrides>
<!--
@Author: HTC Shawn Ku
@Date: 2010/02/23
This is a list for operator specific SPNs.
We will use below SPN for instead if numeric is matched.
Format is listed as below:
<spnOverrides
numeric="MCC+MNC"
spn="SPN Name"/>
-->
<spnOverride
numeric="44020"
spn="SoftBank"/>
</spnOverrides>
<spnOverride
numeric="46000"
spn="中国移动"/>
如上所示,可根据所希望显示的PLMN,修改对应字串,某些用户有爱的显示为中国移不动或者用户自己的姓名等等,类似的道理。
问题解决:
这个问题,本身严格来说不是故障,因为代码的编写符合标准要求,由于2G和3G SIM未启用OPN和SPN,因此获取的字串为空,直接走到了获取PLMN逻辑,4G SIM中网络运营商预留了默认的英文字串,原则上也并无不妥,但欠完美。作为研发,我个人建议不必修改,但此处体现了我的局限,产品经理坚持修改,并建议保留优先级逻辑,但若显示为英文字串,则修改为中文,但我认为这样的修改可实现却并不合标准,且手边并无联通4G SIM,无从得知联通SIM状况,几番讨论后,由于客户投诉,坚持修改,因此,针对移动SIM,增加临时性patch,修改获取PLMN条件,若为英文CMCC,则转入PLMN逻辑,如下:
if ((0 == network_str_ptr->wstr_len)
|| (0 == MMIAPICOM_WstrStrncmp((const wchar*)network_str_ptr->wstr_ptr, (const uint8*)"CMCC", 4)))
{
network_str_ptr->wstr_len = MMIPHONE_MAX_OPER_NAME_LEN;
MMIPHONE_GenPLMNDisplay(
MMIAPIGET_SpecSim_TDOrGsm(dual_sys),
&g_service_status[dual_sys].plmn,
network_str_ptr->wstr_ptr,
&network_str_ptr->wstr_len,
FALSE);
}
问题总结:
从问题中,获取到新的SIM知识,也了解到研发和产品岗位不同的思考角度,产品经理的修改方法,是我第一时间就会排除,却的确是有一定道理的。学习了。