运营商名字是如何获取的?(理论篇)

我的未来我决定 提交于 2020-01-01 02:44:37

       Haykey哥近期接手了一个案例,同一运营商名字在M平台上显示1O1O,而在Q平台上显示CSL,如下图所示:

 

 

包括这个具体问题的分析之路,Haykey哥将在下期实践篇带来一共2个经典案例。这期带大家先把理论知识梳理清楚,例如,我们需要知道为什么PLMN 460-00就要和中国移动/CMCC/China Mobile关联起来。

 

       在手机端一般有两个地方需要显示运营商名字,1是在状态栏上显示当前注册的运营商名,2是手动搜网返回当前可用的运营商名。

(图1:状态栏上的运营商名 )

(图2:手动搜网返回的运营商名 )

 

针对这两个情景,安卓AP层分别调用两个不同的RIL request获取运营商名字。

通过RIL_REQUEST_OPERATOR获取在状态栏显示的运营商名,返回结果包括长名,短名和MCC+MNC pair。至于什么时候,在哪里显示长名,还是显示短名,逻辑全在AP侧。Haykey哥的理解就是完全依赖显示空间大小,过小则短名,如能容纳下则长名。至于MCC+MNC pair,完全是后手之举,运营商长短名都为空时,只能显示MCC+MNC pair给用户。

 

通过RIL_REQUEST_QUERY_AVAILABLE_NETWORKS获取在手动搜网返回的运营商名。返回结果只是多了个运营商状态,是禁止FPLMN,还是当前注册的Current,还是可及的Available。

 

       至此,相信有慧根的读者可以得出运营商名字实际获取处是在ATel层之下,或者Vendor RIL处,或者Modem处,我只能说Q平台肯定是这样的。但是万事不能这么绝对,也有放在AP侧继续搞的,例如M平台的spn_conf.xml。一种在特定环境下trade off的设计理念和哲学而已,例如为了加强应用层数据传输的可靠性,可以选择用户面的TCP ACK,也可以选择控制面RLC ARQ,也可以选择MAC HARQ,当然也可以全方位多角度全开,也是种不费脑的不错选择。

 

摘自 3GPP TS 22.101 Technical Specification Group Services and System Aspects; Service aspects; Service principles

 

从规范上可以看出,运营商名字的来源可以在手机中,网络NITZ下发,USIM卡中,并且优先级卡 > 网络NITZ > 手机。换句话说就是同一PLMN的运营商名字如果存在冲突,以优先级高的来源为主。而存在手机中,可以是AP,Vendor RIL,Modem处,八仙过海各显神通了,后面我会逐一介绍这三个来源的。

 

        在看三大来源前,需要再了解下SPN的概念。Haykey哥简单理解SPN就是你通过购买SIM卡作为客户签约的运营商,为你提供服务Service Provide么。只有在出国漫游时有些意思,如中国移动用户在美国漫游到AT&T网络上,有的会显示AT&T(registered PLMN) - CMCC(SPN), 有的仅是AT&T。这些显示规则,有的如同时显示Registered PLMN - SPN与否,存储在USIM卡中,有的如同在手动搜网中只显示SPN等,作为配置开关放到Android Properties中。

 

实际上类似“中国移动”,“China Mobile”等SPN名的字符串以UCS2编码格式或者GSM7位码存放到EFSPN的Service Provider Name字段,如下:

摘自 3GPP TS 31.102 Characteristics of the Universal Subscriber Identity Module (USIM) application

 

关于占第一个字节的Display Condition字段那一堆解释,翻译过来就是

真正有意思的就是Display Condition的b2,控制着当手机漫游注册到VPLMN上时(既不是hplmn/ehplmn,也不在EFSPDI里),除了显示当前VPLMN的名称,是否还要显示SPN名称。例如Haykey哥在美帝出差时发现有时显示AT&T - CMCC还是仅仅显示AT&T。这时有人会说我如何关联哪些PLMN对应这个SPN名字呢?这个就是EFSPDI的工作了。以下是从3GPP TS31.102上摘抄的EFSPDI,可以看到内容是TLV格式,即Type/Tag - Length - Value。Tag = 0x80, Length = N * 3,Value就是含有N个PLMN元素的数组。例如460-00,460-02,460-07,460-08。

 

Q平台下通过NAS_GET_PLMN_NAME这条QMI消息返回获取到的SPN和PLMN name,以及PLMN name的来源,是卡,手机Modem Hard Coded,还是NW。

 

举例,MCS QCSI PayloadPacket          02:48:32.321     Length: 0071

      nas_get_plmn_name {

           eons_plmn_name_3gpp {

              spn_enc =NAS_CODING_SCHEME_CELL_BROADCAST_GSM

              spn_len = 4

               spn = {1, O, 1, O }

              plmn_short_name_enc =NAS_CODING_SCHEME_CELL_BROADCAST_GSM

              plmn_short_name_ci =NAS_COUNTRY_INITIALS_DO_NOT_ADD

              plmn_short_spare_bits =NAS_SPARE_BITS_UNKNOWN

              plmn_short_name_len = 3

               plmn_short_name = { C, S, L }

              plmn_long_name_enc =NAS_CODING_SCHEME_CELL_BROADCAST_GSM

              plmn_long_name_ci =NAS_COUNTRY_INITIALS_DO_NOT_ADD

              plmn_long_spare_bits =NAS_SPARE_BITS_UNKNOWN

              plmn_long_name_len = 3

               plmn_long_name = { C, S, L }

           nw_name_source {

              nw_name_source = NAS_NW_NAME_SOURCE_SE13}

}

此时,Vendor RIL还有二次裁剪的机会,根据某些运营商的特殊需求而配置的Android Properties来进行到底把SPN还是PLMN name作为那两条RIL request响应的填充。常用Android属性列举如下:

1. persist.radio.always_send_plmn

如果值为1,只使用PLMN name,忽略SPN;

 

2. persist.radio.prefer_spn

如果Modem同时反馈SPN和PLMN name,是否优先填充SPN,如果是,分别在什么情景下填充SPN;取值范围0到4,意义如下:

3. persist.radio.use_se_table_only

如果值为1,只查询hard code在手机端的名为SE13 table的那张PLMN名称列表,其余来源忽略不计。Haykey哥大胆地猜测SE = Sony Ericsson的缩写,毕竟在索爱待的那几年,瑞典团队维护了一张非常全的运营商列表,每月还会定期更新。可能Q公司也直接借鉴过来了,如果不对,请在Q的读者朋友们私信给我哦:)。(PS, 附赠一个查运营商名字的官方网站 http://www.mcc-mnc.com/ )

  

现在Haykey哥可以带大家来看PLMN name的三大来源了。

来源1.  USIM卡中的EFopl and EFpnn,如果是欧洲运营商CPHS SIM卡,还可以是EF-ONS

EFopl和EFpnn的关系类似于EFspdi和EFspn, 运营商长短名均包含在EFpnn里,EFopl里第8字节相当于一个索引或者指针指向EFpnn的第几个记录。

 

 

CPHS SIM不同于USIM把长名和短名都放入了EFpnn文件,而是分别放到了两个文件,长名6F14,短名6F18。

 

 

来源2. NITZ transfer in MM/EMM Information Msg

什么是NITZ呢?请阅读TS 22.042,我这里也把重点内容贴出来解释一下。

 

摘自 3GPP TS 22.042: "NetworkIdentity and Time Zone (NITZ)

但要注意承载NITZ信息的NAS信令MM Information Message/EMM Information Message在运营商网络上是可选部署,并不是每家运营商网络在以上5个情景下都会下发这条信令的。

 

摘自 3GPP TS 24.008 Mobileradio interface Layer 3 specification; Core network protocols; Stage 3

如下,TS 22.042还强调了关机,拔卡等操作均不会删除网络下发NITZ的运营商名,换言之终端为了持续化需要有永久性存储NITZ的地方。但是存储的最大运营商名数量是终端厂商实现问题。

 

为了满足这个协议规定,Q平台是通过一个名为rplmn_info_ext.txt的EFs file来存储NITZ信息的,结构如下

 

来源3. 手机Hard Coded PLMN列表

如前所述,这个手机内部列表可以在Modem维护,也可以在Vendor RIL维护,甚至可以在Android侧维护。我这次只讨论Q平台上默认实现,在Modem维护的名为SE13 table。

 

 

可以看到这个SE13 table实际上就是一个名为mmgsdi_network_table的结构体数组,包含了MCC-MNC pair,PLMN长短名,该PLMN是什么RAT的,以及是否是实网(FALSE=Lab NW; TRU=Live NW)。

 

       最后,即使前面你看得云山雾绕,也请记住下面这张图。Haykey哥总结的运营商名字获取的出处。

有了这些信息,平台商是如何总结归纳后上报给AP侧的呢?我以M平台逻辑为例,实际上Q平台的步骤也大致相同。

 

差异点为Q平台在读取NITZ后,如果网络不下发MM/EMM Information Msg后还会继续读取EFs file rplmn_info_ext.txt里内容填充。以及最后是读取Modem SE13 table非Spn-Conf.xml。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!