Android RIL 动态切换 4G 模块适配

目录

修改的文件

文件修改说明

runtime.h

Android.mk(在 rild 目录下)

rild.c

Android.mk(在 runtime-ril-port 目录下)

runtime_port.c

如何适配


这个补丁是我加在全志A40 4.4上面的做模块动态适配的 , 毋庸置疑 后面的Android 版本也是适用的 , 比如rockchip 也是没问题的 只是我懒得搞了而已。

调试4G模块非常简单 只是说早期模块经常切换 , 换了还得换固件 , 固件其实只是更换了so库而已。因为kernel driver 已经对vid/pid进行了适配。

这个补丁是直接在hal 层rild 做的vid/pid 然后选择so库文件的。

这个补丁主要修改了 Android RIL (Radio Interface Layer) 的部分代码,以支持动态切换不同的 3G/4G 模块。

修改的文件

  • android/hardware/ril/include/runtime/runtime.h
  • android/hardware/ril/rild/Android.mk
  • android/hardware/ril/rild/rild.c
  • android/hardware/ril/runtime-ril-port/Android.mk
  • android/hardware/ril/runtime-ril-port/runtime_port.c

文件修改说明

runtime.h

这是一个新文件,定义了一些函数和变量,用于启动 uevent 监视器,获取当前的 3G 端口设备,数据和类型。

Android.mk(在 rild 目录下)

在这个 makefile 文件中,添加了 libruntime-ril-portLOCAL_SHARED_LIBRARIES,这样 rild 就可以链接到这个新的库。

rild.c

这个文件中的修改主要是在 rild 的主函数中,添加了对 3G 模块类型的检测,并根据检测到的模块类型,动态地设置 RIL 库的路径。此外,还添加了对 uevent 的监视,当检测到 3G 模块的变化时,会重新启动 rild。

Android.mk(在 runtime-ril-port 目录下)

这是一个新文件,用于编译 runtime_port.c,生成 libruntime-ril-port 库。

runtime_port.c

这是一个新文件,实现了在 runtime.h 中定义的函数。这些函数主要用于检测当前的 3G 模块类型,以及启动对 uevent 的监视。

如何适配

  1. 将这个补丁应用到你的 Android 源码树中。
  2. 根据你的 3G 模块的特性,修改 runtime_port.c 中的 modem_3g_device_table
  3. 编译并刷入你的 Android 系统。
  4. 当你的设备启动时,rild 会自动检测当前的 3G 模块类型,并加载相应的 RIL 库。

     
    diff --git a/android/hardware/ril/include/runtime/runtime.h b/android/hardware/ril/include/runtime/runtime.h
    new file mode 100755
    index 0000000000..c381b4f2f8
    --- /dev/null
    +++ b/android/hardware/ril/include/runtime/runtime.h
    @@ -0,0 +1,22 @@
    +/*
    + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
    + */
    +
    +#ifndef RUNTIME_H
    +#define RUNTIME_H
    +
    +extern int start_uevent_monitor(void);
    +extern const char *runtime_3g_port_device(void);
    +extern const char *runtime_3g_port_data(void);
    +extern int runtime_3g_port_type(void);
    +enum {
    +	ME909S_MODEM = 0,
    +	U9300C_MODEM,
    +	EC20_MODEM,
    +	EM8000_MODEM,
    +	UNKNOWN_MODEM,
    +};
    +
    +extern int current_modem_type;
    +
    +#endif
    diff --git a/android/hardware/ril/rild/Android.mk b/android/hardware/ril/rild/Android.mk
    index d8ca6d368d..83c0a1a130 100755
    --- a/android/hardware/ril/rild/Android.mk
    +++ b/android/hardware/ril/rild/Android.mk
    @@ -13,7 +13,8 @@ LOCAL_SHARED_LIBRARIES := \
     	liblog \
     	libcutils \
     	libril \
    -	libdl
    +	libdl  \
    +	libruntime-ril-port
     
     # temporary hack for broken vendor rils
     #LOCAL_WHOLE_STATIC_LIBRARIES := \
    diff --git a/android/hardware/ril/rild/rild.c b/android/hardware/ril/rild/rild.c
    index 4a555f275c..e79cd3cb71 100755
    --- a/android/hardware/ril/rild/rild.c
    +++ b/android/hardware/ril/rild/rild.c
    @@ -36,10 +36,19 @@
     #include "hardware/qemu_pipe.h"
     
     #include "radio_monitor.h"
    -
    +#include 
     #define LIB_PATH_PROPERTY   "rild.libpath"
     #define LIB_ARGS_PROPERTY   "rild.libargs"
     #define MAX_LIB_ARGS        16
    +#define MAX_POLL_DEVICE_CNT 8
    +
    +
    +
    +
    +#define REFERENCE_RIL_ME909S_PATH "/system/lib/libreference_me909s-ril.so"
    +#define REFERENCE_RIL_U9300C_PATH "/system/lib/libreference_u9300c-ril.so"
    +#define REFERENCE_RIL_EC20_PATH "/system/lib/libreference_ec20-ril.so"
    +#define REFERENCE_RIL_EM8000_PATH "/system/lib/libreference_em8000-ril.so"
     
     static void usage(const char *argv0)
     {
    @@ -64,6 +73,7 @@ static struct RIL_Env s_rilEnv = {
         RIL_onUnsolicitedResponse,
         RIL_requestTimedCallback
     };
    +static int s_poll_device_cnt = 0;
     
     extern void RIL_startEventLoop();
     
    @@ -109,44 +119,21 @@ int main(int argc, char **argv)
         char libPath[PROPERTY_VALUE_MAX];
         unsigned char hasLibArgs = 0;
         int ret = 0;
    +	int modem_type = UNKNOWN_MODEM;
         int i;
     	char platform[PROPERTY_VALUE_MAX] = {0};
     
     	//is telephony platform?
     	if(property_get("ro.sw.embeded.telephony", platform, NULL)){
     		if(strcmp(platform, "true")) {
    -			RLOGI("platform: wifi-only");
    +			RLOGI("platform: wifi-only --1");
     			radio_monitor();
     		}else{
    -			RLOGI("platform: telephony");
    +			RLOGI("platform: telephony --2");
     		}
     	}
     
    -#if 0
    -    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
    -    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.
    -            goto done;
    -        } else {
    -            rilLibPath = libPath;
    -        }
    -    }
    -#else
     	ret = property_get(LIB_PATH_PROPERTY, libPath, NULL);
     	if (ret <= 0) {
     		/* nothing to do */
    @@ -174,9 +161,62 @@ int main(int argc, char **argv)
     		RLOGD("err: get rilLibPath failed\n");
     		goto done;
     	}
    +	///$shh$20180906$add$Dynamic switching module$
    +	 //Wait for device ready.
    +   // if (rilLibPath == NULL) {
    +		while(UNKNOWN_MODEM == modem_type){
    +		    modem_type = runtime_3g_port_type();
    +		    ALOGD("111 -Couldn't find proper modem, retrying...");
    +		    s_poll_device_cnt++;
    +		    if (s_poll_device_cnt > MAX_POLL_DEVICE_CNT){
    +				/*
    +				*Maybe no device right now, start to monitor
    +				*hotplug event later.
    +				*/
    +				start_uevent_monitor();
    +				goto done;
    +		    }
    +		    sleep(5);
    +		}
    +    //}
     
    -#endif
    -    RLOGD("\nrilLibPath = %s\n\n", rilLibPath);
    +	start_uevent_monitor();
    +
    +    switch (modem_type){
    +		case ME909S_MODEM:
    +		{
    +			rilLibPath = REFERENCE_RIL_ME909S_PATH;
    +			break;
    +		}
    +		case U9300C_MODEM:
    +		{
    +		   rilLibPath = REFERENCE_RIL_U9300C_PATH;
    +		   break;
    +		}
    +		case EC20_MODEM:
    +		{
    +		   rilLibPath = REFERENCE_RIL_EC20_PATH;
    +		   break;
    +		}
    +		case EM8000_MODEM:
    +		{
    +		   rilLibPath = REFERENCE_RIL_EM8000_PATH;
    +		   printf("");
    +		   break;
    +		}
    +
    +		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.
    +				goto done;
    +			} else {
    +				rilLibPath = libPath;
    +			}
    +		}
    +	}
    +	RLOGD("shh->rilLibPath:%s,modem_type=%d",rilLibPath,modem_type);
    +	///$shh$20180906$add$Dynamic switching module$
     
         /* special override when in the emulator */
     #if 0 //ignore this by SW
    diff --git a/android/hardware/ril/runtime-ril-port/Android.mk b/android/hardware/ril/runtime-ril-port/Android.mk
    new file mode 100755
    index 0000000000..fdf21f4844
    --- /dev/null
    +++ b/android/hardware/ril/runtime-ril-port/Android.mk
    @@ -0,0 +1,19 @@
    +# Copyright 2006 The Android Open Source Project
    +
    +LOCAL_PATH:= $(call my-dir)
    +include $(CLEAR_VARS)
    +
    +LOCAL_SRC_FILES:= \
    +    runtime_port.c
    +
    +LOCAL_SHARED_LIBRARIES := \
    +    libutils \
    +    libcutils
    +
    +LOCAL_CFLAGS :=
    +
    +LOCAL_MODULE_TAGS := optional
    +LOCAL_MODULE:= libruntime-ril-port
    +
    +
    +include $(BUILD_SHARED_LIBRARY)
    diff --git a/android/hardware/ril/runtime-ril-port/runtime_port.c b/android/hardware/ril/runtime-ril-port/runtime_port.c
    new file mode 100755
    index 0000000000..f7682c7df1
    --- /dev/null
    +++ b/android/hardware/ril/runtime-ril-port/runtime_port.c
    @@ -0,0 +1,452 @@
    +/*
    + * Licensed under the Apache License, Version 2.0 (the "License");
    + * you may not use this file except in compliance with the License.
    + * You may obtain a copy of the License at
    + *
    + *	http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +/*
    + * Copyright 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved.
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#define LOG_TAG "RIL"
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +int current_modem_type = UNKNOWN_MODEM;
    +
    +#define FAKE_PORT "/dev/ttyFAKEPort"
    +/* Rild need a fake port to pass continue init job,
    + * return a fake port make it runable.
    + * Or the system will enter 15s in early suspend.
    + */
    +
    +struct modem_3g_device {
    +	const char *idVendor;
    +	const char *idProduct;
    +	const char *deviceport;	/* sending AT command */
    +	const char *dataport;	/* sending 3g data */
    +	const char *name;
    +	const int   type;
    +};
    +
    +#define PATH_SIZE 1024
    +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
    +static const char *USB_DIR_BASE = "/sys/bus/usb/devices/";
    +
    +static struct modem_3g_device modem_3g_device_table[] = {
    +
    +	{
    +		.name           = "ME909S_MODEM",
    +		.idVendor       = "12d1",
    +		.idProduct      = "15c1",
    +		.deviceport     = "/dev/ttyUSB0",
    +		.dataport       = "/dev/ttyUSB2",
    +		.type           = ME909S_MODEM,
    +	 },
    +
    +
    +	{
    +		.name			= "U9300C_MODEM",
    +		.idVendor		= "1c9e",
    +		.idProduct		= "9b3c",
    +		.deviceport = "/dev/ttyUSB1",
    +		.dataport		= "/dev/ttyUSB2",
    +		.type			= U9300C_MODEM,
    +	},
    +	{
    +		.name			= "EC20_MODEM",
    +		.idVendor		= "2c7c",
    +		.idProduct		= "0125",
    +		.deviceport = "/dev/ttyUSB0",
    +		.dataport		= "/dev/ttyUSB2",
    +		.type			= EC20_MODEM,
    +	},
    +	{
    +		.name		= "EM8000_MODEM",
    +		.idVendor	= "19d2",
    +		.idProduct	= "0532",
    +		.deviceport     = "/dev/ttyUSB0",
    +		.dataport	= "/dev/ttyUSB2",
    +		.type		= EM8000_MODEM,
    +	},
    +};
    +
    +/* -------------------------------------------------------------- */
    +
    +#define DEBUG_UEVENT 0
    +#define UEVENT_PARAMS_MAX 32
    +
    +enum uevent_action { action_add, action_remove, action_change };
    +
    +struct uevent {
    +    char *path;
    +    enum uevent_action action;
    +    char *subsystem;
    +    char *param[UEVENT_PARAMS_MAX];
    +    unsigned int seqnum;
    +};
    +
    +static void dump_uevent(struct uevent *event);
    +
    +int readfile(char *path, char *content, size_t size)
    +{
    +	int ret;
    +	FILE *f;
    +	f = fopen(path, "r");
    +	if (f == NULL)
    +		return -1;
    +
    +	ret = fread(content, 1, size, f);
    +	fclose(f);
    +	return ret;
    +}
    +
    +int is_device_equal(struct modem_3g_device *device,
    +		     const char *idv, const char *idp)
    +{
    +	long pvid = 0xffff, ppid = 0xffff;
    +	long t_vid, t_pid;
    +	if (device == NULL)
    +		return 0;
    +	t_vid = strtol(device->idVendor, NULL, 16);
    +	t_pid = strtol(device->idProduct, NULL, 16);
    +	pvid = strtol(idv, NULL, 16);
    +	ppid = strtol(idp, NULL, 16);
    +
    +	return (t_vid == pvid && t_pid == ppid);
    +}
    +
    +struct modem_3g_device *
    +find_devices_in_table(const char *idvendor, const char *idproduct)
    +{
    +	int i;
    +	int size = ARRAY_SIZE(modem_3g_device_table);
    +	struct modem_3g_device *device;
    +
    +	for (i = 0; i < size; i++) {
    +		device = &modem_3g_device_table[i];
    +
    +		if (is_device_equal(device, idvendor, idproduct)) {
    +			ALOGI("Runtime 3G port found matched device with "
    +			     "Name:%s idVendor:%s idProduct:%s",
    +			     device->name, device->idVendor, device->idProduct);
    +
    +			return device;
    +		}
    +	}
    +
    +	return NULL;
    +}
    +
    +struct modem_3g_device *find_matched_device(void)
    +{
    +	struct dirent *dent;
    +	DIR *usbdir;
    +	struct modem_3g_device *device = NULL;
    +	char *path, *path2;
    +	char idvendor[64];
    +	char idproduct[64];
    +	int ret, i;
    +
    +	path = malloc(PATH_SIZE);
    +    if (!path)
    +        return NULL;
    +
    +	path2 = malloc(PATH_SIZE);
    +    if (!path2) {
    +        free(path);
    +        return NULL;
    +    }
    +
    +	usbdir = opendir(USB_DIR_BASE);
    +	if (usbdir == NULL) {
    +		free(path);
    +		free(path2);
    +		return NULL;
    +	}
    +
    +	memset(path, 0, PATH_SIZE);
    +	memset(path2, 0, PATH_SIZE);
    +
    +	while ((dent = readdir(usbdir)) != NULL) {
    +		if (strcmp(dent->d_name, ".") == 0
    +		    || strcmp(dent->d_name, "..") == 0)
    +			continue;
    +		memset(idvendor, 0, sizeof(idvendor));
    +		memset(idproduct, 0, sizeof(idproduct));
    +		path = strcpy(path, USB_DIR_BASE);
    +		path = strcat(path, dent->d_name);
    +		strcpy(path2, path);
    +		path = strcat(path, "/idVendor");
    +		path2 = strcat(path2, "/idProduct");
    +
    +		ret = readfile(path, idvendor, 4);
    +		if (ret <= 0)
    +			continue;
    +		ret = readfile(path2, idproduct, 4);
    +		if (ret <= 0)
    +			continue;
    +		device = find_devices_in_table(idvendor, idproduct);
    +		if (device != NULL)
    +			goto out;
    +	}
    +
    +	if (device == NULL)
    +		ALOGI("Runtime 3G can't find supported modem");
    +out:
    +	closedir(usbdir);
    +	free(path);
    +	free(path2);
    +
    +	return device;
    +}
    +
    +
    +const char *runtime_3g_port_device(void)
    +{
    +	struct modem_3g_device *device;
    +	device = find_matched_device();
    +	if (device == NULL)
    +		return FAKE_PORT;
    +
    +	/* Set gobal modem type. */
    +	current_modem_type = device->type;
    +
    +	ALOGI("Current modem type = %d", current_modem_type);
    +
    +	return device->deviceport;
    +}
    +
    +const char *runtime_3g_port_data(void)
    +{
    +	struct modem_3g_device *device;
    +
    +	device = find_matched_device();
    +	if (device == NULL)
    +		return FAKE_PORT;
    +	return device->dataport;
    +}
    +
    +int runtime_3g_port_type(void)
    +{
    +       struct modem_3g_device *device;
    +       int type = UNKNOWN_MODEM;
    +       if (UNKNOWN_MODEM == current_modem_type){
    +               if (NULL != (device = find_matched_device())){
    +                       /* Set gobal modem type. */
    +                       type = device->type;
    +               }
    +       }else{
    +               type = current_modem_type;
    +       }
    +
    +       ALOGI("Current modem type = %d", type);
    +
    +       return type;
    +}
    +
    +static void free_uevent(struct uevent *event)
    +{
    +    int i;
    +    free(event->path);
    +    free(event->subsystem);
    +    for (i = 0; i < UEVENT_PARAMS_MAX; i++) {
    +	    if (!event->param[i])
    +		    break;
    +	    free(event->param[i]);
    +    }
    +    free(event);
    +}
    +
    +static int dispatch_uevent(struct uevent *event)
    +{
    +	/* if it's a usb tty event in our table. make the rild reboot. */
    +	int i;
    +	int ret;
    +	for (i = 0; i < UEVENT_PARAMS_MAX; i++) {
    +		if (!event->param[i])
    +			break;
    +		if (strncmp(event->param[i], "PRODUCT=", 8) == 0) {
    +			char vbuf[5], pbuf[5];
    +			ret = sscanf(event->param[i],
    +				     "PRODUCT=%4s/%4s/", vbuf, pbuf);
    +			if (ret < 0)
    +				return -1;
    +			if (find_devices_in_table(vbuf, pbuf))
    +				alarm(1);
    +			/* Restart in 1 second, since USB usually have
    +			 * many devices, this avoid rild restart too
    +			 * many times. */
    +		}
    +	}
    +	return 0;
    +}
    +
    +int process_uevent_message(int sock)
    +{
    +	char buffer[64 * 1024];
    +	char *s = buffer, *p;
    +	char *end;
    +	int count, param_idx = 0, ret;
    +	struct uevent *event;
    +	count = recv(sock, buffer, sizeof(buffer), 0);
    +	if (count < 0) {
    +		ALOGE("Error receiving uevent (%s)", strerror(errno));
    +		return -errno;
    +	}
    +	event = malloc(sizeof(struct uevent));
    +	if (!event) {
    +		ALOGE("Error allcating memroy (%s)", strerror(errno));
    +		return -errno;
    +	}
    +	memset(event, 0, sizeof(struct uevent));
    +
    +	end = s + count;
    +
    +	for (p = s; *p != '@'; p++)
    +		;
    +	p++;
    +	event->path = strdup(p);
    +	s += strlen(s) + 1;
    +
    +	while (s < end) {
    +		if (!strncmp(s, "ACTION=", strlen("ACTION="))) {
    +			char *a = s + strlen("ACTION=");
    +			if (!strcmp(a, "add"))
    +				event->action = action_add;
    +			else if (!strcmp(a, "change"))
    +				event->action = action_change;
    +			else if (!strcmp(a, "remove"))
    +				event->action = action_remove;
    +		} else if (!strncmp(s, "SEQNUM=", strlen("SEQNUM=")))
    +			event->seqnum = atoi(s + strlen("SEQNUM="));
    +		else if (!strncmp(s, "SUBSYSTEM=", strlen("SUBSYSTEM=")))
    +			event->subsystem = strdup(s + strlen("SUBSYSTEM="));
    +		else
    +			event->param[param_idx++] = strdup(s);
    +		s += strlen(s) + 1;
    +	}
    +
    +	ret = dispatch_uevent(event);
    +#if DEBUG_UEVENT
    +	dump_uevent(event);
    +#endif
    +	free_uevent(event);
    +	return ret;
    +}
    +
    +static void dump_uevent(struct uevent *event)
    +{
    +    int i;
    +
    +    ALOGD("[UEVENT] Sq: %u S: %s A: %d P: %s",
    +	      event->seqnum, event->subsystem, event->action, event->path);
    +    for (i = 0; i < UEVENT_PARAMS_MAX; i++) {
    +	    if (!event->param[i])
    +		    break;
    +	    ALOGD("%s", event->param[i]);
    +    }
    +}
    +
    +void restart_rild(int p)
    +{
    +	ALOGI("3G Modem changed,RILD will restart...");
    +	exit(-1);
    +}
    +
    +void *usb_tty_monitor_thread(void *arg)
    +{
    +	struct sockaddr_nl nladdr;
    +	struct pollfd pollfds[2];
    +	int uevent_sock;
    +	int ret, max = 0;
    +	int uevent_sz = 64 * 1024;
    +	int timeout = -1;
    +	struct sigaction timeoutsigact;
    +
    +	ALOGI("3G modem monitor thread is start");
    +
    +	timeoutsigact.sa_handler = restart_rild;
    +	sigemptyset(&timeoutsigact.sa_mask);
    +	sigaddset(&timeoutsigact.sa_mask, SIGALRM);
    +	sigaction(SIGALRM, &timeoutsigact, 0);
    +
    +	memset(&nladdr, 0, sizeof(nladdr));
    +	nladdr.nl_family = AF_NETLINK;
    +	nladdr.nl_pid = getpid();
    +	nladdr.nl_groups = 0xffffffff;
    +
    +	uevent_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
    +	if (uevent_sock < 0) {
    +		ALOGE(" Netlink socket faild, usb monitor exiting...");
    +		return NULL;
    +	}
    +
    +	if (setsockopt(uevent_sock, SOL_SOCKET, SO_RCVBUFFORCE, &uevent_sz,
    +		       sizeof(uevent_sz)) < 0) {
    +		ALOGE("Unable to set uevent socket options: %s", strerror(errno));
    +		return NULL;
    +	}
    +
    +	if (bind(uevent_sock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
    +		   ALOGE("Unable to bind uevent socket: %s", strerror(errno));
    +		   return NULL;
    +	}
    +	pollfds[0].fd = uevent_sock;
    +	pollfds[0].events = POLLIN;
    +
    +	ret = fcntl(uevent_sock,F_SETFL, O_NONBLOCK);
    +	if (ret < 0)
    +		ALOGE("Error on fcntl:%s", strerror(errno));
    +
    +	while (1) {
    +		ret = poll(pollfds, 1, timeout);
    +
    +		switch (ret) {
    +		case 0:
    +			ALOGD("poll timeout");
    +			continue;
    +		case -1:
    +			ALOGD("poll error:%s", strerror(errno));
    +			break;
    +
    +		default:
    +			if (pollfds[0].revents & POLLIN)
    +				process_uevent_message(uevent_sock);
    +		}
    +	}
    +
    +	close(uevent_sock);
    +}
    +
    +int start_uevent_monitor(void)
    +{
    +	pthread_t pth_uevent_monitor;
    +	return pthread_create(&pth_uevent_monitor, NULL,
    +			      usb_tty_monitor_thread, NULL);
    +}
    +
    +
    

你可能感兴趣的:(#,【Android,Allwinner平台】,android,全志,4G)