Android電話功能各部分深入探討
Android手機(jī)操作系統(tǒng)是一款基于Linux平臺的開源系統(tǒng)。開發(fā)人員可以根據(jù)不同的需求對其進(jìn)行修改等操作。在這系統(tǒng)中有很多比較重要的功能值得我們?nèi)パ芯?。比如Android電話功能就是其中一個基礎(chǔ)知識點(diǎn)。#t#
第一部分 Android電話功能概述
Android的Radio Interface Layer (RIL)提供了電話服務(wù)和的radio硬件之間的抽象層。
Radio Interface Layer RIL(Radio Interface Layer)負(fù)責(zé)數(shù)據(jù)的可靠傳輸、AT命令的發(fā)送以及response的解析。應(yīng)用處理器通過AT命令集與帶GPRS功能的無線通訊模塊通信。
AT command由Hayes公司發(fā)明,是一個調(diào)制解調(diào)器制造商采用的一個調(diào)制解調(diào)器命令語言,每條命令以字母"AT"開頭。
JAVA Framework
代碼的路徑為:
- frameworks/base/telephony/java/android/telephony
- android.telephony以及android.telephony.gsm
Core native:
在hardware/ril目錄中,提供了對RIL支持的本地代碼,包括4個文件夾:
- hardware/ril/include
- hardware/ril/libril
- hardware/ril/reference-ril
- hardware/ril/rild
kernel Driver
在Linux內(nèi)核的驅(qū)動中,提供了相關(guān)的驅(qū)動程序的支持,可以建立在UART或者SDIO,USB等高速的串行總線上。
第二部分 Android電話功能各個部分
hardware/ril/include/telephony/目錄中的ril.h文件是ril部分的基礎(chǔ)頭文件。
其中定義的結(jié)構(gòu)體RIL_RadioFunctions如下所示:
- typedef struct {
- int version;
- RIL_RequestFunc onRequest;
- RIL_RadioStateRequest onStateRequest;
- RIL_Supports supports;
- RIL_Cancel onCancel;
- RIL_GetVersion getVersion;
- } RIL_RadioFunctions;
RIL_RadioFunctions中包含了幾個函數(shù)指針的結(jié)構(gòu)體,這實(shí)際上是一個移植層的接口,下層的庫實(shí)現(xiàn)后,由rild守護(hù)進(jìn)程得到這些函數(shù)指針,執(zhí)行對應(yīng)的函數(shù)。
幾個函數(shù)指針的原型為:
- typedef void (*RIL_RequestFunc) (int request, void *data,
- size_t datalen, RIL_Token t);
- typedef RIL_RadioState (*RIL_RadioStateRequest)();
- typedef int (*RIL_Supports)(int requestCode);
- typedef void (*RIL_Cancel)(RIL_Token t);
- typedef const char * (*RIL_GetVersion) (void);
其中最為重要的函數(shù)是onRequest(),它是一個請求執(zhí)行的函數(shù)。
2.1 rild守護(hù)進(jìn)程
rild 守護(hù)進(jìn)程的文件包含在hardware/ril/rild目錄中,其中包含了rild.c和radiooptions.c兩個文件,這個目錄中的文件經(jīng)過編譯后生成一個可執(zhí)行程序,這個程序在系統(tǒng)的安裝路徑在:
- /system/bin/rild
rild.c是這個守護(hù)進(jìn)程的入口,它具有一個主函數(shù)的入口main,執(zhí)行的過程是將請求轉(zhuǎn)換成AT命令的字符串,給下層的硬件執(zhí)行。在運(yùn)行過程中,使用dlopen 打開路徑為/system/lib/中名稱為libreference-ril.so的動態(tài)庫,然后從中取出 RIL_Init符號來運(yùn)行。
RIL_Init符號是一個函數(shù)指針,執(zhí)行這個函數(shù)后,返回的是一個RIL_RadioFunctions類型的指針。得到這個指針后,調(diào)用RIL_register()函數(shù),將這個指針注冊到libril庫之中,然后進(jìn)入循環(huán)。
事實(shí)上,這個守護(hù)進(jìn)程提供了一個申請?zhí)幚淼目蚣?,而具體的功能都是在libril.so和libreference-ril.so中完成的。
2.2 libreference-ril.so動態(tài)庫
libreference-ril.so動態(tài)庫的路徑是:
- hardware/ril/reference-ril
其中Android電話功能主要的文件是reference-ril.c和atchannel.c。這個庫必須實(shí)現(xiàn)的是一個名稱為RIL_Init的函數(shù),這個函數(shù)執(zhí)行的結(jié)果是返回一個RIL_RadioFunctions結(jié)構(gòu)體的指針,指針指向函數(shù)指針。
這個庫在執(zhí)行的過程中需要創(chuàng)建一個線程來執(zhí)行實(shí)際的功能。在執(zhí)行的過程中,這個庫將打開一個/dev/ttySXXX的終端(終端的名字是從上層傳入的),然后利用這個終端控制硬件執(zhí)行。
2.3 libril.so動態(tài)庫
libril.so庫的目錄是:
- hardware/ril/libril
其中主要的文件為ril.cpp,這個庫主要需要實(shí)現(xiàn)的以下幾個接口為:
- RIL_startEventLoop(void);
- void RIL_setcallbacks (const RIL_RadioFunctions *callbacks);
- RIL_register (const RIL_RadioFunctions *callbacks);
- RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response,
size_t responselen);- void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
- size_t datalen);
- RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
- const struct timeval *relativeTime);
這些函數(shù)也是被rild守護(hù)進(jìn)程調(diào)用的,不同的vendor可以通過自己的方式實(shí)現(xiàn)這幾個接口,這樣可以保證RIL可以在不同系統(tǒng)的移植。其中 RIL_register()函數(shù)把外部的RIL_RadioFunctions結(jié)構(gòu)體注冊到這個庫之中,在恰當(dāng)?shù)臅r候調(diào)用相應(yīng)的函數(shù)。在Android電話功能執(zhí)行的過程中,這個庫處理了一些將請求轉(zhuǎn)換成字符串的功能。