title: Passing USB file descriptor to Android NDK program
body: <p>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.</p>
  
  <p>Below is the (relevant) output of <code>lsof</code> for my app which shows I have two descriptors for the USB device:</p>
  
  <pre>
  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
  </pre>
  
  <p>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, <code>write()</code> returns <code>-1</code>, and I get an <code>EINVAL</code> error.</p>
  
  <p>Here is the body of my native method:</p>
  
  <pre><code>char buff[1024] = {0};
  jsize len = (*env)-&gt;GetArrayLength(env, fds);
  jint *arr = (*env)-&gt;GetIntArrayElements(env, fds, 0);
  int i;
  
  char data[4] = {
      0x09,
      0x90,
      0x50,
      0x50,
  };
  
  for (i = 0; i &lt; 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 &amp; O_NONBLOCK,
          flags &amp; O_RDONLY, flags &amp; O_WRONLY, flags &amp; O_RDWR, flags &amp; O_APPEND,
          flags &amp; O_LARGEFILE);
  }
  return (*env)-&gt;NewStringUTF(env, buff);
  </code></pre>
  
  <p>The string that is returned when invoking that method is:</p>
  
  <pre>
  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
  </pre>
  
  <p>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.</p>
  
  <p>Does anyone have any experience doing something like this?</p>