修改libusb以接受文件描述符

时间:2013-01-04 01:18:35

标签: android android-ndk usb libusb libusb-1.0

我修改了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实际上并没有被继承!

2 个答案:

答案 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接口可以封送文件描述符。

或者你可以继承句柄 - 如果它在生成进程时已经打开,那么句柄在生成的进程中也是有效的。