Search code examples
android.netserial-portuartftdi

Does the cross-platform System.IO.Ports.SerialPort library work on Android with FTDI UART chips? (e.g FT232R)?


I am trying to write a cross-platform GUI to control hardware for use on both Windows and Android. I am using an FTDI serial cable. When the cable is plugged in, the SerialPort.GetPortNames() identifies the cable as
/dev/ttyUSB0

When I try to open the connection to this port, I get an exception with the following message:
Access to the port '/dev/ttyUSB0' is denied.

I have also tried the following strings:
'ttyUSB0', 'USB0', 'dev/ttyUSB0'

I can confirm the “Serial USB Terminal” software from the Play Store works fine on my Android device. I can connect and send strings without problems.

Is this cross platform?
Information about Port.IO.SerialPort ability to support Android.
https://github.com/dotnet/runtime/pull/95749

My Questions:

  • Should IO.Ports library V9.0 work with this setup?
  • If not, will it be supported in the future? (If not, I may abandon Android support and just use the Windows FTDI DLL)
  • Am I missing some magic Android permissions fiddle?
  • Have you got .NET IO.Ports library working with FTDI UART on another Android setup?

This is as far as I got:
My feeling is that it Open() falls back on Linux, and expects drivers to be installed as per:
https://ftdichip.com/wp-content/uploads/2020/08/AN_220_FTDI_Drivers_Installation_Guide_for_Linux-1.pdf

Feel free to share your experiences here. When I saw ‘GetPortNames()’ working on my phone, I got so excited but never got any further. I was so close!

My Setup:

Debugging:
The Exception message is as follows:

Access to the port '/dev/ttyUSB0' is denied.
 at System.IO.Ports.SafeSerialDeviceHandle.Open(string portName)
 at System.IO.Ports.SerialStream..ctor(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, int readTimeout, int writeTimeout, Handshake handshake,
            bool dtrEnable, bool rtsEnable, bool _1 , byte _2)
 at System.IO.Ports.SerialPort.Open()
 at .. < then into my project code>

I think the exception message relates to this line in the .NET SerialPort library
https://github.com/dotnet/runtime/blob/1d1bf92fcf43aa6981804dc53c5174445069c9e4/src/libraries/System.IO.Ports/src/System/IO/Ports/SafeSerialDeviceHandle.Unix.cs#L29


Solution

  • I reached out to the developer and got the following response:

    Hey, yes the System.IO.Ports implementation uses the /dev/tty functionality common to many Unix systems. Unfortunately Android by default has a SELinux policy preventing access to that device:
    https://github.com/dotnet/runtime/issues/86619#issuecomment-1843502371

    The same would happen if you try to fopen("/dev/ttyUSB0", "r+")​ in regular native C code.

    If you can't root the device or have custom Android then as far as I know you're out of luck and need to rely on custom libraries/drivers.

    Summary
    It will work if you are targeting a custom Android platform or a rooted phone (after some fiddle), but not for a phone running stock ROM.