diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/datatrak.c | 1 | ||||
-rw-r--r-- | core/device.cpp | 142 | ||||
-rw-r--r-- | core/device.h | 14 | ||||
-rw-r--r-- | core/divecomputer.c | 3 | ||||
-rw-r--r-- | core/divecomputer.h | 1 | ||||
-rw-r--r-- | core/divelist.c | 18 | ||||
-rw-r--r-- | core/libdivecomputer.c | 17 | ||||
-rw-r--r-- | core/load-git.c | 19 | ||||
-rw-r--r-- | core/parse-xml.c | 5 | ||||
-rw-r--r-- | core/parse.c | 6 | ||||
-rw-r--r-- | core/save-git.c | 10 | ||||
-rw-r--r-- | core/save-xml.c | 12 |
12 files changed, 70 insertions, 178 deletions
diff --git a/core/datatrak.c b/core/datatrak.c index 2fa89010e..c19c243a5 100644 --- a/core/datatrak.c +++ b/core/datatrak.c @@ -566,7 +566,6 @@ static unsigned char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive dt_dive->dc.deviceid = 0; else dt_dive->dc.deviceid = 0xffffffff; - create_device_node(devices, dt_dive->dc.model, dt_dive->dc.deviceid, "", "", dt_dive->dc.model); dt_dive->dc.next = NULL; if (!is_SCR && dt_dive->cylinders.nr > 0) { get_cylinder(dt_dive, 0)->end.mbar = get_cylinder(dt_dive, 0)->start.mbar - diff --git a/core/device.cpp b/core/device.cpp index c251144a2..42c2be004 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -13,31 +13,33 @@ struct device_table device_table; bool device::operator==(const device &a) const { return model == a.model && - deviceId == a.deviceId && - firmware == a.firmware && - serialNumber == a.serialNumber && - nickName == a.nickName; + serialNumber == a.serialNumber; } static bool same_device(const device &dev1, const device &dev2) { - return dev1.deviceId == dev2.deviceId && strcoll(dev1.model.c_str(), dev2.model.c_str()) == 0; + return strcmp(dev1.model.c_str(), dev2.model.c_str()) == 0 && + strcmp(dev1.serialNumber.c_str(), dev2.serialNumber.c_str()) == 0; } bool device::operator<(const device &a) const { - if (deviceId != a.deviceId) - return deviceId < a.deviceId; + int diff; - // Use strcoll to compare model-strings, since these might be unicode - // and therefore locale dependent? Let's hope that not, but who knows? - return strcoll(model.c_str(), a.model.c_str()) < 0; + diff = strcmp(model.c_str(), a.model.c_str()); + if (diff) + return diff < 0; + + return strcmp(serialNumber.c_str(), a.serialNumber.c_str()) < 0; } extern "C" const struct device *get_device_for_dc(const struct device_table *table, const struct divecomputer *dc) { + if (!dc->model || !dc->serial) + return NULL; + const std::vector<device> &dcs = table->devices; - device dev { dc->model ?: "", dc->deviceid, {}, {}, {} }; + device dev { dc->model, dc->serial }; auto it = std::lower_bound(dcs.begin(), dcs.end(), dev); return it != dcs.end() && same_device(*it, dev) ? &*it : NULL; } @@ -48,79 +50,51 @@ extern "C" bool device_exists(const struct device_table *device_table, const str return it != device_table->devices.end() && same_device(*it, *dev); } -/* - * When setting the device ID, we also fill in the - * serial number and firmware version data - */ -extern "C" void set_dc_deviceid(struct divecomputer *dc, unsigned int deviceid, const struct device_table *device_table) +void device::showchanges(const std::string &n) const { - if (!deviceid) - return; - - dc->deviceid = deviceid; - - // Serial and firmware can only be deduced if we know the model - if (empty_string(dc->model)) - return; - - const device *node = get_device_for_dc(device_table, dc); - if (!node) - return; - - if (!node->serialNumber.empty() && empty_string(dc->serial)) { - free((void *)dc->serial); - dc->serial = strdup(node->serialNumber.c_str()); - } - if (!node->firmware.empty() && empty_string(dc->fw_version)) { - free((void *)dc->fw_version); - dc->fw_version = strdup(node->firmware.c_str()); + if (nickName != n) { + if (!n.empty()) + qDebug("new nickname %s for DC model %s serial %s", n.c_str(), model.c_str(), serialNumber.c_str()); + else + qDebug("deleted nickname %s for DC model %s serial %s", nickName.c_str(), model.c_str(), serialNumber.c_str()); } } -void device::showchanges(const std::string &n, const std::string &s, const std::string &f) const +static int addDC(std::vector<device> &dcs, const std::string &m, const std::string &s, const std::string &n) { - if (nickName != n && !n.empty()) - qDebug("new nickname %s for DC model %s deviceId 0x%x", n.c_str(), model.c_str(), deviceId); - if (serialNumber != s && !s.empty()) - qDebug("new serial number %s for DC model %s deviceId 0x%x", s.c_str(), model.c_str(), deviceId); - if (firmware != f && !f.empty()) - qDebug("new firmware version %s for DC model %s deviceId 0x%x", f.c_str(), model.c_str(), deviceId); -} - -static void addDC(std::vector<device> &dcs, const std::string &m, uint32_t d, const std::string &n, const std::string &s, const std::string &f) -{ - if (m.empty() || d == 0) - return; - device dev { m, d, {}, {}, {} }; + if (m.empty() || s.empty()) + return -1; + device dev { m, s, n }; auto it = std::lower_bound(dcs.begin(), dcs.end(), dev); if (it != dcs.end() && same_device(*it, dev)) { // debugging: show changes if (verbose) - it->showchanges(n, s, f); + it->showchanges(n); // Update any non-existent fields from the old entry - if (!n.empty()) - it->nickName = n; - if (!s.empty()) - it->serialNumber = s; - if (!f.empty()) - it->firmware = f; + if (n.empty()) { + dcs.erase(it); + return -1; + } + it->nickName = n; + return it - dcs.begin(); } else { - dcs.insert(it, device{m, d, s, f, n}); + if (n.empty()) + return -1; + + dev.deviceId = calculate_string_hash(s.c_str()); + dcs.insert(it, dev); + return it - dcs.begin(); } } -extern "C" void create_device_node(struct device_table *device_table, const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname) +extern "C" int create_device_node(struct device_table *device_table, const char *model, const char *serial, const char *nickname) { - addDC(device_table->devices, model ?: "", deviceid, nickname ?: "", serial ?: "", firmware ?: ""); + return addDC(device_table->devices, model ?: "", serial ?: "", nickname ?: ""); } -/* Does not check for duplicates! */ extern "C" int add_to_device_table(struct device_table *device_table, const struct device *dev) { - auto it = std::lower_bound(device_table->devices.begin(), device_table->devices.end(), *dev); - int idx = it - device_table->devices.begin(); - device_table->devices.insert(it, *dev); - return idx; + return create_device_node(device_table, dev->model.c_str(), dev->serialNumber.c_str(), dev->nickName.c_str()); } extern "C" int remove_device(struct device_table *device_table, const struct device *dev) @@ -165,34 +139,6 @@ extern "C" int is_default_dive_computer_device(const char *name) return qPrefDiveComputer::device() == name; } -extern "C" void add_devices_of_dive(const struct dive *dive, struct device_table *device_table) -{ - if (!dive) - return; - - const struct divecomputer *dc; - - for_each_dc (dive, dc) { - if (!empty_string(dc->model) && dc->deviceid && - !get_device_for_dc(device_table, dc)) { - // we don't have this one, yet - if (std::any_of(device_table->devices.begin(), device_table->devices.end(), - [dc] (const device &dev) - { return !strcasecmp(dev.model.c_str(), dc->model); })) { - // we already have this model but a different deviceid - std::string simpleNick(dc->model); - if (dc->deviceid == 0) - simpleNick += " (unknown deviceid)"; - else - simpleNick += " (" + QString::number(dc->deviceid, 16).toStdString() + ")"; - addDC(device_table->devices, dc->model, dc->deviceid, simpleNick, {}, {}); - } else { - addDC(device_table->devices, dc->model, dc->deviceid, {}, {}, {}); - } - } - } -} - const char *get_dc_nickname(const struct divecomputer *dc) { const device *existNode = get_device_for_dc(&device_table, dc); @@ -227,21 +173,11 @@ extern "C" const char *device_get_model(const struct device *dev) return dev ? dev->model.c_str() : NULL; } -extern "C" const uint32_t device_get_id(const struct device *dev) -{ - return dev ? dev->deviceId : -1; -} - extern "C" const char *device_get_serial(const struct device *dev) { return dev ? dev->serialNumber.c_str() : NULL; } -extern "C" const char *device_get_firmware(const struct device *dev) -{ - return dev ? dev->firmware.c_str() : NULL; -} - extern "C" const char *device_get_nickname(const struct device *dev) { return dev ? dev->nickName.c_str() : NULL; diff --git a/core/device.h b/core/device.h index 1de436e33..6bfb85e3c 100644 --- a/core/device.h +++ b/core/device.h @@ -16,10 +16,7 @@ struct dive_table; // global device table extern struct device_table device_table; -extern void set_dc_deviceid(struct divecomputer *dc, unsigned int deviceid, const struct device_table *table); - -extern void add_devices_of_dive(const struct dive *dive, struct device_table *table); -extern void create_device_node(struct device_table *table, const char *model, uint32_t deviceid, const char *serial, const char *firmware, const char *nickname); +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); extern const struct device *get_device(const struct device_table *table, int i); extern struct device *get_device_mutable(struct device_table *table, int i); @@ -35,9 +32,7 @@ extern void remove_from_device_table(struct device_table *table, int idx); // struct device accessors for C-code. The returned strings are not stable! const char *device_get_model(const struct device *dev); -const uint32_t device_get_id(const struct device *dev); const char *device_get_serial(const struct device *dev); -const char *device_get_firmware(const struct device *dev); const char *device_get_nickname(const struct device *dev); // for C code that needs to alloc/free a device table. (Let's try to get rid of those) @@ -56,16 +51,15 @@ extern void free_device_table(struct device_table *devices); struct device { bool operator==(const device &a) const; // TODO: remove, once devices are integrated in the undo system bool operator<(const device &a) const; - void showchanges(const std::string &n, const std::string &s, const std::string &f) const; + void showchanges(const std::string &n) const; std::string model; - uint32_t deviceId; std::string serialNumber; - std::string firmware; std::string nickName; + uint32_t deviceId; // Always the string hash of the serialNumber }; struct device_table { - // Keep the dive computers in a vector sorted by (model, deviceId) + // Keep the dive computers in a vector sorted by (model, serial) std::vector<device> devices; }; diff --git a/core/divecomputer.c b/core/divecomputer.c index fa836f7ca..200094588 100644 --- a/core/divecomputer.c +++ b/core/divecomputer.c @@ -475,6 +475,9 @@ void add_extra_data(struct divecomputer *dc, const char *key, const char *value) { struct extra_data **ed = &dc->extra_data; + if (!strcasecmp(key, "Serial")) + dc->deviceid = calculate_string_hash(value); + while (*ed) ed = &(*ed)->next; *ed = malloc(sizeof(struct extra_data)); diff --git a/core/divecomputer.h b/core/divecomputer.h index eb48e9b86..8bb571c44 100644 --- a/core/divecomputer.h +++ b/core/divecomputer.h @@ -68,6 +68,7 @@ extern struct event *add_event(struct divecomputer *dc, unsigned int time, int t extern void remove_event_from_dc(struct divecomputer *dc, struct event *event); extern void add_extra_data(struct divecomputer *dc, const char *key, const char *value); extern bool is_dc_planner(const struct divecomputer *dc); +extern uint32_t calculate_string_hash(const char *str); /* Check if two dive computer entries are the exact same dive (-1=no/0=maybe/1=yes) */ extern int match_one_dc(const struct divecomputer *a, const struct divecomputer *b); diff --git a/core/divelist.c b/core/divelist.c index a1420e407..9beea4d7c 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -807,13 +807,6 @@ void delete_single_dive(int idx) void process_loaded_dives() { - int i; - struct dive *dive; - - /* Register dive computer nick names. */ - for_each_dive(i, dive) - add_devices_of_dive(dive, &device_table); - sort_dive_table(&dive_table); sort_trip_table(&trip_table); @@ -1172,17 +1165,6 @@ void process_imported_dives(struct dive_table *import_table, struct trip_table * add_to_device_table(devices_to_add, dev); } - /* check if we need a nickname for the divecomputer for newly downloaded dives; - * since we know they all came from the same divecomputer we just check for the - * first one */ - if (flags & IMPORT_IS_DOWNLOADED) { - add_devices_of_dive(import_table->dives[0], devices_to_add); - } else { - /* they aren't downloaded, so record / check all new ones */ - for (i = 0; i < import_table->nr; i++) - add_devices_of_dive(import_table->dives[i], devices_to_add); - } - /* Sort the table of dives to be imported and combine mergable dives */ sort_dive_table(import_table); merge_imported_dives(import_table); diff --git a/core/libdivecomputer.c b/core/libdivecomputer.c index dff44e287..d2d25306d 100644 --- a/core/libdivecomputer.c +++ b/core/libdivecomputer.c @@ -548,7 +548,7 @@ static uint32_t calculate_diveid(const unsigned char *fingerprint, unsigned int return csum[0]; } -static uint32_t calculate_string_hash(const char *str) +uint32_t calculate_string_hash(const char *str) { return calculate_diveid((const unsigned char *)str, strlen(str)); } @@ -556,10 +556,7 @@ static uint32_t calculate_string_hash(const char *str) /* * 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 + * This also sets the device ID by hashing the serial * number string. */ static void set_dc_serial(struct divecomputer *dc, const char *serial, const device_data_t *devdata) @@ -567,14 +564,7 @@ static void set_dc_serial(struct divecomputer *dc, const char *serial, const dev const struct device *device; dc->serial = strdup(serial); - if ((device = get_device_for_dc(&device_table, dc)) != NULL) // prefer already known ID over downloaded ID. - dc->deviceid = device_get_id(device); - - if (!dc->deviceid && (device = get_device_for_dc(devdata->devices, dc)) != NULL) - dc->deviceid = device_get_id(device); - - if (!dc->deviceid) - dc->deviceid = calculate_string_hash(serial); + dc->deviceid = calculate_string_hash(serial); } static void parse_string_field(device_data_t *devdata, struct dive *dive, dc_field_string_t *str) @@ -937,7 +927,6 @@ static unsigned int fixup_suunto_versions(device_data_t *devdata, const dc_event (devinfo->firmware >> 8) & 0xff, (devinfo->firmware >> 0) & 0xff); } - create_device_node(devdata->devices, devdata->model, devdata->deviceid, serial_nr, firmware, ""); return serial; } diff --git a/core/load-git.c b/core/load-git.c index c44a880ae..3826099e4 100644 --- a/core/load-git.c +++ b/core/load-git.c @@ -725,8 +725,7 @@ static void parse_dc_deviceid(char *line, struct membuffer *str, struct git_pars { UNUSED(str); int id = get_hex(line); - set_dc_deviceid(state->active_dc, id, &device_table); // prefer already known serial/firmware over those from the loaded log - set_dc_deviceid(state->active_dc, id, state->devices); + UNUSED(id); // legacy } static void parse_dc_diveid(char *line, struct membuffer *str, struct git_parser_state *state) @@ -974,16 +973,16 @@ static void parse_divecomputerid_keyvalue(void *_cid, const char *key, const cha { struct divecomputerid *cid = _cid; - if (!strcmp(key, "deviceid")) { - cid->deviceid = get_hex(value); + // Ignored legacy fields + if (!strcmp(key, "firmware")) return; - } + if (!strcmp(key, "deviceid")) + return; + + // Serial number and nickname matter if (!strcmp(key, "serial")) { cid->serial = value; - return; - } - if (!strcmp(key, "firmware")) { - cid->firmware = value; + cid->deviceid = calculate_string_hash(value); return; } if (!strcmp(key, "nickname")) { @@ -1014,7 +1013,7 @@ static void parse_settings_divecomputerid(char *line, struct membuffer *str, str break; line = parse_keyvalue_entry(parse_divecomputerid_keyvalue, &id, line, str); } - create_device_node(state->devices, id.model, id.deviceid, id.serial, id.firmware, id.nickname); + create_device_node(state->devices, id.model, id.serial, id.nickname); } static void parse_picture_filename(char *line, struct membuffer *str, struct git_parser_state *state) diff --git a/core/parse-xml.c b/core/parse-xml.c index c5864d6f5..5b9abc341 100644 --- a/core/parse-xml.c +++ b/core/parse-xml.c @@ -830,11 +830,8 @@ static void try_to_fill_dc(struct divecomputer *dc, const char *name, char *buf, return; if (MATCH("model", utf8_string, &dc->model)) return; - if (MATCH("deviceid", hex_value, &deviceid)) { - set_dc_deviceid(dc, deviceid, &device_table); // prefer already known serial/firmware over those from the loaded log - set_dc_deviceid(dc, deviceid, state->devices); + if (MATCH("deviceid", hex_value, &deviceid)) return; - } if (MATCH("diveid", hex_value, &dc->diveid)) return; if (MATCH("dctype", get_dc_type, &dc->divemode)) diff --git a/core/parse.c b/core/parse.c index 241d5763f..fdc73fc9f 100644 --- a/core/parse.c +++ b/core/parse.c @@ -203,8 +203,10 @@ void dc_settings_start(struct parser_state *state) void dc_settings_end(struct parser_state *state) { - create_device_node(state->devices, state->cur_settings.dc.model, state->cur_settings.dc.deviceid, state->cur_settings.dc.serial_nr, - state->cur_settings.dc.firmware, state->cur_settings.dc.nickname); + create_device_node(state->devices, + state->cur_settings.dc.model, + state->cur_settings.dc.serial_nr, + state->cur_settings.dc.nickname); reset_dc_settings(state); } diff --git a/core/save-git.c b/core/save-git.c index cea69974b..6bd237a8b 100644 --- a/core/save-git.c +++ b/core/save-git.c @@ -853,19 +853,15 @@ static void save_one_device(struct membuffer *b, const struct device *d) const char *model = device_get_model(d); const char *nickname = device_get_nickname(d); const char *serial = device_get_serial(d); - const char *firmware = device_get_firmware(d); - if (!empty_string(nickname) && !strcmp(model, nickname)) - nickname = NULL; + if (empty_string(serial)) serial = NULL; - if (empty_string(firmware)) firmware = NULL; if (empty_string(nickname)) nickname = NULL; - if (!nickname && !serial && !firmware) + if (!nickname || !serial) return; show_utf8(b, "divecomputerid ", model, ""); - put_format(b, " deviceid=%08x", device_get_id(d)); + put_format(b, " deviceid=%08x", calculate_string_hash(serial)); show_utf8(b, " serial=", serial, ""); - show_utf8(b, " firmware=", firmware, ""); show_utf8(b, " nickname=", nickname, ""); put_string(b, "\n"); } diff --git a/core/save-xml.c b/core/save-xml.c index 4c7c2ee04..3836ea35c 100644 --- a/core/save-xml.c +++ b/core/save-xml.c @@ -583,29 +583,23 @@ static void save_one_device(struct membuffer *b, const struct device *d) const char *model = device_get_model(d); const char *nickname = device_get_nickname(d); const char *serial_nr = device_get_serial(d); - const char *firmware = device_get_firmware(d); /* Nicknames that are empty or the same as the device model are not interesting */ if (empty_string(nickname) || !strcmp(model, nickname)) - nickname = NULL; + nickname = NULL; /* Serial numbers that are empty are not interesting */ if (empty_string(serial_nr)) serial_nr = NULL; - /* Firmware strings that are empty are not interesting */ - if (empty_string(firmware)) - firmware = NULL; - /* Do we have anything interesting about this dive computer to save? */ - if (!serial_nr && !nickname && !firmware) + if (!serial_nr || !nickname) return; put_format(b, "<divecomputerid"); show_utf8(b, model, " model='", "'", 1); - put_format(b, " deviceid='%08x'", device_get_id(d)); + put_format(b, " deviceid='%08x'", calculate_string_hash(serial_nr)); show_utf8(b, serial_nr, " serial='", "'", 1); - show_utf8(b, firmware, " firmware='", "'", 1); show_utf8(b, nickname, " nickname='", "'", 1); put_format(b, "/>\n"); } |