android - 将 USB 文件描述符传递给 Android NDK 程序

标签 android android-ndk java-native-interface

我正在尝试将一些用 C 编写的软件移植到 Android 平台。该软件有一个组件,可以读取和写入连接的 USB 设备。我想做的是用 Java 打开与设备的连接,然后将 USB 设备的文件描述符传递给 JNI 代码。

下面是我的应用的 lsof 的(相关)输出,显示我有两个 USB 设备描述符:

com.tim    8861     u0_a66   35       ???                ???       ???        ??? /dev/bus/usb/001/002
com.tim    8861     u0_a66   36       ???                ???       ???        ??? socket:[51170]
com.tim    8861     u0_a66   37       ???                ???       ???        ??? socket:[51173]
com.tim    8861     u0_a66   38       ???                ???       ???        ??? /dev/bus/usb/001/003

I've passed both descriptors (above as 35 and 38) to my native method, but when I try and write to either of the file descriptors, write() returns -1, and I get an EINVAL error.

Here is the body of my native method:

char buff[1024] = {0};
jsize len = (*env)->GetArrayLength(env, fds);
jint *arr = (*env)->GetIntArrayElements(env, fds, 0);
int i;

char data[4] = {
    0x09,
    0x90,
    0x50,
    0x50,
};

for (i = 0; i < len; i++) {
    int wrote = write(arr[i], data, 4);

    int flags = fcntl(arr[i], F_GETFL);
    char *err = strerror(errno);
    sprintf(buff, "%sFD: %d  \n"
    "wrote: %d  \n"
    "(err: %d %s)  \n"
    "flags: %d  \n"
    "NBIO %d  \n"
    "readonly %d  \n"
    "writeonly %d  \n"
    "both %d  \n"
    "append %d  \n"
    "large file %d  \n\n", buff, arr[i], wrote, errno, err, flags, flags & O_NONBLOCK,
        flags & O_RDONLY, flags & O_WRONLY, flags & O_RDWR, flags & O_APPEND,
        flags & O_LARGEFILE);
}
return (*env)->NewStringUTF(env, buff);

调用该方法时返回的字符串是:

FD: 35  
wrote: -1  
(err: 22 Invalid argument)  
flags: 32770  
NBIO 0  
readonly 0  
writeonly 0  
both 2  
append 0  
large file 32768  

FD: 38  
wrote: -1  
(err: 22 Invalid argument)  
flags: 32770  
NBIO 0  
readonly 0  
writeonly 0  
both 2  
append 0  
large file 32768

写入 USB 设备确实可以通过 Java 进行,因此在尝试通过 native 代码进行时这似乎只是一个问题。

有没有人有过这样的经历?

最佳答案

似乎在 USB 文件描述符上使用 write() 并不完全有效,因为 USB 设备上有多个可以写入数据的端点。

我能够使用 ioctl() 函数向设备上的特定端点执行批量传输:

#include <linux/usbdevice_fs.h>
#include <sys/ioctl.h>

// ...

char data[4] = {0x09, 0x90, 0x50, 0x50};

struct usbdevfs_bulktransfer bt;
bt.ep = usb_endpoint;  /* endpoint (received from Java) */
bt.len = 4;            /* length of data */
bt.timeout = 100;      /* timeout in ms */
bt.data = data;        /* the data */

int rtn = ioctl(fd, USBDEVFS_BULK, &bt);

关于android - 将 USB 文件描述符传递给 Android NDK 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16963237/

相关文章:

java - 将序列化对象写入文件

android - cpu-features.h 没有这样的文件或目录 webrtc Android 构建

gcc - 可以在没有自由的情况下构建 binutils 吗?或者report_times可以禁用吗?

Android NDK R8E 缺少 stdlib.h

c++ - 使用 JNI 和 C++ 将 Unicode const char* 转换为 JString

android - 蓝牙延迟和 Android 音频的提示

Android:如何以编程方式将键盘旋转 180 度?

android - 底部导航栏与 Jetpack Compose 中的屏幕内容重叠

Android NDK 获取 ArrayList 错误

java-native-interface - LibGDX : JNI ERROR (app bug): non-zero capacity for NULL pointer: 80000 错误