RIL 流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/engineer_james/article/details/82711809

RIL 分为RILJ 和RILC 部分,而RIL 和modem 通信通过socket ,发送的是串口 AT command

[其实只要熟悉linux 编程,rild 部分确实很好理解]花了4天左右认认真真分析

ril

在初始化 reference-ril 库的时候,创建 客户端socket 连接到modem,而通过atchannel 的at_send_command_full_nolock发送AT command到modem,通过轮询 readline 读取返回信息

hardware/ril/reference-ril/reference-ril.c

const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv){

    //....
    fd = socket_local_client( s_device_path,ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
                                            SOCK_STREAM );    
}

hardware/ril/reference-ril/atchannel.c


static const char *readline(){
//....
   count = read(s_fd, p_read,MAX_AT_RESPONSE - (p_read - s_ATBuffer));

}

代码段 小部件

但是RILJ和RILC 通信的,其实在开机启动的时候,在init.rc文件中,会配置socket 管道,RIL.java和rild.c会根据socketname 相互得到socket,并且,RIL.java 端会充当客户端,rild.c 端充当服务器端

service rild  /system/bin/rild
    class main
    socket rild0 stream 660 root radio

上面的rild进程 申明创建socket rild0 权限是660 owner是root 归属于radio ,并且在RIL.java中会创建rild0的socket

class RILReceiver implements Runnable {
    static final String[] SOCKET_NAME_RIL = {"rild0", "rild1", "rild2"};

    @Override
    public void run() {
        
        rilSocket = SOCKET_NAME_RIL[0];
        
        s = new LocalSocket();
        l = new LocalSocketAddress(rilSocket,
                LocalSocketAddress.Namespace.RESERVED);
        s.connect(l);
    
    }

}

 重点在RILC端,因为rild守护进程随开机启动,所以rild.c开机就启动,rild的socket 服务器端如下

hardware/ril/rild/rild.c

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

    if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
        strlcat(rild, clientId, MAX_SOCKET_NAME_LENGTH);
        RIL_setRilSocketName(rild);  //socketname =rild0
    }

 
}

hardware/ril/libril/ril.cpp

static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) {

    switch(socket_id) {
        case RIL_SOCKET_1:
            strncpy(socket_name, RIL_getRilSocketName(), 9);
            break;

    fdListen = android_get_control_socket(socket_name);
    ret = listen(fdListen, 4);

}

在startListen 找到socket 使得RILJ和RILC 通信,但是如何读写数据?

的到了socket ,就可以接收RILJ发送的请求消息

hardware/ril/libril/ril.cpp

static void processCommandsCallback(int fd, short flags, void *param) {

     for (;;) {
        /* loop until EAGAIN/EINTR, end of stream, or other error */
        //获取消息 存入p_record buffer中
        ret = record_stream_get_next(p_rs, &p_record, &recordlen);
        
        if (ret == 0 && p_record == NULL) {
            /* end-of-stream */
            break;
        } else if (ret < 0) {
            break;
        } else if (ret == 0) { /* && p_record != NULL */
            //获取请求消息,处理请求消息
            processCommandBuffer(p_record, recordlen, p_info->socket_id);
        }
    }

}
int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord,
                                    size_t *p_outRecordLen)
{

    countRead = read (p_rs->fd, p_rs->read_end, p_rs->buffer_end - p_rs->read_end);
    ret = getNextRecord (p_rs, p_outRecordLen);
    *p_outRecord = ret;
}

在processCommandBuffer 过程中将请求消息,转化为 AT指令通过dispatchFunction方法,最后通过   at_send_command_full_nolock发送给modem

最后就是读取modem 返回的消息,并且返回给RILJ端口

在轮询readerLoop,通过 readline获取返回数据,然后通过

s_unsolHandler (line1, line2)
processLine(line); 

处理读取的一行数据

modem 上报分为主动上报和主动上报,也就和URC 和非URC

static void processLine(const char *line)
{
    if (sp_response == NULL) {
        /* no command pending */
        handleUnsolicited(line);  //主动上报
    } else if (isFinalResponseSuccess(line)) {
        sp_response->success = 1;
        handleFinalResponse(line);  //非主动上报


}
/** add an intermediate response to sp_response*/
static void addIntermediate(const char *line)
{
    ATLine *p_new;

    p_new = (ATLine  *) malloc(sizeof(ATLine));

    p_new->line = strdup(line);

    /* note: this adds to the head of the list, so the list
       will be in reverse order of lines received. the order is flipped
       again before passing on to the command issuer */
    p_new->p_next = sp_response->p_intermediates;
    sp_response->p_intermediates = p_new;
}
/** assumes s_commandmutex is held */
static void handleFinalResponse(const char *line)
{
    sp_response->finalResponse = strdup(line);

    pthread_cond_signal(&s_commandcond);
}

当处理 handleFinalResponse 时候,说明modem 已经返回数据完毕,但是在读取中会走addIntermediate ,数据全部保存在sp_response中,当读取完成会通过handleFinalResponse 唤醒在阻塞在at_send_command_full_nolock 函数中,通过  pthread_cond_wait 等待handleFinalResponse 释放s_commandcond,最后将数据保存在pp_outResponse

如果返回数据成功,会通过 RIL_onRequestComplete返回,直接write写回 RILJ客户端

RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(int));
sendResponse(p, socket_id);
static int
blockingWrite(int fd, const void *buffer, size_t len) {

    while (writeOffset < len) {
        ssize_t written;
        do {
            written = write (fd, toWrite + writeOffset,
                                len - writeOffset);
        } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
    }

    return 0;
}

当然主动上报直接回调 onUnsolicited 通過 RIL_onUnsolicitedResponse 将数据写回RILJ

ret = sendResponse(p, soc_id);

猜你喜欢

转载自blog.csdn.net/engineer_james/article/details/82711809
RIL