Transfer USB file descriptor to Android NDK

I am trying to port some software written in C to the Android platform. This software has a component that reads and writes to and from a connected USB device. I am trying to open a connection with a device in Java, and then pass the file descriptor for the USB devices (s) to the JNI code.

Below is the (relevant) lsof output for my application, which shows that I have two descriptors for a USB device:

  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 passed both descriptors (above 35 and 38) to my own method, but when I try to write to any of the file descriptors, write() returns -1 , and I get an EINVAL error.

Here is the body of my own 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); 

The string returned when this method is called:

  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

Writing to a USB device works through Java, so it seems like it's just a problem when trying to do this using native code.

Does anyone have experience doing something like this?

+4
source share
1 answer

It seems that using write() in the USB file descriptor does not exactly work, as there are several endpoints on the USB device where data can be written.

I managed to use the ioctl() function to perform bulk migration to a specific endpoint on the device:

 #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); 
+8
source

Source: https://habr.com/ru/post/1484835/


All Articles