`

Android RIL 本地代码(c/c++) 和 Java代码部分分析

 
阅读更多
第一部分, c/c++代码



Android系统源代码目录里面: hardware/ril 目录包含了所有有关于telephony的底层代码.



1.目录架构(20101215的git版本):

ril

|-- CleanSpec.mk

|-- include

|   |-- telephony

|       |-- ril_cdma_sms.h                                              //CDMA SMS

|       |-- ril.h                                                    //Android RIL 框架的一些接口和数据结构

|-- libril

|   |-- Android.mk

|   |-- MODULE_LICENSE_APACHE2

|   |-- NOTICE

|   |-- ril_commands.h                                      //RIL命令列表

|   |-- ril.cpp                                                   

|   |-- ril_event.cpp

|   |-- ril_event.h

|   |-- ril_unsol_commands.h                            //RIL 主动上报信息列表

|-- reference-cdma-sms

|   |-- Android.mk

|   |-- reference-cdma-sms.c

|   |-- reference-cdma-sms.h

|-- reference-ril

|   |-- Android.mk

|   |-- atchannel.h                                             //负责向modem读写数据

|   |-- atchannel.c

|   |-- at_tok.h

|   |-- at_tok.c

|   |-- misc.h

|   |-- misc.c

|   |-- MODULE_LICENSE_APACHE2

|   |-- NOTICE

|   |-- reference-ril.c                                          //主要负责与modem进行交互

|-- rild

    |-- Android.mk

    |-- MODULE_LICENSE_APACHE2

    |-- NOTICE

    |-- radiooptions.c                                          //调试时配置Modem参数

    |-- rild.c                                                        //RIL守护进程



其中include/telephony目录下面的ril.h文件,定义了104个如下的宏:

         RIL_REQUEST_XXXX

这些宏代表客户进程向Android telephony发送的命令,包括SIM卡相关的功能,打电话,发短信,网络信号查询等等。



2.目录hardware/ril/libril

本目录下代码负责与客户进程进行交互。在接收客户进程命令后,调用相应函数进行处理,然后将命令响应结果传回客户进程。在收到来自网络端的事件后,也传给客户进程。



v  文件ril_commands.h:列出了telephony可以接收的命令;每个命令对应的处理函数;以及命令响应的处理函数。

v  文件ril_unsol_commands.h:列出了telephony可以接收的事件类型;对每个事件的处理函数;以及WAKEType???

v  文件ril_event.h/cpp:处理与事件源(端口,modem等)相关的功能。ril_event_loop监视所有注册的事件源,当某事件源有数据到来时,相应事件源的回调函数被触发(firePending-> ev->func())

v  文件ril.cpp:

?  RIL_register函数:打开监听端口,接收来自客户进程的命令请求(s_fdListen   =android_get_control_socket(SOCKET_NAME_RIL);),当与某客户进程连接建立时,调用listenCallback函数;创建一单独线程监视并处理所有事件源(通过ril_event_loop)

?  listenCallback函数:当与客户进程连接建立时,此函数被调用。此函数接着调用  processCommandsCallback处理来自客户进程的命令请求

?  processCommandsCallback函数:具体处理来自客户进程的命令请求。对每一个命令,ril_commands.h中都规定了对应的命令处理函数(dispatchXXX),processCommandsCallback会调用这个命令处理函数进行处理。

?  dispatch系列函数:此函数接收来自客户进程的命令己相应参数,并调用onRequest进行处理。

?  RIL_onUnsolicitedResponse函数:将来自网络端的事件封装(通过调用responseXXX)后传给客户进程。

?  RIL_onRequestComplete函数:将命令的最终响应结构封装(通过调用responseXXX)后传给客户进程。



?  response系列函数:对每一个命令,都规定了一个对应的response函数来处理命令的最终响应;对每一个网络端的事件,也规定了一个对应的response函数来处理此事件。response函数可被onUnsolicitedResponse或者onRequestComplete调用。



3. 目录hardware/ril/reference-ril分析:

本目录下代码主要负责与modem进行交互。

v  文件reference-ril.c:此文件核心是两个函数:onRequest和onUnsolicited

?  onRequest 函数:在这个函数里,对每一个RIL_REQUEST_XXX请求,都转化成相应的ATcommand,发送给modem,然后睡眠等待。当收到此ATcommand的最终响应后,线程被唤醒,将响应传给客户进程(RIL_onRequestComplete-> sendResponse)。

?  onUnsolicited函数:这个函数处理modem从网络端收到的各种事件,如网络信号变化,拨入的电话,收到短信等。然后将时间传给客户进程(RIL_onUnsolicitedResponse -> sendResponse)



v  文件atchannel.c:负责向modem读写数据。其中,写数据(主要是ATcommand)功能运行在主线程中,读数据功能运行在一个单独的读线程中。

?  at_send_command_full_nolock函数:运行在主线程里面。将一个ATcommand命令写入modem后进入睡眠状态(使用pthread_cond_wait或类似函数),直到modem读线程将其唤醒。唤醒后此函数获得了ATcommand的最终响应并返回。

?  readerLoop函数: 运行在一个单独的读线程里面,负责从modem中读取数据。读到的数据可分为三种类型:网络端传入的事件;modem对当前ATcommand的部分响应;modem对当前AT command的全部响应。对第三种类型的数据(ATcommand的全部响应),读线程唤醒(pthread_cond_signal)睡眠状态的主线程。







第二部分, Java代码



1.package简介:

Android中,telephony相关的java代码主要在下列目录中:

v  frameworks/base/telephony/java/android/telephony

提供Android telephony的公开接口,任何具有权限的第三方应用都可使用,如接口类TelephonyManager、SMSManager。

v  frameworks/base/telephony/java/com/android/internal/telephony

v  frameworks/base/services/java/com/android/server

提供一系列内部接口,目前第三方应用还不能使用。当前似乎只packages/apps/Phone能够使用.

v  packages/apps/Phone

目录packages/apps/Phone是一个特殊应用,或者理解为一个平台内部进程。其他应用通过intent方式调用这个进程的服务。

2.详细介绍

v  TelephonyManager(telephony/java/android/telephony/TelephonyManager.java)主要使用两个IBinder接口(AIDL接口)来访问telephony功能:

?  ITelephony, 提供与telephony进行操作,交互的接口,在packages/apps/Phone中由PhoneInterfaceManager.java实现。

?  ITelephonyRegistry,其提供一个通知机制,将一些底层状态或变更通知给电话服务的用户,如网络状态、信号强度等。它的服务实现在框架代码中,即:frameworks/base/services/java/com/android/server/TelephonyRegistry.java。

底层通知的来源是GSMPhone/CDMAPhone通过PhoneNotifier接口的实现者DefaultPhoneNotifier将具体的事件转化为函数调用,通知到TelephonyRegistry。TelephonyRegistry再通过两种方式通知用户:

§  Broadcast机制广播事件;

§  通过服务用户在TelephonyRegistry.java中注册的IPhoneStateListener接口,实现回调机制。注册函数是用户可见的:

TelephonyManager.listen();

->TelephonyRegistry.listen(,IPhoneStateListener callback,,);

v  接口PhoneNotifier定义电话事件的通知方法

v  类DefaultPhoneNotifier从PhoneNotifier派生而来。在其方法实现中,通过调用service ITelephonyRegistry来发布电话事件。

v  接口Phone描述了对电话的所有操作接口。 PhoneBase直接从Phone派生而来。而另外两个类,CDMAPhone和GSMPhone,又从PhoneBase派生而来,分别代表对CDMA和GSM的操作。

v  PhoneProxy也从Phone直接派生而来。当当前不需要区分具体是CDMA Phone还是GSMPhone时,可使用PhoneProxy。

备注:

在PhoneApp创建时,

sPhoneNotifier = new DefaultPhoneNotifier();

...

sCommandsInterface = newRIL(context, networkMode, cdmaSubscription);

然后根据当前phone是cdma还是gsm,创建对应的phone,如

sProxyPhone = newPhoneProxy(new GSMPhone(context,sCommandsInterface, sPhoneNotifier));





v  PhoneFactory.java: 获取电话实例,如GSMPhone/CDMAPhone.

PhoneFactory.makeDefaultPhones();

->PhoneFactory.makeDefaultPhone();//注册相应的Phone实例

                ->Phone phone = (Phone)PhoneFactory.getDefaultPhone();

v  接口IPhoneStateListener: 手机状态监听接口(AIDL),其服务实现在/frameworks/base/telephony/java/android/telephony/PhoneStateListener.java

v  接口CommandsInterface 描述了对电话的所有操作接口,如命令, 查询状态,以及电话事件监听等。



v  类BaseCommands是CommandsInterface的直接派生类,实现了电话事件的处理(发送message给对应的handler)。

v  类RIL又派生自BaseCommands。RIL负责实际实现CommandsInterface中的接口方法。RIL通过Socket和rild守护进程进行通讯。对于每一个命令接口方法,如acceptCall,或者状态查询,将它转换成对应的RIL_REQUEST_XXX,发送给rild。RIL中的几个类如下:

?  RILRequest:代表一个电话服务命令请求;

?  RIL.RILSender:负责处理命令的发送;

?  RIL.RELReceiver:负责处理命令相应以及主动上报信息的接受;线程RILReceiver监听socket,当有数据上报时,读取该数据并处理。读取的数据有两种。

§  电话事件,RIL_UNSOL_xxx, RIL读取相应数据后,发送message给对应的handler(详见函数processUnsolicited);

§  命令的异步响应。(详见函数processSolicited)

v  RILConstants.java : 定义了电话服务的具体命令。

v  抽象类Call代表一个call,有两个派生类CdmaCall和GsmCall。



第三部分, 流程分析



1.Outgoing Call流程。

v  TwelveKeyDialer.java

|_onKeyUp()

|_placeCall()

v  OutgoingCallBroadcaster.java,

|_onCreate()

|_sendOrderedBroadcast(broadcastIntent, PERMISSION,

new OutgoingCallReceiver(), null, Activity.RESULT_OK, number,null);

                        |_ OutgoingCallReceiver

                                    |_onReceive()

|_ doReceive()

|_context.startActivity(newIntent);

v  InCallScreen.java

|_ onCreate()

|_onNewIntent()

|_placeCall()

v  PhoneUtils.java

|_placeCall()

v  GSMPhone.java,

|_dial()

v  GsmCallTracker.java,

|_dial()

v  RIL.java

|_dial()

|_  RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);

     |...

     |send(rr);



2.    Incoming Call的流程:

v  创建GsmPhone时,mCT = new GsmCallTracker(this);

v  创建GsmCallTracker时:

?  cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE,null);

?  mCallStateRegistrants.add(r);

v  RIL中的RILReceiver线程首先读取从rild中传来的数据:

?  processResponse()

?  processUnsolicited()

v  对应于incoming call,RIL收到RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED消息,触发mCallStateRegistrants中的所有记录。

v  GsmCallTracker处理EVENT_CALL_STATE_CHANGE,调用pollCallsWhenSafe

v  函数pllCallsWhenSafe 处理:

§  lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);

§  cm.getCurrentCalls(lastRelevantPoll);

v  RIL::getCurrentCalls

§  RILRequestrr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS,result);

§  ...

§  send(rr);

v  接着RIL调用processSolicited处理RIL_REQUEST_GET_CURRENT_CALLS的返回结果

v  GsmCallTracker的handleMessage被触发,处理事件EVENT_POLL_CALLS_RESULT,调用函数 handlePollCalls

v  handlPollCalls 调用phone.notifyNewRingingConnection(newRinging);

v  PhoneApp中创建CallNotifier

v  CallNotifier注册:

§  registerForNewRingingConnection ->mNewRingingConnectionRegistrants.addUnique(h, what, obj);



第四部分, 参考文档



1.《Android系统原理及开发详解》

2. http:/www.meegozu.com/thread-391-1-1.html

3.    http://www.netmite.com/android/mydroid/development/pdk/docs/telephony.html

4.    http://wenku.baidu.com/view/8d57336aaf1ffc4ffe47ac75.html

5.    http:/wenku.baidu.com/view/ca78fabef121dd36a32d8258.html

备注
在PhoneApp创建时,

sPhoneNotifier = new DefaultPhoneNotifier();

...

sCommandsInterface = newRIL(context, networkMode, cdmaSubscription);

然后根据当前phone是cdma还是gsm,创建对应的phone,如

sProxyPhone = newPhoneProxy(new GSMPhone(context,sCommandsInterface, sPhoneNotifier));
分享到:
评论

相关推荐

    Android RIL 实现原理

    - **JNI (Java Native Interface)**:Java层通过JNI调用本地C/C++代码,进而与libril库交互。 - **TTY设备**:libril库通过TTY设备与rild进行通信。 - **设备驱动**:rild通过设备驱动与基带处理器通信。 - **其他...

    RIL_lib.rar_android_c builder android

    NDK允许开发者使用C和C++编写部分应用代码,尤其适用于性能要求高的底层模块如RIL。 4. **RIL库的开发**: 开发RIL库涉及以下步骤: - 阅读和理解RIL接口规范,如RILRequest.java和RILConstants.java。 - 编写C/...

    Android RIL深入解析.pdf

    Android RIL 的架构可以分为两个部分:RILJ 和 RILC。RILJ 是 Java 语言编写的,位于 Android 框架层中,负责处理上层应用程序的请求;RILC 是 C/C++ 语言编写的,位于 HAL 层中,负责与 MODEM 进行通信。 RILJ 和 ...

    安卓RIL代码

    这个目录包含了许多与RIL相关的Java和C/C++源文件,这些文件定义了RIL接口、处理RIL消息、解析AT命令响应等功能。例如,`RIL.java`是RIL的主要接口,它提供了诸如注册网络、发起呼叫、发送短信等方法。而`RILRequest...

    华为模块在android下集成RIL库文件试用2.x 3.x 4.x

    这些库文件通常包含C或C++编写的代码,用于与硬件通信,并通过Android的RIL抽象层提供服务。集成过程分为以下几个步骤: 1. **获取RIL库文件**:在本例中,RIL-V100R005B003D27SP00C03很可能是华为3G模块对应的一个...

    reference-ril.rar_RIL_android

    - **源代码**:RIL的Java源码,用于处理上层请求和事件,以及C/C++源码,用于与基带处理器交互。 - **配置文件**:针对特定Quectel模块的配置文件,定义了RIL如何与模块通信的细节。 - **库文件**:编译后的动态链接...

    Android平台呼叫流程框架分析

    RIL的设计遵循分层原则,主要由Java层和C/C++层组成。其中,Java层负责与上层应用交互,而C/C++层则直接与底层硬件通信。 - **Java层**:这部分主要包括TelephonyManager类,它提供了用于管理电话设备的API,比如...

    android代码结构分析

    1. **Base**:这是Android框架的核心部分,包含了基础的Java和C++实现。其中,API子目录存储的是XML文件,用于定义Java API的版本信息,这些信息对开发者编写兼容不同Android版本的应用至关重要。 2. **Cmds**:...

    Android RIL使用详解

    前言 Android作为一个通用的移动平台,其首要的功能就是通话、短信以及上网等通信功能。那么,从系统的角度来看,...RIL C++(RILD): 系统守护进程,负责将RILJ的请求命令发送给CP(Communication Processor) 什么是RI

    Android_中添加_AT_命令流程.doc

    需要注意的是,整个过程中涉及到多个层次的代码实现,从上层的Java代码到底层的C/C++代码,每一个步骤都需要仔细考虑和实现。此外,为了保证系统的稳定性和兼容性,还需要对新增加的功能进行充分的测试。

    华为通用referenc-ril

    5. **源代码结构**:通常,RIL的源代码包括Java代码(用户空间的RIL守护进程)和C/C++代码(内核空间的驱动)。Java部分主要处理与Android系统的交互,而C/C++部分则与硬件通信。 通过研究huaweigeneric-ril,...

    android系统原理及开发要点详解

     第5章“Android的Java虚拟机和Java环境”,这是介于本地和Java层之间的相关内容,主要介绍Android的Java虚拟机Dalvik的基本概念、Android Java程序的环境、JNI的使用方法,以及Java框架的启动流程等。  第6章...

    RIL时序图.zip

    RIL(Radio Interface Layer,无线接口层)是Android操作系统中通信子系统的关键组成部分,主要负责设备与基带处理器之间的通信。在移动设备中,RIL是操作系统与物理无线电硬件之间的桥梁,它允许操作系统通过标准...

    ril.tar.gz

    3. **接口定义**:RIL提供了Java和C++的API接口,供上层应用和服务调用。 4. **配置文件**:包含了设备特定的RIL配置,如网络频段、调制解调器命令集等。 5. **测试工具和脚本**:为了调试和验证RIL功能,通常会包含...

    android 完全中文版 开发应用详解

    第5章 android的java虚拟机和java环境 88 5.1 dalvik虚拟机和核心库 88 5.1.1 dex工具库和虚拟机的实现 89 5.1.2 核心库 90 5.1.3 nativehelper库 91 5.2 android的java程序环境 91 5.2.1 java类的层次结构 91 5.2.2...

    Android软件流程之App&&Framework&&Ril借鉴.pdf

    首先,RIL(Radio Interface Layer)位于Android的Framework层之下,主要用C语言编写,部分采用C++实现。它的核心职责是确保数据的可靠传输,发送和处理来自上层的命令,以及解析响应信息。RIL不仅管理网络连接,还...

    深入理解Android:卷I--详细书签版

    looper类,掌握这些类的知识后方能在后续的代码分析中做到游刃有余;第6章以mediaserver为切入点,对android中极为重要的binder进行了较为全面的分析,深刻揭示了其本质。第7章对 audio系统进行了深入的分析,尤其...

    Android 提高篇 机制 分析

    分析了Java层中的RIL实现,包括其与C/C++层的交互。 #### 十九、电话系统之GSMCallTacker 详细研究了GSM呼叫跟踪器的工作原理及其与电话系统其他部分的交互。 #### 二十、Android应用程序框架之无边界设计意图 ...

Global site tag (gtag.js) - Google Analytics