RIL-Java在本質上就是一個RIL代理,起到一個轉發的作用,是Android Java概念空間中的電話系統的起點。
在RIL-D的分析中,我們知道RILD建立了一個偵聽套接口,等待RIL-Java的連接。一旦連接成功,RIL-JAVA就可發起一個請求,並等待應答,並將結構發送到目標處理對象。在RIL-Java中,這個請求稱為RILRequest。為了直觀起見,我還是不厭其煩的給出RIL-Java的框架圖。
RIL-Java的大框架包含了四個方面:
Receiver,Sender,CommandInterface,異步通知機制
在ril.java源代碼中,我們可以看到RIL-JAVA對象提供了如下的Command Interface:
…
getlccCardStatus
getCurrrentCalls
dial
acceptCall
rejectCall
sendDTMF
sendSMS
setupDataCall
setRadioPower
…
為什麼要定義這些接口呢?這函數接口不是憑空捏造出來的,這些都是電話的基本功能的描述,是對Modem AT指令的提煉抽象。大多數Modem都是根據通訊協議提供接口,我們如果不熟悉通訊協議,請參閱3GPP的相關文檔,以及自己使用的Modem的SPEC說明。
V.25ter AT Commands
3GPP 07.07 AT Comamnds-General commands
3GPP 07.07 AT Comamnds-Call Control commans
3GPP 07.07 AT Comamnds-Network Service related commands
3GPP 07.07 AT Comamnds-MT control and status command
3GPP 07.07 AT Comamnds-GPRS Commands
3GPP 07.07 Mobile Termination Errors
3GPP 07.05 SMS AT Commands
Receiver連接到RILD的服務套接口,接收讀取RILD傳遞過來的Response Parcel。Response分為兩種類型,一種是URC,一種是命令應答。對於URC將會直接分發到通知注冊表中的Handler。而命令應答則通過Receiver的異步通知機制傳遞到命令的發送者進行相應處理。
Sender應該分為兩部分架構,
上層函數調用Command Interface將請求消息發送到Sender的架構。
Sender接收到EVENT_SEND消息後,將請求發送到RILD的架構。
對於異步應答來講,命令的發起者發送後,並不等待應答就返回,應答的回應是異步的,處理結果通過消息的方式返回。站在設計者的角度思考如何設計合適的框架來完成異步通訊的功能呢?對於異步系統我們首先應該考慮的是如何標識命令和結果,讓命令和結果有一個對應關系,還有命令沒有響應了,如何管理命令超時?讓我們來看看Android設計者如何完成這些工作。
Android設計者利用了Result Message 和RILRequest對象來完成Request和Result的對應對於關系。在上層做調用的時候生成Result Message對象傳遞到ril_java,並在Modem有應答後,通過Result Message對象帶回結果。如何保證該應答是該RILRequest的呢?Android設計者還提供了一個Token(令牌)的概念。在源代碼中RILRequest的mSerail就用作了Token。Token用來唯一標識每次發送的請求,並且Token將被傳遞到RILD,RILD在組裝應答是將Token寫入,並傳回到ril-java,ril-java根據該Token找到相應的Request對象。
協議的真正實現是在rild中,RIL-JAVA更多的是一個抽象和代理,我們在研究源代碼的過程中就會體會到到RIL-JAVA中的命令函數都有一個共同的框架。
SendXxxCmd(傳入參數Data,傳出參數result){
組合RILRequest(請求號,result,mSerail)
Data->RR
send(RILRequest): Message
}
1)RILRequest
請求號:
request將傳遞到RILD用以標識命令,request代表某個功能。例如撥叫的request號為:RIL_REQUEST_DIAL。在libs/telephony/ril_commands.h有定義。RILRequest.obtain@RILRequest根據命令請求號,傳入參數Result Message,mSerail構造了一個RILRequest。Result Message將帶回應答信息回到命令的發起者。
mSerail:
Android使用了一個RILRequest對象池來管理Andoird RILRequest。mSerail是一個遞增的變量,用來唯一標識一個RILRequest。在發送時正是用了該變量為Token,在rild層看到的token就是該mSerail。
EVENT_END:
EVENT_END@handleMessage@[email protected]2)發送步驟:
第一步:
生成RILRequest,此時將生成m_Serial(請求的Token)並將請求號,數據,及其Result Message 對象填入到RILRequest中
第二步:
使用send將RILRequest打包到EVENT_SEND消息中發送到到RIL Sender Handler,
第三步:
RilSender 接收到EVENT_SEND消息,將RILRequest通過套接口發送到RILD,同時將RILRequest保存在mRequest中以便應答消息的返回。
(4.2) 接收模式
第一步:分析接收到的Parcel,根據類型不同進行處理。
第二步:根據數據中的Token(mSerail),反查mRequest,找到對應的請求信息。
第三步:將是數據轉換成結果數據。
第四步:將結果放在RequestMessage中發回到請求的發起者。