Working with the Radio Layer Interface (RIL) in Android

Beware: I did this work in Froyo (2.2) and I got to the point where I could start a ppp (Point to Point Protocol) but I couldn’t have a network access. I don’t know whether the bug came from Android or my work. I then decided to use Gingerbread (2.3.4), so the work here is targeting Ginger, but you could try it on Froyo as weel or any other version. If you got it working, I’d be glad to put your work here or link to it.

Intro

Google made it “easy” for vendors to integrate their modem into Android. Indeed, it would have been a pain if HTC, Samsung, … would have had to create a complete library and work on the low level system layers in Android. Everything one has to do to be able to use a modem (either with a 2G, 3G, or another access technology) is included in the directory /hardware/ril/ (provded that the java framework doesn’t have any bug, but if it does i’ll try to point them out).

Actually, apart from a few bug fixes in the RIL sources, from what I understand you’ll only have to modify the libreference-ril.c file. Google and the Android team provide a typical RIL (called libreference-ril) implementing the functions needed, and providing some kind of low level documentation (documentation in Android, for the system parts and not the application dev part, is really, REALLY, light).

In order to make it easier to compile and debug the RIL for the steps that are coming, i’ll put some tips and scripts.

Setup Android before building it

You should read this entire post before doing anything, as you’ll have to do a couple of things before actually building Android.

First of all, you need to add PPP support to the linux kernel. Here are the things you need to set:

Device drivers

network device support

enable PPP support

enable ppp suport for async serial line

enable ppp support for sync serial line

enable SLIP (TBD)

Enable telephony support (TBD)

USB support

USB Modem (CDC ACM) support

USB Serial Converter support

Also, in Gingerbread I am not able to get a USB/RS232 converter to be mounted as the system boots. So when booted, I just do a

insmod /sdcard/ftdi_sio.ko

to load the ftdi kernel module. I previously had to enable ftdi support in device drivers/usb support/usb serial converter/. I added it as a module, and after building it, moved it to the sdcard.

Building the ril

The first script will first compile the RIL with the Android build system, and push the library to the target using adb (so you need to be connected to your target with adb). Be carefull here: I spent a few days debugging a non working RIL because I didn’t use the Android build system to compile it. The system didn’t give me any error when building/using the RIL, but the RIL was indeed buggy as it didn’t output the messages in the good order, and was reseting every 15 seconds … I have to thank vrb (from rowboat IRC channel on irc.freenode.net): vrb, love ya.

During the development, I used to put the Android source tree in the directory /home/<whatever_your_session_name_is>/bin/gingerbread. The RIL provided here is on my github page.

Note that when pushing the new RIL to the target device, you can use it right away without having to reboot. Simply kill the rild process by using the ps command, finding out the rild PID (process identifier) and using the command kill <rild_PID>.

Fixing the base RIL

As I said the base RIL is buggy.

First, you need to explicitly set your modem speed in Android, so that you don’t have problems when talking to your device. You do this in the reference-ril.c file, located in ../hardware/ril/libreference-ril/. In the static void mainLoop function replace the following:

Right below this part is another thing you need to change: the #if 1 to #if 0. This is to prevent the debug socket interface from being setup

In the file hardware/ril/rild/rild.c, change this part

/* special override when in the emulator */
#if 1
{
to
/* special override when in the emulator */
#if 0
{

Fixing Android

Now you have to make Android be aware that the modem is on whatever device (/dev/<something>) you put it on. I used a Sierra Wireless Q26 modem, with a USB and 2 RS232 interfaces (they will allow me not to use the AT commands software multiplexer). When connecting the modem with the USB interface, I have to add both the cdc_acm driver and the sierra wireless driver that are available in the linux kernel. The modem will then show up as a ttyACMx device node. The RIL needs this information to figure out where to send commands, and we’ll provide this information in the init.rc file located in the root directory of your Android system.

The first line increases the debug level so that you can see at commands being sent and answered. Then, we tell Android it must use the RIL and after that, that it has a phone device.

The next part defines the ril-daemon service. You have to provide here the device node you’ll use, the ril library, and the groups allowed to use the daemon. Permissions are very important in Android, and you’ll see that there are a few things you’ll have to do to make it all work.

The last part defines the pppd_gprs service, which will allow you to get a data connection. Now, I have seen a few ways to get the data connection: using the Point to Point Protocol, which you will see here, using RMNET, a Qualcomm proprietary implementation.

ueventd.rc

You also need to set permissions for the device node. The RIL and all radio frequency related devices, daemons and libraries are in the radio group. So, at boot time or when you connect the modem, Android should auto magically set the correct permissions. This will be done in the file ueventd.rc in the root dir of Gingerbread. Note that this is only for Android 2.3 and above. With earlier versions, you need to add those permissions in a file called devices.c.

So in ueventd.rc, add the following, with /dev/ttyACM0 and/dev/ttyUSB0 pointing to whatever device nodes you want:

/dev/ttyACM0 0660 radio radio
/dev/ttyUSB0 0660 radio radio

From now on, you should be able to start the RIL successfully.

You’ll also have to set the init.gprs_pppd permission to 755 once you put it in its directory. Plus, to add it to the radio group, you’ll have to modify the file called property_service.c located in the Android source tree at ../system/core/init/property_service.c.

Thank you, for this blog……..
There is not much info about RIL. But thank god i found this blog.
Its a very good blog.
Hey i followed this blog and now I am able to make a call,sms,signal strength….
But I am not getting gprs connection.I followed this and ppp blog. But I am not able to make a Internet access.

I am getting Connect script failed… error. Can anybody have any solution for this.

I found your weblog site on google and verify just a few of your early posts. Continue to maintain up the superb operate. I simply additional up your RSS feed to my MSN Information Reader. Looking for ahead to studying extra from you in a while!…

HI,
I find few thing difficult to understand in this blog. Till Fixing Android I can understand everything. I checked in ril its taking the path of the device it will communicate from system.prop in the line: rild.libargs=-d /dev/ttyUSB2. When I comment my modem to the snowball board its detected Detected FT2232C on ttyUSB1 so I changed the value in the system.prop to rild.libargs=-d /dev/ttyUSB1. Is it the same thing what you are trying to do in init.rc.
And the next step
changes in the file ueventd.rc
I checked in my android source code it like below

# AT USB device – used by ATC
/dev/ttyGS0 0060 root radio

# modem storage pipe
/dev/rpc 0600 radio radio

So Do I need to change like what you mentioned, but I do not understand why there are 2 device for radio?

One more thing for the modem I need to communicate with the snowball its required CAIF protocol for communication. So please suggest me how to achieve that by changing the android source code.

ueventd.rc means you are targeting gingerbread right? If so I mention in the introduction that the modifications are targeted for froyo and not gingerbread and this may be why you find it difficult to understand.

I think the ttyGS0 is a serial gadget, but you definetly use the node name you get when connecting your modem (use dmesg after you plugged in the modem and check the last few lines).

I am working on a u300-ril package and have looked at your code for ideas. However, I am greatly constrained by a lack of documentation on the Ericsson specific AT commands. For example, I can not find anything on AT*EGNCI. It shows up on the supported command list for the f5521gw, but I get a CME error when trying to implement.

It seems like you have access to the Ericsson command reference documents. Can you provide a copy/link?

Hi adrien. This is some very good information and it’s helping me a lot on my work. If you want, i’d like your opinion on something i’m doing. I’m currently doing an application that works with the phonestatelistener. And since my application is a tool, i need it to be very precise and sensitive. But it looks like the listener doesnt change often like its not enough sensitive or the refresh rare isn’t high enough. i’m currently trying to mod the ril to increase the sensitivity of the listener on sate change. So far i looked at all the ril libraries and it seems i can’t find where to tweek. Do you know something about that ?

Hi, if you want i need some help because i browsed trough all the ril libraries and i can’t find the information i want. I’m trying to increase the refresh rate/sensivity for android.telephony.statelistener. as i am sure the hardware can detect faster change but it’s set differently to (probably) save on batteries. One thing sure the information on your blog helped me get the closest from my goal. 🙂

Hi ,
It was the great post , i have never seen like this before about the RIL .
As i worked on Ril i know alll the RIL files but i have not seen any where about this file ueventd.rc
What us this file ?
Can u explain more about this?

AFAIK ueventd.rc is the equivalent of udev for android. This will allow to mount peripherals like tty, … and to launch some scripts when those peripherals are plugged in.

For instance I use udev (in linux) to auto magically map my modem ports to specific nodes so that I can use those nodes without having to check if the modem is mounted on ttyUSB0, ttyUSB1, ttyUSB10 or whatever…

hi !
I am trying to port 3G telephony to a ti card using rowbat ICS project.
I am able now to receive sms and calls but when I try to make an outgoing call I am having an alert saying “Mobile network not availabe”.

I think that this issue is related to “checkIfOkToInitiateOutgoingCall: ServiceState = 1” which corresponds to STATE_OUT_OF_SERVICE.
is there any document that could help me to understand the origin of this value or a configuration that should be done to avoid such errors in outgoing calls ?
are the incoming and outgoing calls independants in android RIL ? ( I could receive calls and I could call nobody !).

It seems weird that you are able to receive calls/text messages and are not able to emit anything. Do you have the output of the radio logcat? I do not know if the incoming/outgoing calls are not related, sorry.

I am sorry to say that the point of the android related articles on this blog is that there is not much info/docs on those parts of android. You could take a look at the source code commentaries or check out Karim Yagmour’s book (Embedded Android) but I doubt that Karim is talking about the RIL part.

I want to use GSM/GPRS services in AM3354 standard board. I am using Norway GSM/GPRS module as an externel module which is connected through UART0. I also able to get the node namely mux1, mux2,mux3. I am able to make call/sms through AT commands in picocom terminal. I had also installed Dialer-One.APK to make calls form android application.But I am unable to make calls as well as message from android application.However GPRS and TCP/IP AT commands are also not working in picocom.

I have done some modification in following lib file as vendor send me:

1) /devices/ti/am335xevm_sk/system.pro

2) /devices/ti/am335xevm_sk/init.rc

3) /external/ppp/pppd/pathnames.h

4) /system/core/init/property_service.c

5) /system/core/include/private/android_filesystem_config.h

6 Place libreference-ril.so to system / lib of out folder;
7 Place the chat and gsm0710muxd to system / bin in out folder