mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: add structures for handling fingerprints
This just adds the basic structures and the accessor functions needed to manage a table of fingerprint data. The table is indexed by the hash of the model name and binary serial number as created by libdivcecomputer. This way the data is accessible when libdivecomputer fist accesses a dive computer (which is the point in time when we need to use the fingerprint. The table also contains the corresponding device id and dive id so we can verify that the current dive table still contains that dive. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
95192bdf83
commit
fa250906c9
2 changed files with 77 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "ssrf.h"
|
||||
#include "dive.h"
|
||||
#include "divelist.h"
|
||||
#include "subsurface-string.h"
|
||||
#include "device.h"
|
||||
#include "errorhelper.h" // for verbose flag
|
||||
|
@ -9,6 +10,7 @@
|
|||
#include <QString> // for QString::number
|
||||
|
||||
struct device_table device_table;
|
||||
struct fingerprint_table fingerprint_table;
|
||||
|
||||
bool device::operator==(const device &a) const
|
||||
{
|
||||
|
@ -197,3 +199,56 @@ extern "C" void free_device_table(struct device_table *devices)
|
|||
{
|
||||
delete devices;
|
||||
}
|
||||
|
||||
// managing fingerprint data
|
||||
bool fingerprint_record::operator<(const fingerprint_record &a) const
|
||||
{
|
||||
if (model == a.model)
|
||||
return serial < a.serial;
|
||||
return model < a.model;
|
||||
}
|
||||
|
||||
// annoyingly, the Cressi Edy doesn't support a serial number (it's always 0), but still uses fingerprints
|
||||
// so we can't bail on the serial number being 0
|
||||
extern "C" unsigned int get_fingerprint_data(const struct fingerprint_table *table, uint32_t model, uint32_t serial, const unsigned char **fp_out)
|
||||
{
|
||||
if (model == 0 || fp_out == nullptr)
|
||||
return 0;
|
||||
struct fingerprint_record fpr = { model, serial };
|
||||
auto it = std::lower_bound(table->fingerprints.begin(), table->fingerprints.end(), fpr);
|
||||
if (it != table->fingerprints.end() && it->model == model && it->serial == serial) {
|
||||
// std::lower_bound gets us the first element that isn't smaller than what we are looking
|
||||
// for - so if one is found, we still need to check for equality
|
||||
if (has_dive(it->fdeviceid, it->fdiveid)) {
|
||||
*fp_out = it->raw_data;
|
||||
return it->fsize;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void create_fingerprint_node(struct fingerprint_table *table, uint32_t model, uint32_t serial,
|
||||
const unsigned char *raw_data_in, unsigned int fsize, uint32_t fdeviceid, uint32_t fdiveid)
|
||||
{
|
||||
// since raw data can contain \0 we copy this manually, not as string
|
||||
unsigned char *raw_data = (unsigned char *)malloc(fsize);
|
||||
if (!raw_data)
|
||||
return;
|
||||
memcpy(raw_data, raw_data_in, fsize);
|
||||
|
||||
struct fingerprint_record fpr = { model, serial, raw_data, fsize, fdeviceid, fdiveid };
|
||||
auto it = std::lower_bound(table->fingerprints.begin(), table->fingerprints.end(), fpr);
|
||||
if (it != table->fingerprints.end() && it->model == model && it->serial == serial) {
|
||||
// std::lower_bound gets us the first element that isn't smaller than what we are looking
|
||||
// for - so if one is found, we still need to check for equality - and then we
|
||||
// can update the existing entry; first we free the memory for the stored raw data
|
||||
free(it->raw_data);
|
||||
it->fdeviceid = fdeviceid;
|
||||
it->fdiveid = fdiveid;
|
||||
it->raw_data = raw_data;
|
||||
it->fsize = fsize;
|
||||
} else {
|
||||
// insert a new one
|
||||
table->fingerprints.insert(it, fpr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ struct dive_table;
|
|||
|
||||
// global device table
|
||||
extern struct device_table device_table;
|
||||
extern struct fingerprint_table fingerprint_table;
|
||||
|
||||
extern int create_device_node(struct device_table *table, const char *model, const char *serial, const char *nickname);
|
||||
extern int nr_devices(const struct device_table *table);
|
||||
|
@ -40,6 +41,12 @@ const char *device_get_nickname(const struct device *dev);
|
|||
extern struct device_table *alloc_device_table();
|
||||
extern void free_device_table(struct device_table *devices);
|
||||
|
||||
// create fingerprint entry - raw data remains owned by caller
|
||||
extern void create_fingerprint_node(struct fingerprint_table *table, uint32_t model, uint32_t serial,
|
||||
const unsigned char *raw_data, unsigned int fsize, uint32_t fdeviceid, uint32_t fdiveid);
|
||||
// look up the fingerprint for model/serial - returns the number of bytes in the fingerprint; memory owned by the table
|
||||
extern unsigned int get_fingerprint_data(const struct fingerprint_table *table, uint32_t model, uint32_t serial, const unsigned char **fp_out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -59,11 +66,26 @@ struct device {
|
|||
uint32_t deviceId; // Always the string hash of the serialNumber
|
||||
};
|
||||
|
||||
struct fingerprint_record {
|
||||
bool operator<(const fingerprint_record &a) const;
|
||||
uint32_t model; // model and libdivecomputer serial number to
|
||||
uint32_t serial; // look up the fingerprint
|
||||
unsigned char *raw_data; // fingerprint data as provided by libdivecomputer
|
||||
unsigned int fsize; // size of raw fingerprint data
|
||||
unsigned int fdeviceid; // corresponding deviceid
|
||||
unsigned int fdiveid; // corresponding diveid
|
||||
};
|
||||
|
||||
struct device_table {
|
||||
// Keep the dive computers in a vector sorted by (model, serial)
|
||||
std::vector<device> devices;
|
||||
};
|
||||
|
||||
struct fingerprint_table {
|
||||
// Keep the fingerprint records in a vector sorted by (model, serial) - these are uint32_t here
|
||||
std::vector<fingerprint_record> fingerprints;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DEVICE_H
|
||||
|
|
Loading…
Add table
Reference in a new issue