【文章內容簡介】
g scAddrsss,String text、 PendingIntent sentIntent、 PendingIntent deliveryIntent,也就是收件人號碼、發(fā)件 13 信息科學與技術學院學士學位論文 人號碼、信息內容、發(fā)送是否成功回執(zhí)、接收是否成功回執(zhí)。 sendTextMessage 方法是通過 AIDL 的方式,獲得服務,再調用這個服務對象的sendText()方法 。這個服務對象繼承了 , 所以 ()方法調用了 IccSmsInterfaceManager 對象的 sendText()方法 。 IccSmsInterfaceManager 是一個繼承了 的抽象類 ,IccSmsInterfaceManager 對象的 sendText()方法調用了 SMSDispatcher 類的 sendText()方法 ,這個方法又調用了 中 的 sendSms()方法 。 sendSms()方法 調用了 CommandsInterface 接口, CommandsInterface 是一個特殊的接口 ,與 相關,于是進入了 Framework 層。 Framework 層 ( 1)通話部分 進入 GSMPhone 的 dial 方法:其中有個 mCT(GsmCallTracker 類 ).dial 方法,深入其中有: (, clirMode,obtainCompleteMessage()); cm 為 CommandsInterface( interface 接口)的對象。 因為 ( 在 android/internal/telephony 目錄中 ) extends BaseCommands implements CommandsInterface 接口,所以 就等同于 。 ()方法中,創(chuàng)建 RILRequest 對象,并將此 RILRequest 對象放入 messagequeue 中。 RIL 中有個內部類叫 RILSender: class RILSender extends Handler implements Runnable,查看其 handleMessage 方法的核心代碼如下: case EVENT_SEND: ().write(dataLength)。 ().write(data)。 s 為 mSocket,而文件中 mSocket 為 LocalSocket 對象,而在實例化中。 s = new LocalSocket()。 l=newLocalSocketAddress(SOCKET_NAME_RIL,.RESERVED)。 14 信息科學與技術學院學士學位論文 (l)。 可以看到 LocalSocket 與 SOCKET_NAME_RIL 打 上 了 交 道 , 查 看 其SOCKET_NAME_RIL=rild,可以得知 ().write(data)是往 rild 的socket 寫數(shù)據(jù)。其實 RILSender 和 RILReceiver 都是共用的一個 socket。也可以知道RIL 中有 RILD 這個守護進程(負責控制 RIL 串口 )。 這里總結下發(fā)送步驟: ① 創(chuàng)建 RILRequest,將請求數(shù)據(jù)及 Msg 放入到 RILRequest 中 ; ② 利用 Send 方法 (參數(shù): EVENT_SEND)將 RILRequest 放入到消息隊列中 ; ③ RILSender 類獲取此消息,把 RILRequest 通過 SOCKET 方式發(fā)送到 Rild 并保存在 mRequest 中,以便消息的返回。 ( 2)短信部分 進入 Framework 層后,主要靠 CommandsInterface 對象的 sendSMS()方法來做事情 , sendSMS()方法 源碼如下: public void sendSMS (String smscPDU, String pdu, Message result) { RILRequest rr=(RIL_REQUEST_SEND_SMS, result)。 (2)。 (smscPDU)。 (pdu)。 if (RILJ_LOGD) riljLog(() + + requestToString())。 send(rr)。 } 在 sendSMS()方法中,把上面?zhèn)飨聛淼亩绦畔嚓P的數(shù)據(jù)寫入到了 Parcel 中 ,協(xié)同一個特殊的 RILRequest 寫入到 Socket 的輸出流中,進而將數(shù)據(jù)傳遞到 RIL 層。 Native 層 RIL(Radio Interface Layer)層,主要是基于 AT 命令的操作,也就是把上層的傳遞 15 信息科學與技術學院學士學位論文 下來的數(shù)據(jù)包(電話數(shù)據(jù)或是短信數(shù)據(jù))分解,并轉化為可以讓 3G 模塊識別的 AT命令,最后把 3G 模塊處理完數(shù)據(jù)返回的 response 解析,再傳遞回上層。 Android RIL 概念 Android RIL 是基于 telephony 服務和 raido 硬件層的抽象層, Android 的 Rild 庫介 于硬件抽象層 HAL 接口與基于 Modem 之間,它同樣提供了語音、數(shù)據(jù)、短信、SIM 卡管理以及 STK 應用的功能,實現(xiàn)思路跟微軟的 RIL 有異曲同工之妙,也是把標準的 中常用的如 Dial 這些做主動請求的操作稱之為 request,一共 75個;另外一類信息是 GSM 模塊主動上報的例如信號強度、基站信息等,稱之為unsolicited response,一共 17 個。其開發(fā)模式是跟微軟 RIL 開發(fā)差不多,需要針對不同的 GSM 模塊進行不同的 GSM 驅動開發(fā),公用的部分 google 已經(jīng)做好了,特定的部分需要用戶自己 去定制,這樣做可以大大地提高開發(fā)效率。以下是 RIL 交互圖,如圖 42 所示。 C a l l T r a c k e r S M S D i s p a t h e r S e r v i c e r T r a c k e r D a t a T r a c k e rP h o n e A p p l i c a t i o nR I LR a d i o D a c m o nV e n d o r R I LL i n u x I P s t a c kp a c k e t D r v e rB a s e b a n dA p p l i c a t i o nF r a m e w o r kL i b r a r i e s( u s e r s p a c e )L i n u x K e r n e lB a s e b a n d 圖 42 RIL 交互圖 16 信息科學與技術學院學士學位論文 本地代碼 RIL 支持的本地代碼包括 RIL 庫和守護進程。 hardware/ril/include hardware/ril/libril hardware/ril/rild hardware/ril/referenceril 編譯結果是: /system/bin/rild :守護進程 /system/lib/ : RIL 的庫 /system/lib/ : RIL 參考庫 Android 的 RIL 驅動模塊,在 hardware/ril 目錄下,一共分 rild, 以及 三個部分,另外 radiooptions 可供自動或手動調試使用。它們都依賴于 include 目錄中 。目前 cupcake 分支上帶的是 gsm的支持,另有一個 cdma分支, 3G 通信模塊 MG3732 用到的是 gsm 驅動。 ( 1) rild 與 以及 的關系 ① rild 僅以 main 函數(shù)作為整個 RIL 層的入口點,負責完成初始化。 在 文件中,將完成 RIL 的加載過程,它會執(zhí)行如下操作: 首先動態(tài)加載 Vendor RIL 的 .so 文件; 其次執(zhí)行 RIL_startEventLoop()開啟消息隊列以進行事件監(jiān)聽; 最后通過執(zhí)行 Vendor RIL 的 rilInit()方法來進行 Vendor RIL與 libril 的關系建立。 ② 與 rild 結合緊密,是其共享庫。編譯時就已經(jīng)建立了這一關系(其實也可以編譯成可執(zhí)行程序, 作為守護進程運行)。組成部分為 和 。 駐留在 rild 這一守護進程中,主要完成同上層通信的工作,接受 RIL 請求并傳遞給,同時把來自 的反饋回傳給調用進程。 17 信息科學與技術學院學士學位論文 編譯時, libril 被鏈入 rild,它為 rild 提供了 event 處理功能,還提供了在 rild 與Vendor RIL 之間傳遞請求和響應消息的能力。 Libril 提供的主要功能分布在兩個主要方法中:一個是 RIL_startEventLoop()方法;另一個是 RIL_register()方法。 RIL_startEventLoop()方法所提供的功能就是啟用 eventLoop 線程,執(zhí)行 RIL 消息隊列; RIL_register()方法的功能是啟動名為 rild 的監(jiān)聽端口。 ③ rild 通過手動的 dlopen 方式加載,結合稍微松散,這主要是因為 負責跟 Modem 硬件通信。這樣做更方便替換或修改加載的方式,以適配更多種類的Modem。它將來自 的請求轉換為 AT 命令,同時監(jiān)控 Modem 的反饋信息,并傳遞回 。在初始化時, rild 通過符號 RIL_Init 獲取一組函數(shù)指針并以此與之建立聯(lián)系。 referenceril 會接收調用者傳來的參數(shù),參數(shù)內容為與 radio 的通信方式。如通過串口連接 radio,那么參數(shù)形式為: d /dev/ttySx,如圖 43 所示。 C a l l i n g , S M SA n d r o i d T e l e p h o n e R I L p a r tJ a v a A p p l i c a t i o nJ a v a F r a m e w o r kN a t i v e F r a m e w o r kR i l d d e a m o nL i b r e f e r e n c e r i l . s oL i b r i l . s oR I L D r i v e r ( U A R T . S D I D . U S B )K e r n e l S p a c eR I L R a d i o F u n c t i o nD l o p e n i n t e r f a n c e R I L i n i tS o c k e t “ R I L ”圖 43 Rild、 及 關系圖 18 信息科學與技術學院學士學位論文 ④ radiootions radiooptiongs 通過獲取啟動參數(shù),利用 socket 與 rild 通信,其作用是通過串口將一些與 radio 相關的參數(shù)直接傳給 rild??捎糜谡{試時配置 Modem 參數(shù)的配置。 ( 2)初始化流程 rild 是一個守護進程 ,在這里定義宏 RIL_SHLIB。執(zhí)行的過程為: 獲取參數(shù) — 打開功能庫 — 建立事件循環(huán) — 執(zhí)行 RIL_Init— RIL_register。 主入口是 中的 main 函數(shù),主要完成三個任務: ① 任務一:開啟 中的 event 機制。在 RIL_startEventLoop 中,最核心的是由多路 I/O 驅動的消息循環(huán)。 ② 任務二:初始化 。也就是跟硬件或模擬硬件 modem 通信的部分(后面統(tǒng)一稱硬件),通過 RIL_Init 函數(shù)完成。 ③ 任務三:通過 RIL_Init 獲取一組函數(shù)指針 RIL_RadioFunctions,并通過RIL_register 完成注冊,并打開接受上層命令的 socket 通道。 初始化流程分析如下: ① 任務一:也就是 RIL_startEventLoop 函數(shù)。 RIL_startEventLoop 在 中 實 現(xiàn) , 它 的 主 要 目 的 是 通 過pthread_create(amp。s_tid_dispatch, amp。attr, eventLoop, NULL)建立一個 dispatch 線程,入口點在 eventLoop. 而 eventLoop 中,會調用 中的 ril_event_loop()函數(shù),建立起消息 (event)隊列機制。 這一消息隊列的機制討論如下: void ril_event_init()。 // 初始化消息隊列 void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param)。// 設置消息隊列相關的屬性 void ril_event_add(struct ril_event * ev)。 // 增加消息 void ril_timer_add(struct ril_event * ev, struct timeval * tv)。 // 增加時間計時器 void ril_event_del(struct ril_eve