(1)RIL简析(高通)——RIL如何启动及初始化

来源:互联网 发布:退伍军人召回通知软件 编辑:程序博客网 时间:2024/05/01 18:29

Android设置了RIL层,是上层framework与Modem沟通的桥梁。高通使用qcril作为其vendor-RIL,与modem之间使用QMI机制通讯。


分3篇分析下面的问题:

  • RIL如何启动及初始化?
    • RILJ和RILD如何关联?
  • RILJ的消息如何传递和被处理?
    • event table的定义
    • event如何管理
    • event的处理、返回结果和主动上报(UNSOL)
  • 如何正确地添加一个RIL消息和对应的处理函数?

RILD进程启动

RIL、QCRIL运行在RILD进程,在开机后启动,Rild.c的main函数为入口:
/system/core/rootdir/init.rc

service netd /system/bin/netd    class main    socket netd stream 0660 root system    socket dnsproxyd stream 0660 root inet    socket mdns stream 0660 root system    socket fwmarkd stream 0660 root inet

RILD2
/device/qcom/common/rootdir/etc/init.qcom.rc

service ril-daemon2 /system/bin/rild -c 2    class main    socket rild2 stream 660 root radio    socket rild-debug2 stream 660 radio system    user root    disabled    group radio cache inet misc audio sdcard_r sdcard_rw qcom_diag diag log

rild主函数入口:

#define LIB_PATH_PROPERTY   "rild.libpath"int main(int argc, char **argv) {    const char * rilLibPath = NULL;    if (rilLibPath == NULL) {        //这里的property值为:vendor/lib64/libril-qc-qmi-1.so        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.            goto done;        } else {            rilLibPath = libPath;        }    }    //获取libril-qc-qmi-1.so库的句柄    dlHandle = dlopen(rilLibPath, RTLD_NOW);    if (dlHandle == NULL) {        RLOGE("dlopen failed: %s", dlerror());        exit(EXIT_FAILURE);    }    RIL_startEventLoop();    //获取RIL_Init函数指针    rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))        dlsym(dlHandle, "RIL_Init");    //调用RIL_Init函数,s_rilEnv定义见后面    funcs = rilInit(&s_rilEnv, argc, rilArgv);    RLOGD("RIL_Init rilInit completed");    RIL_register(funcs);}//提供给qcril的回调函数,消息处理完成后调用这些callback函数返回static struct RIL_Env s_rilEnv = {    RIL_onRequestComplete,    RIL_onUnsolicitedResponse,    RIL_requestTimedCallback};

RILD入口主要关注这3个函数:
RIL_startEventLoop() —— ril.cpp,线程中开启一个消息循环来监听消息并触发事件处理。
RIL_Init() —— qcril.c初始化工作
RIL_register() —— 注册qcril.c消息函数入口(ril与qcril的关联)

RIL_startEventLoop()

int main(int argc, char **argv) {
RIL_startEventLoop();

ril.cppextern "C" voidRIL_startEventLoop(void) {    /* spin up eventLoop thread and wait for it to get started */    s_started = 0;    pthread_mutex_lock(&s_startupMutex);    pthread_attr_t attr;    pthread_attr_init(&attr);    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);    //创建线程,负责执行eventLoop函数    int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);    if (result != 0) {        RLOGE("Failed to create dispatch thread: %s", strerror(result));        goto done;    }    while (s_started == 0) {        pthread_cond_wait(&s_startupCond, &s_startupMutex);    }done:    pthread_mutex_unlock(&s_startupMutex);}

RIL_startEventLoop(void) {
int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);

eventloop函数开始在线程中执行,初始化并开始一个消息循环:

static fd_set readFds;static int nfds = 0;static struct ril_event * watch_table[MAX_FD_EVENTS];static struct ril_event timer_list;static struct ril_event pending_list;static void *eventLoop(void *param) {    int ret;    int filedes[2];    //初始化watch_table、timer_list、pending_list、readFds    ril_event_init();    pthread_mutex_lock(&s_startupMutex);    s_started = 1;    pthread_cond_broadcast(&s_startupCond);    pthread_mutex_unlock(&s_startupMutex);    //管道    ret = pipe(filedes);    if (ret < 0) {        RLOGE("Error in pipe() errno:%d", errno);        return NULL;    }    s_fdWakeupRead = filedes[0];    s_fdWakeupWrite = filedes[1];    fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);    //创建一个event,回调函数为processWakeupCallback    ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,                processWakeupCallback, NULL);    //将event加入watchtable,唤醒eventloop    rilEventAddWakeup (&s_wakeupfd_event);    // Only returns on error    //开始event循环    ril_event_loop();    RLOGE ("error in event_loop_base errno:%d", errno);    // kill self to restart on error    kill(0, SIGKILL);    return NULL;}static fd_set readFds;static int nfds = 0;static struct ril_event * watch_table[MAX_FD_EVENTS];static struct ril_event timer_list;static struct ril_event pending_list;// 初始化消息列表、计时器消息列表、待处理消息列表void ril_event_init(){    MUTEX_INIT();    FD_ZERO(&readFds);    init_list(&timer_list);    init_list(&pending_list);    memset(watch_table, 0, sizeof(watch_table));}//唤醒event loopstatic void rilEventAddWakeup(struct ril_event *ev) {    //将event加入到watch_table    ril_event_add(ev);    //向s_fdWakeupWrite写入空值,唤醒select    triggerEvLoop();}

ril_event.cpp::ril_event_set
初始化一个event,fd是监听的设备文件描述,persist指定event是否一直存在于watchtable,以上面代码为例:
ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
processWakeupCallback, NULL);

s_fdWakeupRead会一直存在于readFds,因此起到长期监听的作用。

//初始化一个event,persist值若为true则此event会一直存在于watchtablevoid ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param){    dlog("~~~~ ril_event_set %x ~~~~", (unsigned int)ev);    memset(ev, 0, sizeof(struct ril_event));    ev->fd = fd;    ev->index = -1;    ev->persist = persist;    ev->func = func;    ev->param = param;    fcntl(fd, F_SETFL, O_NONBLOCK);}

static void *eventLoop(void *param) {
ril_event_loop();

ril_event_loop函数是循环的主体,在获取到消息后触发3个处理函数:

void ril_event_loop(){    int n;    fd_set rfds;    struct timeval tv;    struct timeval * ptv;    for (;;) {        // make local copy of read fd_set        memcpy(&rfds, &readFds, sizeof(fd_set));        if (-1 == calcNextTimeout(&tv)) {            // no pending timers; block indefinitely            dlog("~~~~ no timers; blocking indefinitely ~~~~");            ptv = NULL;        } else {            dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);            ptv = &tv;        }        printReadies(&rfds);        //select,等待被唤醒        n = select(nfds, &rfds, NULL, NULL, ptv);        printReadies(&rfds);        dlog("~~~~ %d events fired ~~~~", n);        if (n < 0) {            if (errno == EINTR) continue;            RLOGE("ril_event: select error (%d)", errno);            // bail?            return;        }        //处理timer_list中超时的event,加入到pending_list        processTimeouts();        //从watch_table获取event加入到pending_list        processReadReadies(&rfds, n);        //分发pending_list中的事件给对应的处理函数        firePending();    }}

RIL_INIT

回到rild.c的main函数,继续分析Ril_Init。
int main(int argc, char **argv) {
funcs = rilInit(&s_rilEnv, argc, rilArgv);

RIL_startEventLoop()执行过后,RIL的消息循环已经开始进入工作,接下来RIL_Init负责Qcril的初始化及消息循环的创建。

qcril.c/*===========================================================================  FUNCTION:  RIL_Init===========================================================================*//*!    @brief    Returns the current state of the RIL    @return    The current state of the RIL*//*=========================================================================*/const RIL_RadioFunctions *RIL_Init(  const struct RIL_Env *env,  int argc,  char **argv){  //response函数(ril.cpp)  // o maintain compatibility with data and UIM code which use instance_id and may respond on "second instance" context  qcril_response_api[ QCRIL_DEFAULT_INSTANCE_ID ] = (struct RIL_Env *) env;  qcril_response_api[ QCRIL_SECOND_INSTANCE_ID ] = (struct RIL_Env *) env;----------  //初始化unsol消息列表 qmi_ril_android_pending_unsol_resp  qmi_ril_init_android_unsol_resp_pending_list();  //在新线程中执行event loop(qcril_event_main())  qcril_event_init();  // 初始化QCRIL(初始化消息函数的table等)  qcril_init(c_argc, c_argv);  //qcril_event_main开始进入循环,等待被唤醒并处理event。  qcril_event_start();----------  // start bootup if applicable  qmi_ril_initiate_bootup();  //返回RIL_RadioFunctions函数数组给rild.c  return &qcril_request_api[ QCRIL_DEFAULT_INSTANCE_ID ];}//qcril的request相关函数接口static const RIL_RadioFunctions qcril_request_api[] = {  { RIL_VERSION, onRequest_rid, currentState_rid, onSupports_rid, onCancel_rid, getVersion_rid }};

RIL_Init(){
qcril_event_init()
}

qcril_event.cvoid qcril_event_init(void){    qcril_event.started = 0;    //开启线程来执行qcril_event_main    ret = pthread_create(&qcril_event.tid, &attr, qcril_event_main, NULL);    //等待qcril_event_main执行    while (qcril_event.started == 0){        pthread_cond_wait(&qcril_event_startupCond, &qcril_event.startup_mutex);  }}

qcril_event_init(){
ret = pthread_create(&qcril_event.tid, &attr, qcril_event_main, NULL);
}
qcril_event_main开始一个循环,被唤醒后将event list中的消息分发给qcril_process_event处理。

qcril_event.cstatic void *qcril_event_main(void *param){  qcril_event.started = 1;  pthread_cond_broadcast(&qcril_event_startupCond);  while (qcril_event.started < 2)  {    //    pthread_cond_wait(&qcril_event_startupCond, &qcril_event.startup_mutex);  }  for (;;)  {    n = select(qcril_event.fdWakeupRead + 1, &rfds, NULL, NULL, NULL);    do    {      ret = read(qcril_event.fdWakeupRead, &buff, sizeof(buff));      if (ret > 0)      {        QCRIL_LOG_DEBUG("%d items on queue", ret);      }    } while (ret > 0 || (ret < 0 && errno == EINTR)); do    {      if ( ( NULL != ( ev = qcril_event.list.next ) && ( ev != &qcril_event.list ) ) )      {        qcril_event_remove_from_list( ev );         //处理消息——qcril_process_event        err_no = qcril_process_event( ev->instance_id, ev->modem_id, ev->event_id, ev->data, ev->datalen, ev->t );      }    }   }}

RIL_Init(){
qcril_init ()
}

qcril.c//定义了所有消息和处理函数的对应数组static qcril_dispatch_table_entry_type qcril_event_table[] = {{ QCRIL_REG_ALL_STATES( QCRIL_EVT_UIM_QMI_COMMAND_CALLBACK, qcril_uim_process_qmi_callback ) },}//使用hash值来存储qcril_event_table的数据(是实际操作所用的数组)static qcril_dispatch_table_entry_type *qcril_hash_table[ QCRIL_HT_ENTRIES_MAX ];void qcril_init(  int argc,  char **argv){  //qcril_setup_timed_callback 设置timed callback等初始化动作。  qcril_init_state();  //qcril_event_table存储到qcril_hash_table,使用hash id为索引  qcril_init_hash_table();  //初始化qcril_reqlist(qcril_reqlist.c专门用于管理request info,提供添加、查询、删除等函数)  qcril_reqlist_init();}

RIL_Init(){
qcril_event_start()
开始qcril_event_main中的循环

void qcril_event_start( void ){  QCRIL_MUTEX_LOCK( &qcril_event.startup_mutex, "[Main Thread] qcril_event.startup_mutex" );  qcril_event.started = 2;  pthread_cond_broadcast(&qcril_event_startupCond);  QCRIL_MUTEX_UNLOCK( &qcril_event.startup_mutex, "[Main Thread] qcril_event.startup_mutex" );} /* qcril_event_start() */

RIL_Init完成了qcril 初始化,开始eventloop循环,最后返回了qcril_request_api[]

RIL_register

int main(int argc, char **argv) {
funcs = rilInit(&s_rilEnv, argc, rilArgv);
RIL_register(funcs);

监听socket并设置event callback等。

ril.cppRIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};extern "C" voidRIL_register (const RIL_RadioFunctions *callbacks) {    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));    //定义socket,双卡项目需要定义2个    /* Initialize socket1 parameters */    s_ril_param_socket = {                        RIL_SOCKET_1,             /* socket_id */                        -1,                       /* fdListen */                        -1,                       /* fdCommand */                        PHONE_PROCESS,            /* processName */                        &s_commands_event,        /* commands_event */                        &s_listen_event,          /* listen_event */                        processCommandsCallback,  /* 回调函数 */                        NULL                      /* p_rs */                        };  #if (SIM_COUNT >= 2)    s_ril_param_socket2 = {                        RIL_SOCKET_2,               /* socket_id */                        -1,                         /* fdListen */                        -1,                         /* fdCommand */                        PHONE_PROCESS,              /* processName */                        &s_commands_event_socket2,  /* commands_event */                        &s_listen_event_socket2,    /* listen_event */                        processCommandsCallback,                            NULL                        /* p_rs */                        };   #endif    //开始监听socket1    startListen(RIL_SOCKET_1, &s_ril_param_socket);    #if (SIM_COUNT >= 2)    //开始监听socket2    startListen(RIL_SOCKET_2, &s_ril_param_socket2);}//开始监听static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) {    fdListen = android_get_control_socket(socket_name);    if (fdListen < 0) {        RLOGE("Failed to get socket %s", socket_name);        exit(-1);    }    //监听rild(2)    ret = listen(fdListen, 4);    if (ret < 0) {        RLOGE("Failed to listen on control socket '%d': %s",             fdListen, strerror(errno));        exit(-1);    }    socket_listen_p->fdListen = fdListen;    //唤醒eventloop,回调方法为listenCallback(persist为false)    ril_event_set (socket_listen_p->listen_event, fdListen, false,                listenCallback, socket_listen_p);    rilEventAddWakeup (socket_listen_p->listen_event);}//eventloop执行回调,设置对socket的监听static void listenCallback (int fd, short flags, void *param) {    if(NULL == sapSocket) {        p_info->fdCommand = fdCommand;        p_rs = record_stream_new(p_info->fdCommand, MAX_COMMAND_BYTES);        p_info->p_rs = p_rs;        //event persist属性为true,回调为processCommandsCallback        ril_event_set (p_info->commands_event, p_info->fdCommand, 1,        p_info->processCommandsCallback, p_info);        rilEventAddWakeup (p_info->commands_event);        onNewCommandConnect(p_info->socket_id);    }}

ril和qcril的event loop及消息函数入口完成了初始化并开始监听消息。
后面的来分析下消息处理和上报。

1 1
原创粉丝点击