Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I open/write from a serial port on Android?

I have written an Android app which runs on a custom kernel on Android 4.4 Kitkat device, which uses the Android Serial Port API (https://code.google.com/p/android-serialport-api/) in order to open the serial port "/dev/ttyACM0" which is the port associated with my serial device. The port has the proper "666" permissions (crw-rw-rw), and the app itself even has the WRITE_EXTERNAL_STORAGE" permission.

However, even though the permissions appear correct, when my app tries to open said serial port using the library, it fails. In my java code, if I try to do a "device.canWrite()" it returns false, whereas a "device.canRead()" returns true. I feel like this is a symptom of a greater permissions problem.

If I use the sample apk bundled with the serial port api/library, I get the same issue, where the app fails at the device.canWrite() and throws a SecurityException.

The exact same code DOES successfully run and open when ran on a custom kernel ICS device, for which the app was originally developed for. However, the kernels for both were written by the same developer, and at least on a surface glance, the permissions on the port seem to be the same.

Is it likely this is an issue that I can resolve on the application code side? I have tried some other serial port libraries (USBSerial3.0, usb-serial-for-android-master) and I seem to encounter the same issue.

Regardless of where the issue may lie, would anyone have any ideas of what the problem may be? Making changes to the kernel, app, and api are all on the table. Thank you.

like image 845
gabe3vino Avatar asked Jun 09 '15 20:06

gabe3vino


3 Answers

Gabe, Google changed the SELinux mode from Permissive Mode to Enforce Mode in Android 4.4, by default apps do not have the (SELinux) permissions to access the serial ports. Here are a couple of ways to work around the issue: (1). If your device is rooted you can toggle the SELinux mode from Enforce Mode to Permissive Mode: “su setenforce 0”. You will need to run the command every time you restart your device. see http://www.xda-developers.com/easily-change-your-android-selinux-mode/ (2). If you have access to the kernel framework files for the device you can change them and grant serial port access to your apps.

like image 114
bruce zakett Avatar answered Sep 25 '22 16:09

bruce zakett


run setenforce 0 from shell to disable SELinux. It worked for me and I was able to read/write on tty/ACM0.

like image 37
Amit Avatar answered Sep 23 '22 16:09

Amit


The issue turned out to be with SELinux, which most of the Samsung line of devices use as a security enforcement policy. That security policy was set to enforcing, such that no apps could access files outside of their designated app space, such as the serial port I was trying to open.

Given that we could change the kernel, we were able to add a policy exception to SELinux that gave my app elevated priviliges, thereby allowing it to open the port correctly.

like image 33
gabe3vino Avatar answered Sep 24 '22 16:09

gabe3vino