summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/libdivecomputer.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/core/libdivecomputer.c b/core/libdivecomputer.c
index e7f88a517..cfe6a8049 100644
--- a/core/libdivecomputer.c
+++ b/core/libdivecomputer.c
@@ -452,6 +452,39 @@ static uint32_t calculate_string_hash(const char *str)
return calculate_diveid((const unsigned char *)str, strlen(str));
}
+/*
+ * Find an existing device ID for this device model and serial number
+ */
+static void dc_match_serial(void *_dc, const char *model, uint32_t deviceid, const char *nickname, const char *serial, const char *firmware)
+{
+ struct divecomputer *dc = _dc;
+
+ if (!deviceid)
+ return;
+ if (!model || strcasecmp(dc->model, model))
+ return;
+ if (!serial || strcasecmp(dc->serial, serial))
+ return;
+ dc->deviceid = deviceid;
+}
+
+/*
+ * Set the serial number.
+ *
+ * This also sets the device ID by looking for existing devices that
+ * have that serial number.
+ *
+ * If no existing device ID exists, create a new by hashing the serial
+ * number string.
+ */
+static void set_dc_serial(struct divecomputer *dc, const char *serial)
+{
+ dc->serial = serial;
+ call_for_each_dc(dc, dc_match_serial, false);
+ if (!dc->deviceid)
+ dc->deviceid = calculate_string_hash(serial);
+}
+
static void parse_string_field(struct dive *dive, dc_field_string_t *str)
{
// Our dive ID is the string hash of the "Dive ID" string
@@ -462,11 +495,7 @@ static void parse_string_field(struct dive *dive, dc_field_string_t *str)
}
add_extra_data(&dive->dc, str->desc, str->value);
if (!strcmp(str->desc, "Serial")) {
- dive->dc.serial = strdup(str->value);
- /* should we just overwrite this whenever we have the "Serial" field?
- * It's a much better deviceid then what we have so far... for now I'm leaving it as is */
- if (!dive->dc.deviceid)
- dive->dc.deviceid = calculate_string_hash(str->value);
+ set_dc_serial(&dive->dc, str->value);
return;
}
if (!strcmp(str->desc, "FW Version")) {
@@ -660,6 +689,10 @@ static int dive_cb(const unsigned char *data, unsigned int size,
import_dive_number++;
dive = alloc_dive();
+ // Fill in basic fields
+ dive->dc.model = strdup(devdata->model);
+ dive->dc.diveid = calculate_diveid(fingerprint, fsize);
+
// Parse the dive's header data
rc = libdc_header_parser (parser, devdata, dive);
if (rc != DC_STATUS_SUCCESS) {
@@ -667,9 +700,6 @@ static int dive_cb(const unsigned char *data, unsigned int size,
goto error_exit;
}
- dive->dc.model = strdup(devdata->model);
- dive->dc.diveid = calculate_diveid(fingerprint, fsize);
-
// Initialize the sample data.
rc = parse_samples(devdata, &dive->dc, parser);
if (rc != DC_STATUS_SUCCESS) {