Eventloop把RILJ命令发送给reference库
实际上主要是拿到reference中RIL_RadioFunctions的句柄,然后在RILC初始化注册的时候将func作为参数传递进去。
为之后的上层下发指令时的调用做准备。
s_commands数据起到了承上启下的作用,提供调用reference onRequest的方法,也提供reference传往Env的方法
@rild.c
int main(int argc, char **argv)
{
//搭建EventLoop循环
RIL_startEventLoop();
//对reference动态库进行初始化,funcs是RIL_RadioFunctions类型
funcs = rilInit(&s_rilEnv, argc, rilArgv);
//注册reference 的回调函数,
RIL_register(funcs);
}
@reference-ril.c
static const RIL_RadioFunctions s_callbacks = {
RIL_VERSION,
onRequest,
currentState,
onSupports,
onCancel,
getVersion
};
@ril.cpp
//将reference中的回调函数注册给RIL的框架
void RIL_register (const RIL_RadioFunctions *callbacks) {
//把返回值传给s_callbacks(全局变量)
memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
//#define SOCKET_NAME_RIL "rild" 打开RILC与RILJ之间的Socket通道
s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
ret = listen(s_fdListen, 4);
//用这个Socket通道句柄创建一个Event
ril_event_set (&s_listen_event, s_fdListen, false, listenCallback, NULL);
//添加到Eventloop中
rilEventAddWakeup (&s_listen_event);
}
@ril.cpp
static void listenCallback (int fd, short flags, void *param) {
//从s_fdListen侦听套接字得到s_fdCommand(RILJ与RILC之间的流套接字)
s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
//得到当前命令的选项值
err = getsockopt(s_fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
//对文件描述符s_fdCommand进行控制,当前是设置其非阻塞模式
ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK);
//再次把当前命令放入Eventloop
ril_event_set (&s_commands_event, s_fdCommand, 1, processCommandsCallback, p_rs);
rilEventAddWakeup (&s_commands_event);
//发送URC消息,通知RIL状态发生改变
onNewCommandConnect();
}
processCommandsCallback-->processCommandBuffer
static int processCommandBuffer(void *buffer, size_t buflen) {
Parcel p;
int32_t request;
int32_t token;
RequestInfo *pRI;
p.setData((uint8_t *) buffer, buflen);
//得到请求码和令牌
status = p.readInt32(&request);
status = p.readInt32 (&token);
pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
//设置当前请求的令牌
pRI->token = token;
//s_commands中针对不同的命令对应不同的处理函数
pRI->pCI = &(s_commands[request]);
//链表结构
pRI->p_next = s_pendingRequests;
s_pendingRequests = pRI;
//调用reference 中的
pRI->pCI->dispatchFunction(p, pRI);
return 0;
}
s_commands是一个数组,每个RILJ发送过来的命令在s_commands中都对应一个元素,而每个元素包含3个数据:
requestNumber表示当前命令的编号;
dispatchFunction的作用是,当前命令可以通过这个接口把数据发送到reference库;(往下传递)
responseFunction的作用是:当Modem返回数据后reference侧可以用这个函数把数据进行打包,然后传递给Event侧。(向上传递)
e.g:
{RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus},
@ril.cpp
static void dispatchVoid (Parcel& p, RequestInfo *pRI) {
//发送数据到Modem
clearPrintBuf;
//打印Log信息RLOGD("[%04d]> %s %s", token, requestToString(req), printBuf)
printRequest(pRI->token, pRI->pCI->requestNumber);
//s_callbacks是从reference注册过来的
s_callbacks.onRequest(pRI->pCI->requestNumber, NULL, 0, pRI);
}