Chinaunix首页 | 论坛 | 博客
  • 博客访问: 180616
  • 博文数量: 63
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 69
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-18 13:11
文章分类
文章存档

2013年(64)

我的朋友

分类: LINUX

2013-07-19 13:37:40

今天有进展,找到出错的地方了,根据logcat -b radio的打印信息,追踪代码,对ril有个进一步的了解。
首先,3G模块的驱动要加载insmod **ko,这样会生成/dev/ttyUSB*,作为3G模块和CPU,无线部分和linux的通信通道,
然后,在init.rc里定义服务
 service ril-daemon /system/bin/rild*** -l /system/lib/libreference-ril.so --        -d  /dev/ttyUSB*
 socket rild stream 660 root radio    
 socket rild-debug stream 660 radio system
 user root                                      
 group radio cache inet misc audio 
,这样一开机就会运行守护进程rild,他共过-l system/lib/libreference-ril.so来调用ril的功能解释库,专门用来转换上层的发来的消息和下层送来的AT命令的,-d /dev/ttyUSB*用来指定AT命令的控制端口
接下来见了两个socket ,用来和上层的framework通信,
所有这些反映在代码里就是hardware/ril/目录中
/rild***/rild.c rild守护进程的代码 对应/system/bin/rild
/rild***/radiooptions.c ril的测试程序  对应/system/bin/radiooptoins***
/reference-ril/reference-ril.c ril的功能实现库,消息转换  对应/system/lib/libreference-ril.so
/libril***/ril.cpp  主要用来注册ril,对应/system/lib/libril***.so

在rild.c中

int main(int argc, char **argv)
{
    LOGI("start of main in rild.c ziilabs");

    const char * rilLibPath = NULL;
    char **rilArgv;
    void *dlHandle;
    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    const RIL_RadioFunctions *funcs;
    char libPath[PROPERTY_VALUE_MAX];
#if RILD_RUN_AS_ROOT_WORKAROUND
    char runAsRoot[PROPERTY_VALUE_MAX];
#endif /* RILD_RUN_AS_ROOT_WORKAROUND */
    unsigned char hasLibArgs = 0;

    int i;

    for (i = 1; i < argc ;) {
        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
            rilLibPath = argv[i + 1];
            i += 2;
        } else if (0 == strcmp(argv[i], "--")) {
            i++;
            hasLibArgs = 1;
            break;
        } else {
            usage(argv[0]);
        }
    }

 
    if (rilLibPath == NULL) {
        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
            // No lib sepcified on the command line, and nothing set in props.

            // Assume "no-ril" case.

              LOGD("libPath is %s... no ril",rilLibPath);
        
            goto done;
        } else {
            rilLibPath = libPath;
            LOGD("libPath is %s... have ril",rilLibPath);
        }
    }

    /* special override when in the emulator */
#if 1
    {
        static char* arg_overrides[3];
        static char arg_device[32];
        int done = 0;

#define REFERENCE_RIL_PATH "/system/lib/libreference-ril.so"

        /* first, read /proc/cmdline into memory */
        char buffer[1024], *p, *q;
        int len;
        int fd = open("/proc/cmdline",O_RDONLY);

        if (fd < 0) {
            LOGD("could not open /proc/cmdline:%s", strerror(errno));
            goto OpenLib;
        }

        do {
            len = read(fd,buffer,sizeof(buffer)); }
        while (len == -1 && errno == EINTR);

        if (len < 0) {
            LOGD("could not read /proc/cmdline:%s", strerror(errno));
            close(fd);
            goto OpenLib;
        }
        close(fd);

        if (strstr(buffer, "android.qemud=") != NULL)
        {
            /* the qemud daemon is launched after rild, so
            * give it some time to create its GSM socket
            */

            int tries = 5;
#define QEMUD_SOCKET_NAME "qemud"

            while (1) {
                int fd;

                sleep(1);

                fd = socket_local_client(
                            QEMUD_SOCKET_NAME,
                            ANDROID_SOCKET_NAMESPACE_RESERVED,
                            SOCK_STREAM );

                if (fd >= 0) {
                    close(fd);
                    snprintf( arg_device, sizeof(arg_device), "%s/%s",
                                ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );

                    arg_overrides[1] = "-s";
                    //arg_overrides[2] = arg_device;

                    arg_overrides[2] = "/dev/ttyUSB0";
                    done = 1;
                    break;
                }
                LOGD("could not connect to %s socket: %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                if (--tries == 0)
                    break;
            }
            if (!done) {
                LOGE("could not connect to %s socket (giving up): %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                while(1)
                    sleep(0x00ffffff);
            }
        }

        /* otherwise, try to see if we passed a device name from the kernel */
        if (!done) do {
#define KERNEL_OPTION "android.ril="
#define DEV_PREFIX "/dev/"

            p = strstr( buffer, KERNEL_OPTION );
            if (p == NULL)
                break;

            p += sizeof(KERNEL_OPTION)-1;
            q = strpbrk( p, " \t\n\r" );
            if (q != NULL)
                *q = 0;

            snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
            arg_device[sizeof(arg_device)-1] = 0;
            arg_overrides[1] = "-d";
            //arg_overrides[2] = arg_device;

            arg_overrides[2] = "/dev/ttyUSB0";
            done = 1;

        } while (0);

        if (done) {
            argv = arg_overrides;
            argc = 3;
            i = 1;
            hasLibArgs = 1;
            rilLibPath = REFERENCE_RIL_PATH;

            LOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
        }
    }
OpenLib:
#endif

#if RILD_RUN_AS_ROOT_WORKAROUND
    // If the property is not set, it will be set to "no" by default.

    property_get(RUN_AS_ROOT_PROPERTY, runAsRoot, "no");
    if (0 == strcmp("no", runAsRoot)) {
    switchUser();
    }
#else /* !RILD_RUN_AS_ROOT_WORKAROUND */
    switchUser();
#endif /* !RILD_RUN_AS_ROOT_WORKAROUND */

    dlHandle = dlopen(rilLibPath, RTLD_NOW);

    if (dlHandle == NULL) {
        fprintf(stderr, "dlopen failed: %s\n", dlerror());
        exit(-1);
    }
    LOGD("before RIL start Event Loop");
    //LOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);


    RIL_startEventLoop();
    
    LOGD("after RIL start Event Loop");
    //LOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);


    rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");

    if (rilInit == NULL) {
        fprintf(stderr, "RIL_Init not defined or exported in %s\n", rilLibPath);
        exit(-1);
    }

    if (hasLibArgs) {
        rilArgv = argv + i - 1;
        argc = argc -i + 1;
    } else {
        static char * newArgv[MAX_LIB_ARGS];
        static char args[PROPERTY_VALUE_MAX];
        rilArgv = newArgv;
        property_get(LIB_ARGS_PROPERTY, args, "");
        argc = make_argv(args, rilArgv);
    }

    // Make sure there's a reasonable argv[0]

    rilArgv[0] = argv[0];
    
    LOGD("before riInit %d ,%s in rild.c ziilabs",argc,rilArgv);
    funcs = rilInit(&s_rilEnv, argc, rilArgv);
    LOGD("after riInit %d ,%s in rild.c ziilabs",argc,rilArgv);
    
    LOGD("before RIL register in rild.c ziilabs");
    RIL_register(funcs);
    LOGD("before RIL register in rild.c ziilabs");

done:
    LOGI("start of done while in rild.c ziilabs");

    while(1) {
        // sleep(UINT32_MAX) seems to return immediately on bionic

        LOGI("while in rild.c ziilabs");
        sleep(0x00ffffff);
    }
}



主体是
int main(int argc,char ** argv)
{
    void *dlHandle;
    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    const RIL_RadioFunctions *funcs;
   ....启动服务时通过argv获取*.so和ttyUSB*
   dlHandle = dlopen(rilLibPath, RTLD_NOW);
   RIL_startEventLoop();
   rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char           **))dlsym(dlHandle, "RIL_Init");
   funcs = rilInit(&s_rilEnv, argc, rilArgv);
   RIL_register(funcs);
   while(1) {
        // sleep(UINT32_MAX) seems to return immediately on bionic
   sleep(0x00ffffff);
    }
}

现在报错RIL_register: RIL_RadioFunctions * null or invalid version (expected 2)
出现在RIL_register(funcs);//ril.cpp文件中,libril.so
但原因很可能是funcs指针前面没获取好所致

if (callbacks == NULL || ((callbacks->version != RIL_VERSION)
                && (callbacks->version != 2))) { // Remove when partners upgrade to version 3
        LOGE(
            "RIL_register: RIL_RadioFunctions * null or invalid version"
            " (expected %d)", RIL_VERSION);
       

funcs是一个指向RIL_RadioFunctions的指针,
rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char           **))dlsym(dlHandle, "RIL_Init");
funcs = rilInit(&s_rilEnv, argc, rilArgv);
问题可能就出在这两句话上,rilInit()函数位于reference-ril.c中,从打印信息来看


I/RIL ( 1060): start of ril_init in reference-ril.c
I/RIL ( 1060): opt is 100 in ril_init reference-ril.c
I/RIL ( 1060): Opening tty device /dev/ttyUSB0
I/RIL ( 1060): pthread_attr_init of ril_init in reference-ril.c
I/RIL ( 1060): end of ril_init in reference-ril.c

这里好像没错,那问题可能出在前一句话,看着有点麻烦,明天再看,今天就到这里,总算缩小范围了。

阅读(2654) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~