[quote] Working with the Radio Layer Interface (RIL) in Android

From http://afewe.wordpress.com/android-arm-development/working-with-the-radio-layer-interface-ril-in-android/

 

Working with the Radio Layer Interface (RIL) in Android

Requirements:

Android source tree (rowboat)

Linux kernel (2.6.37)

Ubuntu

adb

RIL (https://github.com/aferre/sierra-ril)

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.

#!/bin/sh
echo "Using defaults"
ANDSOURCES=~/bin
GINGER=$ANDSOURCES/gingerbread
SIERRA=~/sierra-ril
PRODUCT=beagleboard

cp $SIERRA/Android.mk $GINGER/hardware/ril/reference-ril/
cp $SIERRA/atchannel.c $GINGER/hardware/ril/reference-ril/
cp $SIERRA/atchannel.h $GINGER/hardware/ril/reference-ril/
cp $SIERRA/at_tok.c $GINGER/hardware/ril/reference-ril/
cp $SIERRA/at_tok.h $GINGER/hardware/ril/reference-ril/
cp $SIERRA/misc.c $GINGER/hardware/ril/reference-ril/
cp $SIERRA/misc.h $GINGER/hardware/ril/reference-ril/
cp $SIERRA/sierra-ril.c $GINGER/hardware/ril/reference-ril/

cd $ANDSOURCES/gingerbread/
source build/envsetup.sh
make clean
mm libreference-ril TARGET_PRODUCT=beagleboard -j8

adb push $GINGER/out/target/product/$PRODUCT/system/lib/libril.so /system/lib/
adb push $GINGER/out/target/product/$PRODUCT/system/lib/libreference-ril.so /system/lib/

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:

else if (s_device_path != NULL) {
                fd = open (s_device_path, O_RDWR);
                if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
                    /* disable echo on serial ports */
                    struct termios  ios;
                    tcgetattr( fd, &ios );
                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
			tcsetattr( fd, TCSANOW, &ios );
                }

by the following

else if (s_device_path != NULL) {
                fd = open (s_device_path, O_RDWR);
                if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
                    /* disable echo on serial ports */
                    struct termios  ios;
                    tcgetattr( fd, &ios );
                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
                    LOGI("Setting speed");
                   if( cfsetispeed( &ios, B115200) != 0 )
                       LOGE("Failed to set in speed");
                   if ( cfsetospeed( &ios, B115200) != 0 )
                       LOGE("Failed to set out speed");
			tcsetattr( fd, TCSANOW, &ios );
                }

In the file ril.cpp (../hardware/ril/libril/ril.cpp), you have to remove a couple of things. First, find this part:

// start listen socket
#if 0
    ret = socket_local_server (SOCKET_NAME_RIL,
            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);

    if (ret < 0) {
        LOGE("Unable to bind socket errno:%d", errno);
        exit (-1);
    }
    s_fdListen = ret;

#else
    s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
    if (s_fdListen < 0) {
        LOGE("Failed to get socket '" SOCKET_NAME_RIL "'");
        exit(-1);
    }

    ret = listen(s_fdListen, 4);

    if (ret < 0) {
        LOGE("Failed to listen on control socket '%d': %s",
             s_fdListen, strerror(errno));
        exit(-1);
    }
#endif

and change #if 0 to #if 1, and also remove the #else. You should have this

  // start listen socket

#if 1
    ret = socket_local_server (SOCKET_NAME_RIL,
            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);

    if (ret < 0) {
        LOGE("Unable to bind socket errno:%d", errno);
        exit (-1);
    }
    s_fdListen = ret;

//#else
    s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
    if (s_fdListen < 0) {
        LOGE("Failed to get socket '" SOCKET_NAME_RIL "'");
        exit(-1);
    }

    ret = listen(s_fdListen, 4);

    if (ret < 0) {
        LOGE("Failed to listen on control socket '%d': %s",
             s_fdListen, strerror(errno));
        exit(-1);
    }
#endif

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.

init.rc

What you need is to add or modify these lines:

loglevel 4

setprop ro.radio.noril no
setprop hw.nophone false
service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so -- -d /dev/ttyACM0
   socket rild stream 660 root radio
   socket rild-debug stream 660 radio system
   user root
   group radio cache inet misc audio vpn net_admin

service pppd_gprs /etc/ppp/init.gprs-pppd
   user root
   group radio cache inet misc
   disabled

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.

/*
 * White list of UID that are allowed to start/stop services.
 * Currently there are no user apps that require.
 */
struct {
    const char *service;
    unsigned int uid;
    unsigned int gid;
} control_perms[] = {
    { "dumpstate", AID_SHELL, AID_LOG },
    { "pppd_gprs", AID_RADIO, AID_LOG },
     {NULL, 0, 0 }
};

PPP files

For this part, you should go to Use PPP In Android.

36 thoughts on “Working with the Radio Layer Interface (RIL) in Android”

    1. Free Criminal Background Record ChecksOctober 13, 2011 at 6:07 am

      Woh I enjoy your blog posts, bookmarked ! .

      Reply ↓
    2. greenpoison 4 3 1October 13, 2011 at 10:08 pm

      As a Newbie, I am permanently searching online for articles that can help me. Thank you

      Reply ↓
    3. french bedsOctober 15, 2011 at 2:28 am

      what’s up. i like your blog Working with the Radio Layer Interface (RIL) in Android afewe and will certainly insert a link to http://afewe.wordpress.com/android-arm-development/working-with-the-radio-layer-interface-ril-in-android/ on my site.

      Reply ↓
    4. DevindrappaJanuary 11, 2012 at 10:40 am

      thanks a lot….
      i have gone through this blog its awsome………….
      But I want know that does it work on gingerbread……..
      Because am using gingerbread but not able to achieve.

      So in your case is it working?

      Reply ↓
      1. adrienferrePost authorJanuary 16, 2012 at 5:40 pm

        Hi,

        Most of the information available here should work “out of the box” for gingerbread.

        Beware that some mappings differ amongst Android releases (GPRS can be coded as 1 in Froyo, and 2 in Gingerbread, this is not those exact values, but you get my drift…).

        Reply ↓
    5. KumarJanuary 24, 2012 at 4:05 am

      Hi,

      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.

      Thanks in advance.

      Reply ↓
      1. adrienferrePost authorJanuary 24, 2012 at 7:07 am

        What is the output of pppd?

        Reply ↓
    6. KumarJanuary 24, 2012 at 7:11 am

      Hi,
      when i run the init.gprs-pppd, it is showing connect script failed.
      i have checked 3-4 different connect scripts, but getting same error.Connect script failed

      Reply ↓
    7. adrienferrePost authorJanuary 24, 2012 at 10:29 am

      Can you paste the output on pastebin and give us the link here so that we can debug it ?

      Reply ↓
    8. KumarJanuary 24, 2012 at 11:12 am

      Hi,
      this is my link where I pasted the log messages of ril starting from boot

      http://pastebin.com/Pck28PyE

      Reply ↓
    9. ArticlesFebruary 13, 2012 at 12:44 pm

      It’s hard to find knowledgeable people on this topic, but you sound like you know what you’re talking about! Thanks

      Reply ↓
    10. Alva BonowFebruary 14, 2012 at 1:43 am

      Good day there admin, I truly needed to actually leave a brief remark to actually point out that I appreciated your particular posting. Thanks!

      Reply ↓
    11. Enriqueta EichnerFebruary 15, 2012 at 10:15 pm

      It is really a great and useful piece of info. I’m glad that you shared this useful info with us. Please keep us informed like this. Thank you for sharing.

      Reply ↓
    12. Vender ouroFebruary 17, 2012 at 2:22 am

      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!…

      Reply ↓
    13. Vernia PagniFebruary 20, 2012 at 12:33 am

      Very nice post, I certainly love this website, keep on it.

      Reply ↓
    14. Ivette KymFebruary 20, 2012 at 6:37 am

      Hi there! Would you mind if I share your blog with my zynga group? There’s a lot of people that I think would really enjoy your content. Please let me know. Thanks

      Reply ↓
      1. adrienferrePost authorDecember 18, 2012 at 9:19 am

        Go ahead! Thanks for the link

        Reply ↓
    15. Amit BagFebruary 22, 2012 at 9:43 am

      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.

      Thanks,
      Amit Bag

      Reply ↓
      1. adrienferrePost authorFebruary 22, 2012 at 9:56 am

        Hi,

        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).

        For the CAIF part I don’t know.

        Reply ↓
    16. Pingback: For Discussion of Development for CM7 Only - Page 2 - Android Forums

    17. John NewbyJuly 3, 2012 at 3:40 pm

      Hi,

      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?

      Thanks,
      John

      Reply ↓
      1. adrienferrePost authorJuly 3, 2012 at 4:22 pm

        Hi,

        I don’t have that kind of information. You should try to contact your Ericson commercial/technical support.

        Reply ↓
    18. Olivier G-MJuly 10, 2012 at 7:58 pm

      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 ?

      Reply ↓
      1. adrienferrePost authorJuly 20, 2012 at 9:29 am

        I am sorry i am not familiar with the phone state change listener. Could you elaborate? What sensitivity are you talking about? Signal quality?

        Reply ↓
    19. Olivier G-MJuly 12, 2012 at 3:37 pm

      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. :)

      Reply ↓
    20. kanakJuly 20, 2012 at 9:21 am

      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?

      Regards,
      Kanak

      Reply ↓
      1. adrienferrePost authorJuly 20, 2012 at 9:32 am

        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…

        Reply ↓
    21. Pingback: A nice blog post we found about the RIL (Radio Interface Layer) | Team Gelato's Blog

    22. diandehMay 27, 2013 at 12:58 pm

      I have ported Android Gingerbread 2.3.4 on Beagleboard xM version.

      I have made modifications in the Radio Interface Layer(RIL) given by
      Android.

      Now i am able to successfully communicate with the modem(using USB-
      RS232 converter) and also i am able to send and receive the SMS.

      But when i am trying to make a call i get an error

      “The process android.process.acore has stopped unexpectedly.Please try
      again. Force Close”

      Reply ↓
      1. adrienferrePost authorMay 27, 2013 at 4:43 pm

        Hi

        You should ask a question, it helps.

        Anything show up in the radio logcat?

        Reply ↓
    23. billJune 14, 2013 at 8:15 am

      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 !).

      Thank you !

      Reply ↓
      1. adrienferrePost authorJune 15, 2013 at 5:52 pm

        Hi,

        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.

        Reply ↓
    24. vinod kumarJune 26, 2013 at 7:02 am

      Hi,

      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

      To enable the Telephony manager I did the following changes in :

      1) /device/ti/am335xevm_sk/device.mk

      PRODUCT_COPY_FILES += \
      device/ti/am335xevm/android.hardware.screen.xml:system/etc/permissions/android.hardware.screen.xml \
      frameworks/native/data/etc/android.hardware.telephony.gsm.xml:system/etc/permissions/android.hardware.telephony.gsm.xml

      PRODUCT_PACKAGES += \
      rild

      PRODUCT_COPY_FILES += \
      device/ti/am335xevm/ppp/ip-up:system/etc/ppp/ip-up \
      device/ti/am335xevm/ppp/ip-down:system/etc/ppp/ip-down

      2) /device/ti/am335xevm_sk/ueventd.am335xevm.rc

      /dev/ttyUSB0 0660 radio radio

      Please help me so that I can make calls as well sms from android application.

      Reply ↓
      1. adrienferrePost authorAugust 24, 2013 at 6:35 pm

        Hi

        Do you have any logs?

        Reply ↓
    25. winton.chenAugust 12, 2013 at 5:50 am

      Can you tell me pppd in Android4.0 or 4.1,4.2?
      There are not chat binary file in Android4.0,how do use pppd? thx!

      Reply ↓
      1. adrienferrePost authorAugust 24, 2013 at 6:32 pm

        Hi

        You should be able download the sources and compile along with the source tree.

        Reply ↓

posted on 2014-10-28 17:41  Shawn X.Y. Bai  阅读(969)  评论(0编辑  收藏  举报

导航