Ringo001
Ringo001

Reputation: 163

Android i2c permission denied

I’ve developed an NDK application to access an i2c device via the i2c-dev interface. This application is running on an Android development kit, on which we have connected an MPU6050 device via i2c.

I’ve setup the DT binding for the device, as shown below

i2c@78b5000 {                                                           
    MPU6050@68 {
        compatible = "qcom, i2c-msm-v2";
        reg = <0x68>;
    };
};

and enabled the i2c-1 bus – which is the i2c bus the device is connected to – by changing the following line from “disabled” to “okay”

 &i2c_1 {                                                                    
     status = "okay";
 };

The issue is that when I try to open the i2c-1 file in my application via open()

char *filename = "dev/i2c-1";
const int file = open(filename, O_RDWR);

I get the permission denied error code returned.

I have only once successfully read from the WHO-AM-I register, by the following steps:

  1. Adjust the permissions of the /dev/i2c-1 file to 666 using

    $ chmod 666 i2c-1
    
  2. Modify the ueventd.rc file to include this line

    /dev/i2c-1                0666   root       root
    
  3. Kill the ueventd process to allow it to reload.

    $ pgrep ueventd
    $ kill xxx
    

Running ls -la in the /dev folder showed the permissions for i2c-1 as

crw-rw-rw- root root 

More details of this process at this link: Android: how to grant 666 privs to a device via ueventd.rc

The issue with applying this process is that each time the device reboots the ueventd file will be restored back to the original state and the permissions reverted. I have since tried repeating this exact process, rebuilding the boot image with the altered files/permissions and flashing the new boot image to the device. This doesn't seem to work as I still receive the same "permission denied" error.

In an attempt to get around this I included i2ctools into the system image (did not come stock). When trying to run i2cdetect I initially got permission denied, so I followed the same procedure outlined above. This process successfully allowed i2ctools to access /dev/i2c-1 and detect my device.

The problem is that the NDK application - which uses /dev/i2c-1 - is still returning permission denied even after applying the process.

I could potentially modify my application to use i2ctools but my thinking is that if i2ctools can access i2c-1 after modifying the permissions, then my application should be able to - please correct me if i’m wrong.

UPDATE: It seems that I can only use i2ctool if I am running a shell as root; this is with the permissions of i2c-1 set to global read/write. I've also tried setting the permissions of the parent folders in which i2c-1 resides in to 777 - still the same issue.

Can someone please tell me what i'm doing wrong or how I might stop the permission denied error?

Upvotes: 2

Views: 2291

Answers (1)

Ringo001
Ringo001

Reputation: 163

It seems that the issue was due to SELinux. Whilst not a permanent solution, I ran the command

$ /system/bin/setenforce 0

from within the adb shell and the application can now gain access to i2c-1 and read successfully from the device.

A more permenent solution would be to create a new SEPolicy rule and set the new policy to be loaded on boot. This post has some more information regarding the topic: https://android.stackexchange.com/questions/207484/how-to-fix-selinux-avc-denied-errors-when-launching-dnscrypt-as-init-d-script/207647#207647

[UPDATE] I've succesffully set SELinux to permissive and it holds after a reboot by editing the BoardConfig.mk file and adding the line

BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive

doing a rebuild of the boot image and flashing the new image to the device.

Upvotes: 1

Related Questions