AOA Support through ADK driver

From RidgeRun Developer Connection
Jump to: navigation, search

Introduction

Ridgerun SDK offers support to initialize iMX6 machines running Linux-3.14 as an Android accessory host based on an ADK (Accessory development kit) driver that provides skeleton code to establish communication with Android devices in accessory mode through USB and AOA (Android Open Accessory) protocol. This code is fully documented on the adk-driver-skeleton wiki (https://github.com/rajeshsola/adk-driver-skeleton/wiki).

According to the authors of this ADK skeleton driver, this code is for reference as it requires lot of improvements in terms of synchronization, efficiency, and others especially in terms of read, write operations in accessory mode after initialization.

How to use it?

This ADK driver is installed as adk-aoa-skeleton module, once it's loaded and a connected Android device gets probed there are ioctl and sysfs operations to initialize the device in accessory mode from userspace. It's important to mention that the product and vendor IDs of Android devices should be added to a table in the ADK driver for a successful probe.

Below there's an example script based on sysfs operations to initialize an Android device in AOA mode:

insmod /lib/modules/3.14.28-ridgerun/kernel/drivers/usb/adk-driver/adk-aoa-skeleton.ko

cat /sys/kernel/adk_linux/aoa_init/version

echo "manufacturer=Texas Instruments" > /sys/kernel/adk_linux/aoa_init/identity

echo "mode=Test" > /sys/kernel/adk_linux/aoa_init/identity

echo "version=2.0" > /sys/kernel/adk_linux/aoa_init/identity

echo "accessory" > /sys/kernel/adk_linux/aoa_init/start

There's also a module parameter init_on_probe=1 to initialize a device in AOA mode using default identity strings without the need of ioctl or sysfs operations for initial testing.

Upon ioctl/sysfs/init_on_probe operations the Android device reenumerates to an unified configuration as per Android Open Accessory protocol specifications. For example, it'll set vendor id=0x18d1, product id in the range of 0x2d00 to 0x2d05, interface 0 with two bulk end points if started in custom accessory mode.

Using this module and appropriate userspace code it's possible to establish communication between the Android device and the Linux machine using simple file operations like open, read, write, close through system calls in C or any file handling API from other languages.

fd=open("/dev/aoa-skel0",O_RDWR);

/* To send data from ADK to App */
k=write(fd,buf,len);

/* To read data from App to ADK, suitably in an additional thread */
k=read(fd,buf,len);

/* Towards the end */
close(fd);

Some example applications for the Linux machine site can be found at https://github.com/rajeshsola/adk-driver-skeleton/tree/master/adk-userpsace-examples

Also, recommendations to write Android apps in accessory mode for the Android device site can be found at: https://github.com/rajeshsola/adk-driver-skeleton/wiki/Writing-android-apps-in-accessory-mode

Demo video

This demo sends the current time in the Linux device to the Android device and this time is shown in the app UI, also there are four switches in the Android app and their status ("On" or "Off") is send to the Linux device, this one reads that information and shows the new LED status on console.

Hardware:

  • iMX6 Nitrogen6x
  • Sony Xperia Z3

Software:

Useful links