APN(Access Point Name)

APN即接入点,是上网时必须配置的一个参数。对于手机用户来说,可以访问的外部网络类型有很多,例如:Internet、WAP网站,集团企业内部网络、行业内部专用网络。

不同的接入点所能访问的范围以及接入的方式是不同的,网络侧要知道手机激活以后访问哪个网络以及分配哪个网络的IP,需要靠APN来区分。

  • APN常见参数

carrier----运营商名称

mcc -----运营商国家码

mnc-----运营商网络码

apn-----APN名称

mmsc----彩信中心地址

mmsproxy----彩信代理

mmsport----彩信端口

type----APN类型,有default、mms、supl、xcap、mms、dun等

protocol----非漫游IP协议,有IP、IPV6、IPV4V6

roaming_protocol----漫游IP协议,有IP、IPV6、IPV4V6

mvno_type----虚拟网络运营商类型,有gid、spn、imsi

mvno_match_data----mvno_type对应的value

user_editable----在APN菜单中可编辑

user_visible----在APN菜单中可见

network_type_bitmask----网络类型掩码,1~20

  • APN文件存储位置

展讯:

product/etc/apn-conf.xml

MTK:

etc/apns-conf.xml

有APN新增或者修改的需求可以直接修改后push,然后在apn settings界面选择重置为默认即可生效。

也在以下文件进行定制:

MTK:device/mediatek/config/apns-conf.xml

展讯:vendor/sprd/telephony-res/apn/apns-conf_8_v3.xml

高通:vendor/qcom/proprietary/commonsys/telephony-apps/etc/apns-conf.xml

  • APN数据库

手机启动时TelephonyProvider会初始化telephony.db数据库,这时候会读取手机目录中的apn-conf.xml并把其中的内容加入到carriers表中。以后查询有关apn的配置参数都是从carriers表中取出。

数据库保存位置:

data/user_de/0/com.android.providers.telephony/databases/telephony.db

数据业务流程

  • 常用移动数据网络

default 用于访问Internet,默认网络

Mms 收发彩信专用网络

Ims VoLTE专用网络

dun 移动热点专用

  • 数据连接建立条件

data 注册上

SIM卡关键信息加载完毕

DDS设置完毕

APN加载完毕

  • APN匹配

根据sim卡的mcc/mnc、注册的网络制式、network request的capbilities匹配数据库中对应的apn,加入waiting apn列表,等待后续建立数据时按序使用。

  • 数据建立流程

android 通过路径获取 bitmap android通过api获取数据_网络

  • 数据上下行图标

数据连接建立成功后,会周期性(当前为1S)的通过TrafficStats获取TX(数据上行)和RX(数据下行)流量,与上次获取的值比较,判断出数据上下行的状态,然后一层一层通知到SystemUI,就是我们看到的托盘信号处有上下箭头。

代码参考:

android 通过路径获取 bitmap android通过api获取数据_网络协议_02

  • Data recovery

DataStallRecoveryManager用于检验当前建立的移动网络连通性,如果网络不通则认为当前网络错误,执行recovery流程,其实就是异常恢复机制。Android data recovery特殊场景处理方式介绍 (qq.com)

有下面几种处理方式

获取、更新当前数据连接列表

断开所有数据连接

开关radio

重启modem

代码参考:

android 通过路径获取 bitmap android通过api获取数据_网络_03

实验室测试场景,可能实验室模拟网络无法访问外网,从而网络连通性校验失败,触发Data recovery机制,则需要禁用相关流程。

方法:

adb shell settings put global captive_portal_mode 0

  • 数据连接Release流程

android 通过路径获取 bitmap android通过api获取数据_智能手机_04

数据与网络交互

NetworkCapabilities

一般来说,APP可以根据自身所需网络,创建对应NetworkCapabilities的networkRequest调用ConnectivitManager的requestNetwork向ConnectivityManager发起请求,使用结束后调用releaseNetwork释放网络。后续实际调用的是ConnectivityService中的API。

以MMS为例:

android 通过路径获取 bitmap android通过api获取数据_网络协议_05

ConnectivityService

维护Network request列表及当前network列表,每次network或者Network request发生改变时,都会根据特定规则重新匹配,保证每个Network request都能有一个Network能满足。

android 通过路径获取 bitmap android通过api获取数据_android_06

处理逻辑:

没有对应networkAgent的request则发给所有网络工厂,让其各自建立network,等待network建立成功后,会将新的NetworkAgent注册到CS, CS重新match;

没有对应network request的networkAgent将被通知release,一般是10s,超时后如果还没有附着request则会通知拆除。

更新当前网络路由参数到netd,设置系统默认网络。

 NetworkFactory

NetworkFactory会调用register方法向ConnectivityService注册,其实注册的本质就是让cs知道自己的存在,且表明自己的身份及能力,以便cs接收到网络请求后能按需回调到此网络工厂(通过Messenger),进行数据业务处理。

如:

WifiNetworkFactory

TelephonyNetworkFactory

BluetoothTethetworkFactory

以TelephonyNetworkFactory为例,注册NetworkProvider到CM

android 通过路径获取 bitmap android通过api获取数据_网络_07

重写了needNetworkFor和releaseNetworkFor处理network request

android 通过路径获取 bitmap android通过api获取数据_5G_08

当cs接收到网络请求就会回调needNetwork方法进而发起上述移动数据的datacall建立流程

android 通过路径获取 bitmap android通过api获取数据_网络_09

当存在多个network能满足一个network request需要的能力时, 最终选哪个network呢?

网络选择评分机制

WIFI基础分值60

移动数据基础分值50

每次network建立向cs注册networkAgent时,都会通过NetworkMonitor去ping特定网址看是否能ping通,无法ping通的减分,一般是40分(UI可以直观看到信号条旁边出现感叹号)

常驻网络请求

默认网络请求

每个APP上网都需要通过requestNetwork来请求吗?肯定不是。

主要做了以下工作:

1.CS初始化会创建默认的networkrequest,transport type为none,即可以是任何类型的网络,此request会保证始终都会请求一个数据网络;

android 通过路径获取 bitmap android通过api获取数据_智能手机_10

2.当满足默认网络请求的网络建立完毕后CS会将internet网络对应的路由参数设置到netd,同时将此networkId设置为default network id;

至此app可以直接访问网络。

移动数据始终开启功能

此功能的实现则是通过指定transport type为Cellular,在开关开启时保证始终都存在移动数据网络请求,存在高优先的wifi连接时,仍然可以不release移动网络

android 通过路径获取 bitmap android通过api获取数据_网络协议_11

 双卡切换数据

当插入两张SIM卡后,每张SIM都会对应一个TelephonyNetworkFactory,也会出现network request的竞争关系,同时各个芯片在数据这块也存在差异,因此需要一个机制来协调。

1.通过phoneswitcher来判断当前数据该走哪张卡,如果当前是默认数据网络请求,则当且仅当network request对应的phoneId为默认数据卡或者正在通话的数据卡时,才被允许建立数据连接,其他数据连接只要满足所需sim卡与当前TelephonyNetworkFactory对应的sim卡一致即可

android 通过路径获取 bitmap android通过api获取数据_智能手机_12

2.当主卡存在数据连接,副卡需要建立MMS数据连接的时候,不同芯片有不同表现:

MTK:

phoneSwitcher不做任何处理,主卡移动数据会自动断开(底层上报),然后在副卡上建立mms apn。

等待副卡的mms网络请求release后,主卡数据再恢复建立;如果副卡数据连接一直未断开,则主卡永远无法上网(DSDS数据单通)。

比如副卡发送彩信。之前遇到副卡发送彩信后主卡无法上网的问题,原因是因为qq邮箱请求了一个很common的network request,从未release,导致副卡mms apn一直无法被断开,从而主卡建立数据一直失败。

展讯:

phoneSwitcher不做任何处理,主卡默认数据连接保持不变,副卡正常建立mms apn。

完整数据业务流程实例

以mms apn为例

1.收到mms请求

ConnectivityService: requestNetwork for uid/pid:1001/1461 activeRequest: null callbackRequest: 124 [NetworkRequest [ REQUEST id=124, [ Transports: CELLULAR Capabilities: MMS&NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <TelephonyNetworkSpecifier [mSubId = 2]> Uid: 1001..

2.当前不存在能满足的网络

ConnectivityService: NetReassign [no changes]

3.发送到各个NetworkFactory,当前TelephonyNetworkFactory接收到NetworkRequest

TelephonyNetworkFactory[1]: got request NetworkRequest [ REQUEST id=124, [ Transports: CELLULAR Capabilities: MMS&NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <TelephonyNetworkSpecifier [mSubId = 2]>...

PhoneSwitcherNetworkRequstListener: got request NetworkRequest [ REQUEST id=124, [ Transports: CELLULAR Capabilities: MMS&NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <TelephonyNetworkSpecifier [mSubId = 2]>...

TelephonyNetworkFactory[1]: onNeedNetworkFor [NetworkRequest [ REQUEST id=124, [ Transports: CELLULAR Capabilities: MMS&NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <TelephonyNetworkSpecifier [mSubId = 2]>...shouldApply true

4.DataNetworkController处理

DNC-1   : onAddNetworkRequest: added [NetworkRequest [ REQUEST id=124, [ Transports: CELLULAR Capabilities: MMS&NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <TelephonyNetworkSpecifier [mSubId = 2]>...

5.过滤apn

DPM-1   : Satisfied profile: [DataProfile=[ApnSetting] ctwap, 33, 46011, ctwap, , http://mmsc.vnet.mobi, 10.0.0.200, 80, null, 0, mms, IPV4V6, IPV4V6, true, 0, false, 0, 0, 0, 0, 0, null, , false, UNKNOWN, UNKNOWN, 0, -1, -1, false,....

6.开始建立网络

DNC-1   : Data evaluation: evaluation reason:NEW_REQUEST, Data allowed reason: UNMETERED_USAGE, candidate profile=[DataProfile=[ApnSetting] ctwap, 33, 46011, ctwap, , http://mmsc.vnet.mobi, 10.0.0.200, 80, null, 0, mms, IPV4V6, IPV4V6, true, 0, false, 0, 0, 0, 0, 0, null, , false, UNKNOWN, UNKNOWN, 0, -1, -1, false, TrafficDescriptor={mDnn=ctwap, null}, preferred=false], time=11:35:14.442, network type=NR, reg state=HOME, [NetworkRequest [ REQUEST id=124, [ Transports: CELLULAR Capabilities: MMS&NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <TelephonyNetworkSpecifier [mSubId = 2]> Uid: 1001 RequestorUid: 1001 ...

7.新建DataNetwork

DNC-1   : Creating data network on WWAN with [DataProfile=[ApnSetting] ctwap, 33, 46011, ctwap, , http://mmsc.vnet.mobi, 10.0.0.200, 80, null, 0, mms, IPV4V6, IPV4V6, true, 0, false, 0, 0, 0, 0, 0, null, , false, UNKNOWN, UNKNOWN, 0, -1, -1, false, TrafficDescriptor={mDnn=ctwap, null}, preferred=false], and attaching 1 network requests to it.

8.通过RIL下发数据建立请求

RILJ    : [3638]> SETUP_DATA_CALL,reason=NORMAL,accessNetworkType=NGRAN,dataProfile=[DataProfile=[ApnSetting] ctwap, 33, 46011, ctwap, , http://mmsc.vnet.mobi, 10.0.0.200, 80, null, 0, mms, IPV4V6, IPV4V6, true, 0, false, 0, 0, 0, 0, 0, null, , false, UNKNOWN, UNKNOWN, 0, -1, -1, false, ... [PHONE1]

9.底层上报建立数据成功,携带路由参数

RILJ    : [3638]< SETUP_DATA_CALL DataCallResponse: { cause=NONE(0x0) retry=-1 cid=1 linkStatus=2 protocolType=0 ifname=sipa_eth8 addresses=[10.128.30.175/32] dnses=[/218.2.2.2, /218.4.4.4] gateways=[/0.0.0.0] pcscf=[] mtu=0 mtuV4=0 mtuV6=0... [PHONE1]

10.CS处理,设置路由参数,并将mms request map到MMS网络

ConnectivityService: Adding iface sipa_eth8 to network 101

ConnectivityService: Setting DNS servers for network 101 to [/218.2.2.2, /218.4.4.4]

ConnectivityService: [101 CELLULAR] EVENT_NETWORK_INFO_CHANGED, going from CONNECTING to CONNECTED

ConnectivityService: NetReassign [124 : null → 101]