mik3y / usb-serial-for-android

Android USB host serial driver library for CDC, FTDI, Arduino and other devices.
MIT License
4.81k stars 1.58k forks source link

Second interaction with CDC-ACM device fails only on Xiaomi phone #490

Closed kholia closed 1 year ago

kholia commented 1 year ago

Hi folks,

I am running into a puzzling corner-case failure while setting RTS off on a CDC ACM device on a Xiaomi phone running the original ROM.

The usb-serial-for-android is able to turn RTS on just fine. However, while trying to turn off RTS, I run into the following exception:

> W  java.io.IOException: controlTransfer failed
> W         at com.hoho.android.usbserial.driver.CdcAcmSerialDriver$CdcAcmSerialPort.sendAcmControlMessage(CdcAcmSerialDriver.java:213)
> W         at com.hoho.android.usbserial.driver.CdcAcmSerialDriver$CdcAcmSerialPort.setDtrRts(CdcAcmSerialDriver.java:286)
> W         at com.hoho.android.usbserial.driver.CdcAcmSerialDriver$CdcAcmSerialPort.setRTS(CdcAcmSerialDriver.java:281)
> W         at com.company.app.CatControl.cat_ptt_control(CatControl.java:549)
> W         at com.company.app.MainActivity$4$1.run(MainActivity.java:740)
> W         at java.lang.Thread.run(Thread.java:1012)

This happens only on a Xiaomi phone running the original (Android 12 based) stock ROM.

Once I run into this exception (on the second interaction with the CDC ACM device), the subsequent interactions with the CDC ACM device also fail.

I do NOT run into this problem on other phones like another Xiaomi phone running some non-stock ROM(s).

The CDC ACM device happens to be a Waveshare RP2040-Zero.

Are there any workaround I can use to avoid running into this exception? Thanks!

kai-morich commented 1 year ago

have you tried closing and opening the serial port again?

kholia commented 1 year ago

Yes - I tried doing so and it results in a different set of problems:

2023-04-23 12:12:43.866  6360-6513  UsbDeviceConnectionJNI  com.company.app                  D  close
2023-04-23 12:12:43.866  6360-6513  CdcAcmSerialDriver      com.company.app                  D  trying default interface logic
2023-04-23 12:12:43.866  6360-6513  CdcAcmSerialDriver      com.company.app                  D  claiming interfaces, count=2
2023-04-23 12:12:43.866  6360-6513  CdcAcmSerialDriver      com.company.app                  D  Control iface=UsbInterface[mId=0,mAlternateSetting=0,mName=Board CDC,mClass=2,mSubclass=2,mProtocol=0,mEndpoints=[
                                                                                                    UsbEndpoint[mAddress=129,mAttributes=3,mMaxPacketSize=8,mInterval=16]]
2023-04-23 12:12:43.866  6360-6513  UsbDeviceConnectionJNI  com.company.app                  E  device is closed in native_claim_interface
2023-04-23 12:12:43.866  6360-6513  UsbDeviceConnectionJNI  com.company.app                  E  device is closed in native_release_interface
2023-04-23 12:12:43.866  6360-6513  UsbDeviceConnectionJNI  com.company.app                  E  device is closed in native_release_interface

2023-04-23 12:12:43.866  6360-6513  > W  java.io.IOException: Could not claim control interface
2023-04-23 12:12:43.866  6360-6513  > W         at com.hoho.android.usbserial.driver.CdcAcmSerialDriver$CdcAcmSerialPort.openInterface(CdcAcmSerialDriver.java:183)
2023-04-23 12:12:43.866  6360-6513  > W         at com.hoho.android.usbserial.driver.CdcAcmSerialDriver$CdcAcmSerialPort.openInt(CdcAcmSerialDriver.java:112)
2023-04-23 12:12:43.866  6360-6513  > W         at com.hoho.android.usbserial.driver.CommonUsbSerialPort.open(CommonUsbSerialPort.java:121)
2023-04-23 12:12:43.866  6360-6513  > W         at com.company.app.CatControl.cat_ptt_control(CatControl.java:552)
2023-04-23 12:12:43.866  6360-6513  > W         at com.company.app.MainActivity$4$1.run(MainActivity.java:734)
2023-04-23 12:12:43.866  6360-6513  > W         at java.lang.Thread.run(Thread.java:1012)

Steps to reproduce:

  1. Connect a CDC-ACM device to the Xiaomi phone running stock Android 12 ROM.

  2. Open connection as usual using this library -> port.open(connection).

  3. Set RTS -> port.setRTS(true).

  4. After a while unset RTS -> port.setRTS(false).

  5. BAM!

...

Next steps for me:

Thanks for the help!

kholia commented 1 year ago

Try another Xiaomi phone running stock ROM.

Nope - this bug is NOT reproducible on another older Xiaomi phone running a similar Android 12 based stock ROM.

...

After scratching my head for a while, I began suspecting a loose USB-C connection. I removed the protective case of the phone and reconnected the CDC-ACM device to the USB-C port of the phone. This immediately fixed the "problem"!

It is still a mystery why the first SetRTS would succeed fine and all the subsequent serial operations failed. Perhaps the physical USB-C connection became "looser" progressively. Not sure!

I am glad that this was not some hairy software problem - thanks for the help! I am closing the issue now.