core: load and save fingerprints to XML

We always use the global fingerprint table - maybe this should just not
be a parameter of the accessor functions?

The syntax is very simple - the raw data is encoded as a hex string, the
rest of the components are hex numbers.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2021-10-30 16:31:29 -07:00
parent 33527cb9e5
commit 2b1db9da82
4 changed files with 67 additions and 0 deletions

View file

@ -743,6 +743,22 @@ static void try_to_fill_dc_settings(const char *name, char *buf, struct parser_s
nonmatch("divecomputerid", name, buf);
}
static void try_to_fill_fingerprint(const char *name, char *buf, struct parser_state *state)
{
start_match("fingerprint", name, buf);
if (MATCH("model.fingerprint", hex_value, &state->cur_settings.fingerprint.model))
return;
if (MATCH("serial.fingerprint", hex_value, &state->cur_settings.fingerprint.serial))
return;
if (MATCH("deviceid.fingerprint", hex_value, &state->cur_settings.fingerprint.fdeviceid))
return;
if (MATCH("diveid.fingerprint", hex_value, &state->cur_settings.fingerprint.fdiveid))
return;
if (MATCH("data.fingerprint", utf8_string, &state->cur_settings.fingerprint.data))
return;
nonmatch("fingerprint", name, buf);
}
static void try_to_fill_event(const char *name, char *buf, struct parser_state *state)
{
start_match("event", name, buf);
@ -1480,6 +1496,7 @@ static bool entry(const char *name, char *buf, struct parser_state *state)
return true;
}
if (state->in_settings) {
try_to_fill_fingerprint(name, buf, state);
try_to_fill_dc_settings(name, buf, state);
try_to_match_autogroup(name, buf);
return true;
@ -1629,6 +1646,7 @@ static struct nesting {
const char *name;
parser_func start, end;
} nesting[] = {
{ "fingerprint", fingerprint_settings_start, fingerprint_settings_end },
{ "divecomputerid", dc_settings_start, dc_settings_end },
{ "settings", settings_start, settings_end },
{ "site", dive_site_start, dive_site_end },
@ -1744,6 +1762,7 @@ int parse_xml_buffer(const char *url, const char *buffer, int size,
state.trips = trips;
state.sites = sites;
state.devices = devices;
state.fingerprints = &fingerprint_table; // simply use the global table for now
state.filter_presets = filter_presets;
doc = xmlReadMemory(res, strlen(res), url, NULL, XML_PARSE_HUGE | XML_PARSE_RECOVER);
if (!doc)

View file

@ -186,6 +186,16 @@ void reset_dc_settings(struct parser_state *state)
state->cur_settings.dc.deviceid = 0;
}
void reset_fingerprint(struct parser_state *state)
{
free((void *)state->cur_settings.fingerprint.data);
state->cur_settings.fingerprint.data = NULL;
state->cur_settings.fingerprint.model = 0;
state->cur_settings.fingerprint.serial = 0;
state->cur_settings.fingerprint.fdeviceid = 0;
state->cur_settings.fingerprint.fdiveid = 0;
}
void settings_start(struct parser_state *state)
{
state->in_settings = true;
@ -196,6 +206,20 @@ void settings_end(struct parser_state *state)
state->in_settings = false;
}
void fingerprint_settings_start(struct parser_state *state)
{
reset_fingerprint(state);
}
void fingerprint_settings_end(struct parser_state *state)
{
create_fingerprint_node_from_hex(state->fingerprints,
state->cur_settings.fingerprint.model,
state->cur_settings.fingerprint.serial,
state->cur_settings.fingerprint.data,
state->cur_settings.fingerprint.fdeviceid,
state->cur_settings.fingerprint.fdiveid);
}
void dc_settings_start(struct parser_state *state)
{
reset_dc_settings(state);

View file

@ -30,6 +30,13 @@ struct parser_settings {
uint32_t deviceid;
const char *nickname, *serial_nr, *firmware;
} dc;
struct {
uint32_t model;
uint32_t serial;
uint32_t fdeviceid;
uint32_t fdiveid;
const char *data;
} fingerprint;
};
enum import_source {
@ -83,6 +90,7 @@ struct parser_state {
struct trip_table *trips; /* non-owning */
struct dive_site_table *sites; /* non-owning */
struct device_table *devices; /* non-owning */
struct fingerprint_table *fingerprints; /* non-owning */
struct filter_preset_table *filter_presets; /* non-owning */
sqlite3 *sql_handle; /* for SQL based parsers */
@ -113,6 +121,8 @@ void reset_dc_info(struct divecomputer *dc, struct parser_state *state);
void reset_dc_settings(struct parser_state *state);
void settings_start(struct parser_state *state);
void settings_end(struct parser_state *state);
void fingerprint_settings_start(struct parser_state *state);
void fingerprint_settings_end(struct parser_state *state);
void dc_settings_start(struct parser_state *state);
void dc_settings_end(struct parser_state *state);
void dive_site_start(struct parser_state *state);

View file

@ -607,6 +607,16 @@ static void save_one_device(struct membuffer *b, const struct device *d)
put_format(b, "/>\n");
}
static void save_one_fingerprint(struct membuffer *b, int i)
{
put_format(b, "<fingerprint model='%08x' serial='%08x' deviceid='%08x' diveid='%08x' data='%s'/>\n",
fp_get_model(&fingerprint_table, i),
fp_get_serial(&fingerprint_table, i),
fp_get_deviceid(&fingerprint_table, i),
fp_get_diveid(&fingerprint_table, i),
fp_get_data(&fingerprint_table, i));
}
int save_dives(const char *filename)
{
return save_dives_logic(filename, false, false);
@ -676,6 +686,10 @@ static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonym
if (!select_only || device_used_by_selected_dive(d))
save_one_device(b, d);
}
/* save the fingerprint data */
for (int i = 0; i < nr_fingerprints(&fingerprint_table); i++)
save_one_fingerprint(b, i);
if (autogroup)
put_format(b, " <autogroup state='1' />\n");
put_format(b, "</settings>\n");