RIL层源码分析w(4)

2019-09-01 20:03

上面绕了一圈,还是把对消息的处理从动态库(也就是reference-ril.c文件)饶回到了ril.c文件中。这也符合整个RIL架构的设计理念:框架和处理方式由ril.c管理,差异化的AT命令由reference实现。 @ril.cpp

void RIL_onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen, RILId id) {

//得到当前命令的请求码

unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE; //从ril_unsol_commands.h文件中得到命令的类型

wakeType = s_unsolResponses[unsolResponseIndex].wakeType; //根据不同命令的不同类型进行解析 switch (wakeType) { case WAKE_PARTIAL: case DONT_WAKE: }

appendPrintBuf(\

Parcel p;

p.writeInt32 (RESPONSE_UNSOLICITED); p.writeInt32 (unsolResponse);

//调用当前命令的打包函数进行数据打包

ret = s_unsolResponses[unsolResponseIndex].responseFunction(p, data, datalen); //把数据发送到RILJ中 ret = sendResponse(p,id);

if (shouldScheduleTimeout) { }

return; }

上面的处理过程分为2步:1、调用当前命令对应的打包函数进行数据打包;2、将数据发送给RILJ。 数据打包的过程涉及到一个数组s_unsolResponses,他的详细作用在本文的最后一张有说明,这里简要介绍一下。s_unsolResponses是一个文件,文件中对所有的URC消息都有一个对应的数组相对应,每个数组分3部分:1、命令的请求码;2、命令的打包函数;3、命令的类型;我们要做的就是用当前Modem给出的命令,找到对应的请求码,然后得到相应的打包函数进行数据打包。

而发送的过程就是调用sendResponse把Parcel数据发送给RILJ。

在上面的过程中,用reference中通过AT头转换的命令值与RIL_UNSOL_RESPONSE_BASE相减得到在

s_unsolResponses表中对应的命令索引。查找相应的wakeType类型去决定是否计算超时(shouldScheduleTimeout),之后就用s_unsolResponses中的responseFunction去解析命令,最后通过sendResponse将数据发送给RILJ: static int sendResponse (Parcel &p) {

return sendResponseRaw(p.data(), p.dataSize()); }

发送数据:

static int sendResponseRaw (const void *data, size_t dataSize) { //发送通道的Socket ID int fd = s_fdCommand; int ret;

uint32_t header;

//将数据长度这个整数转换为适合Socket 传输的字节顺序 header = htonl(dataSize);

//先发送一个关于数据大小的字节

ret = blockingWrite(fd, (void *)&header, sizeof(header));

//再发送数据本身

ret = blockingWrite(fd, data, dataSize);

return 0; }

继续看发送过程:

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 {

//发送数据到fd指定的句柄中,也就是RILJ对应的Socket通道 written = write (fd, toWrite + writeOffset,len - writeOffset); } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN))); } return 0; }

这里注意到,发送的最终操作,就是把数据放到一个fd指向的句柄中,那么这个句柄从哪里来的呢? #define SOCKET_NAME_RIL \ //得到\的Socket连接

s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);

//accept的函数默认会阻塞进程,直到有一个客户连接建立后把可用的连接套接字返回 s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);

上面的递归关系我们可以看出,s_fdCommand就是RILJ与RILC之间建立的Socket通道的套接字!因此我们可以通过这个通道发送数据给RILJ。

2.3、非URC消息处理流程

上面介绍了URC消息的流程,下面分析一下更普遍的非URC消息的处理流程。

前面说道,非URC消息就是一种回应。当上层通过AT向Modem发送请求后,会一直处于阻塞状态等待回应,一旦readerLoop得到了非URC的消息,就会去唤醒Event端等待的进程。 我们在此主要介绍reference如何唤醒eventLoop端的线程。 非URC消息的上报流程也是从processLine开始的: @atchannel.c

static void processLine(const char *line) {

if (sp_response == NULL) {

} else if (isFinalResponseSuccess(line)) { sp_response->success = 1; //发送回应消息给eventLoop handleFinalResponse(line); } else if (isFinalResponseError(line)) {

} else if (s_smsPDU != NULL && 0 == strcmp(line, \ } else switch (s_type) { case NO_RESULT: case NUMERIC:

if (sp_response->p_intermediates == NULL && isdigit(line[0]) ) {

addIntermediate(line); } else {

handleUnsolicited(line); } break; case SINGLELINE:

if (sp_response->p_intermediates == NULL && strStartsWith (line, s_responsePrefix) ) {

addIntermediate(line); } else {

handleUnsolicited(line); } break; case MULTILINE: break; } }

这里简要介绍以下Modem对于非URC消息的回复格式。消息一般大于2行,前几行是返回值的有效数据,最后一行是作为当前命令结束的标志位。如果是有效数据,那么当前数据就有一个s_type的类型与之相关联(从EventLoop发送给reference时决定)。因此就会在processLine中的switch中进入addIntermediate函数,而这个函数的作用就是把当前的数据放入到反馈数据的sp_response->p_intermediates里面。等到命令的最后,因为是标志位,就会走到processLine的handleFinalResponse中,将数据发送给Event侧。 下面贴出涉及到的重要函数:

a、将数据放到反馈数据中:addIntermediate static void addIntermediate(const char *line) {

ATLine *p_new;

p_new = (ATLine *) malloc(sizeof(ATLine)); p_new->line = strdup(line);

p_new->p_next = sp_response->p_intermediates; //把有效的返回值放到sp_response->p_intermediates中 sp_response->p_intermediates = p_new; }


RIL层源码分析w(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2018年湖南省政府采购评审专家库培训测评-多选题部分答案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: