felHR85 / UsbSerial

Usb serial controller for Android

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ArrayIndexOutOfBoundsException From PL2303SerialDevice

eyedol opened this issue · comments

Here's the relevant stacktrace:

Caused by java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
       at android.hardware.usb.UsbDevice.getInterface(UsbDevice.java:232)
       at com.felhr.usbserial.PL2303SerialDevice.<init>(PL2303SerialDevice.java:54)
       at com.felhr.usbserial.UsbSerialDevice.createUsbSerialDevice(UsbSerialDevice.java:76)
       at com.felhr.usbserial.UsbSerialDevice.createUsbSerialDevice(UsbSerialDevice.java:58)

This issue seems to be related to this one. Then that looks like an OS level bug

Another of those beautiful Android USB related bugs. I will look at it next weekend to be if some fix can be implemented.

I just ran into this bug today as well, on Android 5.1. My project's at a standstill until I can figure this one out. I might take a crack at a workaround if you haven't had a chance yet, @felHR85 .

Sure! @lordjabez It would be great.

I did some reading today, and the fixes so far are all within the Android code itself, not the application side (see the link @eyedol posted). Rebuilding/upgrading the OS isn't an option for me, do you have any thoughts on what could be done app-side?

This is the best idea someone in the above thread had:

The only privileged bit in the USB API is the usbfd file descriptor from the service. It might be possible to work around this with JNI or reflection to create UsbEndpoint objects (there's nothing magic in there). You can discover the actual interfaces and endpoints by trawling /sys directly.

It would be ugly and not API portable and a lot of extra work, but if you're desperate for a workaround it would probably function.

I have been investigating this issue and it is basically not possible to solve this from android user-space. Sadly I think the only way is not using Android 5.1 if possible.

I added a note #145 to the readme regarding this issue. Essentially recommending against the use of Android 5.1.1 due to this bug.

I was thinking we drop support for Android 5.1.1. Basically, bump the minSDK from 12 to say 23 but looking at the platform versions distribution chart, 5.1.1 seems to be widely used. 19.4% is a substantial amount in the Android world. Thoughts?

You can discover the actual interfaces and endpoints by trawling /sys directly.

@lordjabez or @felHR85, might you know what this entails?

@eyedol I only know enough about it to know I couldn't actually get it to work, and if somehow it did work it wouldn't be nearly robust enough to recommend to anyone else.

@eyedol @lordjabez The only way I see would be using Android NDK, JNI and C/C++ code taking advantage that PL2303, CP2102 and all of those drivers have their drivers implemented in the linux kernel that powers Android.
I attach here a little snippet that I've used in the past to open a serial connection. This code, correctly glued through JNI and compiled with the NDK should work in at least any Android rooted device

int init_serial()
{
  fd_serial_port = open("/dev/ttyS1", O_RDWR); // Must be open in  blocking mode 

  if(fd_serial_port == -1)
    return -1;
    
  /*
     Configure Termios
  */
  struct termios current_config; 
  tcgetattr(fd_serial_port, &old_config);
  current_config = old_config;

  current_config.c_iflag = 0;
  current_config.c_oflag = 0;
  current_config.c_cflag = CS8 | CREAD | CLOCAL;
  current_config.c_lflag = 0;
  current_config.c_cc[VMIN] = 1;
  current_config.c_cc[VTIME] = 0;

  // Baud rate config
  cfsetispeed(&current_config, B115200);
  cfsetospeed(&current_config, B115200);

  // Set configuration
  tcsetattr(fd_serial_port, TCSANOW, &current_config);
  
  is_initialized = 1;
  return fd_serial_port;    
}

This method returns a file descriptor if the connection has been opened properly. Writing and reading should be simple using write(2) and read(2).

But I think this is overly complicated (more because of NDK and JNI than the C code itself) so I discourage anybody to try this approach.

I know I'm bumping this (sorry), however my team is ordering a batch of tablets running 5.1 for our app.

What exactly raises this exception? Does this bug render UsbSerial useless on 5.1?

Our app is just a simple interface that sends basic serial commands so it isn't too complex.

UsbSerial can be used, but it's a pain. Only the last USB device plugged in to the tablet will be functional.

@ltd9938 @lordjabez I understand it should work normally if you only plug one device right?

Probably, but if you restart the tablet and don't unplug and re-plug in the device it might not work until you do. The enumeration order of USB devices can be somewhat arbitrary.

Thanks for the info guys. We're probably just going to avoid it all together.

@ltd9938 I'm not sure how fixed of a constraint you've to use Android 5.1 but my team and I have successfully used it on Android 6.0.1 Marshmallow with two USB devices. If you're able to upgrade to a later version of Android you won't have this particular issue.

Anyone know if the CP2102SerialDevice driver has the same issue? We are stuck with 5.1.1 and are getting the same exception on occasion. The device fails to be detected from a cold start, unplugging-replugging the device seems to be the only way to properly detect and use the device.

@mtinnes As far as We know there is no way to solve this in 5.1.1

Hi, I want a clarification on something, since I don't have many devices to test with.

The problem only occurred in 5.1.1 exclusively, or affected all devices running API level 22?
What about API level 21, does it affected too?

I am confused since it looks like some of you guys, presumably, scoped the affected devices down to version 5.1.1, but some discussed the issue with broader version range, especially on the Google issue tracker thread mentioned by eyedol.

Also, can we try/catch ArrayIndexOutOfBoundsException around device.getInterface and throw a different exception, specific to this library and not some generic ArrayIndexOutOfBoundsException?

I have used https://github.com/mik3y/usb-serial-for-android for connecting for PL2303 my problem is that connection is successful but if there is nothing to read and write for sometime 15-20 sec then I am unable to read or write further, The exception is raised sometimes but sometimes it is successful any help, please?