RIL 机制---消息从RIL到RILJ

8 RIL -->RILJ

8.1 上报消息处理

ril.cpp的RIL_onUnsolicitedResponse方法主要代码如下,

//得到当前命令的请求码  
    unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;  
    //从ril_unsol_commands.h文件中得到命令的类型  
    wakeType = s_unsolResponses[unsolResponseIndex].wakeType;  
    //根据不同命令的不同类型进行解析   
    switch (wakeType) {  
        case WAKE_PARTIAL:  
        case DONT_WAKE:  
    }  
    appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));  
  
    Parcel p;  
    p.writeInt32 (RESPONSE_UNSOLICITED);  
    p.writeInt32 (unsolResponse);  
    //调用当前命令的打包函数进行数据打包  
    ret = s_unsolResponses[unsolResponseIndex].responseFunction(p, data, datalen);  
    //把数据发送到RILJ中  
    ret = sendResponse(p,id);  

1,调用s_unsolResponses将对应的方法进行打包。

2,调用sendResponse方法将数据发送到RILJ。

s_unsolResponses定义如下,

static UnsolResponseInfo s_unsolResponses[] = {
#include "ril_unsol_commands.h"
};

是一个文件,该文件部分内容如下,

{RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
{RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
{RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
{RIL_UNSOL_RESPONSE_NEW_SMS, responseString, WAKE_PARTIAL},
和5.2.2 章节的消息封装机制完全一样,只是上报消息和回应消息的区别。

8.2 回应消息处理

ril.cpp的RIL_onRequestComplete方法主要代码如下,

p.writeInt32 (RESPONSE_SOLICITED);
        p.writeInt32 (pRI->token);
        errorOffset = p.dataPosition();

        p.writeInt32 (e);

        if (response != NULL) {
            // there is a response payload, no matter success or not.
            ret = pRI->pCI->responseFunction(p, response, responselen);

            /* if an error occurred, rewind and mark it */
            if (ret != 0) {
                RLOGE ("responseFunction error, ret %d", ret);
                p.setDataPosition(errorOffset);
                p.writeInt32 (ret);
            }
        }

        if (e != RIL_E_SUCCESS) {
            appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
        }

        if (fd < 0) {
            RLOGD ("RIL onRequestComplete: Command channel closed");
        }
        sendResponse(p, socket_id);

在RILC发送数据给RILJ之前,会先调用当前命令的回应处理方法,也就是responseFunction,

对将要传输的数据进行差异化处理,然后再通过sendResponse发送给RILJ。

消息封装机制在5.2.2 小节有详细的论述。RIL_REQUEST_DIAL消息对应的类型是responseVoid。该方法如下,

static int responseVoid(Parcel &p, void *response, size_t responselen) {
    startResponse;
    removeLastChar;
    return 0;
}

8.3 将消息发送给RILJ

回应消息和上报消息首先都对消息内容进行了封装打包,然后才进一步调用

sendResponse方法将数据发送到RILJ。其实这里所谓的打包处理,不过是根据不同的命令,

把相应的回应写入到给RILJ的返回数据包中。

sendResponse方法如下,

sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) {
    printResponse;
    return sendResponseRaw(p.data(), p.dataSize(), socket_id);
}

sendResponseRaw方法如下,

int fd = s_ril_param_socket.fdCommand; //发送Socket
int ret;
uint32_t header;
pthread_mutex_t * writeMutexHook = &s_writeMutex;
•••
pthread_mutex_lock(writeMutexHook);
header = htonl(dataSize); //将数据长度这个整数转换为适合Socket  传输的字节顺序
ret = blockingWrite(fd, (void *)&header, sizeof(header));
    if (ret < 0) {
        pthread_mutex_unlock(writeMutexHook);
        return ret;
    }
    ret = blockingWrite(fd, data, dataSize); //发送一个关于数据大小的字节
    if (ret < 0) {
        pthread_mutex_unlock(writeMutexHook);
        return ret;
    }
    pthread_mutex_unlock(writeMutexHook);// 发送数据本身

和RILJ类似,首先发送数据的大小,然后发送数据。

Fd指向的Socket就是端口名为rild的Socket,和RILJ的Socket一致。

#define SOCKET_NAME_RIL "rild"

blockingWrite方法如下,

static int blockingWrite(int fd, const void *buffer, size_t len) {
    size_t writeOffset = 0;
    const uint8_t *toWrite;

    toWrite = (const uint8_t *)buffer;

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

        if (written >= 0) {
            writeOffset += written;
        } else {   // written < 0
            RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
            close(fd);
            return -1;
        }
    }
#if VDBG
    RLOGE("RIL Response bytes written:%d", writeOffset);
#endif
    return 0;
}

小结:

Modem上报的消息数据都经过了RIL封包处理,然后才发送到RILJ。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值