【通信篇4】APN模块总结

您所在的位置:网站首页 apnmmsc 【通信篇4】APN模块总结

【通信篇4】APN模块总结

#【通信篇4】APN模块总结| 来源: 网络整理| 查看: 265

1 APN 简介

APN(Access Point Name)是通过手机上网必须配置的一个参数,用来决定手机通过哪种接入方式来访问网络。只要我们的手机插上 SIM 卡之后就可以在手机的设置中查看当前 SIM 卡内置的默认 APN 参数,一般的安卓智能机都可以在 SIM 卡设置中找到“接入点名称(APN)”并可以查看和新增 APN。

下面我们看看 APN 到底是怎么使用的,在启动 Android 手机或者启动 Android 虚拟设备后,所有的 APN 配置信息都会保存在telephony.db的 SQLite 数据库表名为 carriers 的表中。我们可以将此数据库文件 pull 到本地,然后可以查看 carriers 表的结构和其中的 APN 配置信息数据,命令如下:

adb pull /data/user_de/0/com.android.providers.telephony 如上可以将mmssms.db和telephony.db等数据都pull出来。

在Android系统中APN配置文件的路径: 1)vendor\qcom\proprietary\qrdplus\Extension\apps\etc\apns-config.xml 2)framework\base\core\res\xml\apn.xml

开机后,启动 phone 进程时,会加载运行在 phone 进程中的 TelephonyProvider,TelephonyProvider负责解析apns-conf.xml文件,将其中定义的APN参数写入到数据库中。

1.1 APN 配置关键字段 字段名称描述nameAPN配置名称,如CMNETnumeric运营商编号,如46000mcc移动国家码,如460mnc移动网络码,如00apnAPN接入点,比如中国移动有两个接入点:cmwap和cmnetuser用户名server服务器地址password密码proxy代理服务器地址,如10.0.0.172port端口号,如80mmsproxy彩信代理服务器地址,如10.0.0.172mmsport彩信代理服务器端口号,如80mmsc彩信接入服务器地址,如mmsc.monternet.comtypeAPN接入类型,如default,net,supl,xcap,不同类型用","分隔currentprotocol连接该APN所用的协议,如IPV4IPV6roaming_protocol漫游时连接该APN所用的协议,如IPV4IPV6carrier_enabled用于标识APN是否可用bearer无线接入,如LTE和eHRPDbearer_bitmask无线接入技术位掩码,用于标明当前APN可以包含的RATnetwork_type_bitmaskmvno_type移动虚拟网络运营商(Mobile virtual network operator)的类型,可用的数据有spn,IMSI,GID(Group Identifier Level 1)mvno_match_dataMVNO_TYPE数据,这个值是和MVNO_TYPE对应的。例如:SPN:A MOBILE,BEN NL,IMSI:302720x94,2060188 GID:4E,33sub_id用于表明这个APN属于哪个subscription,此值从siminfo表获取profile_idProfile id,profile是modem侧存储信息的方式,这个值将APN和modem侧的profile联系起来modem_cognitive用于表明这个APN是否会在modem侧设置max_connsAPN支持的最大连接数量wait_time使用该APN进行数据连接时,如果失败,retry要等待的时间max_conns_time限制APN最大连接的时间mtu使用该APN建立的连接,可以传输的最大单元edited表明该APN是否被用户或运营商添加、编译或删除的状态user_visibleAPN是否对用户可见user_editable用户是否可以编辑APNowned_byAPN的拥有者,0或者1apn_set_idAPN集合id,如果用户或者框架选择了一个apn作为首选APN,那么所有与选中apn相同集合id的APN拥有更高的优先级persistentread_only是否只读ppp_numbersourcetypecsdnumipversion 1.2 Android 支持的 APN 类型 类型描述default默认数据连接、即浏览器、Email等手机上网数据连接mms发送和接收彩信使用的数据连接supl支持AGPS的数据连接dun(dial-up-network)拨号连接hipri扩展ims 1.3 APN 配置信息

APN 配置在apns-conf.xml中,carriers表中的数据和此文件中的数据内容一致,在加载 TelephonyProvider 的时候,会调用其 initDatabase 方法,将apns-conf.xml配置文件内容加载到carriers表中。

1.4 APN 分工

image.png

2 APN 设置 2.1 重置 APN

image.png

image.png

在 ApnSettings 界面点击重置后,通过 Uri: “content://telephony/carriers/restore"进行 delete 操作,删除完成后会重新 fillList。

进行 delete 操作时,TelephonyProvider 通过 URL_RESTOREAPN 进行删除操作,会删除carriers表,同时删除首选 APN,获取 preferred-full-apn 的 SP,如果 SP 包含version1,表示 APN 已经存储起来了,删除该 subId 对应的 version1 字段以及 APN 唯一字段与 subId 组合在一起的字段,删除完成,重新初始化加载carrier表

在 ApnSettings 界面查询到 APN 后,会通过 Uri:"content://telephony/carriers/preferapn" 去设置首选 APN

初始化完成后,DcTracker 监听到数据库变化执行 onApnChanged,然后会设置偏好 APN,此时会将 oldApnSettings 设置成首选 APN,同时 ApnSettings 查询到 APN list 检测到如果没有偏好 APN,会将第一个 APN 设置成偏好 APN。APN 如果配置了 bearer_bitmask,且 bearer_bitmask 不为 0,如果插入的卡网络类型识别的是 unknown,查询出来的 APN 则会被过滤掉不显示。

2.2 切换 APN

image.png

image.png

在 ApnSettings 界面点击 onPreferenceChange,执行 setSelectedApnKey,设置首选 APN 通过 URI:content://telephony/carriers/preferapn 和 APN_ID 为选中的 id 进行 update

TelephonyProvider:获取 subId,检查 values 中是否包含 apn_id,如果包含apn_id,获取 apn_id 带过来的 id 值,将对应的 apn_id 保存为该 subId 的首选 APN

DcTracker:监听到数据库变化,ApnChangeObserver 的 onChange 函数将被调用,触发 onApnChange 函数,onApnChange 的时候,底层会清除掉所有的连接。

2.3 新建 APN

image.png

ApnEditor:布局初始化,获取相关控件,获取 subId 等 intent 传过来的参数,插入一条仅有 id 的信息,并根据插入信息返回 uri,根据 uri 查询相应 id 的数据。

根据查询到的数据 fillUi 进行显示,如果是新建的,mvnoType 显示有差异,mvnoMatchData显示有差异

移动定制版本,APN 协议和 APN 漫游协议默认为 IpV4V6、设置 SIM 卡相关的监听、 APN 变化的 TextWatcher

在 onResume 中会注册 phone 状态、插拔卡等的监听

点击保存:内置的 APN 则弹框提示是否保存,非内置的 APN ,直接验证并保存,如果APN 相关有用信息为空,则 toast 提示,不保存返回,根据各项字段,通过 uri 更新数据库中数据。

2.4 编辑 APN

image.png

ApnEditor:布局初始化,获取相关控件,获取 subId 等 intent 传过来的参数,获取传递过来的 uri,uri 以 id 结尾,如果 uri 为空或不满足要求则返回,关闭界面

根据 uri 查询相应 id 的数据,根据查询到的数据 fillUi 进行显示,设置 SIM 卡相关的监听、APN 变化的 TextWatcher

在 onResume 中会注册 phone 状态、插拔卡等的监听,如果配置了 ReadOnly 字段,则不可保存、不可编辑 preferene 项

点击保存:name、APN、mcc、mnc 四项不能为空,如果为空则返回不让保存,内置的 APN 则弹框提示是否保存,非内置的 APN,直接验证并保存,如果 APN 相关有用信息为空,则 toast 提示,不保存返回,根据各项字段,通过 uri 更新数据库中数据

修改 mcc,点击保存,此时发生冲突时,更新旧的那条数据,然后删除掉要更新的这条数据,此时要更新这条 APN 就从数据库中删除了,此时不会触发 onApnChange,不会导致 DcTracker 重新触发连接的逻辑。重启手机后,此时通过 numeric 查询 APN 是无法查到的,因为数据库中的那条 APN 的 mnc 和 numeric 已经相对应的被修改了

3 TelephonyProvider 3.1 APN 升级

image.png APN 升级在 TelephonyProvider 中实现,先获取首选 APN 保存,然后根据条件删除数据库。重新根据 xml 插入 APN,根据名称、APN、numeric、bearer 四个属性恢复首选 APN,若其中有属性变更,则不恢复。

4 APN 流程 4.1 卡加载后,监听 APN 数据库变化 public DcTracker(Phone phone) { ....... //每个Phone对象有自己DcTracker //每个DcTracker加载各自卡可用的APN mPhone = phone; ....... //1、监听卡载入 mUiccController = UiccController.getInstance(); mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null); ....... //2、监听卡信息变化 mSubscriptionManager = SubscriptionManager.from(mPhone.getContext()); mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); ....... //监听APN数据库变化 mApnObserver = new ApnChangeObserver(); phone.getContext().getContentResolver().registerContentObserver( Telephony.Carriers.CONTENT_URI, true, mApnObserver); ............. //初始化不同APN类型对应的网络能力,后文介绍 initApnContexts(); ............. // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases initEmergencyApnSetting(); addEmergencyApnSetting(); ............... } 复制代码

插卡或卡发生变化后,就要创建当前卡可用的 APN,同时设置初始时使用的 APN

private void onRecordsLoadedOrSubIdChanged() { .............. //1、创建当前卡可用的APN createAllApnList(); //2、设置初始使用的APN setInitialAttachApn(); if (mPhone.mCi.getRadioState().isOn()) { if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability"); notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED); } //卡变化也会触发拨号流程;不过若此时数据开关未开,那么拨号是不会成功的 setupDataOnConnectableApns(Phone.REASON_SIM_LOADED); } 复制代码

创建卡对应的 APN 的过程:

private void createAllApnList() { //表示mvno是否匹配 //mvno也是APN的一种属性,代表该APN适用于虚拟运营商,目前用的比较少 mMvnoMatched = false; //用于保存结果 mAllApnSettings = new ArrayList(); //得到当前卡的信息 IccRecords r = mIccRecords.get(); //得到卡对应的MCC/MNC String operator = (r != null) ? r.getOperatorNumeric() : ""; if (operator != null) { //构造SQL语句 String selection = "numeric = '" + operator + "'"; String orderBy = "_id"; ............... //查询MCC/MNC对应的APN Cursor cursor = mPhone.getContext().getContentResolver().query( Telephony.Carriers.CONTENT_URI, null, selection, null, orderBy); if (cursor != null) { if (cursor.getCount() > 0) { //1、利用数据创建APN mAllApnSettings = createApnList(cursor); } cursor.close(); } } //2、添加emergencyApnSettings addEmergencyApnSetting(); //3、去除重复的APN dedupeApnSettings(); if (mAllApnSettings.isEmpty()) { mPreferredApn = null; } else { //4、得到用户偏爱的APN (用户在UI界面主动选择的) mPreferredApn = getPreferredApn(); if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator) { mPreferredApn = null; //用户偏爱的与当前卡不匹配,删除数据库中对应信息 setPreferredApn(-1); } } //5、在需要的情况下,构造APN文件发送给modem setDataProfilesAsNeeded(); } 复制代码 5 APN 举例

1 以中国移动举例:其中carrier、apn、mcc、mnc几个字段是一个完整的 APN 一定要有的,不同的卡 mnc 会存在不同的情况如,00、02,设置错误的情况下会无法上网

复制代码

这里需要强调一下 type 和 authtype,type 字段可以有多个属性值,依次用逗号隔开, authtype 在自己添加 APN 时可能给定的值是字符串,我们需要转换为相应的值。具体关系如下:

属性值合入值None0不写(默认值)-1PAP1CHAP2PAP OR CHAP3

2 上网分为 wap 和 net 两种方式,使用 net 手机就会直接连入互联网,而使用 wap 则会中间多了一个代理网关,移动联通均是 10.0.0.172,端口 80。

3 彩信 APN 彩信 APN 中 mmsproxy 和 mmsport 两个字段在发彩信的 APN 中是必须的

6 Android 支持的 APN 类型

Android 中支持的 APN 类型(”default, mms, supl, dun, hipri, fota, ims…….”),其功能如下所示:

类型描述default默认数据连接,即浏览器、Email等普通连接(internet、wap、web)mms接收和发送彩信使用的数据连接supl支持APGS的数据连接(gprs上网)dun拨号连接(wifi等上网类型,tethering)hipri扩展

此表中的数据优先级是由低到高的,即 default 数据连接的优先级最低,而 hipri 数据连接的优先级最高。比如在手机上网聊天时,将建立 default 数据连接;当手机收到一条彩信,因为彩信的数据连接是 mms,这时会断开 default 数据连接而创建 mms 数据连接,从而能快速接收到此彩信,因为 mms 比 default 的数据连接优先级高。因此,在发送和接收彩信的同时不能上网。

APN分类

1 default 默认网络连接,当激活时所有数据传输都使用该连接,不能与其他网络连接同时使用 适用场合: 绝大部分正常上网时可以使用

2 mms 彩信专用连接,此连接与default类似,用于与载体的多媒体信息服务器对话的应用程序,此连接能与default连接同时使用 适用场合:使用彩信服务时,必须有mms类型的接入点,不必选中,应用程序会自动使用此接入点

3 supl 是 SecureUser Plane Location “安全用户面定位”的简写,此连接与 default 类似,用于帮助定位设备与载体的安全用户面定位服务器对话的应用程序,此连接能与 default 连接同时使用

4 dun Dial UpNetworking 拨号网络的简称,此连接与 default 连接类似,用于执行一个拨号网络网桥,使载体能知道拨号网络流量的应用程序,此连接能与 default 连接同时使用 适用场合:当我们使用自己的手机给别人做热点时使用,不管是 USB 热点,wifi 热点或则 bluetooth 热点。将他与 default 区别开来的主要目的一般是方面计费,国外很多运营商手机自己上网和做热点计费不同的。目前在国内三大运营商都没有区分,所以也就没有 dun 这个 APN

5 hipri 高优先级网络,与 default 类似,但路由设置不同。使用较少。

6、ims 当 ims 发起激活请求时会使用这个 APN 连建立 ims 的专用承载.

7 FOTA 手机FOTA升级的时候使用

8 IA IA 的 APN 专用于 LTE attach 使用,在手机检测到 SIM 卡后,便会加载这个 attach apn. 不过很多运营商并没有严格规定 attach apn,所以常常复用 default 类型的 APN。 在 attach apn加载的时候它有一个优先级顺序,如下:

IaApn  > PreferredApn > DefaultApn > FirstApn

IaApn : 类型为 ia 的 APN,优先级最高。 PreferredApn :选中的 APN。比如在手机 settin g里面设置的那个 APN DefaultApn :从 apnlist 里面查询到的第一个类型为“default”的 APN FirstApn :apnlist 中的第一个 APN

APN 加载和过滤

在每次开机的时候系统回自动检查telephony.db是否存在,如果不存在则会创建数据库telephony.db,并利用apns-conf.xml中的内容生成表carriers, 以后所有对 APN 的操作都会是直接针对表carriers,包括查询,创建,修改,删除等。 当插入一张卡后系统会根据卡的相关信息来匹配相应的 APN,在 APN list 中主要涉及匹配的项有:mcc,mnc,mvno_type, mvno_match_data mvno_type 值决定 mvno_match_data 的值,android 原生代码里 mvno_type 会有4个值,他们分别是 “spn”, “imsi”, “gid”, “iccid”。所以,在 APN 读取的时候,会先根据 SIM 卡的 mcc,mnc 读取出相应的 APN list,接着会判断 APN list 中的每一个 APN 的 mvno_type 的值,如果不为空,则会根据mvno_type 和 mvno_match_data 再一次对 APN list 进行过滤,一般情况下,mvno_type, mvno_match_data 为空。 7 常见的APN问题

7.1 重置APN,显示为默认的APN接入点后又变为手动更改的接入点

D ApnSettings: --restoreDefaultApn-- ——开始重置 D TelephonyProvider: restoreDefaultAPN: where: owned_by!=0 D TelephonyProvider: deletePreferredApn: for subId 1 D TelephonyProvider: deletePreferredApn: apn is stored. Deleting it now for subId 1 D TelephonyProvider: dbh.initDatabase:+ db=SQLiteDatabase: /data/user_de/0/com.android.providers.telephony/databases/telephony.db ——重新创建 D TelephonyProvider: dbh.initDatabase:- db=SQLiteDatabase: /data/user_de/0/com.android.providers.telephony/databases/telephony.db ——插入数据库完成 D TelephonyProvider: setPreferredApn: _id 2965 subId 1 ————设置偏好APN DCT : [ApnContext:default] getApnSetting: apnSetting=[ApnSettingV5] CUWAP, 2966, 46001, 3gwap, 10.0.0.172, http://mmsc.myuni.com.cn, 10.0.0.172, 80, 80, -1, default | mms, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0 DCT : [ApnContext:default] getApnSetting: apnSetting=[ApnSettingV5] CUWAP, 2966, 46001, 3gwap, 10.0.0.172, http://mmsc.myuni.com.cn, 10.0.0.172, 80, 80, -1, default | mms, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0 QtiDCT : [0]buildWaitingApns: reset preferred APN to [ApnSettingV5] CUWAP, 2966, 46001, 3gwap, 10.0.0.172, http://mmsc.myuni.com.cn, 10.0.0.172, 80, 80, -1, default | mms, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0 ——设置偏好APN失败,重置到2966了 从log可知,上层设置2965 APN时未设置成功,底层重新设置了2966 复制代码 //上层设置偏好APN 2965 Line 58117: 06-21 14:43:07.940 2883 3252 D TelephonyProvider: setPreferredApn: _id 2965 subId 1 //framework设置偏好APN 2966 Line 4405: 06-21 14:43:07.939 2883 2883 D QtiDCT : [0]buildWaitingApns: reset preferred APN to [ApnSettingV5] CUWAP, 2966, 46001, 3gwap, 10.0.0.172, http://mmsc.myuni.com.cn, 10.0.0.172, 80, 80, -1, default | mms, IPV4V6, IPV4V6, true, 0, 0, 0, false, 0, 0, 0, 0, , , false, 0, 0 ——设置偏好APN失败,重置到2966了 //framerok调用删除 Line 4406: 06-21 14:43:07.939 2883 2883 D QtiDCT : [0]setPreferredApn: delete //OS写入完成,数据库执行完打印的log Line 58119: 06-21 14:43:07.943 5337 5337 D _ApnSettings: set key to 2965 //framework开始写入偏好APN Line 4407: 06-21 14:43:07.967 2883 2883 D QtiDCT : [0]setPreferredApn: insert //响应framework的操作,写入偏好APN 2966 Line 58161: 06-21 14:43:07.967 2883 2883 D TelephonyProvider: delete:match=12 Line 58162: 06-21 14:43:07.967 2883 2883 D TelephonyProvider: subIdString = 1 subId = 1 Line 58163: 06-21 14:43:07.967 2883 2883 D TelephonyProvider: deletePreferredApn: for subId 1 Line 58164: 06-21 14:43:07.967 2883 2883 D TelephonyProvider: deletePreferredApn: apn is stored. Deleting it now for subId 1 Line 58170: 06-21 14:43:07.972 2883 2883 D TelephonyProvider: subIdString = 1 subId = 1 ——此处log只有对应URL_PREFERAPN_NO_UPDATE_USING_SUBID 或者URL_PREFERAPN_USING_SUBID URI才会打印出来 Line 58171: 06-21 14:43:07.973 2883 2883 D TelephonyProvider: setPreferredApn: _id 2966 subId 1 //从上面流程可以看出,最后执行的是响应 framework的写入2966的操作 复制代码

【分析】 如上分析,在 buildWaitingAPN() 中增加的 reset preferred APN 的逻辑和上层冲突,导致 preferred APN 值不对,这段已经不需要。上层在 restore APN 时会设置 default preferred APN 【方案】 删除reset prefered APN逻辑

7.2 升级后,SIM2的APN需要重新选择 【分析】 (1)从 log 来看,卡 2 没有选择默认的 APN,故会弹框通知设置 APN (2)对比升级前后的 APN 可知,升级后由于名称改变了,相当于 APN 变更了,故需要重新设置 APN

7.3 手动配置APN 手动配置APN需要配置的元素,例如: (1)name:ims (2)APN:ims (3)type:ims (4)APN protocol & APN roaming protocol:IPV4V6



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3