device_set_fingerprint

Jef Driesen jefdriesen at telenet.be
Sun Jan 29 12:25:22 UTC 2012


On 01/28/2012 09:33 PM, Steve Boyd wrote:
> I am starting to write my own program to download my dive computer using
> the libdivecomputer DLL.
>
> I am a bit confused about exactly what the device_set_fingerprint
> function does.  The documentation suggests that it has something to do
> with limiting downloads to just new dives, but it is unclear about
> exactly how it accomplishes that.
>
> Any light you can shed on this is appreciated.

The explanation is as follows.

In the dive callback you receive for every dive, both the dive data and a 
fingerprint. This fingerprint is some piece of data that uniquely identifies 
that particular dive. Usually it's the date/time of the dive, but that's no 
guarantee. You shouldn't care about the actual contents and treat it as a opaque 
piece of data.

Now when a download finished successfully, you should store the fingerprint of 
the most recent dive somewhere. Keep in mind that dives are downloaded in 
reverse order, so the most recent dive is always the first one you get. Since a 
user may have more than one dive computer, you should store a separate 
fingerprint for each device. That's where you'll need the serial number from the 
DEVINFO event, so you can store a fingerprint for every serial number (and 
preferable combined with the backend type too, because serial numbers are not 
guaranteed to be unique across different backends.).

During the next download, when you get the DEVINFO event, you have to lookup the 
corresponding fingerprint and pass it to the device_set_fingerprint function. 
Then the backend code will internally do the right thing, and download only the 
dives that are more recent than the dive associated with that fingerprint.


You can find an example implementation in the universal application. When you 
use the -c option to point to an (existing) directory, it will store/load the 
fingerprints as small files there. There is also a -f option to supply a hex 
encoded fingerprint directly.


There is however one additional complication due to downloading in reverse 
order, and that's how to handle partial downloads where you downloaded some 
dives successfully, but not all. Imagine there are three dives A, B and C to 
download, with A being the oldest and C the newest. Let's assume you download C 
successfully, but an error occurs during downloading dive B:

C -> success
B -> error
A

Now, imagine you would ignore the error, and update the fingerprint store with 
that fingerprint of dive C (as you would do in the case of success). If you try 
to download again, the fingerprint of dive C will be recognized as already 
downloaded, and abort the downloading. Thus you are unable to download dive B 
and A, which is bad. However if you would not update the fingerprint store, 
you'll download all three dives again. Thus you end up with a duplicate of dive 
C, but at least you can still get B and A. This is obviously the least bad 
option. A possible solution would be to maintain an ignore list, where you store 
the fingerprints of the dives that did download successfully, and then compare 
every downloaded dive against this list. If all dives downloaded without errors 
this ignore list can be cleared, so you don't have to match against your entire 
logbook.


You can always implement your own "download only new dives" feature manually in 
your application, but I advise against doing that for a number of reasons:

1. The fingerprint support can take advantage of device specific knowledge, 
resulting in the most efficient experience. For example there are backends where 
this feature is incorporated into the download protocol. By doing this manually 
you can't take advantage of that, and you'll always perform a worst case 
download scenario where you download everything and then ignore the dives you 
already have. Even if it's not part of the protocol, there are backends where we 
have a more efficient implementation.

2. When you rely on the date/time field to make the decision whether you already 
have a dive or not (which is probably the most likely way to implement this), 
you may run into a number of issues. For example many dive computers allow you 
to set the clock backwards (e.g. clock reset due to battery replacement, 
timezone adjustments, etc). Some devices require the host clock for calculating 
the dive time, and a small change in the host clock may lead to slightly 
different dive times (e.g. clock drifts, downloading on a different system, 
etc). Again with the fingerprints we take advantage of device specific knowledge 
and match directly against the device timestamp, avoiding all these problems.

If you have more questions, just let me know!

Jef




More information about the Devel mailing list