通过深入理解Android Telephony 之RILD机制分析对原生RILD的分析,可以总结成以下三点:
1、RIL_startEventLoop创建s_tid_dispatch主线程,用来监听RILJ下发到socket的消息并分发。
2、RIL_Init创建s_tid_mainloop线程,负责初始化RILD与modem的socket通道,创建s_tid_reader线程来读取modem上报给RILD的信息。
3、RIL_register注册RILD与RILJ之间的socket,并为每个socket注册监听器,把监听的事件添加到s_tid_dispatch线程中。
厂商定制化原生ril,形成vendor ril,就从上面三点来定制。
1、RIL_startEventLoop不需要怎么修改,因为只是负责监听socket是否有消息,然后分发,与具体的消息内容关系不大。
2、RIL_Init负责初始化RILD与modem的socket通道,这里可以定制有多个socket通道,而每个socket都需要有自己的tid_reader线程来读取socket信息,而且可以增加厂商自己的unsolicited type命令。
s_tid_mainloop线程的循环体mainLoop中,打开RILD与modem的socket通道时调用openChannelFds,看看都做了啥
void openChannelFds() {
RILChannelCtx *p_channel;
//遍历支持的通道,然后打开
for (i = 0; i < getSupportChannels(); i++) {
p_channel = getChannelCtxbyId(i);
while (p_channel->fd < 0) {
do
p_channel->fd = open(s_mux_path[i], O_RDWR);
while (p_channel->fd < 0 && errno == EINTR);
s_closed = 0;
ret = at_open(p_channel->fd, onUnsolicited, p_channel);
}
}
3、RIL_register注册RILD与RILJ之间的socket,厂商可以增加多个socket及socket listener。可以增加厂商自己的AT命令。
extern "C" void
RIL_register (const RIL_RadioFunctions *callbacks) {
s_isEngLoad = isEngLoad();
//支持几张卡,定义几个socket
for (i = 0; i < SIM_COUNT; i++) {
s_ril_param_socket[i] = {
(RIL_SOCKET_ID)(RIL_SOCKET_1+i), /* socket_id */
-1, /* fdListen */
-1, /* fdCommand */
PHONE_PROCESS, /* processName */
&s_commands_event[i], /* commands_event */
&s_listen_event[i], /* listen_event */
processCommandsCallback, /* processCommandsCallback */
NULL /* p_rs */
};
}
s_registerCalled = 1;
//s_commands,s_unsolResponses是原生通用的命令,s_xxx_commands,s_xxx_unsolResponses,s_xxx_local_commands,s_xxx_local_urc_commands是厂商自定义的命令
for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
assert(i == s_commands[i].requestNumber);
}
for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
assert(i + RIL_UNSOL_RESPONSE_BASE
== s_unsolResponses[i].requestNumber);
}
for (int i = 0; i < (int)NUM_ELEMS(s_xxx_commands); i++) {
if (i + RIL_REQUEST_VENDOR_BASE != s_mtk_commands[i].requestNumber) {
}
}
for (int i = 0; i < (int)NUM_ELEMS(s_xxx_unsolResponses); i++) {
if (i + RIL_UNSOL_VENDOR_BASE != s_mtk_unsolResponses[i].requestNumber) {
}
}
for (int i = 0; i < (int)NUM_ELEMS(s_xxx_local_commands); i++) {
if (i + RIL_LOCAL_REQUEST_VENDOR_BASE != s_mtk_local_commands[i].requestNumber) {
}
}
for (int i = 0; i < (int)NUM_ELEMS(s_xxx_local_urc_commands); i++) {
if (i + RIL_LOCAL_GSM_UNSOL_VENDOR_BASE != s_mtk_local_urc_commands[i].requestNumber) {
}
}
// 为每个socket注册监听器
for (i = 0; i < SIM_COUNT; i++) {
startListen((RIL_SOCKET_ID)(RIL_SOCKET_1+i), &s_ril_param_socket[i]);
}
......
}
由于增加了许多自定义命令,在onUnsolicited中也得增加处理
static void onUnsolicited(const char *s, const char *sms_pdu, void *pChannel)
{
RILChannelCtx *p_channel = (RILChannelCtx *)pChannel;
//MTK-START [mtk04070][111213][ALPS00093395] ATCI for unsolicited response
char atci_urc_enable[PROPERTY_VALUE_MAX] = { 0 };
property_get("persist.service.atci_urc.enable", atci_urc_enable, "0");
if ((NULL != s) && (atoi(atci_urc_enable) == 1)) {
RIL_onUnsolicitedResponse(RIL_UNSOL_ATCI_RESPONSE, s, strlen(s), getRILIdByChannelCtx(p_channel));
if (isSMSUnsolicited(s)) {
RIL_onUnsolicitedResponse(RIL_UNSOL_ATCI_RESPONSE, sms_pdu, strlen(sms_pdu)+1,
getRILIdByChannelCtx(p_channel));
}
}
//MTK-END [mtk04070][111213][ALPS00093395] ATCI for unsolicited response
//TODO: use api only for chip test now, will apply to phone mode afterwards
int rid = getRILIdByChannelCtx(p_channel);
if(rid == getMainProtocolRid() && s != NULL && isMalSupported() && !strStartsWith(s, "+EIND: 128")) {
if (isSMSUnsolicited(s)){
// 5 for 2 \r\n and 1 \0
urcToMalLength = strlen(s) + strlen(sms_pdu) + 9;
line = (char *) calloc(1, urcToMalLength);
strcpy(line, "\r\n");
strcat(line, s);
strcat(line, "\r\n");
strcat(line, "\r\n");
strcat(line, sms_pdu);
strcat(line, "\r\n\0");
} else {
urcToMalLength = strlen(s) + 5;
line = (char *) calloc(1, urcToMalLength);
strcpy(line, "\r\n");
strcat(line, s);
strcat(line, "\r\n\0");
}
cacheRawUrcToMal(MAL_MD_ID_GSM, rid, line);
}
//可以看到,厂商把Unsolicited命令分成了网络、通话、补充服务、短信、stk、oem、数据连接、sim卡和电话本九类
if (!(rilNwUnsolicited(s, sms_pdu, p_channel) ||
rilCcUnsolicited(s, sms_pdu, p_channel) ||
rilSsUnsolicited(s, sms_pdu, p_channel) ||
rilSmsUnsolicited(s, sms_pdu, p_channel) ||
rilStkUnsolicited(s, sms_pdu, p_channel) ||
rilOemUnsolicited(s, sms_pdu, p_channel) ||
rilDataUnsolicited(s, sms_pdu, p_channel) ||
rilSimUnsolicited(s, sms_pdu, p_channel) ||
rilPhbUnsolicited(s, sms_pdu, p_channel)))
RLOGE("Unhandled unsolicited result code: %s\n", s);
}