I am trying to port some software written in C to the Android platform. This software has a component that reads and writes from and to a connected USB device. What I am trying to do is open up a connection to the device in Java, then pass the file descriptor for the USB device(s) to the JNI code.
Below is the (relevant) output of lsof
for my app which shows I have two descriptors for the 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'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);
The string that is returned when invoking that method is:
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 the USB device does work through Java, so it appears to just be an issue when trying to do it via native code.
Does anyone have any experience doing something like this?