Android OS Layer

Today I’ll talk about how the interaction with the modem is arranged in the Android OS. This article describes the structure of the components of the Android operating system responsible for network interaction over packet data protocols - GPRS, EDGE, 3G, etc.
This article contains a large number of theory, but the practice will be in the second article.

Description of the radio interface layer


Consider the so-called layer of the radio interface, from the English - Radio Interface Layer. In the Android OS, it represents an abstract layer between the telephony service (android.telephony) and the modem.


Figure 1. Layer of the radio interface.

In Figure 1, the red layer of the radio interface is highlighted in red, which includes:
  • java radio interface layer;
  • RIL daemon;
  • event planner;
  • RIL manufacturer.

The components of the air interface layer perform the following tasks: The
Java air interface layer (Java RIL) sends RIL requests to the daemon through the local Linux socket / dev / socket / rild. Java RIL sources are located in the /telephony/java/com/android/internal/telephony/gsm/RIL.java file.
The RIL daemon loads and initializes the producer RIL and event scheduler. The source code for the RIL daemon is located in the / hardware / ril / rild / directory.
The event scheduler processes requested and unsolicited commands. It is an intermediary between RIL Java and RIL manufacturer. The source code for the event scheduler is located in the / hardware / ril / libril / directory.
RIL manufacturerinitializes the modem, interacts directly with the modem. RIL of the manufacturer is a dynamic library developed by the manufacturer of the modem. The development template is located in the / hardware / ril / reference-ril / directory. The most popular manufacturers of modems for mobile devices today are Intel and Qualcomm, and the library source codes are not available.

The internal structure of the RIL daemon


Figure 2 shows the internal structure of the RIL daemon. The task of the RIL daemon is to initialize the layer of the radio interface when the OS starts. Having examined the small amount of RIL daemon code, you can see that it does its work according to the following algorithm:
1. Reads the path to the manufacturer RIL (rild.libpath) and the system properties used by the RIL manufacturer from the system settings.
2. Loads the manufacturer RIL and starts the event loop in the event scheduler.
3. Calls the RIL_Init function to initialize and obtain references to the manufacturer's RIL functions.
4. Calls the RIL_register function, for the event planner to register references to the manufacturer's RIL functions.


Figure 2. Internal structure of the RIL daemon.
There are two types of interactions between components of the radio interface layer: requested (solicited) and unsolicited (unsolicited) command. The requested commands are initiated by the telephony service, for example, an outgoing call, establishing an Internet connection. Unsolicited commands are initiated by the modem, for example, an incoming SMS message, an incoming call.

The relationship between a telephony service and an event planner

The interaction between Java RIL and the event scheduler occurs through the local Linux socket / dev / socket / rild . Each request to the library level is recorded in an instance of the com.android.internal.telephony.RILRequest class , to store information about the request until a response is received from the underlying layers of the radio interface.
The request parameters are written to the parcel structure, and the request itself is sent to the com.android.internal.telephony.RIL.RILSender class . The format of the request is shown in the figure below:

Class com.android.internal.telephony.RIL.RILReceiverlistens on a local Linux socket, waiting for responses from the event scheduler. RILReceiver receives two types of responses: requested and unsolicited. Their format is shown in the figures below.

Figure 4. The format of the requested response.

Figure 5. The format of an unsolicited response.

Implementation of RIL Manufacturer


To implement the manufacturer’s RIL, the manufacturer of the modem is developing a dynamic library that implements many of the functions required by the Android operating system to process requests addressed to the modem. Its name is defined by the following convention: libril- <company name> - <version of RIL> .so
The header file /include/telephony/ril.h contains:
  • Description of many structures, for example: RIL_RadioState, RIL_Data_Call_Response;
  • function prototypes, for example: RIL_Init, RIL_onRequestComplete;
  • numerical definitions for requested and unsolicited commands, for example: #define RIL_REQUEST_SETUP_DATA_CALL 27.

The air interface layer is hardware independent and the manufacturer’s RIL can use any protocol to communicate with the modem. As a rule, many standardized Hayes AT commands are used, however, some modem manufacturers supplement the standard set of AT commands with their own extensions.
To manage the requested commands, the modem manufacturer must implement a set of functions, prototypes of which are described below. The request types of the requested commands are defined in the ril.h header file with the prefix RIL_REQUEST_.
  • void (*RIL_RequestFunc)(int request,void *data, size_t datalen,RIL_Token t) 
    
    This is a function for processing requested commands. It is it that processes the requested commands, which are defined in the ril.h header file and begin with the prefix RIL_REQUEST_.
  • RIL_RadioState (*RIL_RadioStateRequest)() 
    
    this function returns the current state of the modem.
  • int (*RIL_Supports)(int requestCode)
    
    the function returns 1 if the given request code is supported, and 0 otherwise.
  • void (*RIL_Cancel)(RIL_Token t)
    
    this function is used to indicate that a pending request will be canceled. Called in a separate thread, different from the one in which the RIL_RequestFunc function is called.
  • const char * (*RIL_GetVersion) (void)
    
    returns the RIL version of the manufacturer.

The manufacturer RIL uses the following callbacks to communicate with the RIL daemon:
  • void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen)
    
    reports that the requested command has been processed.
  • void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime)
    
    function responsible for the period of time that you need to call back later.

The callback function used by the RIL manufacturer to run unsolicited commands should look like this:
void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, size_t datalen);


Requested Commands

There are 61 teams requested. They can be grouped as follows:
  • work with a SIM card, input / output and a unique device identifier (11);
  • call status and processing (16);
  • network status (4);
  • network settings (12);
  • SMS messages (3);
  • connection using packet data protocols (4);
  • power and restart (2);
  • additional services (5);
  • manufacturer definitions and support (4).

Figure 6 illustrates the sequence of calls at different levels of the radio interface layer when the requested “establish an Internet connection” command arrives:
1. RIL Java calls RILSender.handleMessage () and sends a request to the event planner via the local Linux socket / dev / socket / rild with grouped arguments.
2. The event planner sequentially calls listenCallback (), processCommandCallback (), proccessCommandBuffer (), preprocesses the data and calls dispatch (Request code)
3. In the manufacturer’s RIL, the OnRequest () function is called, in which the action code (SETUP_DATA_CALL) determines what action should be performed in the future. The manufacturer’s RIL sends a sequence of AT commands to the modem corresponding to the request and receives responses to them. Ends the processing of the request code by calling the OnRequestComplete () function. If necessary, sends a response to the event planner.
4. The event planner processes the response from the manufacturer's RIL and calls the response (Request code) function and sends the Java RIL response.
5. RIL Java accepts the response using the RILReceiver.run () method.


Figure 6. The requested command.

Unsolicited Commands

There are 11 unsolicited teams, grouped as follows:
  • change in network status (4);
  • incoming SMS message (3);
  • incoming USSD notification (2);
  • change in signal strength or time (2).



Figure 7. Unsolicited command.
Figure 7 illustrates the sequence of calls at various levels of the radio interface layer when an unsolicited “incoming SMS message” command is received:
1. An AT response is received from the modem, the manufacturer’s RIL reads it and the processor calls the corresponding function. The manufacturer's RIL prepares the data for sending to the event planner. Ends processing by calling OnUnsolicitedResponse ().
2. The event scheduler processes the data that came with the response, sends the Java RIL response through the local Linux socket / dev / socket / rild.
3. RIL Java accepts the response using RILReceiver.run ().

In the next article I plan to talk about how to write my own program for interacting directly with the modem and what can be achieved in this way.
When writing the article the following were used:
1. Android OS source codes android.googlesource.com
2. dpsm.wordpress.com/2010/09/01/smart-phones-are-still-phones
3. www.netmite.com/android/mydroid /development/pdk/docs/telephony.html
4. www.slideshare.net/ssusere3af56/android-radio-layer-interface

Also popular now: