Android中RIL层详细分析解析 联系客服

发布时间 : 星期六 文章Android中RIL层详细分析解析更新完毕开始阅读124fdd7c657d27284b73f242336c1eb91b37334a

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

readerLoop()作用:阻塞地去读取,modem发过来的AT命令,并回应(OK)和上报上层,后再去阻塞的形式读取等待下一个AT命令

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

static void *readerLoop(void *arg)

{

LOGD(\ for (;;) {

const char * line;

line = readline();

if (line == NULL) { break; }

if((isSMSUnsolicited(line)) { char *line1; const char *line2;

LOGD(\ // The scope of string returned by 'readline()' is valid only // till next call to 'readline()' hence making a copy of line // before calling readline again. line1 = strdup(line); line2 = readline(); if (line2 == NULL) { break; }

if (s_unsolHandler != NULL) { s_unsolHandler (line1, line2); }

free(line1); } else {

processLine(line); }

#ifdef HAVE_ANDROID_OS if (s_ackPowerIoctl > 0) {

/* acknowledge that bytes have been read and processed */ ioctl(s_fd, OMAP_CSMI_TTY_ACK, &s_readCount); s_readCount = 0; }

#endif /*HAVE_ANDROID_OS*/ }

onReaderClosed();

return NULL; }

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ /**

* Reads a line from the AT channel, returns NULL on timeout. * Assumes it has exclusive read access to the FD *

* This line is valid only until the next call to readline *

* This function exists because as of writing, android libc does not * have buffered stdio. */

static const char *readline()

{

ssize_t count; char *p_read = NULL; char *p_eol = NULL; char *ret;

LOGD(\

/* this is a little odd. I use *s_ATBufferCur == 0 to

* mean \ * the buffer continues until a \\0 */

if (*s_ATBufferCur == '\\0') { /* empty buffer */

s_ATBufferCur = s_ATBuffer; *s_ATBufferCur = '\\0'; p_read = s_ATBuffer;

} else { /* *s_ATBufferCur != '\\0' */

/* there's data in the buffer from the last read */ // skip over leading newlines

while (*s_ATBufferCur == '\\r' || *s_ATBufferCur == '\\n') s_ATBufferCur++;

p_eol = findNextEOL(s_ATBufferCur); if (p_eol == NULL) {

/* a partial line. move it up and prepare to read more */ size_t len;

len = strlen(s_ATBufferCur);

memmove(s_ATBuffer, s_ATBufferCur, len + 1); p_read = s_ATBuffer + len; s_ATBufferCur = s_ATBuffer; }

/* Otherwise, (p_eol !- NULL) there is a complete line */ /* that will be returned the while () loop below */ }

while (p_eol == NULL) {

if (0 == MAX_AT_RESPONSE - (p_read - s_ATBuffer)) { LOGE(\ /* ditch buffer and start over again */ s_ATBufferCur = s_ATBuffer; *s_ATBufferCur = '\\0'; p_read = s_ATBuffer; } do {

count = read(s_fd, p_read,

MAX_AT_RESPONSE - (p_read - s_ATBuffer)); } while (count < 0 && errno == EINTR); if (count > 0) {

AT_DUMP( \ s_readCount += count; p_read[count] = '\\0'; // skip over leading newlines

while (*s_ATBufferCur == '\\r' || *s_ATBufferCur == '\\n') s_ATBufferCur++;

p_eol = findNextEOL(s_ATBufferCur); p_read += count; } else if (count <= 0) {

/* read error encountered or EOF reached */ if(count == 0) {

LOGD(\ } else {

LOGD(\ }

return NULL; } }

/* a full line in the buffer. Place a \\0 over the \\r and return */ ret = s_ATBufferCur; *p_eol = '\\0';

s_ATBufferCur = p_eol + 1; /* this will always be <= p_read, */ /* and there will be a \\0 at *p_read */ //在这打印Modem回应的OK信息 LOGD(\

return ret;//返回,读取好的上面信息 }

------------------

<二>---RIL层代码分析

---RIL_startEventLoop()->eventLoop()->ril_event_ loop()

ril/rild/rild.c->main()为函数入口

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.消息队列select为非阻塞的去轮询事件 2.read的阻塞的去读取上层发下来的命令,并响应

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- int main(int argc, char **argv) {

const char * rilLibPath = NULL; char **rilArgv; void *dlHandle;

const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **); const RIL_RadioFunctions *funcs; char libPath[PROPERTY_VALUE_MAX]; unsigned char hasLibArgs = 0; ........ OpenLib: #endif

switchUser();

/*打开dlopen()函数,就会动态去加载动态库vendor RIL 获取由RIL_register(funcs);注册进来的参数,并解析*/ dlHandle = dlopen(rilLibPath, RTLD_NOW); if (dlHandle == NULL) {

fprintf(stderr, \ exit(-1); }

/*消息队列的入口,添加到select,用阻塞方式去读取那些ril_event_set()的数据##每当看到打印信息,不按顺序打下来说明阻塞##*/

RIL_startEventLoop();

/*通过dlsym函数得到rilInit函数指针的引用*/

rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, \ if (rilInit == NULL) {

fprintf(stderr, \ exit(-1); }

if (hasLibArgs) { rilArgv = argv + i - 1;