Tuesday, November 24, 2009

Radio Layer Interface in Android

There is a Radio Layer Interface in Android and it is about telephony service. Like my previous article, I was working on using an external GSM modem in Beagle board. Currently, I am using it to verify telephony service and I can trace the whole log between framework (Telephony service) and ril-daemon. It is the real GSM network and then I can trace the traffic between modem and GSM base station.

Here is some RIL information from Android Platform Development Kit.

RIL Initialization

Android initializes the telephony stack and the Vendor RIL at startup as described in the sequence below:

RIL daemon reads rild.lib path and rild.libargs system properties to determine the Vendor RIL library to use and any initialization arguments to provide to the Vendor RIL
- these arguments are from /system/build.prop
rild.libargs=-d /dev/pts/0

RIL daemon loads the Vendor RIL library and calls RIL_Init to initialize the RIL and obtain a reference to RIL functions
- open modem device
- connect with telephony service (Android Frameworks)

RIL daemon calls RIL_register on the Android telephony stack, providing a reference to the Vendor RIL functions
- start listen socket (SOCKET_NAME_RIL = rild)
- set ril event to listenCallback function

Below text is from radio log and we can see the sequence:

I/RIL ( 954): Opening tty device /dev/pts/0
D/AT ( 954): entering mainLoop()
I/RILJ ( 820): Connected to 'rild' socket
I/RILC ( 954): libril: new connection
D/RILJ ( 820): Radio OFF @ init
I/RILC ( 954): RIL Daemon version: android reference-ril 1.0
D/AT ( 954): AT< AT-Command Interpreter ready
D/AT ( 954): AT> ATE0Q0V1
D/AT ( 954): ATE0Q0V1
D/RILB ( 820): Notifying: radio available

RIL Interaction

There are two forms of communication that the RIL handles:

Solicited commands: Solicited commands originated by RIL lib, such as DIAL and HANGUP.

The vendor RIL must provide the functions described in the table below to handle solicited commands. The RIL solicited command request types are defined in ril.h with the RIL_REQUEST_ prefix. Check the header file for details.

eg. ask GSM network signal strength

Send a request from framework (telephony service) to GSM modem (ril-daemon)

D/RILJ ( 791): [0048]> SIGNAL_STRENGTH
D/RILJ ( 791): send rr to ril-daemon...
D/RILJ ( 791): [0048]> SIGNAL_STRENGTH
D/RILJ ( 791): EVENT_SEND 001
V/RILJ ( 791): writing packet: 8 bytes
D/RILC ( 943): [0048]> SIGNAL_STRENGTH
D/RIL ( 943): onRequest: SIGNAL_STRENGTH
D/AT ( 943): AT> AT+CSQ
D/AT ( 943): AT+CSQ
D/AT ( 943): +CSQ: 20,99
D/AT ( 943): OK
D/AT ( 943): AT< +CSQ: 20,99
D/AT ( 943): AT< OK
D/RILC ( 943): [0048]< SIGNAL_STRENGTH {[ 20 99]}
V/RILJ ( 791): Read packet: 40 bytes
D/RILJ ( 791): [0048]< SIGNAL_STRENGTH {20, 99, 0, 0, 0, 0, 0}
D/GSM ( 791): [PhoneNotifier] notifySignalStrength
D/GSM ( 791): GSMPhone getSignalStrength

Unsolicited responses: Unsolicited responses that originate from the baseband, such as CALL_STATE_CHANGED and NEW_SMS.

eg. Receive an incoming call (from ril-daemon to telephony service)

D/AT ( 943): RING
D/AT ( 943): AT< RING
V/RILJ ( 791): Read packet: 8 bytes
D/GSM ( 791): [GsmCallTracker] checkNoOperationsPending: pendingOperations=0
D/RILJ ( 791): [0283]> GET_CURRENT_CALLS
D/RILJ ( 791): send rr to ril-daemon...
D/RILJ ( 791): [0283]> GET_CURRENT_CALLS
D/RILJ ( 791): EVENT_SEND 001
V/RILJ ( 791): writing packet: 8 bytes
D/RILC ( 943): [0283]> GET_CURRENT_CALLS
D/RIL ( 943): onRequest: GET_CURRENT_CALLS
D/AT ( 943): AT> AT+CLCC
D/AT ( 943): AT+CLCC
D/AT ( 943): +CLCC: 1,1,4,0,0,"0952123687",129,"808
D/AT ( 943): 42C771F"
D/AT ( 943): OK
D/AT ( 943): AT< +CLCC: 1,1,4,0,0,"0952123687",129,"80842C771F"
D/AT ( 943): AT< OK
D/RILC ( 943): [0283]< GET_CURRENT_CALLS {[id=1,INCOMING,toa=129,norm,mt,als=0,voc,noevp,0952082687,cli=0,name='(null)',0}
V/RILJ ( 791): Read packet: 88 bytes
D/RILJ ( 791): InCall VoicePrivacy is disabled
D/RILJ ( 791): [0283]< GET_CURRENT_CALLS [id=1,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,0]

PS. tag information
RIL: /hardware/ril/reference-ril/refereince-ril.c
AT: /hardware/ril/reference-ril/atchannel.c
RILD: /hardware/ril/rild/rild.c
RILC: /hardware/ril/libril/ril.cpp
RILJ: /frameworks/base/telephony/java/com/android/internal/telephony/gsm/RIL.java
GSM: /frameworks/base/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java

Thursday, November 19, 2009

Pick up the phone in Beagle board

I just uploaded two videos about using NEO as external GSM modem in Beagle board. We were trying to make both MT and MO phone call in Beagle board. Since we'd like to hear something during the phone call, I set it to SPEAKER mode in Android Dev phone. Therefore, we can hear what we speak in NEO and also hear some annoyed ECHO sound. Sorry for this....

Friday, November 6, 2009

External GSM modem in Beagle board

My friend Tick just migrated 0xdroid to beagle-donut branch and then I go back to work on external GSM modem issue in Beagle board. This time I tried to connect two devices from my working Ubuntu machine via two USB cables. It becomes very easy to debug and trace the behaviour between GSM modem and Beagle board. I set up an ethernet bridge in Ubuntu machine ( and two USB networks. One is to connect with NEO phone ( and the other is to connect with Beagle board ( All of these three devices can see each other. Therefore, I can use ssh or adb shell to control them.

GSM modem is a device "/dev/ttySAC0" in NEO GTA02 phone and I use netcat to make it be listened in port 4270. This modem becomes now. How to make Android to see it? I use a pty small program from OpenedHand. It's like a pseudo terminal and it can reads and writes to the socket. Running it can make GSM modem become a device "/dev/pts/0" in Android. After starting ril-daemon service, it would connect to GSM modem. Then, everything is like usual. We can camp to GSM network and can dial out a phone call.
I am going to close this issue and then file other issues about ril problems later.