RIL 机制---消息从RIL到reference-ril

本文详细介绍了Android RIL(Radio Interface Layer)如何将消息从RIL传递到reference-ril。重点讲解了RIL读取数据的流程,包括Event的初始化、Event循环以及Event机制。在Event循环中,通过processTimeouts、processReadReadies、firePending处理数据。此外,还阐述了ril中数据的处理,包括消息封装机制,如何将数据发送到reference-ril并进行回调处理。
摘要由CSDN通过智能技术生成

5,RIL—>reference-ril

首先ril从socket中读取RILJ发送的数据,然后在ril进行处理封装,最后发送到reference-ril进行处理。

5.1 读取数据

读取数据流程图如下,


eventLoop方法如下,

static void *eventLoop(void *param) {
    int ret;
    int filedes[2];
    ril_event_init();//Event的初始化
    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); //设置管道读端属性
//利用pipe创建一个Event
    ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true, processWakeupCallback, NULL);

    rilEventAddWakeup (&s_wakeupfd_event);

    // Only returns on error
    ril_event_loop();//进入loop循环
    RLOGE ("error in event_loop_base errno:%d", errno);
    // kill self to restart on error
    kill(0, SIGKILL);

    return NULL;
}

主要分为2个步骤:

1,调用ril_event_init方法进行Event的初始化。

2,调用ril_event_loop方法进入循环。

5.1.1 Event初始化

ril_event_init方法如下,

void ril_event_init()
{
    MUTEX_INIT();

    FD_ZERO(&readFds);
    init_list(&timer_list);
    init_list(&pending_list);
    memset(watch_table, 0, sizeof(watch_table));
}

对三个链表进行初始化。

5.1.2 Event循环

ril_event_loop方法如下,

void ril_event_loop()
{
    int n;
    fd_set rfds;
    struct timeval tv;
    struct timeval * ptv;


    for (;;) { //死循环检测Event消息

        // 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; /NULL说明select是阻塞模式
        } else {
            dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);
            ptv = &tv; //非空说明在超时时间内是阻塞模式
        }
        printReadies(&rfds);
//用select去扫描readFds中的所有管道集合,检测RILJ是否有新数据出现。
        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?
            retu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值