RILD(一)---Event简述

RILD主要起到承上启下的作用,作为modem和RILJ的通信的中转站。RILD可分为两部分,一是负责与RILJ通讯的部分,主要通过socket通信;另一个是负责与modem交互,主要通过AT指令。

在整个指令的传递过程中,主要是事件Event的传递。RIL的Event管理体系中存在3个链表结构:watch_table,timer_list,pending_list,并使用了一个设备句柄池readFDS,把所有的Socket管道的文件句柄保存起来。

与RILJ通信的部分是libril,与负责与modem交互的是厂商自己定制的reference。libril部分主要是在/hardware/ril/libril/

rild.c是libril与reference相互关联的入口,在这里libril获取到了func的指针,而reference获取到了s_rilEnv的指针,当上层有指令通过RILJ下发给libril的时候,就可以调用reference的func去传递上层命令给底层,而当底层有请求响应或者自主上报的响应的时候,便可以通过reference调用s_rilEnv指针,来上报给上层。

@rild.c
main(){int main(int argc, char **argv) {

    #define  REFERENCE_RIL_PATH  "libreference-ril.so"

    switchUser();
    //打开链接库
    dlHandle = dlopen(rilLibPath, RTLD_NOW);
    
    //开启EventLoop循环
    RIL_startEventLoop();
    
    //从链接库中(也就是reference-ril.c)寻找RIL_Init函数地址
    rilInit =
        (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
        dlsym(dlHandle, "RIL_Init");
        
    //调用reference-ril.c中的RIL_Init函数进行初始化INIT,同时得到reference-ril的回调函数
    //将s_rilEnv全局变量传递给了reference
    funcs = rilInit(&s_rilEnv, argc, rilArgv);
    RLOGD("RIL_Init rilInit completed");
    
    //注册funcs
    RIL_register(funcs);
    RLOGD("RIL_Init RIL_register completed");

}

RIL_startEventLoop主要是处理Event事件的执行条件,事件需要放到pending_list才会被执行,watch_table和timer_list的都会以不同的方式将Event放入到pengding_list中 

@ril.cpp
RIL_startEventLoop(void) {
    //开启eventloop循环
    int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
}

static void *
eventLoop(void *param) {
    //事件初始化
    ril_event_init();

    ret = pipe(filedes);

    s_fdWakeupRead = filedes[0];
    s_fdWakeupWrite = filedes[1];

    fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
    
    //创建一个event
    ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
                processWakeupCallback, NULL);
                
    //将上面创建的event添加到watch_table中
    rilEventAddWakeup (&s_wakeupfd_event);

    // Only returns on error
    ril_event_loop();

    return NULL;
}
@ril_event.cpp
void ril_event_loop()
{
    int n;
    fd_set rfds;
    struct timeval tv;
    struct timeval * ptv;

    //用for循环监测事件
    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扫描所有rfds的管道集合,检测RILJ是否有新数据产生,如果有新数据来就去遍历watch_table和timer_list
        n = select(nfds, &rfds, NULL, NULL, ptv);

        //检测超时事件,如果超时,把event加入到pending_list中
        // Check for timeouts
        processTimeouts();
        
        //检测watch_table,将事件加入到pending_list
        // Check for read-ready
        processReadReadies(&rfds, n);
        
        //执行pending_list中的event
        // Fire away
        firePending();
    }
}
static void processTimeouts()
{
    dlog("~~~~ +processTimeouts ~~~~");
    MUTEX_ACQUIRE();
    struct timeval now;
    struct ril_event * tev = timer_list.next;
    struct ril_event * next;

    getNow(&now);
    // walk list, see if now >= ev->timeout for any events

    dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec);
    while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) {//如果event超时,进入循环
        // Timer expired
        dlog("~~~~ firing timer ~~~~");
        next = tev->next;
        //从timer_list把事件删除
        removeFromList(tev);  
        //将事件添加到pending_list中
        addToList(tev, &pending_list);
        tev = next;
    }
    MUTEX_RELEASE();
    dlog("~~~~ -processTimeouts ~~~~");
}
//将watch_table中的事件全部取出,添加到pending_list中
static void processReadReadies(fd_set * rfds, int n)
{
    dlog("~~~~ +processReadReadies (%d) ~~~~", n);
    MUTEX_ACQUIRE();

    for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) {
        struct ril_event * rev = watch_table[i];
        if (rev != NULL && FD_ISSET(rev->fd, rfds)) {
            addToList(rev, &pending_list);
            if (rev->persist == false) {
                removeWatch(rev, i);
            }
            n--;
        }
    }

    MUTEX_RELEASE();
    dlog("~~~~ -processReadReadies (%d) ~~~~", n);
}
//调用func方法处理event
static void firePending()
{
    dlog("~~~~ +firePending ~~~~");
    struct ril_event * ev = pending_list.next;
    while (ev != &pending_list) {
        struct ril_event * next = ev->next;
        removeFromList(ev);
        ev->func(ev->fd, 0, ev->param);
        ev = next;
    }
    dlog("~~~~ -firePending ~~~~");
}

猜你喜欢

转载自blog.csdn.net/binge__/article/details/81477372