libusb_init失败及open failed (Permission denied)

本文针对Android 5.0及6.0系统中出现的libusb_init失败和openfailed(Permission denied)错误进行了深入探讨。提供了两种解决方案:一是通过SELinuxModeChanger更改SELinux模式;二是修改libusb源代码,添加libusb_open_fd函数。此外,对于API 23及以上版本,还介绍了如何申请读写外部存储权限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考http://stackoverflow.com/questions/25662307/android-l-libusb-init-returns-libusb-error-other-99

http://stackoverflow.com/questions/8854359/exception-open-failed-eacces-permission-denied-on-android

http://www.freehum.com/2014/06/operate-usb-device-under-android-by-libusb-without-root.html

在将原来的程序(Android 4.x)部署到Android 5.0和6.0的时候,遇到libusb_init失败和open failed (Permission denied)的错误,Google之后,发现是权限问题。

libusb_init失败(error -99)

Android 5.0之后强制开启了Selinux:

  • Android sandbox reinforced with SELinux. Android now requires SELinux in enforcing mode for all domains. SELinux is a mandatory access control (MAC) system in the Linux kernel used to augment the existing discretionary access control (DAC) security model. This new layer provides additional protection against potential security vulnerabilities.

详见https://source.android.com/security/enhancements/enhancements50.html

解决办法有2种

  1. 安装SELinuxModeChanger,将模式改为permissive —— 貌似需要root

  2. 修改libusb,stackoverflow上说如下2个链接已经fix了:https://github.com/martinmarinov/rtl_tcp_andro-https://github.com/Gritzman/libusb

  3. 本人使用的https://github.com/Gritzman/libusb

另外,可能需要增加libusb_open_fd,编译之后的so见http://pan.baidu.com/s/1hrzAfZ2

1) core.c 中在 libusb_open 后面增加 libusb_open_fd 函数

int API_EXPORTED libusb_open_fd(libusb_device *dev, libusb_device_handle **handle, int fd)
{
	struct libusb_context *ctx = DEVICE_CTX(dev);
	struct libusb_device_handle *_handle;
	size_t priv_size = usbi_backend->device_handle_priv_size;
	int r;
	usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);

	_handle = malloc(sizeof(*_handle) + priv_size);
	if (!_handle)
		return LIBUSB_ERROR_NO_MEM;

	r = usbi_mutex_init(&_handle->lock, NULL);
	if (r) {
		free(_handle);
		return LIBUSB_ERROR_OTHER;
	}

	_handle->dev = libusb_ref_device(dev);
	_handle->claimed_interfaces = 0;
	memset(&_handle->os_priv, 0, priv_size);

	r = usbi_backend->open_fd(_handle, fd);
	if (r < 0) {
		usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r);
		libusb_unref_device(dev);
		usbi_mutex_destroy(&_handle->lock);
		free(_handle);
		return r;
	}

	usbi_mutex_lock(&ctx->open_devs_lock);
	list_add(&_handle->list, &ctx->open_devs);
	usbi_mutex_unlock(&ctx->open_devs_lock);
	*handle = _handle;

/* At this point, we want to interrupt any existing event handlers so
 * that they realise the addition of the new device's poll fd. One
 * example when this is desirable is if the user is running a separate
 * dedicated libusb events handling thread, which is running with a long
 * or infinite timeout. We want to interrupt that iteration of the loop,
 * so that it picks up the new fd, and then continues. */
	usbi_fd_notification(ctx);

	return 0;
}

2) os/linux_usbfs.c 中在 op_open 后面增加 op_open_fd 函数

static int op_open_fd(struct libusb_device_handle *handle, int fd) {
	struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);

	hpriv->fd = fd;

	return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT);
}

3)os/linux_usbfs.c中.open = op_open,后添加.open_fd = op_open_fd,

4) 在libusbi.h中,

int (*open)(struct libusb_device_handle *handle);

后添加

int (*open_fd)(struct libusb_device_handle *handle, int fd);

'open failed: EACCES (Permission denied)' 

API 23(6.0)之后,需要请求读写外设权限

private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};
//在需要读写外设的地方
int permission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        requestPermissions(PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);
    }


转载于:https://my.oschina.net/shanlilaideyu/blog/630481

这个错误信息通常出现在使用libusb库进行USB设备通信时,表示程序无法访问指定的USB设备。以下是一些可能的原因和解决方法: 1. **权限问题**:程序可能没有足够的权限访问USB设备。 - **解决方法**:在Linux系统中,可以尝试以root用户运行程序,或者将当前用户添加到`usbusers`组中。在Windows系统中,确保以管理员身份运行程序。 2. **设备被其他程序占用**:其他程序可能正在使用该USB设备。 - **解决方法**:关闭所有可能使用该设备的程序,或者确保没有其他程序在后台占用该设备。 3. **驱动程序问题**:设备驱动程序可能未正确安装或配置。 - **解决方法**:检查设备管理器(Windows)或`lsusb`命令输出(Linux),确保设备驱动程序已正确安装。如果需要,重新安装驱动程序。 4. **设备路径错误**:程序中指定的设备路径可能不正确。 - **解决方法**:确认设备路径是否正确,可以在程序中使用`libusb_get_device_list`列出所有连接的USB设备,并检查目标设备的路径。 5. **系统策略限制**:某些系统策略可能阻止对USB设备的访问。 - **解决方法**:检查系统策略设置,确保允许对USB设备的访问。 示例代码(以C语言为例): ```c #include <stdio.h> #include <libusb-1.0/libusb.h> int main() { libusb_context *ctx = NULL; libusb_device_handle *handle = NULL; int r; r = libusb_init(&ctx); if (r < 0) { fprintf(stderr, "Failed to initialize libusb: %s\n", libusb_error_name(r)); return 1; } libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, 3); handle = libusb_open_device_with_vid_pid(ctx, 0x1234, 0x5678); if (handle == NULL) { fprintf(stderr, "Failed to open device: %s\n", libusb_error_name(libusb_get_last_error(ctx))); libusb_exit(ctx); return 1; } // Perform USB operations here libusb_close(handle); libusb_exit(ctx); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值