您的位置:首页 > 移动开发 > Android开发

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

2017-05-14 07:58 246 查看

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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android RIL机制 RILJ RIL