Gsoc idea: Android downloader

Anton Lundin glance at acc.umu.se
Wed Mar 5 06:10:06 PST 2014


On 05 March, 2014 - Jef Driesen wrote:

> On 2014-03-03 15:41, Dirk Hohndel wrote:
> >On Mon, 2014-03-03 at 15:24 +0100, Anton Lundin wrote:
> >>For subsurface we don't need no stinking jni wrappers, we run real code!
> >>=)
> >
> >Correct. As native app we can call native code directly.
> 
> I'm aware of that, but I'm thinking a bit broader. Subsurface isn't the only
> application using libdivecomputer :-)
> 
> >>Kernel drivers is a no-go if you would like to support anything but
> >>hand-built roms. Not even CM ships any kernel-modules.
> >>
> >>I've seen libusb based drivers for at least ftdi and acm based things,
> >>and ftdi is what my dc's use so I'm happy with atleast that =)
> >
> >ftdi is one of the most common ones. But there are a few more. And of
> >course there are a few divecomputers that use different protocols. Let's
> >forget for a moment about the iRDA ones... but there's Bluetooth
> >(shouldn't be too hard - Android does have a Bluetooth stack... all we
> >need is to use that directly instead of the serial emulation that
> >current libdivecomputer still uses), some use full USB - with libusb
> >available, that should be possible, too. And then of course there is the
> >UEMIS that simulates a FAT filesystem. That should be reasonably
> >straight forward as well.
> 
> Yes, being able to get rid of the bluetooth emulation would be really nice.
> 
> >>>Assume we manage to implement the necessary userspace driver, how do
> >>>we
> >>>integrate this nicely into libdivecomputer? This a question for which
> >>>I have
> >>>no good answer at the moment. Right now, an application simply passes
> >>>the
> >>>device node (e.g. /dev/ttyXXX), and libdivecomputer takes care of
> >>>opening
> >>>the serial port. This works well because there is just one driver for
> >>>each
> >>>platform. But once we have multiple serial drivers, we'll also need
> >>>some
> >>>mechanism to select the right driver.
> >>
> >>From what I've understod about usb-devices on android is that you need
> >>to call a user consent dialog from your app (java thingie, but you can
> >>call into java from c++ so thats not a problem), and then the system
> >>chown/setfacl the device so your app have rights to access it.
> >>
> >>My guess would be to have a way to map all the serial calls in
> >>libdivecomputer to external functions that can be implemented outside
> >>libdivecomputer, for ex in the app that interfaces with the rest of the
> >>world.
> >>
> >>From the top of my head that would be building libdivecomputer without
> >>any serial_*.c or maybe a serial_external.c that implements all the
> >>things that libdivecomputer needs, that can be enabled compile time.
> >
> >That sounds like the right approach.
> 
> What I have been thinking about is to turn the serial code into an
> interface, and then we can have multiple implementations of that interface.
> The current serial backend would be one of those implementation. For the
> application, instead of passing the device node for the serial port to the
> dc_device_open() function, it would create an instance of the new interface
> and pass that. Then the application can pick the right implementation. For
> Linux, Windows and Mac OS X, the default implementation would be sufficient.
> 
> Thus in the application, the code would look something like this:
> 
> dc_serial_t *serial = NULL;
> dc_device_t *device = NULL;
> 
> /* Create an instance of the serial port interface.
>  * Here I just use the default implementation, but
>  * that can of course be replaced with another one. */
> dc_serial_open(&serial, devname);
> 
> /* Open a connection to the device. */
> dc_device_open(&device, ..., serial);
> 
> /* Close the connection. */
> dc_device_close(device);
> dc_serial_close(serial);
> 
> The downside is the extra code on the application side. Although a nice side
> effect is that it would also solve the enumeration problem. Right there is a
> function to enumerate serial ports, but because the serial code is private,
> applications can't really use it.
> 

One trick would be to keep current dc_device_open, and just introduce a
dc_device_open_proxy(...., proxy) that uses function pointers for
everything in the proxy struct. Also a dc_serial_proxy that returns a
proxy struct to the current serial backend.

That way there is no api breakage, and you can switch to using another
serial api if you would like to. You could also use multiple serial
api's in the same app. For subsurface that could be
android_userspace_serial, android_jni_bluetooth and so on.

A side effect from that is that it would become way simpler to write
emulators to your memory dumps, to qa changes to the parsers.

As a test we could port subsurface to use QtSerialPort[1] to test such a
interface.

And maybe we could trick someone else into porting QtSerialPort to
android =)

Another "test" for such a api would for it to be compatible with doing
jni to a Android BluetoothSocket[2]


//Anton - Braindumps


1. http://qt-project.org/wiki/QtSerialPort
2. http://developer.android.com/reference/android/bluetooth/BluetoothSocket.html

-- 
Anton Lundin	+46702-161604


More information about the subsurface mailing list