我修改了libusb1.0 open函数如下:
static int op_open2(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);
}
其中fd是通过android.hardware.usb.UsbDeviceConnection.html#getFileDescriptor()
获得的final UsbDeviceConnection connection = manager.openDevice(device);
return connection.getFileDescriptor();
不幸的是,当我打电话
时,我一直收到错误static int op_claim_interface(struct libusb_device_handle *handle, int iface)
{
int fd = _device_handle_priv(handle)->fd;
int r = ioctl(fd, IOCTL_USBFS_CLAIMINTF, &iface);
if (r) {
if (errno == ENOENT)
return LIBUSB_ERROR_NOT_FOUND;
else if (errno == EBUSY)
return LIBUSB_ERROR_BUSY;
else if (errno == ENODEV)
return LIBUSB_ERROR_NO_DEVICE;
usbi_err(HANDLE_CTX(handle),
"claim interface failed, error %d errno %d", r, errno);
return LIBUSB_ERROR_OTHER;
}
return 0;
}
声明接口失败,错误-1错误9
被翻译为“Bad file number”。我从Java得到的文件描述符是一个正整数!
唯一的另一个小细节是我的本机代码作为使用Java ProcessBuilder生成的单独二进制文件运行。但是它们共享相同的uid,所以我认为我从Java获得的USB权限仍然适用于libusb。
我不需要独立于平台,所以任何黑客都可以做到这一点:)
任何想法都会非常感激!
其他信息!我从 lsof 获得的输出是(缩短为强调其中最有趣的部分)
my.activity 13374 u0_a62 exe ??? ??? ??? ??? /system/bin/app_process
my.activity 13374 u0_a62 0 ??? ??? ??? ??? /dev/null
my.activity 13374 u0_a62 1 ??? ??? ??? ??? /dev/null
my.activity 13374 u0_a62 2 ??? ??? ??? ??? /dev/null
my.activity 13374 u0_a62 3 ??? ??? ??? ??? /dev/log/main
my.activity 13374 u0_a62 4 ??? ??? ??? ??? /dev/log/radio
my.activity 13374 u0_a62 5 ??? ??? ??? ??? /dev/log/events
my.activity 13374 u0_a62 6 ??? ??? ??? ??? /dev/log/system
my.activity 13374 u0_a62 7 ??? ??? ??? ??? /system/framework/core.jar
my.activity 13374 u0_a62 8 ??? ??? ??? ??? /system/framework/core-junit.jar
my.activity 13374 u0_a62 9 ??? ??? ??? ??? /dev/__properties__ (deleted)
...
my.activity 13374 u0_a62 44 ??? ??? ??? ??? /dev/bus/usb/002/002
...
my.activity 13374 u0_a62 51 ??? ??? ??? ??? pipe:[51015]
my.activity 13374 u0_a62 53 ??? ??? ??? ??? pipe:[51016]
...
my_exe 13546 u0_a62 exe ??? ??? ??? ??? /data/data/my.activity/files/my_exe
my_exe 13546 u0_a62 0 ??? ??? ??? ??? pipe:[51015]
my_exe 13546 u0_a62 1 ??? ??? ??? ??? pipe:[51016]
my_exe 13546 u0_a62 2 ??? ??? ??? ??? pipe:[51016]
my_exe 13546 u0_a62 3 ??? ??? ??? ??? /dev/log/main
my_exe 13546 u0_a62 4 ??? ??? ??? ??? /dev/log/radio
my_exe 13546 u0_a62 5 ??? ??? ??? ??? /dev/log/events
my_exe 13546 u0_a62 6 ??? ??? ??? ??? /dev/log/system
my_exe 13546 u0_a62 9 ??? ??? ??? ??? /dev/__properties__ (deleted)
my_exe 13546 u0_a62 mem ??? b3:09 0 302530 /data/data/my.activity/files/my_exe
my_exe 13546 u0_a62 mem ??? b3:09 36864 302530 /data/data/my.activity/files/my_exe
my_exe 13546 u0_a62 mem ??? b3:09 40960 302530 /data/data/my.activity/files/my_exe
my_exe 13546 u0_a62 mem ??? b3:03 0 200 /system/bin/linker
my_exe 13546 u0_a62 mem ??? b3:03 57344 200 /system/bin/linker
my_exe 13546 u0_a62 mem ??? b3:03 61440 200 /system/bin/linker
这让我觉得我传递给my_exe的文件描述符44实际上并没有被继承!
答案 0 :(得分:7)
事实证明,进程没有继承文件描述符。如果使用JNI,一切都应该没问题,但是如果你想与第三方应用程序连接,你需要将文件描述符转移到第三方应用程序。
我的解决方案是use UNIX sockets通过JNI转移fd并且它有效!
P.S。
我在GNU许可下发布了该项目 - https://github.com/martinmarinov/rtl_tcp_andro-
答案 1 :(得分:0)
文件句柄对进程是私有的。将它们原样传递给不同的进程保证不会对* nix的任何风格起作用。
Android的Binder / Parcel IPC接口可以封送文件描述符。
或者你可以继承句柄 - 如果它在生成进程时已经打开,那么句柄在生成的进程中也是有效的。