RIL Socket 资源创建
service ril-daemon /system/bin/rild
class mainsocket rild stream 660 root radio
socket sap_uim_socket1 stream 660 bluetooth bluetooth
socket rild-debug stream 660 radio system
user root
group radio cache inet misc audio log
radiooptions.c 解析:
int main(int argc, char *argv[])
{
int fd;
int num_socket_args = 0;
int i = 0;
int modem_socket_type = 0;
int sim_id = 0;
char socket_name[20];
if(error_check(argc, argv)) {
print_usage();
exit(-1);
}
num_socket_args = get_number_args(argv); // 执行参数个数
modem_socket_type = atoi(argv[(num_socket_args-1)]); //The last argument must be modem-socket style \n\
sim_id = atoi(argv[(num_socket_args-2)]); // The argument before the last one must be SIM slot \n\
memset(socket_name, 0, sizeof(char)*20);
if (sim_id == 0 || modem_socket_type == 1) {
strncpy(socket_name, SOCKET_NAME_RIL_DEBUG, 19);
} else if (sim_id == 1) {
strncpy(socket_name, SOCKET_NAME_RIL2_DEBUG, 19);
}
fd = socket_local_client(socket_name,
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM);
if (fd < 0) {
perror ("opening radio debug socket");
exit(-1);
}
/* It is not necessacry to pass the argument "modem-socket style" to rild */
最后一个参数modem-socket style 不需要发送到rild 进程
num_socket_args--; // 将参数个数减1
int ret = send(fd, (const void *)&num_socket_args, sizeof(int), 0); //发送参数个数
if(ret != sizeof(int)) {
perror ("Socket write error when sending num args");
close(fd);
exit(-1);
}
for (i = 0; i < num_socket_args; i++) { //将参数发送到rild 进程
// Send length of the arg, followed by the arg.
int len = strlen(argv[1 + i]); //获取每个参数的长度,并发送
ret = send(fd, &len, sizeof(int), 0);
if (ret != sizeof(int)) {
perror("Socket write Error: when sending arg length");
close(fd);
exit(-1);
}
ret = send(fd, argv[1 + i], sizeof(char) * len, 0); //发送每个参数的值
if (ret != len * sizeof(char)) {
perror ("Socket write Error: When sending arg");
close(fd);
exit(-1);
}
}
close(fd);
return 0;
}
编译radiooptions.c ,生成mtkradiooptions 可执行文件;
push 到手机 system/bin ,添加可执行权限:chmod 777 /system/bin/mtkradiooptions
执行如下:
mtkradiooptions 1 1 1 ;关闭radio
mtkradiooptions 5 1 1 ;打开radio
Native 端Ril.cpp ,以 rild-debug socket 讲解
extern "C" void
RIL_register (const RIL_RadioFunctions *callbacks) {
s_fdDebug = android_get_control_socket(rildebug);//获取ril-debug socket 描述符
if (s_fdDebug < 0) {
RLOGE("Failed to get socket : %s errno:%d", rildebug, errno);
exit(-1);
}
ret = listen(s_fdDebug, 4);//监听ril-debug socket
if (ret < 0) {
RLOGE("Failed to listen on ril debug socket '%d': %s",
s_fdDebug, strerror(errno));
exit(-1);
}
ril_event_set (&s_debug_event, s_fdDebug, true,
debugCallback, NULL); //传递socket 文件描述符,debugCallback 处理接收到的消息
}
static void debugCallback (int fd, short flags, void *param) {
acceptFD = accept (fd, (sockaddr *) &peeraddr, &socklen); // 接收socket 连接
if (acceptFD < 0) {
RLOGE ("error accepting on debug port: %d\n", errno);
return;
}
if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) { // 接收第一个数据(参数的个数)请求
RLOGE ("error reading on socket: number of Args: \n");
return;
}
args[i] = (char *) calloc(1, (sizeof(char) * len) + 1); // 接收参数数据
if (recv(acceptFD, args[i], sizeof(char) * len, 0)
!= (int)sizeof(char) * len) {
RLOGE ("error reading on socket: Args[%d] \n", i);
freeDebugCallbackArgs(i, args);
return;
}
}
static void
issueLocalRequest(int request, void *data, int len, RIL_SOCKET_ID socket_id) {
pRI->p_next = *pendingRequestsHook;
*pendingRequestsHook = pRI;
callOnRequest(request, data, len, pRI, pRI->socket_id);
}