当前位置:   article > 正文

Android APN开发流程分析(一)_android apn 拨号上网流程

android apn 拨号上网流程

2 Data Connect流程分析

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

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

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

 

3 APN流程分析

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

3.1 Create New APN流程分析

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

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

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

1 ActivityManagerService.java:startActivity

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

2telephony/TelephonyProvider.javainsert函数:

说明:通过对URL s_urlMatcher.matchURL_TELEPHONY宏的处理,对NameAPN等的检查和容错

3MobileDataStateTracker.javaMobileDataStateReceiver函数

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

4ConnectivityService.javahandleMessage()函数

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

5GpsLocationProvider.java:updateNetworkState函数

说明:GPS状态的更新

6MobileDataStateTracker.javaMobileDataStateReceiver()函数:

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

7NetworkStateTracker.javasetDetailedState()函数

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

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

8ConnectivityService.javahandleMessage()函数:

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

9Checkin.javaupdateStats函数:

说明:update statistics in the database

10MobileDataStateTracker.javaMobileDataStateReceiver

说明:处理在onReceive里,状态为:state= CONNECTED, old= CONNECTING, reason= apnChanged

11NetworkStateTracker.javasetDetailedState()函数

说明:(7),状态:old =CONNECTING and new state=CONNECTED

12NetworkStateTracker.java:updateNetworkSettings函数

说明:该函数从Network TCP buffer读取network设置参数,并设置网络

13ConnectivityServicejavahandleDnsConfigurationChange

说明:从dnsList里读取预设的dns 通过writePidDns设置dns

二、下面分析RIL Java层的处理:

该部分的核心实现存在于Ril.java以及GsmDataConnectionTracker.java之中,Ril.javaRIL.RILSender负责处理命令的发送,RIL.RILReceiver用于处理命令响应以及主动上报信息的接收;

Ril.Java中一个命令发送的流程为:RILRequest.obtain(命令ID)→复制参数→通过Send()函数发送EVENT_SEND→在RILSender线程中处理EVENT_SEND→将命令写到out streamsocket);

Ril.java响应和主动上报消息的流程为:RILReceiver线程监视mSocket inputreadMessage(读取完整响应)→processReponse→分别处理RESPONSE_UNSOLICITED(主动上报)与REPONSE_SOLICITED(命令响应)

RILD守护进程里的Request都是由RIL.java发起

3.2 APN 切换流程分析

1ApnPreference.java: onCheckedChanged

说明:检查接入点切换的ID是否合法

2MobileDataStateTracker.javaMobileDataStateReceiver

说明:处理在onReceive里,状态为:state= DISCONNECTED, old= CONNECTED

3ConnectivityService.javahandleMessage()函数:

说明:状态:DISCONNECTED/DISCONNECTED

4ActivityThread.javagetProvider

说明:ActivityThread.javaapp里的一个实例,在main里创建了一个thread,在getProvider   holder = ActivityManagerNative.getDefault().getContentProvider(getApplicationThread(), name);进行了判断

5Checkin.javaupdateStats函数:

说明: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的错误

6MobileDataStateTracker.javaMobileDataStateReceiver

说明:处理在onReceive里,state= CONNECTED, old= CONNECTING

7NetworkStateTracker.javasetDetailedState()函数

说明:状态:old =CONNECTING and new state=CONNECTED

8ConnectivityService.javahandleMessage()函数:

说明:状态:CONNECTED/CONNECTED

9NetworkStateTracker.java:updateNetworkSettings函数

说明:该函数从Network TCP buffer读取network设置参数,并设置网络

10ConnectivityService.javahandleDnsConfigurationChange

说明:从dnsList里读取预设的dns 通过writePidDns设置dns

 

3.3 RILD源码分析

RIL对对消息的处理是将消息通过LocalSocket发送到以rild为名称的有名端口。这个有名Socket的创建在ril.cpp代码中。s_fdListen = android_get_control_socket(SOCKET_NAME_RIL)

RILD是守护进程,执行的过程为:获取参数→打开功能库→建立事件循环→执行RIL_InitRIL_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-rilRIL_RadioFunction结构指针,Request请求在这里转入底层的libreference-ril处理,handlerreference-ril.cpp中的Request

onRequest根据Request号进行简单的switch分发,然后将命令和参数转换成对应的AT命令,由writeline()完成驱动层的发送,writeline通过驱动程序节点的文件描述符进行写操作实现控制。

2.   Response流程

Response有两类:unsolicited表示主动上报的消息,如来电,来短信等,而solicitedAT命令的响应,判断是否是solicited的依据有两点:一是当前用AT命令正在等待响应;二是读取的响应符合该AT命令的响应格式。

对于Response流程来讲,流程是从Modem设备发回响应数据开始的。

RIL通过readerLoop函数,利用readline逐行读取响应数据,随后通过processLine进行分析,主动上报的一般以+XXXX的形式出现,而AT命令的响应格式则有一行或多行之分,但最终一定以OK或者ERROR结尾,于是PrcessLine有以下几种情况:

1)、没有AT命令等待响应或不符合AT响应格式,一般是主动上报行,由handleUnsolicited处理,handleUnsolicitedonUnsolicetdRIL_onUnsolicitedResponse

2)、isFinalResponseSucess/isFinalResponseError是最终响应行,转到handleFinalResponse处理,handleFInalResponse会发送线程同步信号,激活等到的发送线程;

3)、符合当前AT命令响应格式的行,解析并获取数据,这是响应处理的中间过程,然后继续收到最终响应行,然后进入2)流程

最后的发送动作由sendResponsesendResponseRawblockingWrite通过Socket回传给上层来完成,响应解析由上层完成。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/988263
推荐阅读
相关标签
  

闽ICP备14008679号