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列表,等待后续建立数据时按序使用。
- 数据建立流程
- 数据上下行图标
数据连接建立成功后,会周期性(当前为1S)的通过TrafficStats获取TX(数据上行)和RX(数据下行)流量,与上次获取的值比较,判断出数据上下行的状态,然后一层一层通知到SystemUI,就是我们看到的托盘信号处有上下箭头。
代码参考:
- Data recovery
DataStallRecoveryManager用于检验当前建立的移动网络连通性,如果网络不通则认为当前网络错误,执行recovery流程,其实就是异常恢复机制。Android data recovery特殊场景处理方式介绍 (qq.com)
有下面几种处理方式
获取、更新当前数据连接列表
断开所有数据连接
开关radio
重启modem
代码参考:
实验室测试场景,可能实验室模拟网络无法访问外网,从而网络连通性校验失败,触发Data recovery机制,则需要禁用相关流程。
方法:
adb shell settings put global captive_portal_mode 0
- 数据连接Release流程
数据与网络交互
NetworkCapabilities
一般来说,APP可以根据自身所需网络,创建对应NetworkCapabilities的networkRequest调用ConnectivitManager的requestNetwork向ConnectivityManager发起请求,使用结束后调用releaseNetwork释放网络。后续实际调用的是ConnectivityService中的API。
以MMS为例:
ConnectivityService
维护Network request列表及当前network列表,每次network或者Network request发生改变时,都会根据特定规则重新匹配,保证每个Network request都能有一个Network能满足。
处理逻辑:
没有对应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
重写了needNetworkFor和releaseNetworkFor处理network request
当cs接收到网络请求就会回调needNetwork方法进而发起上述移动数据的datacall建立流程
当存在多个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会保证始终都会请求一个数据网络;
2.当满足默认网络请求的网络建立完毕后CS会将internet网络对应的路由参数设置到netd,同时将此networkId设置为default network id;
至此app可以直接访问网络。
移动数据始终开启功能
此功能的实现则是通过指定transport type为Cellular,在开关开启时保证始终都存在移动数据网络请求,存在高优先的wifi连接时,仍然可以不release移动网络
双卡切换数据
当插入两张SIM卡后,每张SIM都会对应一个TelephonyNetworkFactory,也会出现network request的竞争关系,同时各个芯片在数据这块也存在差异,因此需要一个机制来协调。
1.通过phoneswitcher来判断当前数据该走哪张卡,如果当前是默认数据网络请求,则当且仅当network request对应的phoneId为默认数据卡或者正在通话的数据卡时,才被允许建立数据连接,其他数据连接只要满足所需sim卡与当前TelephonyNetworkFactory对应的sim卡一致即可
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]