




已閱讀5頁,還剩80頁未讀, 繼續免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
Android的電話功能介紹整個RIL文件夾的分析介紹本文檔對Android RIL部分的內容進行了介紹,其重點放在了Android RIL的原生代碼部分。包括四個主題:1.Android RIL框架介紹2.Android RIL與WindowsMobile RIL3.Android RIL porting4.Android RIL的java框架在本文檔中將Android代碼中的重要模塊列出進行分析,并給出了相關的程序執行流程介紹,以加深對模塊間交互方式的理解。對于java代碼部分,這里僅進行簡單的介紹。如果需要深入了解,可以查看相關參考資料。本文檔中還對Android RIL的Porting部分內容進行了描述和分析。針對對unix操作系統環境并不熟悉的讀者,本文檔中所涉及到的相關知識包括: Unix file system Unix socket Unix thread Unix下I/O多路轉接以上信息可以在任意一份描述Unix系統調用的文檔中找到。1.Android RIL框架介紹術語:fd Linux文件描述符pipe Linux管道cond 一般是condition variable的縮寫tty 通常使用tty來簡稱各種類型的終端設備unsolicited response 被動請求命令來自basebandevent loop android的消息隊列機制,由Linux的系統調用select()實現init.rc init守護進程啟動后被執行的啟動腳本。HAL 硬件抽象層(Hardware Abstraction Layer,HAL)1.1 Android RIL概況Android RIL提供了無線硬件設備與電話服務之間的抽象層。下圖展示了RIL在Android體系中的位置。android的ril位于應用程序框架與內核之間,分成了兩個部分,一個部分是rild,它負責socket與應用程序框架進行通信。另外一個部分是Vendor RIL,這個部分負責向下是通過兩種方式與radio進行通信,它們是直接與radio通信的AT指令通道和用于傳輸包數據的通道,數據通道用于手機的上網功能。對于RIL的java框架部分,也被分成了兩個部分,一個是RIL模塊,這個模塊主要用于與下層的rild進行通信,另外一個是Phone模塊,這個模塊直接暴露電話功能接口給應用開發用戶,供他們調用以進行電話功能的實現。1.2 Android RIL目錄結構Android的RIL模塊位于Android/hardware/ril文件夾,有三個子模塊:rild , libril , reference-ril所在目錄結構:/hardware/ril/|- ril (無線電抽象層)| |- include (頭文件)| |- libril (庫)| |- reference-cdma-sms (cdma短信參考)| |- reference-ril (ril參考)| |- rild (ril后臺服務程序)hardware/ril$ lsincludelibrilreference-cdma-smsreference-rilrild1.hardware/ril/rild$ lsAndroid.mk MODULE_LICENSE_APACHE2 NOTICEradiooptions.crild.c2.hardware/ril/include/telephony$ lsril_cdma_sms.hril.h3.hardware/ril/libril$ lsAndroid.mk NOTICEril_event.hril.cppril_event.cpp ril_commands.hril_unsol_commands.hMODULE_LICENSE_APACHE24.hardware/ril/reference-cdma-sms$ lsAndroid.mk reference-cdma-sms.c reference-cdma-sms.h5.hardware/ril/reference-ril$ lsAndroid.mk atchannel.h at_tok.h misc.h NOTICEatchannel.cat_tok.cril_event.hreference-ril.c misc.c MODULE_LICENSE_APACHE2include文件夾:包含RIL頭文件,最主要的是ril.hrild文件夾:RIL守護進程,開機時被init守護進程調用啟動,里面僅有main函數作為入口點,負責完成RIL初始化工作。在rild.c文件中,將完成ril的加載過程,它會執行如下操作:動態加載Vendor RIL的.so文件執行RIL_startEventLoop()開啟消息隊列以進行事件監聽通過執行Vendor RIL的rilInit()方法來進行Vendor RIL與libril的關系建立。在rild文件夾中還包括一個radiooptions.c文件,它的作用是通過串口將一些radio相關的參數直接傳給rild來對radio進行配置。libril文件夾:在編譯時libril被鏈入rild,它為rild提供了event處理功能,還提供了在rild與Vendor RIL之間傳遞請求和響應消息的能力。Libril提供的主要功能分布在兩個主要方法內,一個是RIL_startEventLoop()方法,另一個是RIL_register()方法RIL_startEventLoop()方法所提供的功能就是啟用eventLoop線程,開始執行RIL消息隊列。RIL_register()方法的主要功能是啟動名為 rild 的監聽端口,等待java 端通過socket進行連接。reference-ril文件夾:Android自帶的Vendor RIL的參考實現。被編譯成.so文件,由于本部分是廠商定制的重點所在。所以被設計為松散耦合,且可靈活配置的。在rild中通過opendl()的方式加載。librefrence.so負責直接與radio通信,這包括將來自libril的指令轉換為AT指令,并且將AT指令寫入radio中。reference-ril會接收調用者傳來的參數,參數內容為與radio的通信方式。如通過串口連接radio,那么參數為這種形式:-d /dev/ttySx1.3.Android RIL中的消息(event)隊列機制 在Android RIL中,為了達到等待多路輸入并且不出現阻塞的目的,使用了IO多路復用機制。 如果使用阻塞I/O進行網絡的讀取寫入,這意味著假如需要同時從兩個網絡文件描述符中讀內容,那么如果讀取操作在等待網絡數據到來,這將可能很長時間阻塞在一個描述符上,另一個網絡文件描述符不管有沒有數據到來都無法被讀取。一種解決方案是: 如果使用非阻塞I/O進行網絡的讀取寫入,在讀取其中一個網絡文件描述符如果阻塞將直接返回,再讀取另外一個,這種方式的循環被稱之為輪詢。輪詢方式確實能解決進行多路io操作時的阻塞問題,但是這種方法的不足之處是反復的執行讀寫調用將浪費cpu時鐘。I/O多路轉接技術在這里提供了另一種比較好的解決方案: 它會先構造一張有關I/O描述符的列表,然后調用select函數,當IO描述符列表中的一個描述符準備好進行I/O時,該函數返回,并告知可以讀或寫哪個描述符。 Android RIL中消息隊列的核心實現思想就是這種I/O多路轉接技術。消息隊列機制的實現在ril_event.cpp中,其中被定義的ril_event結構是消息的主體。 每個ril_event結構,與一個fd句柄綁定(可以是文件,socket,管道等),并且帶一個func指針,這個func指針所指的函數是個回調函數,它指定了當所綁定的fd準備好進行讀取時所要進行的操作。 消息隊列的開始點為RIL_startEventLoop函數。RIL_startEventLoop在ril.cpp中實現,它的主要目的是通過pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL)建立一個dispatch線程,線程入口點在eventLoop. 而在eventLoop中,會調ril_event.cpp中的ril_event_loop()函數,建立起消息隊列機制。 ril_event是一個帶有鏈表行為的struct,它最主要的成員一個是fd,一個是func:struct ril_event struct ril_event *next;struct ril_event *prev;int fd;int index;bool persist;struct timeval timeout;ril_event_cb func;void *param; 初始化一個新ril_event的操作是通過ril_event_set()來完成的,并通過ril_event_add()加入到消息隊列之中,add會把隊列里所有ril_event的fd,放入一個fd集合readFds中。這樣 ril_event_loop能通過一個多路復用I/O的機制(select)來等待這些fd。在進入ril_event_loop()之前,在eventLoop中已經創建和掛入了s_wakeupfd_event,它是通過pipe的機制實現的,這個管道fd的回調函數并沒有實現什么功能,它的目的只是為了讓select方法能返回一次,這樣select()方法就能重新跟蹤新加入事件隊列的fd和timeout設置。所以在添加新fd到eventLoop時,往往不是直接調用ril_event_add,實際通常用rilEventAddWakeup來添加,這個方法除了會間接調用ril_event_add外,還會調用triggerEvLoop()函數來向s_fdWakeupWrite中寫入一個空字符,這樣select()函數會返回并重新執行,新加入的文件描述符便得以被select()加載并跟蹤。如果在ril_event隊列中任何一個fd已經準備好,則進入分析流程:processTimeouts(),processReadReadies(&rfds, n),firePending()其中firePending()方法執行這個event的func,也就是回調函數。 在Android RIL初始化完成后,將有幾個event被掛入到eventLoop中:1.s_listen_event:名為rild的socket,主要requeset & response通道2.s_debug_event:名為rild-debug的socket,調試用requeset & response通道3.s_wakeupfd_event:無名管道,用于隊列主動喚醒 這其中最為重要的event就是s_listen_event,它作為request與response的通道實現。在ril_event.cpp中還持有一個watch_table數組,一個timer_list鏈表和一個pending_list鏈表。watch_table數組的目的很單純,存放當前被eventLoop等待的ril_event(非timer event),供eventLoop喚醒時使用。timer_list是存放timer event的鏈表,在eventLoop喚醒時要對這些timer event單獨進行處理pending_list:待處理(對其回調函數進行調用)的所有ril_event的鏈表。1.4.Android RIL中初始化流程分析Rild的初始化流程初始化流程從rild.c中的main函數開始,它被init守護進行調用執行:首先在main()函數內會首先通過dlopen()函數加載Vendor RIL(在自帶的參考實現中為librefrence_ril.so)。接著調用RIL_startEventLoop()函數來啟動消息隊列機制。調用librefrence_ril.so的RIL_Init()函數來進行Vendor RIL的初始化。RIL_Init()函數執行后會返回一個RIL_RadioFunction結構體,這個結構體內最重要的成員就是onRequest()方法。onRequest()方法會被dispatchFunction調用,也就是說dispatchFunction調用是程序流從rild轉入Vendor RIL的分界點。RIL_register()函數將實現兩個目地,一個是將RIL_INIT中獲得的RIL_RadioFunction進行注冊,rild通過此種方式保證自己持有一個RIL_RadioFunction實例,第二個是將s_fdListen加入到消息隊列機制中,開啟s_fdListen的事件監聽。Vendor RIL的初始化流程:RIL_Init被調用后首先通過參數獲取硬件接口的設備文件或模擬硬件接口的socket。(參見上文中對reference-ril文件夾的介紹)接下來是創建mainLoop線程,并跳入到線程內執行。mainLoop會建立起與硬件的通信,然后通過read方法阻塞等待硬件的主動上報或響應。mainLoop還會調用initlizeCallBack()函數來向radio發送一系列的AT命令來進行radio的初始化設置工作。1.5.Android RIL中request流程分析 上層應用開始向rild通過socket傳輸數據時,通過RIL消息隊列機制,s_listen_event的回調函數listenCallBack將會被調用,開始進行數據流的分析與處理。接下來s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen),獲取傳入的socket描述符,也就是上層的java RIL傳入的連接。然后,通過record_stream_new()建立起一個RecordStream, 將這個record_stream與s_fdCommand綁定, RecordStream實際上是一個用于存放數據的結構體,這個結構體提供了一些操作類來保證這個RecordStream所綁定的文件描述符被讀取時里面的數據會被完整讀取。一旦s_fdCommand中有數據,它的回調函數processCommandsCallback()將會被調用,processCommandsCallback()通過record_stream_get_next阻塞讀取s_fdCommand上發來的 數據, 直到收到一完整的request。然后將其傳遞進processCommandBuffer()函數,processCommandBuffer()正式進入了命令的解析部分。每個接收到的命令將以RequestInfo的形式存在。從socket過來的數據流,是Parcel處理過的序列化字節流, 在這里會通過反序列化的方法提取出來。最前面的是request號, 以及token域(request的遞增序列號)。request號是一個CommandInfo,它在ril_command.h中定義。接下來, 這個RequestInfo會被掛入pending的request隊列, 執行具體的dispatchFunction(), 進行詳細解析。dispatchFunction方法有著多種實現,如dispatchVoid, dispatchString, 它們的調用取決于Parcel的參數傳入形式。比如說在dispatchDial方法中,Parcel對象將被解析為RIL_Dial結構。這是disptachFunction的任務之一,它的另一個任務就是調用onRequest()方法,并將解析的內容傳入onRequest()方法。從onRequest方法開始,程序控制流脫離了RILD,進入到了Vendor RIL中。onRequest方法會通過傳入的請求類型來調用指定的request()方法,request()方法則負責組裝AT指令并下發給at_send_command()方法集合中的一個,這個方法集合提供了針對不同類型AT指令的實現,如單行AT指令at_send_command_singleline(),短信息指令at_send_command_sms()等。最后,執行at_send_command_full(),再通過一個互斥的at_send_command_full_nolock()調用,完成最終的寫出操作,在writeline()中,寫出到初始化時打開的設備中。需要注意的是:at_send_command_full_nolock()在將指令寫入radio后并不會直接返回,而是通過條件變量等待響應信息,得到響應信息后會攜帶這些信息返回。具體流程可以參考下面的response流程分析。1.6.Android RIL中response流程分析AT的response有兩種,一種是unsolicited。另一種是普通response,也就是命令的響應。response信息的獲取在readerLoop()中。由readline()函數讀取上來。讀取到的line將被傳入processLine()函數進行解析,processLine()函數首先會判斷當前的響應是主動響應還是普通響應,如果是主動響應,將調用handleUnsolicited()函數,如果為普通響應,那么將調用handleFinalResponse()函數進行處理對響應串的主要的解析過程,由at_tok.c中的各種解析函數完成,提供字符串分析解析功能。對主動上報的解析 handleUnsolicited ()方法處理主動上報,它會調用onUnsolicited()來進行進一步的解析,這個函數在Vendor-RIL初始化時被傳入at_open()函數,onUnsolicited只解析出頭部(一般是+XXXX的形式),然后按類型決定下一步操作,操作為 RIL_onUnsolicitedResponse和RIL_requestTimedCallback兩種。在RIL_onUnsolicitedResponse()函數中,通過Parcel傳遞,將 RESPONSE_UNSOLICITED,unsolResponse(request號)寫入Parcel,然后調用對應的responseFunction完成進一步的的解析,將解析的數據寫入Parcel中,最后通過sendResponse()sendResponseRaw()blockingWrite()writeLine()將數據寫回給與應用層通信的socket。在RIL_requestTimedCallback()函數中。通過event機制實現的timer機制,回調對應的內部處理函數。通過internalRequestTimedCallback將回調添加到event循環,最終完成callback上掛的函數的回調。比如 pollSIMState,onPDPContextListChanged等回調, 不用返回上層,內部處理就可以。對普通上報的解析 IsFinalResponse()和isFinalResponseError()所處理的是一條AT指令的響應上報,它們將轉入handleFinalResponse方法。 handleFinalResponse()函數會將所有響應信息裝入sp_response,這是一個ATResponse結構,它的成員包括成功與否(success)以及一個中間結果(p_intermediates)。handleFinalResponse()在將響應結果保存至sp_response后,設置s_commandcond這一條件變量,此條件變量由at_send_command_full_nolock等待。 at_send_command_full_nolock獲得到了完整的響應信息(在sp_response中),便開始進行響應信息的處理,最后由RIL_onRequestComplete將響應數據序列化并通過sendResponse傳遞至與應用層通信的socket,這一部分與RIL_onUnsolicitedResponse()函數的功能非常相似,請參考對主動上報的解析部分。2.Android RIL與WindowsMobile RIL Android RIL與WindowsMobile RIL 在設計思路上都是作為一個radio的抽象,為上層提供電話服務,但在實現方式上兩者有著一定的差異,這種差異的產生主要是源自操作系統機制的不同。Android RIL被實現為HAL,相對于windows mobile中被實現為驅動的方式,Android RIL模塊的內聚性更為理想,可維護性也將更強,你也可以把Android Ril 看做一個中間件。Android RIL部分的開發工作,只需要拿到相應的radio文件描述符,就可以進行操作,無需關注radio的I/O驅動實現。2.1兩者在與應用通信上的實現對比 WindowsMobile RIL在實現與應用的通信時提供了RIL Proxy,在這個層面中它定義了大量的RIL_*()函數來作為電話服務請求。這一點與Android RIL的實現比較相似,Android RIL中在ril.h內提供了一系列的宏來定義電話服務請求。在Android中的rild功能類似于windows mobile RIL的RIL proxy。它同樣也是起到一個中介的作用,為上層接口向下傳遞請求,并上傳回響應。在windows mobile RIL中要為每一個應用程序客戶提供一份Ril Proxy實例。對于這兩種操作系統平臺,RIL所定義的所有請求是不可更改的。2.2兩者在線程結構與回調機制上的對比 在windows mobile的設計中,request與response被設計為異步執行的,他們分別使用兩個隊列來對它們的異步行為進行管理,執行命令下發和上報命令處理的過程也互不影響,下發命令與命令的相應響應之間的依賴關系由應用程序來捏合。 在android ril中的request與response設計與windows mobile不同,它的命令與響應之間是同步的過程。也就是說一條命令被下發后,將等待執行結果,并進行處理,再上向上層發。而不是直接異步的進行處理和向上發送。3.Android RIL porting3.1.命名 要實現某個無線模塊的RIL,需要創建一個實現了所有請求方法的共享庫,保證Android能夠響應無線通信請求。所有的請求被定義ril.h中。不同的Modem使用不同的端口,這個在init.rc中設置。Android提供了一個參考Vendor RIL,RIL參考源碼在reference-ril。將你自己的Vendor RIL實現編譯為共享庫形式: libril-.so比如:libril-techfaith-124.so其中: libril:所有vendor RIL的開頭 :公司縮寫:RIL版本number so:文件擴展3.2.Android RIL的配置與加載 在init.rc文件中,將通過這種方式來進行Android RIL的加載。service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so - -d /dev/ttyS0也可以手動加載:/system/bin/rild -l /system/lib/libreference-ril.so - -d /dev/ttyS0這兩種方式,都將啟動rild守護進程,然后通過-l參數將libreference-ril.so共享庫鏈入,libreference-ril.so的參數-d是指加載一個串口設備,/dev/ttyS0則是這個串口設備的具體設備文件,除了參數-d外,還有-s代表加載類型為socket的設備,-p代表回環接口。3.3.Android RIL的編譯結構 rild:被編譯成可執行文件,rild以守進程的形式執行。libril:將被編譯為共享庫,并被鏈入rild。Vendor RIL:可以以兩種方式來運行,如果定義了RIL_SHLIB宏,那么它將被編譯成共享庫,如果沒定義RIL_SHLIB宏,它將以守護進程程序的方式被調用執行。4.Android RIL的java框架 Android RIL的Java部分也被分為了兩個模塊,RIL模塊與Phone模塊。其中RIL模塊負責進行請求以及相應的處理,它將直接與RIL的原聲代碼進行通信。而Phone模塊則向應用程序開發者提供了一系列的電話功能接口。4.1.RIL模塊結構 在RIL.java中實現了幾個類來進行與下層rild的通信。它實現了如下幾個類來完成操作:RILRequest:代表一個命令請求RIL.RILSender:負責AT指令的發送RIL.RILReceiver:用于處理主動和普通上報信息RIL.RILSender與RIL.RILReceiver是兩個線程。RILRequest提供了obtain()方法,用于得到具體的request操作,這些操作被定義在RILConstants.java中(RILConstants.java中定義的request命令與RIL原生代碼中ril.h中定義的request命令是相同的),然后通過send()函數發送EVENT_SEND,在RIL_Sender線程中處理這個EVENT_SEND將命令寫入到stream(socket)中去。Socket是來自常量SOCKET_NAME_RIL,它與RIL原生代碼部分的s_fdListen所指的socket是同一個。 當有上報信息來到時,系統將通過RILReciver來得到信息,并進行處理。在RILReciver的生命周期里,它一直監視著SOCKET_NAME_RIL這個socket,當有數據到來時,它將通過readRilMessage()方法讀取到一個完整的響應,然后通過processResponse來進行處理。4.2.Phone模塊結構Android通過暴露Phone模塊來供上層應用程序用戶使用電話功能相關的接口。它為用戶提供了諸如電話呼叫,短信息,SIM卡管理之類的接口調用。它的核心部分是類GSMPhone,這個是Gsm的電話實現,需要通過PhoneFactory獲取這個GSMPhone。GSMPhone并不是直接提供接口給上層用戶使用,而是通過另外一個管理類TelephonyManager來供應用程序用戶使用。類TelephonyManager實現了android的電話相關操作。它主要使用兩個服務來訪問telephony功能:1.ITelephony,提供給上層應用程序用戶與telephony進行操作,交互的接口,在packages/apps/Phone中由PhoneInterfaceManager.java實現。2.ItelephonyRegistry提供了一個通知機制,將底層來的上報通知給框架中需要得到通知的部分,由TelephonyRegistry.java實現。 GSMPhone通過PhoneNotifier的實現者DefaultPhoneNotifier將具體的事件轉化為函數調用,通知到TelephonyRegistry。TelephonyRegistry再通過兩種方式通知給用戶,其一是廣播事件,另外一種是通過服務用戶在TelephonyRegistry中注冊的IphoneStateListener接口,實現回調(回調方式參見android的aidl機制)。參考資料 相關網站:/android//developerworks/cn/opensource/theme/android//wiki/Android_%28operating_system%295 電話功能概述Android的Radio Interface Layer (RIL)提供了電話服務和的radio硬件之間的抽象層。Radio Interface Layer RIL(Radio Interface Layer)負責數據的可靠傳輸、AT命令的發送以及response的解析。應用處理器通過AT命令集與帶GPRS功能的無線通訊模塊通信。AT command由Hayes公司發明,是一個調制解調器制造商采用的一個調制解調器命令語言,每條命令以字母AT開頭。JAVA Framework代碼的路徑為:frameworks/base/telephony/java/android/telephonyandroid.telephony以及android.telephony.gsmCorenative:在hardware/ril目錄中,提供了對RIL支持的本地代碼,包括4個文件夾:hardware/ril/includehardware/ril/librilhardware/ril/reference-rilhardware/ril/rildkernel Driver 在Linux內核的驅動中,提供了相關的驅動程序的支持,可以建立在UART或者SDIO,USB等高速的串行總線上。電話功能各個部分: hardware/ril/include/telephony/目錄中的ril.h文件是ril部分的基礎頭文件。其中定義的結構體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中包含了幾個函數指針的結構體,這實際上是一個移植層的接口,下層的庫實現后,由rild守護進程得到這些函數指針,執行對應的函數。幾個函數指針的原型為: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);其中最為重要的函數是onRequest(),它是一個請求執行的函數。5.1 rild守護進程rild 守護進程的文件包含在hardware/ril/rild目錄中,其中包含了rild.c和radiooptions.c兩個文件,這個目錄中的文件經過編譯后生成一個可執行程序,這個程序在系統的安裝路徑在:/system/bin/rildrild.c是這個守護進程的入口,它具有一個主函數的入口main,執行的過程是將上層來的請求都由這個函數RIL_RadioFunctionsonReques()的方法進行映射后轉換成對應的AT命令的字符串,發給下層的硬件執行。在運行過程中,使用dlopen 打開路徑為/system/lib/中名稱為libreference-ril.so的動態庫,然后從中取出 RIL_Init符號來運行。ril_register()注冊:RIL_Init符號是一個函數指針,執行這個函數后,返回的是一個RIL_RadioFunctions類型的指針。得到這個指針后,調用RIL_register()函數,將這個指針注冊到libril庫之中,然后進入循環ril_event_loop()。 事實上,這個守護進程提供了一個申請處理的框架,而具體的功能都是在libril.so和libreference-ril.so中完成的。附:RIL守護進程,開機時被init守護進程調用啟動,里面僅有main函數作為入口點,負責完成RIL初始化工作。在rild.c文件中,將完成ril的加載過程,它會執行如下操作:動態加載Vendor RIL的.so文件執行RIL_startEventLoop()開啟消息隊列以進行事件監聽通過執行Vendor RIL的rilInit()方法來進行Vendor RIL與libril的關系建立。在rild文件夾中還包括一個radiooptions.c文件,它的作用是通過串口將一些radio相關的參數直接傳給rild來對radio進行配置。5.2 libreference-ril.so動態庫libreference-ril.so動態庫的路徑是:hardware/ril/reference-ril其中主要的文件是reference-ril.c和atchannel.c。這個庫必須實現的是一個名稱為RIL_Init的函數,這個函數執行的結果是返回一個RIL_RadioFunctions結構體的指針,指針指向函數指針。這個庫在執行的過程中需要創建一個線程來執行實際的功能。在執行的過程中,這個庫將打開一個/dev/ttySXXX的終端(終端的名字是從上層傳入的),然后利用這個終端控制硬件執行。附:在編譯時libril被鏈入rild,它為rild提供了event處理功能,還提供了在rild與Vendor RIL之間傳遞請求和響應消息的能力。Libril提供的主要功能分布在兩個主要方法內,一個是RIL_startEventLoop()方法,另一個是RIL_register()方法RIL_startEventLoop()方法所提供的功能就是啟用eventLoop線程,開始執行RIL消息隊列。RIL_register()方法的主要功能是啟動名為rild的監聽端口,等待java端通過socket進行連接。5.3 libril.so動態庫 libril.so庫的目錄是:hardware/ril/libril 其中主要的文件為ril.cpp,這個庫主要需要實現的以下幾個接口為: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); 這些函數也是被rild守護進程調用的,不同的vendor可以通過自己的方式實現這幾個接口,這樣可以保證RIL可以在不同系統的移植。其中 RIL_register()函數把外部的RIL_RadioFunctions結構體注冊到這個庫之中,在恰當的時候調用相應的函數。在執行的過程中,這個庫處理了一些將請求轉換成字符串的功能。附:Android自帶的VendorRIL的參考實現。被編譯成.so文件,由于本部分是廠商定制的重點所在。所以被設計為松散耦合,且可靈活配置的。在rild中通過opendl()的方式加載。librefrence.so負責直接與radio通信,這包括將來自libril的指令轉換為AT指令,并且將AT指令寫入radio中。reference-ril會接收調用者傳來的參數,參數內容為與radio的通信方式。如通過串口連接radio,那么參數為這種形式:-d /dev/ttySx5.4 ril層的所有代碼分析5.4.1 ril/rild下的文件 rild.c-mian()為函數入口int main(int argc, char *argv)/./OpenLib:#endif switchUser();/打開dlopen()加載vendor RIL 獲取由RIL_register(funcs);注冊進來的參數,并解析dlHandle = dlopen(rilLibPath, RTLD_NOW); if (dlHandle = NULL) fprintf(stderr, dlopen failed: %sn, dlerror(); exit(-1);/1:消息隊列的入口1.到select阻塞/每當看到打印信息,不按順序打下來說明阻塞RIL_startEventLoop();/通過dlsym函數
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 進口汽車買賣銷售合同
- 智能版權法律服務合同
- 智能城市智能商業系統開發合同
- 網站數據抓取與分析服務合同
- 數據提供合同(示范文本)
- 2025年環保設備安裝與運營管理服務合同
- 2025年白酒系列酒類產品區域總代理合同范本
- 2025年安神補腦類藥物合作協議書
- 跨區域股權價值轉讓合同模板
- 精裝修住宅購房合同封面設計
- DB22-T 5040-2020建設工程見證取樣檢測標準-(高清正版)
- 慶七一知識競賽題庫
- 婦幼相關公共衛生服務督導評估表
- 自愿放棄財產協議范本書
- 省級電子政務外網-統一云平臺建設方案
- Soul app用戶體驗分析市場調研分析報告PPT模板
- 柯南偵探原理詳解之3柯南與干冰(專業應用)
- JIS G4304-2021 熱軋不銹鋼板材、薄板材和帶材
- 大氣海洋數據分析與同化考試復習題
- 高中生物校本教材
- 園林綠化工程竣工驗收資料表格-綠化工程竣工驗收單
評論
0/150
提交評論