Tian haili
2012-03-24
This article introduces the overall architecture of androidril and analyzes the implementation of the local library [C/CPP part].
I. Overall Architecture
Android RIL (radio interface layer) provides an abstraction layer between the Telephony Service and the radio hardware. RIL is responsible for reliable data transmission, at command sending, and Response Parsing. Generally, the application processor (AP) communicates with the wireless communication module (baseband/BP) through the AT command set. Call the operations that are commonly used in the standard gsm27.007, such as dial, as follows:RequestAnother type of information that is actively reported by GSM, such as signal strength, base station information, and SMS.Unsolicited Response.
Ii. Implement file distribution
SMS/MMS, call ,...
The application layer of telephony is implemented in specific apps. Call is in packages/apps/phone, SMS/MMS is in packages/apps/MMS, and network selection is in packages/apps/settings.
Android. telephony .*
Telephony's javaframework code for upper-layer use
Com. Android. Internal. telephony .*
The internal implementation of telephony's Java framework code. This package is hidden and cannot be accessed outside.
Hardware/RIL/include/telephony/RIL. h
Header file of Local Code
Hardware/RIL/libril
RIL local library implementation source code, generate libril. So
Hardware/RIL/rild
The implementation source code of the RIL daemon rild to generate the executable file rild.
Hardware/RIL/reference-RIL
RIL implementation library reference implementation source code, generate libreference-ril.so
Different hardware platforms can follow this to implement a specific functional library.
Iii. RIL Initialization
1. rild parses the RIL implementation library <rillibpath> -- you can specify it through the command line or property.
In init. RC, rild can use command line parameters.-L <rillibpath>Specify the specific implementation library of RIL;
If the Implementation library is not specified in the command line, use property_get ("Rild. libpath",...) Obtain the implementation library.
And in the simulated environment, it will use/system/lib/libreference-ril.so, which is also the path of the libreference-ril.so that was finally put in the previous section.
2. Load the RIL implementation library through dlopen (<rillibpath>;
3. Call ril_starteventloop () in libril to enable and ensureEventloop threadStarted;
4. Use dlsym () to obtain the ril_init () function defined in <rillibpath>.
5. Get the parameters required by ril_init ()-You can specify them through the command line or property.
In init. RC, rild can use command line parameters.--Specify the ril_init parameter;
If the Implementation library is not specified in the command line, use property_get ("Rild. libargs",...) Obtain parameters.
6. Execute the functions and parameters obtained from 4 & 5.Ril_init() StartMainloop threadAnd obtain ril_radiofunctions;
7. RunRil_register() Keep these callback functions to s_callbacks, enable the name of socket "rild", and accept the upper-layer socket commands.
Shows the sequence chart:
Note: The sequence numbers in the figure do not exactly match the steps described above.
In the above time series, there are several important data:S_rilenv: Ril_env is defined in rild, but the specific implementation of the function is registered to the implementation library in the standard library libril. So for the RIL implementation library to call;S_callbacks: Ril_radiofunctions is defined in reference-RIL to implement request and other operations.
Iv. Request Process
The eventloop started in step 3 of the initialization process calls ril_event_loop () to process the request.
Use select () to select multiple sockets to listen for socket requests from the Java layer. Run:
Ril_event_loop ()->
-> Processtimeouts ()
-> Processreadreadies (): Move ril_event from watch_table [] to pendling_list
-> Firepending ()-> ev-> func () [listencallback () [RIL. cpp]
-> Record_stream_new () creates a recordstream.
-> After receiving the complete request, execute processcommandscallback ()
->Processcommandbuffer() [RIL. cpp]
The specific execution is in processcommandbuffer ()
In RIL. cpp, s_comamnds: commandinfo [] is defined.
typedef struct { int requestNumber; void (*dispatchFunction)(Parcel &p, struct RequestInfo *pRI); int (*responseFunction)(Parcel &p, void *response, size_t responselen);} CommandInfo; static CommandInfo s_commands[] = {#include “ril_commands.h”};
In processcommandbuffer (), find commandinfo in s_commands through the request index, and then execute the dispatch operation through the dispatchfunction of commandinfo.
You can open ril_commands.h to view the dispatch function of a specific request.
{RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus},{RIL_REQUEST_SEND_SMS, dispatchString, responseSMS},//…
Dispatchxyz () is a series of reqeust encapsulation for specific parameters. See the implementation of dispatchstring (parcel & P, requestinfo * Pri:
char *string8 = strdupReadString(p);s_callbacks.onRequest(pRI->pCI->requestNumber,string8, sizeof(char *), pRI);
Parse the parameters and call Reference-RIL through s_callbacks.onrequest () to implement onrequest in the library. [S_callbacks is registered and retained during initialization in Section 3]
Onrequest () in reference-RIL has a large switch... Case statement to process various requests.
switch(request) { caseRIL_REQUEST_SEND_SMS: requestSendSMS(); break; //…}
In requestsendsms (), call at_send_command_sms () to send a text message with "+ cmgs" and obtain the returned value.
Called in requestsendsms ()Ril_onrequestcomplete(T, E: ril_errno) to complete the request.
5. Response Process
Response has solicited response, that is, the response to the request mentioned in the previous section. In addition, there is also an unsolicitedresponse that is actively reported, such as a phone call or text message.
5.1 solicited response
For solicited response, the last call in the previous section is ril_onrequestcomplete (). In reference-RIL, this function calls s_rilenv-> onrequestcomplete (). According to the initialization in section 3, the specific implementation is in ril_onrequestcomplete () in RIL. cpp.
In ril_onrequestcomplete,
If the commandinfo defined in "ril_commsnds.h" contains the response function, call responsefunction;
Convert the response information structure defined by rIL, call sendresponse (), and report the response result to the upper layer through socket.
5.2 Unsolicited Response
In mainloop starting from step 6 in Section 3, onunsolicited () is passed to atchannel through at_open. The readerloop thread is enabled in at_open () of atchannel.
In readerloop:
Readline ()-> processline () calls handleunsolicited () to handle unsolicited messages, and calls back the onunsolicited () function registered in reference-RIL in handleunsolicited.
After the onunsolicited () of reference-RIL processes various special commands, call the ril_onunsolicitedresponse () in the ril_env registered in [section 3] during initialization. The final implementation is in RIL. CPP ril_onunsolicitedresponse ().
Like request, rIL. cpp defines s_comamnds: commandinfo []
typedef struct { int requestNumber; int (*responseFunction)(Parcel &p, void *response, size_t responselen); WakeType wakeType;} UnsolResponseInfo; static UnsolResponseInfo s_unsolResponses[] = {#include “ril_unsol_commands.h”};
In ril_onunsolicitedresponse, unsolresponseindex is used to find unsolresponseinfo in s_unsolresponses. Then, the unsolresponseinfo waketype is used to wake up the wakelock of the mobile phone. Then, the responsefunction is used to perform the respon.
You can open ril_unsol_commands.h to see the definition of a specific unsolicitedresponse.
{RIL_UNSOL_RESPONSE_NEW_SMS, responseString, WAKE_PARTIAL},{RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, responseString, WAKE_PARTIAL},{RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, responseInts, WAKE_PARTIAL},//…
Finally, like solicited response, unsolicited response calls sendresponse () and reports it to the Java upper layer through socket.