3 守护进程

ril与上层的RILJ沟通方式是通过Socket传输数据与命令,而reference-ril与底层Modem的信号传输是通过串口用AT命令来实现。

RILC是一个守护进程,由init进程启动,init.rc文件配置如下,

service ril-daemon /system/bin/rildclass mainsocket rild stream 660 root radiosocket rild-debug stream 660 radio systemuser rootgroup radio cache inet misc audio log qcom_diag

由配置文件可知,

1,如果该守护进程异常退出,android系统会进行重新加载。

2,会建立2个socket,端口号为rild负责和RILJ进行通信。

该守护进程的入口为rild.c的main方法,main方法比较长,主要逻辑如下,

1、开启EventLoop循环,完成RILC与RILJ层数据交互(通过Socket)

2、打开动态库reference并构建ReaderLoop循环,完成RIL与Modem层数据交互(通过AT)

3、注册reference的回调函数。

根据通信方法,将该守护进程分为2部分:

1,Event:利用socket完成RILC与RILJ层数据交互。

2, reference-ril:利用AT指令完成RILC与Modem层数据交互。

3.1,EventLoop

ril.cpp的RIL_startEventLoop方法如下,

extern "C" void RIL_startEventLoop(void) {/* spin up eventLoop thread and wait for it to get started */s_started = 0;pthread_mutex_lock(&s_startupMutex);pthread_attr_t attr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//打开Event线程,并调用eventLoop进入循环int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);if (result != 0) {RLOGE("Failed to create dispatch thread: %s", strerror(result));goto done;}while (s_started == 0) {pthread_cond_wait(&s_startupCond, &s_startupMutex);}done:pthread_mutex_unlock(&s_startupMutex);
}

这样,Event线程就会监听RILJ发过来的数据了,eventLoop方法在后面会详细分析。好了,RILJ到RILC这条路已经通了。

3.2 ReaderLoop

rild.c中main方法有关加载动态库reference代码如下,

#define  REFERENCE_RIL_PATH  "libreference-ril.so"
rilLibPath = REFERENCE_RIL_PATH;rilInit =(const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");dlHandle = dlopen(rilLibPath, RTLD_NOW);//加载库
•••
funcs = rilInit(&s_rilEnv, argc, rilArgv);//初始化   实际调用的是RIL_Init方法

s_rilEnv结构体定义如下,也就是reference-ril可以回调ril的方法

static struct RIL_Env s_rilEnv = {RIL_onRequestComplete,RIL_onUnsolicitedResponse,RIL_requestTimedCallback
};

将ril的s_rilEnv传给reference-ril的s_rilenv之后,reference-ril就可以利用该结构调用ril的方法。这样,reference-ril到ril这条路也通了。

reference-ril.c的RIL_Init主要代码如下,

ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);//创建线程,入口方法是mainLoopreturn &s_callbacks;

在此必须要说的是, reference-ril.c还有一个main方法,其实main方法和RIL_Init方法作用几乎完全一样。

只是reference-ril.c作为动态库是调用的是RIL_Init方法,如果作为单独进程就会调用main方法。

这样,mainLoop线程就会监听Modem发过来的数据了, mainLoop方法在后面会详细分析。好了, Modem到RILC这条路已经通了。

3.3 RIL_register

rild.c中main方法有关加载动态库RIL注册的代码如下,

funcs = rilInit(&s_rilEnv, argc, rilArgv);RIL_register(funcs); //注册reference  的回调函数

当我们调用reference的初始化函数(也就是RIL_Init)后, 将会得到一个RIL_RadioFunctions类型的返回值,reference-ril.c中如下,

static const RIL_RadioFunctions s_callbacks = {RIL_VERSION,onRequest,currentState,onSupports,onCancel,getVersion
};

ril.h中定义这个变量类型如下,也就是ril可以调用reference-ril的方法。

typedef struct {  int version;        //当前链接库的版本信息  RIL_RequestFunc onRequest;  //用于Event侧向动态库发起请求  RIL_RadioStateRequest onStateRequest;   //得到当前库的状态  RIL_Supports supports;  //查询是否支持某个命令  RIL_Cancel onCancel;       //取消一个Event的处理  RIL_GetVersion getVersion;  //得到版本号
} RIL_RadioFunctions;

RIL_register 主要代码如下,

//把返回值传给s_callbacks(全局变量)
memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));//打开RILC与RILJ之间的Socket通道s_ril_param_socket = {RIL_SOCKET_1,             /* socket_id */-1,                       /* fdListen */-1,                       /* fdCommand */PHONE_PROCESS,            /* processName */&s_commands_event,        /* commands_event */&s_listen_event,          /* listen_event */processCommandsCallback,  /* processCommandsCallback */NULL                      /* p_rs */};
startListen(RIL_SOCKET_1, &s_ril_param_socket);// 监听rild socket

将reference-ril的callbacks传给ril的s_callbacks之后, ril就可以利用该结构调用reference-ril的方法。这样, ril到reference-ril这条路也通了。

startListen主要方法如下,

memset(socket_name, 0, sizeof(char)*10);
fdListen = android_get_control_socket(socket_name); 打开RILC与RILJ之间的Socket通道ret = listen(fdListen, 4);
socket_listen_p->fdListen = fdListen;//用这个Socket通道句柄创建一个Event
ril_event_set (socket_listen_p->listen_event, fdListen, false,listenCallback, socket_listen_p);rilEventAddWakeup (socket_listen_p->listen_event); //添加到Eventloop中

ril_event_set方法如下,

void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param)
{dlog("~~~~ ril_event_set %x ~~~~", (unsigned int)ev);memset(ev, 0, sizeof(struct ril_event));ev->fd = fd;ev->index = -1;ev->persist = persist;ev->func = func;ev->param = param;fcntl(fd, F_SETFL, O_NONBLOCK);
}

在第五章中,消息从socket读取之后,会回调func方法,这里的func就指向listenCallback。

3.4 消息流程

有前面的分析可知,消息会在4个模块中走一遍,消息流动方法如下,

1,从RIL到RIL。

2,从RIL到reference-ril

3, 从reference-ril到Modem

4,Modem处理完成之后,又从modem到reference-ril

5,从reference-ril到RIL

6,从RIL到RILJ。

但是,很多时候,比如来电了,这个信息是直接从Modem出发的, 只需要经过以下三个流程。

1,modem到reference-ril

2,从reference-ril到RIL

3,从RIL到RILJ。

为了便于论述,将modem主动往上层发送的消息称为上报消息;从RILJ发送出Modem处理完成之后再往上层发送的消息称为回应消息。

RILJ和ril利用socket进行通信。

ril和reference-ril在同一个进程,因此只需用简单的回调就可以完成通信。

reference-ril和Modem利用串口进行通信,每个厂商一般都不相同,但是一般都是利用tty端口进行通信。

这样,按照发送到接收,从Java层到C/C++层的顺序来仔细的捋一捋整个ril机制。

RIL 机制---rild守护进程相关推荐

  1. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路(1)

    上一篇文章Android进程间通信(IPC)机制Binder简要介绍和学习计划简要介绍了Android系统进程间通信机制Binder的总体架构,它由Client.Server.Service Mana ...

  2. Android——RIL 机制源码分析

    Android 电话系统框架介绍 在android系统中rild运行在AP上,AP上的应用通过rild发送AT指令给BP,BP接收到信息后又通过rild传送给AP.AP与BP之间有两种通信方式: 1. ...

  3. RIL 机制---开篇

    1, 概念 本文基于android 6.0.RIL(Radio Interface Layer,无线通信接口层)主要相关的结构如下, 为了便于论述,将RIL分为三个部分, 1, Framework层中 ...

  4. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路

    原文地址: http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信(IPC)机制Binder简要介绍和学 ...

  5. Python守护进程命令,再也不怕被整蛊了!

    考虑一下利用Python制作一个整蛊.木马软件,我提供思路.(清楚到没学过编程的人也理解) 1.首先一个黑客做一个整蛊或者木马软件,一定不会让你能够关闭它. 2.里面经常会附带欺骗的方法. 3.最终实 ...

  6. android 8 ril,Android系统启动——8 附录2:相关守护进程简介

    本次系列的内容如下: 在init.rc中定义了很多系统的守护进程,这里主要是做一些简单的介绍 一.uevent 负责相应uevent事件,创建设备节点文件: 代码在init.rc 550行 550se ...

  7. 带你认识Flink容错机制的两大方面:作业执行和守护进程

    摘要:Flink 容错机制主要有作业执行的容错以及守护进程的容错两方面,前者包括 Flink runtime 的 ExecutionGraph 和Execution的容错,后者则包括 JobManag ...

  8. 浅显理解*nix下的守护进程机制及fork函数

    最近空闲时间重新仔细看了一下memcached的使用说明文档,硬着头皮看了一点源码,有时候看到一些晦涩的c函数感觉实在恍惚只能跳过.不过也不算是全无收获,终于LZ还敢再看c语言,终于LZ又看起了c语言 ...

  9. python并发编程之semaphore(信号量)_python 之 并发编程(守护进程、互斥锁、IPC通信机制)...

    9.5 守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就立即终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic process ...

最新文章

  1. mysql error number 1130,[转]mysql error number 1130的解决方法
  2. ExclusiveTouch
  3. 在虚拟机上装win2003 server心得体会
  4. 基于TCP的在线聊天程序
  5. 未发现数据源名称并且未指定默认驱动程序_看我如何发现NVIDIA GeForce Experience代码执行漏洞...
  6. C#LeetCode刷题-字典树
  7. git - 基础 - 01 - git reset --hard 回滚以后,看不到之前的分支版本怎么解决:
  8. 使用 ‘In Place’ 直接从MySQL 5.0升级至5.7
  9. webpack4入门笔记——loader
  10. java用户邮件激活
  11. java毕业设计——基于java+Java Swing+sqlserver的图书馆书库管理系统设计与实现(毕业论文+程序源码)——图书馆书库管理系统
  12. C语言文件指针,如何对文件进行操作,文件指针FILE,指向文件指针
  13. 今天母亲节,作为程序员,我是这样表达母爱的……
  14. 同一服务器中,同一框架下的不同二级域名之间网站session如何互通
  15. 哈代:数学家一生是少年
  16. 骨传导耳机到底怎么样,五款好用的骨传导耳机推荐
  17. python能否取代excel_行,Python玩大了!​取代Excel,程序员:太牛!你怎么看?...
  18. WorldModel世界模型代码训练实录
  19. MATLAB怎么计算曲面面积,Matlab曲面面积估计.doc
  20. 2022“杭电杯”中国大学生算法设计超级联赛(1)1003 Backpack个人题解

热门文章

  1. 网友自制石膏面具可解锁iPhone X
  2. UEG-F-10H-L抗干扰中继电器
  3. 金蝶云星空多组织修改分配物料处理
  4. python微信抢红包代码_用Python实现微信自动化抢红包,再也不用担心抢不到红包了...
  5. L1-075 强迫症 (10 分)
  6. Java中的聚合与组合
  7. 一道基本的计算几何题
  8. 物联网控制基础|计算机控制技术|刘川来胡乃平|4th WEEK
  9. Arduino UNO驱动micro SD卡读写模块
  10. 洛伦茨曲线半高全宽_合理的半高宽FWHM.PPT