当前位置:文档之家› data_connect

data_connect

Data Connect 流程分析
Android 的数据连接是基于PPP 方式的,主要步骤为:首先通过AT 命令激活PDP 连接,然后利用pppd 通过数据端口完成拨号连接;

数据连接的核心控制类是DataConnectionTracker ,存在于GSMPhone 里,数 据连接不需要用户的干预,在 APN 设置好之后,在适当的情况下就会自动激活,激活的入口点是: DataConnectionTracker.trySetupDat a → setupDat a → PdpConnection.connet c →CommandsInterface.setupDefaultPDP, 通过PdpConnection 访问GSMPhone 中的RIL 层的setupDefaultPDP 实现,setupDefaultPDP 的结果由EVENT_SETUP_PDP_DONE 返回,如果成功,则开始调用pppd 完成实际连接,这是通过DataLink.connect 实现的;

DataLink 只是抽象基类,此处它的实现类是PppLink ,实现DataLinkInterface 接口,所以DataLink.connect 实际上调用PppLink.connect ,它通过SystemService.start (SERVICE_PPPD_GPRS )开始pppd 服务,并通过checkPPP 函数访问Linux 的sys 文件系统来查询pppd 的连接状态,如果成功,便可以将LINKUP 的消息通知出去以完成连接流程。


3 APN 流程分析
接入点使用在我看来主要包括接入点的创建、接入点的切换以及接入点的删除三个方面,我们下面按照android 源码,按照程序调用的先后顺序依次分析其流程;

3.1 Create New APN 流程分析
Android 因为是以事件驱动的,因此在诸如接入点设置这样的操作的时候,都是从按键触发事件开始的:Activity.java 里的onKeyDown 函数;由于是基于EVENT 驱动的,因此在每一个动作的时候都会触发一定Type 的Message ,因此对于源代码流程的分析也比较有利;

Create New APN 的过程主要就是APN 如name 、port 、proxy 等的添加以及在设置的过程里状态的切换等;

一、下面为这个过程里JAVA Framework 调用的过程:

1 、 ActivityManagerService.java:startActivity :

说明:界面跳转,使用隐式的界面跳转,这个过程是基于事件的,在Android 中,传递数据使用Intent ,Intent 相当于各个Activity 之间的桥梁,可以传递数据,可以通过Intent 启动另外一个Activity 。Intent 有显式和隐式之分,显式的是直接什么要启动的组件,比如Service 或者Activity ,隐式的通过配置的datatype 、url 、action 来找到匹配的组件启动。

2 、telephony/TelephonyProvider.java :insert 函数:

说明:通过对URL 的s_urlMatcher.match ,URL_TELEPHONY 宏的处理,对Name ,APN 等的检查和容错

3 、MobileDataStateTracker.java :MobileDataStateReceiver 函数

说明:这个是这部分处理的一个核心函数,该函数的一个实现为onReceive (),在此函数里对于APN 的各种参数如Type (isApnTypeIncluded(apnTypeList) )以及状态state 进行判断和转换,在这个时候,状态的切换为:old

=CONNECTED and new state=DISCONNECTED

4 、ConnectivityService.java :handleMessage ()函数

说明:由于系统本身就是事件驱动的,因此这个handleMessage 被调用来完成network state 状态的改变:DISCONNECTED/DISCONNECTED ,并且在这个函数实现了WIFI 接入点有关判断;

5 、GpsLocationProvider.java:updateNetworkState 函数

说明:GPS 状态的更新

6 、MobileDataStateTracker.java :MobileDataStateReceiver ()函数:

说明:类似(3 ),只是状态切换变为:state= CONNECTING, old= DISCONNECTED, reason= apnChanged

7 、NetworkStateTracker.java :setDetailedState ()函数

说明:该函数记录网络状态的改变,并在改变的时候发送一个notify 事件:

Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);

8 、ConnectivityService.java :handleMessage ()函数:

说明:类似(4 ),状态:CONNECTING/CONNECTING

9 、Checkin.java :updateStats 函数:

说明:update statistics in the database

10 、MobileDataStateTracker.java :MobileDataStateReceiver

说明:处理在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: https://www.doczj.com/doc/1e9761390.html,ng.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 回传给上层来完成,响应解析由上层完成。



本文来自CSDN博客,转载请标明出处:https://www.doczj.com/doc/1e9761390.html,/zhaohc_nj/archive/2010/09/02/5858755.aspx

相关主题
相关文档 最新文档