Antidote port to Android

From Wikidb

Jump to: navigation, search

This page refers to Android 2.3 port. The port to 4.0 (Ice Cream Sandwitch) can be found at Antidote port to Android ICS page.

Contents

Warning

Antidote itself has been ported to Android quite some time ago. Android.mk files are in source tree.

This page is about the necessary components around it that need to be updated in Android. These updated components are deemed UNSTABLE. (We hope that Android 4.0 will have everything bundled so we just need to copy Android into phone and use it.)

Laundry list

Running Antidote in an useful way, that is, using Bluetooth HDP and serving com.signove.healthd service over D-Bus implies adding and/or upgrading some core Android components, because the current open source version (Gingerbread) is quite "old". Namely, the following components are affected:

We expect that future releases of Android have more up-to-date components so the porting effort is smaller. Also, dbus-glib has been made obsolete, the alternative is using D-Bus API included with recent GIO, so hopefully dbus-glib can be removed from requirement list, once we cease to use it in Antidote itself.

Environment

Currently, Antidote for Android can be built along with a device image. This means following these instructions: http://source.android.com/source/initializing.html and having a suitable device, whose image can be built from open source. Nexus One and Nexus S are good. (We expect to use NDK in the future, not having to build an entire device image from scratch just to add a library. But for now, that's the way it is.)

It is important to make sure that your environment is capable of generating a good phone image, BEFORE trying to add Antidote to the mix. Once you did that, get the sources below.

Currently, Antidote has been tagged for "eng" and "debug" image type. Build process was tested only for Nexus S (Crespo, the normal one, not the 4G version), always choosing an "userdebug" image in lunch configuration script.

Source code

The big tar.gz file with updated user-level components plus Antidote can be found here: File:Android-userlevel-antidote.tar.gz

This tarball includes all sources, the folders containing 'old' versions, and two stray files of the build system that needed to be changed (build/core/pathmap.mk and build/core/prelink-linux-arm.map).

It also includes a slightly changed version of init.rc that gives permission 0666 to D-Bus socket, so the health service can be run as non-root later.

Unpacking it onto environment's base folder, make clean and 'make' should be enough to generate an image with Antidote. If you want to get the latest Antidote, get patches from gingerbread branch, since master branch contains ICS files already:

cd external/bluetooth/antidote
git pull origin gingerbread

Every subfolder, like external/dbus, external/bluetooth/bluez etc. is a separate Git repository. Third-party software like D-Bus, GLib and BlueZ was downloaded in tar.gz. form, added in Git with one big commit, and additional files and changes necessary to compile under Android have been stored on subsequent commits (so hopefully future updates of the same software will be much easier).

You don't need to cope with each subfolder while building an image, but version control is in place to distinguish clearly stock code from porting changes.

If it builds ok, it is not over yet! You need an updated kernel too.

Pre-testing Antidote

You can test Antidote without having the updated Bluetooth kernel, by running the test agent and test manager. They connect to each other via TCP/IP, to they run regardless of BlueZ, Glib etc.

(in PC)
$ adb shell

(in phone)
$ su
# cd /data
# mkdir test
# cd /data/test
# export TMPDIR=/data/test
# /system/bin/ieee_manager --tcp

Open another shell and do the same, but call "ieee_agent --tcp". They should communicate. Agent exits while manager continues to run (it exits after 3 agent connections.)

It is possible to copy just the executables (/system/bin/ieee_*) to a phone (including non-Nexus) using "adb push" (no need to replace the whole image).

I have done that myself with my HTC Desire for a quick test, and programs ran normally (and my Desire ran Frodo at that time).


Kernel

When you set up the image build environment, kernel tree does not come along; image gets some precooked kernel image. So you need to set up the kernel environment yourself.

Compiling custom kernel for Nexus S

Assuming that one has a full image build enviroment as described in http://source.android.com/source/initializing.html, and tested it in a Nexus S phone successfully, compiling a kernel is not incredibly difficult. The following instructions are a compilation of any number of tutorials about the subject.

git clone git://android.git.kernel.org/kernel/samsung.git
cd samsung
make ARCH=arm clean
make ARCH=arm herring_defconfig
make -j4 ARCH=arm CROSS_COMPILE=arm-eabi-

Some failure (not finding arm-eabi-gcc) means that environment is not setup with envsetup.sh/lunch. Do this as source.android.com URL describes and cross-compiliation will be ok.

Copy originally generated ramdisk from build path:

cp ../out/target/product/crespo/ramdisk.img ..

Generate new boot.img with new kernel

mkbootimg --kernel arch/arm/boot/zImage --base 0x30000000  --pagesize 4096 \
    --ramdisk ../ramdisk.img --cmdline 'no_console_suspend=1 console=null'  \
    -o ../boot.img

cd ..

NOTE: omitting the --cmdline will break Bluetooth, don't know the reason.

Test new kernel with

fastboot boot boot.img

It should boot normally, though WiFi will not work because module needs to be copied to filesystem. If it booted ok, you can copy the module into place using adb:

cd samsung/
cd drivers/net/wireless/bcm4329/
adb root
adb remount
adb push bcm4329.ko /system/modules

Reboot and test WiFi and BT. If everything is OK, flash the boot image definitively:

fastboot flash boot boot.img

Backporting newer Bluetooth stack

Since we want Bluetooth with ERTM, but there seems to be no kernel more recent than 2.6.35 for nexus S, I tried a backport from 2.6.36.4. It is a version where ERTM worked stable and it is 'near' 2.6.35 so no need to cope with more fundamental changes in backport.

Backport tarball: File:Kernel-samsung-backported-bt.tar.gz

I just copied the net/bluetooth/* source (including subdirs) and include/net/bluetooth/* headers from 2.6.36 to samsung tree, and repeated the recompilation/testing/flashing/copying WIFi driver procedure.

Seems to be stable. (Be warned that Bluetooth ERTM support matured (and lots of bugs have been fixed) since kernel 2.6.36. The ideal solution would be to upgrade to a real recent kernel like 2.6.38 or better.)

Running the healthd service

Finally you can run healthd and connect Bluetooth devices. (Tested with Nonin 9650 oximeter and Nexus S). Enable Bluetooth, pair the health device. Then run healthd as shown below and connect the device.

(in PC)
$ adb shell

(in phone)
$ su
# cd /data
# mkdir test
# cd /data/test
# export TMPDIR=/data/test
# /system/bin/healthd --auto

If it works, you can test whether the service run as non-root. Let's suppose that AntidoteClient application is installed (we will talk about that below), and it was assigned the user "app_34". We will use the app's folder to test non-root running:

(in PC)
$ adb shell

(in phone)
$ su
# su app_34
$ cd /data/data/com.signove.oss.antidoteclient
$ export TMPDIR=$(pwd)
$ /system/bin/healthd --auto

If the init.rc is right and boot.img has been flashed, it should run correctly. If it does not, you can set socket permissions manually (as root inside adb shell, of course):

# chmod 666 /dev/socket/dbus

If this permission was the problem, the service should run then. Note that this permission change only last until phone is rebooted. To make it permanent, you need to change init.rc and reflash boot.img which contains this file. (Antidote source package brings this modified file along, so there should be no problems if you flashed correctly.)

Please note that app_34 is the user in my example. It could be any other in your own phone.

End-to-end in Android

This example application starts healthd in background, and displays data from sensors.

Antidote-android11.jpg
Antidote-android12.jpg
Antidote-android13.jpg

Old version pictures

In the old version, we still needed to run healthd manually in shell, that's why there are pictures of terminal screen.

Antidote-android1.jpg
Antidote-android2.jpg
Antidote-android3.jpg
Antidote-android4.jpg
Antidote-android5.jpg
Antidote-android6.jpg
Antidote-android7.jpg

End-to-end: troubleshooting

In order to show an "end-to-end" example in phone using healthd service, we have a problem: there are no D-Bus bindings to Java. Since dbus is heavily patched in Android, it is uncertain whether java-dbus would work.

In order to solve this, we have added a very simple, TCP-based protocol to healthd. It is served (instead of D-Bus service) if you run it with --tcp parameter:

(in PC)
$ adb shell

(in phone)
$ su
# cd /data
# mkdir test
# cd /data/test
# export TMPDIR=/data/test
# /system/bin/healthd --tcp

You can test that either connecting to port 9005 of phone's IP address.

Since AntidoteClient runs healthd as a child process and non-root, make sure healthd is running well as non-root in --auto mode (see earlier topic).

The "ps" command is your friend, you can see whether healthd is being run when AntidoteClient is on foreground.

You can also telnet to port 9005 when healthd is auto-loaded by AntidoteClient, at the same time AntidoteClient is shown in foreground. The TCP service in port 9005 is multi-client (it broadcasts all events to all clients).

Personal tools
Namespaces
Variants
Actions
Navigation
Streams
Communication
Toolbox