/dc_import_android

Application to import data from divecomputer on android based on libdivecomputer.

Primary LanguageC

Import Dives from Divecomputer
==============================

This project attempts to create framework for download of
dive data from divecomputer on Android devices. This is a
project under Subsurface for GSOC '14.
Libdivecomputer is mainly used for all the dive computer
related functions.

It utilizes libftdi for communication with FTDI chips, which is
present in majority of dive computers. And libusb for connection
with USB devices.

The main idea is to get permission for a USB device from
the Java interface. When the user gives permission, then
call the native side of the application to do all import
tasks via libdivecomputer, libftdi and libusb.

All this is experimental as working of the discussed procedure
is not assured.

Dependencies
============

1. Libdivecomputer is the core of this project.
   http://libdivecomputer.org/
2. Libftdi for interfacing with ftdi chips
   http://www.intra2net.com/en/developer/libftdi/
3. Libusb for interfacing with USB
   http://www.libusb.org/
4. Android NDK and SDK
   http://developer.android.com/sdk/index.html
   http://developer.android.com/tools/sdk/ndk/index.html
5. Actionbarsherlock - library used for android application
   http://www.actionbarsherlock.com

Building
========
1. For building, one need to use the build.sh script.
   Modify the script to add the location of android-sdk
   and android-ndk. Also, modify lines at the end to point
   to proper position of actionbarsherlock library.
2. Run bash build.sh x86 (or) bash build.sh arm according
   to the architecture you want to support. The default is
   x86.
3. The script will install the dependencies to crossbuild
   directory.
4. It also runs ndk-build on successful completion for
   building jni libraries for the application.
   Android.mk is the make file for this build.
5. The script also builds the android application and installs
   on the attached device/emulator and starts the application.

Note:
a. For generating the Jni header files, one could use
   javah provided by JDK. For this project, I use this command
   to generate the headers.

   javah -jni -v -d jni -classpath bin/classes:../actionbarsherlock/bin/classes:$ANDROID_SDK/platforms/android-19/android.jar com.subsurface.Home

b. If you are getting build errors, make sure that you have run
   android update project on the actionbarsherlock directory as well.
   Also, use command 'ant clean' to clean actionbarsherlock and/or
   your project if you get 'crunch' related errors.

Android Application
===================
The android application is a simple application which lists the
available USB devices on the screen. Their Vendor ID and Product ID
are also visible in the list.
On selecting one of the devices, the application asks for the permission
to use it. Select yes.
The output of this depends on the experiment.

Experiment 1
-------------
Refer: https://github.com/mik3y/usb-serial-for-android
As the first attempt, I tried to utilise the library usb-serial-for-android
for interfacing with the ftdi interface present on the chip. But this effort
was unsuccessful. The problem was that I was not able to read the response
of the ftdi chip. The read() method was not returning anything except 06 20
and a stream of zeros. Write method worked fine as the divecomputer showed the
message "Download mode enabled" on sending INIT byte as it normally does.
The reason behind this is unknown.
This import interface can be accessed by removing and reconnecting the device.
A dialog pops asking for permission to use this device. On selecting yes,
it automatically goes to java import activity. The result can be seen
on the screen as well as the logcat.

Experiment 2
-------------
Refer:
http://developer.android.com/reference/android/hardware/usb/UsbDeviceConnection.html#getFileDescriptor()
In this experiment, the file descriptor obtained from UsbDeviceConnection
is sent to the native side to be received by the libdivecomputer and
import to be done utiising this. The results are logged using custom
logging function formed in com_subsurface_Home.c which logs it in the
android logcat. The above mentioned file is the tweaked universal.c
script from libdiveomputer/examples/ for importing data from
Heinrichs Weikamp OSTC3. utils.c (also from libdivecomputer/examples)
is also tweaked for logging.
This experiment failed because the file descriptor passed on by
UsbDeviceConnection is the file descriptor of underlying USB device
and not the tty device used for talking with it. Hence the error
received in the logcat was "ENOTTY : Not a typewriter".

Experiment 3
-------------
In this experiment, a new file serial_ftdi.c is made which would be
compiled instead of serial_posix.c while building on android. Make
of libdivecomputer is modified accordingly. Also, libftdi dependecy is
added. Initially on running this application, I am getting error
while opening device. This I tracked down to ERROR_ACCESS of libusb.
Now, this is the main challenge of this approach. Permissions of
usage of USB on android. Looking further in this.

Success
--------
After tweaking libusb and libftdi, I have been successful in extraction
of data from divecompute Heinrichs Weikamp OSTC 3. The key to this
was getting permission from android user. After this, you can open the
attached USB device, and can obtain its USB file descriptor. All this
is done on the java side of the code. Now, using the above file
descriptor, make a libusb_device via libftdi. Now, for this whole
procedure, the USB fd should be passed to libusb. Hence, we fell
back to what was done in Experiment 2. Tweaking libdivecomputer
to pass USB fd instead of file name. But this time it was done
intelligently to allow compilation both on android as well as normal
systems ( Heavy usage of Macros ).
Also, libftdi and libusb were tweaked in the same manner - to accept
USB fd.
After all this, when called upon to download dives from android,
the device did it perfectly. The result can be seen on logcat. One
thing must be kept in mind for logging. For seeing all the logs passed
to stderr on android you should follow certain steps. It could be
seen here :
http://venkateshshukla.wordpress.com/2014/06/05/android-from-command-line-useful-things/

Todo
----

Now, for actually making libdivecomputer to be useful, the Java
parts should be eliminated. Hence, the list of USB devices
and the dialog asking permission to use the device must be
somehow ( using JNI ) be implemented in libdivecomputer itself.
See if this is possible.