当前位置:首页 > Android中RIL层详细分析解析
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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;
共分享92篇相关文档