今天有进展,找到出错的地方了,根据logcat -b radio的打印信息,追踪代码,对ril有个进一步的了解。
首先,3G模块的驱动要加载insmod **ko,这样会生成/dev/ttyUSB*,作为3G模块和CPU,无线部分和linux的通信通道,
然后,在init.rc里定义服务
service ril-daemon /system/bin/rild*** -l /system/lib/libreference-ril.so -- -d /dev/ttyUSB*
socket rild stream 660 root radio
socket rild-debug stream 660 radio system
user root
group radio cache inet misc audio
,这样一开机就会运行守护进程rild,他共过-l system/lib/libreference-ril.so来调用ril的功能解释库,专门用来转换上层的发来的消息和下层送来的AT命令的,-d /dev/ttyUSB*用来指定AT命令的控制端口
接下来见了两个socket ,用来和上层的framework通信,
所有这些反映在代码里就是hardware/ril/目录中
/rild***/rild.c rild守护进程的代码 对应/system/bin/rild
/rild***/radiooptions.c ril的测试程序 对应/system/bin/radiooptoins***
/reference-ril/reference-ril.c ril的功能实现库,消息转换 对应/system/lib/libreference-ril.so
/libril***/ril.cpp 主要用来注册ril,对应/system/lib/libril***.so
在rild.c中
int main(int argc, char **argv)
{
LOGI("start of main in rild.c ziilabs");
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];
#if RILD_RUN_AS_ROOT_WORKAROUND
char runAsRoot[PROPERTY_VALUE_MAX];
#endif /* RILD_RUN_AS_ROOT_WORKAROUND */
unsigned char hasLibArgs = 0;
int i;
for (i = 1; i < argc ;) {
if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
rilLibPath = argv[i + 1];
i += 2;
} else if (0 == strcmp(argv[i], "--")) {
i++;
hasLibArgs = 1;
break;
} else {
usage(argv[0]);
}
}
if (rilLibPath == NULL) {
if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
// No lib sepcified on the command line, and nothing set in props.
// Assume "no-ril" case.
LOGD("libPath is %s... no ril",rilLibPath);
goto done;
} else {
rilLibPath = libPath;
LOGD("libPath is %s... have ril",rilLibPath);
}
}
/* special override when in the emulator */
#if 1
{
static char* arg_overrides[3];
static char arg_device[32];
int done = 0;
#define REFERENCE_RIL_PATH "/system/lib/libreference-ril.so"
/* first, read /proc/cmdline into memory */
char buffer[1024], *p, *q;
int len;
int fd = open("/proc/cmdline",O_RDONLY);
if (fd < 0) {
LOGD("could not open /proc/cmdline:%s", strerror(errno));
goto OpenLib;
}
do {
len = read(fd,buffer,sizeof(buffer)); }
while (len == -1 && errno == EINTR);
if (len < 0) {
LOGD("could not read /proc/cmdline:%s", strerror(errno));
close(fd);
goto OpenLib;
}
close(fd);
if (strstr(buffer, "android.qemud=") != NULL)
{
/* the qemud daemon is launched after rild, so
* give it some time to create its GSM socket
*/
int tries = 5;
#define QEMUD_SOCKET_NAME "qemud"
while (1) {
int fd;
sleep(1);
fd = socket_local_client(
QEMUD_SOCKET_NAME,
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM );
if (fd >= 0) {
close(fd);
snprintf( arg_device, sizeof(arg_device), "%s/%s",
ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );
arg_overrides[1] = "-s";
//arg_overrides[2] = arg_device;
arg_overrides[2] = "/dev/ttyUSB0";
done = 1;
break;
}
LOGD("could not connect to %s socket: %s",
QEMUD_SOCKET_NAME, strerror(errno));
if (--tries == 0)
break;
}
if (!done) {
LOGE("could not connect to %s socket (giving up): %s",
QEMUD_SOCKET_NAME, strerror(errno));
while(1)
sleep(0x00ffffff);
}
}
/* otherwise, try to see if we passed a device name from the kernel */
if (!done) do {
#define KERNEL_OPTION "android.ril="
#define DEV_PREFIX "/dev/"
p = strstr( buffer, KERNEL_OPTION );
if (p == NULL)
break;
p += sizeof(KERNEL_OPTION)-1;
q = strpbrk( p, " \t\n\r" );
if (q != NULL)
*q = 0;
snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
arg_device[sizeof(arg_device)-1] = 0;
arg_overrides[1] = "-d";
//arg_overrides[2] = arg_device;
arg_overrides[2] = "/dev/ttyUSB0";
done = 1;
} while (0);
if (done) {
argv = arg_overrides;
argc = 3;
i = 1;
hasLibArgs = 1;
rilLibPath = REFERENCE_RIL_PATH;
LOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
}
}
OpenLib:
#endif
#if RILD_RUN_AS_ROOT_WORKAROUND
// If the property is not set, it will be set to "no" by default.
property_get(RUN_AS_ROOT_PROPERTY, runAsRoot, "no");
if (0 == strcmp("no", runAsRoot)) {
switchUser();
}
#else /* !RILD_RUN_AS_ROOT_WORKAROUND */
switchUser();
#endif /* !RILD_RUN_AS_ROOT_WORKAROUND */
dlHandle = dlopen(rilLibPath, RTLD_NOW);
if (dlHandle == NULL) {
fprintf(stderr, "dlopen failed: %s\n", dlerror());
exit(-1);
}
LOGD("before RIL start Event Loop");
//LOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
RIL_startEventLoop();
LOGD("after RIL start Event Loop");
//LOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");
if (rilInit == NULL) {
fprintf(stderr, "RIL_Init not defined or exported in %s\n", rilLibPath);
exit(-1);
}
if (hasLibArgs) {
rilArgv = argv + i - 1;
argc = argc -i + 1;
} else {
static char * newArgv[MAX_LIB_ARGS];
static char args[PROPERTY_VALUE_MAX];
rilArgv = newArgv;
property_get(LIB_ARGS_PROPERTY, args, "");
argc = make_argv(args, rilArgv);
}
// Make sure there's a reasonable argv[0]
rilArgv[0] = argv[0];
LOGD("before riInit %d ,%s in rild.c ziilabs",argc,rilArgv);
funcs = rilInit(&s_rilEnv, argc, rilArgv);
LOGD("after riInit %d ,%s in rild.c ziilabs",argc,rilArgv);
LOGD("before RIL register in rild.c ziilabs");
RIL_register(funcs);
LOGD("before RIL register in rild.c ziilabs");
done:
LOGI("start of done while in rild.c ziilabs");
while(1) {
// sleep(UINT32_MAX) seems to return immediately on bionic
LOGI("while in rild.c ziilabs");
sleep(0x00ffffff);
}
}
主体是
int main(int argc,char ** argv)
{
void *dlHandle;
const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
const RIL_RadioFunctions *funcs;
....启动服务时通过argv获取*.so和ttyUSB*
dlHandle = dlopen(rilLibPath, RTLD_NOW);
RIL_startEventLoop();
rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");
funcs = rilInit(&s_rilEnv, argc, rilArgv);
RIL_register(funcs);
while(1) {
// sleep(UINT32_MAX) seems to return immediately on bionic
sleep(0x00ffffff);
}
}
现在报错RIL_register: RIL_RadioFunctions * null or invalid version (expected 2)
出现在RIL_register(funcs);//ril.cpp文件中,libril.so
但原因很可能是funcs指针前面没获取好所致
if (callbacks == NULL || ((callbacks->version != RIL_VERSION)
&& (callbacks->version != 2))) { // Remove when partners upgrade to version 3
LOGE(
"RIL_register: RIL_RadioFunctions * null or invalid version"
" (expected %d)", RIL_VERSION);funcs是一个指向RIL_RadioFunctions的指针,
rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");
funcs = rilInit(&s_rilEnv, argc, rilArgv);
问题可能就出在这两句话上,rilInit()函数位于reference-ril.c中,从打印信息来看I/RIL ( 1060): start of ril_init in reference-ril.c
I/RIL(1060):opt is 100 in ril_initreference-ril.c
I/RIL(1060):Opening tty device/dev/ttyUSB0
I/RIL(1060): pthread_attr_initof ril_init inreference-ril.c
I/RIL(1060):end of ril_init inreference-ril.c这里好像没错,那问题可能出在前一句话,看着有点麻烦,明天再看,今天就到这里,总算缩小范围了。