summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--device.h2
-rw-r--r--libdivecomputer.c41
-rw-r--r--libdivecomputer.h1
-rw-r--r--parse-xml.c23
-rw-r--r--save-xml.c37
5 files changed, 93 insertions, 11 deletions
diff --git a/device.h b/device.h
index 5a207f256..896bcb8e0 100644
--- a/device.h
+++ b/device.h
@@ -5,6 +5,8 @@ struct device_info {
const char *model;
uint32_t deviceid;
+ const char *serial_nr;
+ const char *firmware;
const char *nickname;
struct device_info *next;
gboolean saved;
diff --git a/libdivecomputer.c b/libdivecomputer.c
index 47c7b6367..9529861dc 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -5,6 +5,7 @@
#include <glib/gi18n.h>
#include "dive.h"
+#include "device.h"
#include "divelist.h"
#include "display.h"
#include "display-gtk.h"
@@ -418,7 +419,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
dc_parser_destroy(parser);
return rc;
}
- dive->dc.model = str_printf("%s %s", devdata->vendor, devdata->product);
+ dive->dc.model = devdata->model;
dive->dc.deviceid = devdata->deviceid;
dive->dc.diveid = calculate_diveid(fingerprint, fsize);
@@ -526,6 +527,35 @@ static uint32_t calculate_sha1(unsigned int model, unsigned int firmware, unsign
return csum[0];
}
+static void fixup_suunto_versions(device_data_t *devdata, const dc_event_devinfo_t *devinfo)
+{
+ struct device_info *info;
+
+ info = create_device_info(devdata->model, devdata->deviceid);
+ if (!info)
+ return;
+
+ if (!info->serial_nr && devinfo->serial) {
+ char serial_nr[13];
+
+ snprintf(serial_nr, sizeof(serial_nr), "%02d%02d%02d%02d",
+ (devinfo->serial >> 24) & 0xff,
+ (devinfo->serial >> 16) & 0xff,
+ (devinfo->serial >> 8) & 0xff,
+ (devinfo->serial >> 0) & 0xff);
+ info->serial_nr = strdup(serial_nr);
+ }
+
+ if (!info->firmware && devinfo->firmware) {
+ char firmware[13];
+ snprintf(firmware, sizeof(firmware), "%d.%d.%d",
+ (devinfo->firmware >> 16) & 0xff,
+ (devinfo->firmware >> 8) & 0xff,
+ (devinfo->firmware >> 0) & 0xff);
+ info->firmware = strdup(firmware);
+ }
+}
+
static void event_cb(dc_device_t *device, dc_event_type_t event, const void *data, void *userdata)
{
const dc_event_progress_t *progress = data;
@@ -548,6 +578,13 @@ static void event_cb(dc_device_t *device, dc_event_type_t event, const void *dat
devinfo->firmware, devinfo->firmware,
devinfo->serial, devinfo->serial);
devdata->deviceid = calculate_sha1(devinfo->model, devinfo->firmware, devinfo->serial);
+
+ /*
+ * libdivecomputer doesn't give serial numbers in the proper string form,
+ * so we have to see if we can do some vendor-specific munging.
+ */
+ if (!strcmp(devdata->vendor, "Suunto"))
+ fixup_suunto_versions(devdata, devinfo);
break;
case DC_EVENT_CLOCK:
dev_info(devdata, _("Event: systime=%"PRId64", devtime=%u\n"),
@@ -571,6 +608,8 @@ static const char *do_device_import(device_data_t *data)
dc_status_t rc;
dc_device_t *device = data->device;
+ data->model = str_printf("%s %s", data->vendor, data->product);
+
// Register the event handler.
int events = DC_EVENT_WAITING | DC_EVENT_PROGRESS | DC_EVENT_DEVINFO | DC_EVENT_CLOCK;
rc = dc_device_set_events(device, events, event_cb, data);
diff --git a/libdivecomputer.h b/libdivecomputer.h
index 81eb78abd..0950d32ae 100644
--- a/libdivecomputer.h
+++ b/libdivecomputer.h
@@ -13,6 +13,7 @@
typedef struct device_data_t {
dc_descriptor_t *descriptor;
const char *vendor, *product, *devname;
+ const char *model;
unsigned int deviceid, diveid;
dc_device_t *device;
dc_context_t *context;
diff --git a/parse-xml.c b/parse-xml.c
index e7cb1a182..6de518d02 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -14,6 +14,7 @@
#include <glib/gi18n.h>
#include "dive.h"
+#include "device.h"
int verbose;
@@ -148,7 +149,7 @@ static struct {
struct {
const char *model;
uint32_t deviceid;
- const char *nickname;
+ const char *nickname, *serial_nr, *firmware;
} dc;
} cur_settings;
static gboolean in_settings = FALSE;
@@ -619,6 +620,10 @@ static void try_to_fill_dc_settings(const char *name, char *buf)
return;
if (MATCH("divecomputerid.nickname", utf8_string, &cur_settings.dc.nickname))
return;
+ if (MATCH("divecomputerid.serial", utf8_string, &cur_settings.dc.serial_nr))
+ return;
+ if (MATCH("divecomputerid.firmware", utf8_string, &cur_settings.dc.firmware))
+ return;
nonmatch("divecomputerid", name, buf);
}
@@ -1061,8 +1066,12 @@ static void reset_dc_settings(void)
{
free((void *)cur_settings.dc.model);
free((void *)cur_settings.dc.nickname);
+ free((void *)cur_settings.dc.serial_nr);
+ free((void *)cur_settings.dc.firmware);
cur_settings.dc.model = NULL;
cur_settings.dc.nickname = NULL;
+ cur_settings.dc.serial_nr = NULL;
+ cur_settings.dc.firmware = NULL;
cur_settings.dc.deviceid = 0;
}
@@ -1083,8 +1092,20 @@ static void dc_settings_start(void)
static void dc_settings_end(void)
{
+ struct device_info *info;
+
if (cur_settings.dc.model)
remember_dc(cur_settings.dc.model, cur_settings.dc.deviceid, cur_settings.dc.nickname, TRUE);
+
+ info = create_device_info(cur_settings.dc.model, cur_settings.dc.deviceid);
+ if (info) {
+ if (!info->serial_nr && cur_settings.dc.serial_nr)
+ info->serial_nr = strdup(cur_settings.dc.serial_nr);
+ if (!info->firmware && cur_settings.dc.firmware)
+ info->firmware = strdup(cur_settings.dc.firmware);
+ if (!info->nickname && cur_settings.dc.nickname)
+ info->nickname = strdup(cur_settings.dc.nickname);
+ }
reset_dc_settings();
}
diff --git a/save-xml.c b/save-xml.c
index 465010cd1..0fa0aee2a 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -485,23 +485,42 @@ static void save_trip(FILE *f, dive_trip_t *trip)
static void save_dc_if_needed(FILE *f, struct divecomputer *dc)
{
- const char *nickname;
+ struct device_info *info = get_device_info(dc->model, dc->deviceid);
+ const char *nickname, *serial_nr, *firmware;
/* we have no dc or no model or no deviceid information... nothing to do here */
- if (!dc || !dc->model || !*dc->model || !dc->deviceid)
+ if (!info || info->saved)
return;
+ info->saved = 1;
- if (dc_was_saved(dc))
- return;
+ /* Nicknames that are empty or the same as the device model are not interesting */
+ nickname = info->nickname;
+ if (nickname) {
+ if (!*nickname || !strcmp(dc->model, nickname))
+ nickname = NULL;
+ }
+
+ /* Serial numbers that are empty are not interesting */
+ serial_nr = info->serial_nr;
+ if (serial_nr && !*serial_nr)
+ serial_nr = NULL;
+
+ /* Firmware strings that are empty are not interesting */
+ firmware = info->firmware;
+ if (firmware && !*firmware)
+ firmware = NULL;
- mark_dc_saved(dc);
- nickname = get_dc_nickname(dc->model, dc->deviceid);
- /* We have no nickname, or it is the same as the model ID - nothing interesting */
- if (!nickname || !*nickname || !strcmp(dc->model, nickname))
+ /* Do we have anything interesting about this dive computer to save? */
+ if (!serial_nr && !nickname && !firmware)
return;
fprintf(f, "<divecomputerid model='%s' deviceid='%08x'", dc->model, dc->deviceid);
- show_utf8(f, nickname, " nickname='", "'", 1);
+ if (serial_nr)
+ show_utf8(f, serial_nr, " serial='", "'", 1);
+ if (firmware)
+ show_utf8(f, firmware, " firmware='", "'", 1);
+ if (nickname)
+ show_utf8(f, nickname, " nickname='", "'", 1);
fprintf(f, "/>\n");
return;
}