4

C で記述されたソフトウェアを Android プラットフォームに移植しようとしています。このソフトウェアには、接続された USB デバイスから読み書きするコンポーネントがあります。私がやろうとしているのは、Java でデバイスへの接続を開き、USB デバイスのファイル記述子を JNI コードに渡すことです。

lsof以下は、USB デバイスに 2 つの記述子があることを示す、私のアプリの (関連する) 出力です。

com.tim 8861 u0_a66 35 ??? ??? ??? ??? /dev/バス/usb/001/002
com.tim 8861 u0_a66 36 ??? ??? ??? ??? ソケット:[51170]
com.tim 8861 u0_a66 37 ??? ??? ??? ??? ソケット:[51173]
com.tim 8861 u0_a66 38 ??? ??? ??? ??? /dev/バス/usb/001/003

両方の記述子 (35 と 38 以上) をネイティブ メソッドに渡しましたが、いずれかのファイル記述子に書き込もうとすると がwrite()返さ-1れ、EINVALエラーが発生します。

これが私のネイティブメソッドの本体です:

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  
書きました: -1  
(エラー: 22 無効な引数)  
フラグ: 32770  
NBIO 0  
読み取り専用 0  
書き込み専用 0  
両方 2  
追加 0  
大きなファイル 32768  

FD: 38  
書きました: -1  
(エラー: 22 無効な引数)  
フラグ: 32770  
NBIO 0  
読み取り専用 0  
書き込み専用 0  
両方 2  
追加 0  
大きなファイル 32768

USB デバイスへの書き込みは Java を介して機能するため、ネイティブ コードを介してそれを実行しようとすると問題になるようです。

誰かがこのようなことをした経験がありますか?

4

1 に答える 1

8

データを書き込むことができる USB デバイスには複数のエンドポイントがあるため、USB ファイル記述子での使用write()は正確には機能しないようです。

関数を使用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);
于 2013-06-11T14:30:44.617 に答える