Progress on Android Divecomputer Downloader

Venkatesh Shukla venkatesh.shukla.eee11 at
Fri May 30 10:31:53 PDT 2014


I will outline the work I have done till date.

I have tried the following ways to communicate with the divecomputer on android.

1. Usage of usb-serial-for-android library for communication with ftdi
chips. I made a simple android application which listed all devices
attached and took permission for using the device. On receiving
permission, the application tried to use the above mentioned library
to extract data from the device. This involved normal read and write
functions. To crosscheck, I made a simple activity which follows the
following steps for download of dive headers from HW OSTC3 ( I
referred libdivecomputer for steps):
   a. Send an INIT byte to the device (0xBB)
   b. The device responds with an ECHO of the init byte. Read this.
   c. The device sends a READY byte (0x4D). Read this
   d. Send IDENTITY byte (0x69) to the device.
   e. The device responds with the echo. Read this.
   f. The device sends a READY byte (0x4D). Read this.
   g. Then the device sends 64 bytes of data to the device containing
the model number, name and serial number of the device. Read this.
   h. Send HEADER byte (0x61) to the device to extract its dive headers.
   i. The device first responds with an echo. Read this.
   j. Then the device gives back 256x256 byte of data back. It
contains the dive headers. Read this information.
   k. The device sends a READY byte (0x4D) back to the user. Read this.
This effort failed. The application was sending INIT byte
successfully. This was confirmed by the divecomputer showing "Download
Mode Enabled.". But the device was unable to read any data. Not even
the echo of INIT byte. On trying to read from the device, I was
getting just a stream of zeros with intermittent '06 20' bytes'. Most
probably, these were the status bytes which was sent by ftdi devices
on intervals of 40 ms. I tried changing configuration but it did not
help. I could not fathom the reason behind this. If anyone has any
ideas, do mention.

2. Usage of libftdi and libusb. First of all, I began with a simple
python script which utilized pylibftdi - a python library which is
nothing but a wrapper on libftdi. This was done to check if libftdi
could be used to download data from divecomputers. This script was
indeed successful in download of dive headers from the device. This
gave the indication that libftdi could be utilised to extract data
from divecomputers having ftdi chips. Going forward, I made a test
code in C which used libftdi to extract data from the dc. This was
also successful and I was able to extract headers.

3. On advice of glance, I cross compiled this test code for android,
using android standalone toolchain and patched libusb library, to see
if I could use libftdi and libusb for getting data on android. I ran
the compiled binary on adb shell as root user. The experiment was
successful as the output was the similar as that on my fedora. This
indicated that libftdi and libusb can indeed be used for getting data
on android. The remaining piece of the puzzle is getting permissions
for the device. In the above experiment, as I ran it as root user, it
worked well. But we do not expect all subsurface users to have rooted
phones. In android for using USB devices, you have to get necessary
permissions from the user. This can be done from the Java side of the
application. According to glance, after getting required permissions,
you can use the device as it was done above. This needs to be tested.
I have made serial_ftdi.c for libdivecomputer to use libftdi and
libusb for talking with usb devices on android. It is just an initial

4. There is this curious method in UsbDeviceConnection class on
android called getFileDescriptor(). Refer
. It returns native file descriptor for the USB device.
Libdivecomputer also utilizes the file descriptor of tty for all its
communication. As an experiment, I modified the above made android
application. Now, after getting permission for using USB device, the
application ,instead of using usb-serial-for-android for importing
data from dive computer, uses the getFileDescriptor method to acquire
the file descriptor of USB device and passed it on to native side of
the application. I tweaked libdivecomputer to pass file decriptor as
its argument rather than the file path as it usually does. I made a
script on the native side (for which I modified universal.c) which
receives the file descriptor and uses it to import data from OSTC3. I
tried running this but got error ENOTTY : Not a typewriter. The
explanation behind this was given by Jef. The file descriptor acquired
by the method getFileDescriptor() is actually the USB fd and the
descriptor used by libdivecomputer is file descriptor of tty device
which is built on the top of USB device. Hence, it is not possible to
use this approach.
But I gained knowledge on building using android ndk.

5. Again, on advice of glance, I made a git repository containing the
above said android applicationa and build files for cross compilation
of libusb and libftdi. I'll be continuing my work in this repository ( )

Jef, I have uploaded libdivecomputer on github ( ). I hope this is
not a problem. I am working on a separate branch for my

I am pursuing the approach of point 3 above. The plan is to get
permissions from java. then use the serial_ftdi.c ( which in turn uses
liftdi, which in turn uses libusb) to import dives.

It is also worth mentioning a serious flaw that I observed. I am
losing data while reading using libftdi. This is true for pylibftdi
script, the c code using libftdi and the cross compiled version on
android. While reading the headers on 'step j' above the expected
amount of data was 65536. But I was receiving only around 65445 bytes
on fedora, and even less 65210 on android emulator. This is a serious
error. Unfortunately Jef doesn't have an explanation. I am attaching
the output of running import_ostc3.c and similar output of subsurface
on the same device.

Attachments :
1. serial_ftdi.c   - script to download data utilising libdfti and
libusb to download data. This would be called on android instead of
serial_posix.c. Initial version.
2. - script which uses pylibftdi to download dive
headers from hw ostc3.
3. import_ostc3.c  - script which uses libftdi to download data from
hw ostc3. This was cross compiled and run as root on x86 emulator.
4. import_ftdi.logs - output of the script import_ostc3.c on fedora.
There is evident data loss.
5.import_subsurface.logs - output for the same divecomputer while
using subsurface.

Venkatesh Shukla
-------------- next part --------------
A non-text attachment was scrubbed...
Name: import_ftdi.logs
Type: application/octet-stream
Size: 198966 bytes
Desc: not available
URL: <>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: import_ostc3.c
Type: text/x-csrc
Size: 8260 bytes
Desc: not available
URL: <>
-------------- next part --------------
A non-text attachment was scrubbed...
Type: text/x-python
Size: 2970 bytes
Desc: not available
URL: <>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: import_subsurface.logs
Type: application/octet-stream
Size: 178175 bytes
Desc: not available
URL: <>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: serial_ftdi.c
Type: text/x-csrc
Size: 19136 bytes
Desc: not available
URL: <>

More information about the subsurface mailing list