在onReceive里,状态为:state= CONNECTED, old= CONNECTING, reason= apnChanged 11、NetworkStateTracker.java:setDetailedState()函数 说明:(7),状态:old =CONNECTING and new state=CONNECTED 12、NetworkStateTracker.java:updateNetworkSettings函数 说明:该函数从Network TCP buffer读取network设置参数,并设置网络 13、ConnectivityService。java:handleDnsConfigurationChange 说明:从dnsList里读取预设的dns 通过writePidDns设置dns 二、下面分析RIL Java层的处理: 该部分的核心实现存在于Ril.java以及GsmDataConnectionTracker.java之中,Ril.java中RIL.RILSender负责处理命令的发送,RIL.RILReceiver用于处理命令响应以及主动上报信息的接收; Ril.Java中一个命令发送的流程为:RILRequest.obtain(命令ID)→复制参数→通过Send()函数发送EVENT_SEND→在RILSender线程中处理EVENT_SEND→将命令写到out stream(socket); Ril.java响应和主动上报消息的流程为:RILReceiver线程监视mSocket input→readMessage(读取完整响应)→processReponse→分别处理RESPONSE_UNSOLICITED(主动上报)与REPONSE_SOLICITED(命令响应) RILD守护进程里的Request都是由RIL.java发起 3.2 APN 切换流程分析 1、ApnPreference.java: onCheckedChanged 说明:检查接入点切换的ID是否合法 2、MobileDataStateTracker.java:MobileDataStateReceiver 说明:处理在onReceive里,状态为:state= DISCONNECTED, old= CONNECTED 3、ConnectivityService.java:handleMessage()函数: 说明:状态:DISCONNECTED/DISCONNECTED 4、ActivityThread.java:getProvider 说明:ActivityThread.java是app里的一个实例,在main里创建了一个thread,在getProvider里 holder = ActivityManagerNative.getDefault().getContentProvider(getApplicationThread(), name);进行了判断 5、Checkin.java:updateStats函数: 说明:update statistics in the database,会对PHONE_GPRS_ATTEMPTED进行判断,在emulator里会报Can't update stat PHONE_GPRS_ATTEMPTED: java.lang.IllegalArgumentException: Unknown URL content://android.server.checkin/stats的错误 6、MobileDataStateTracker.java:MobileDataStateReceiver 说明:处理在onReceive里,state= CONNECTED, old= CONNECTING 7、NetworkStateTracker.java:setDetailedState()函数 说明:状态:old =CONNECTING and new state=CONNECTED 8、ConnectivityService.java:handleMessage()函数: 说明:状态:CONNECTED/CONNECTED 9、NetworkStateTracker.java:updateNetworkSettings函数 说明:该函数从Network TCP buffer读取network设置参数,并设置网络 10、ConnectivityService.java:handleDnsConfigurationChange 说明:从dnsList里读取预设的dns 通过writePidDns设置dns 3.3 RILD源码分析 RIL对对消息的处理是将消息通过LocalSocket发送到以rild为名称的有名端口。这个有名Socket的创建在ril.cpp代码中。s_fdListen = android_get_control_socket(SOCKET_NAME_RIL) RILD是守护进程,执行的过程为:获取参数→打开功能库→建立事件循环→执行RIL_Init→RIL_register;事件循环式核心,通过Select多路复用机制,读取来自上层的Socket接口的具体操作命令,同时一些命令Timeout唤醒机制,也通过Select实现; 1. Request流程 命令下发流程:首先从JAVA层通过Socket将命令发送到RIL层的RILD守护进程,RILD中负责监听的ril_event_loop消息循环中的Select发现RILD Socket有了请求连接信号,建立一个record_stream,打通与上层的数据通道并开始接收请求数据,数据通道的回调函数processCommandsCallback()会保证收到一个完整的Request后,将其送达processCommandBuffer()函数; 解析过程:processCommandBuffer()从Socket中序列化的数据流里还原信息,将其组织到RequestInfo中;RequestInfo数据结构如下(存在于ril.cpp中): typedef struct RequestInfo { int32_t token; //this is not RIL_Token CommandInfo *pCI; struct RequestInfo *p_next; char cancelled; char local; // responses to local commands do not go back to command process } RequestInfo; RIL层以Request号为基础采用表驱动方式分发请求,CommandInfo结构表示命令的信息,关联了Request号和实际的请求函数,以及响应函数之间的关系; 分发流程:s_callback.onRequest()完成分发操作,s_callback获取自libreference-ril的RIL_RadioFunction结构指针,Request请求在这里转入底层的libreference-ril处理,handler是reference-ril.cpp中的Request。 onRequest根据Request号进行简单的switch分发,然后将命令和参数转换成对应的AT命令,由writeline()完成驱动层的发送,writeline通过驱动程序节点的文件描述符进行写操作实现控制。 2. Response流程 Response有两类:unsolicited表示主动上报的消息,如来电,来短信等,而solicited是AT命令的响应,判断是否是solicited的依据有两点:一是当前用AT命令正在等待响应;二是读取的响应符合该AT命令的响应格式。 对于Response流程来讲,流程是从Modem设备发回响应数据开始的。 RIL通过readerLoop函数,利用readline逐行读取响应数据,随后通过processLine进行分析,主动上报的一般以+XXXX的形式出现,而AT命令的响应格式则有一行或多行之分,但最终一定以OK或者ERROR结尾,于是PrcessLine有以下几种情况: 1)、没有AT命令等待响应或不符合AT响应格式,一般是主动上报行,由handleUnsolicited处理,handleUnsolicited→onUnsolicetd→RIL_onUnsolicitedResponse; 2)、isFinalResponseSucess/isFinalResponseError是最终响应行,转到handleFinalResponse处理,handleFInalResponse会发送线程同步信号,激活等到的发送线程; 3)、符合当前AT命令响应格式的行,解析并获取数据,这是响应处理的中间过程,然后继续收到最终响应行,然后进入2)流程 最后的发送动作由sendResponse→sendResponseRaw→blockingWrite通过Socket回传给上层来完成,响应解析由上层完成。 |
|
来自: arm_embed > 《Framework》