aboutsummaryrefslogtreecommitdiffstats
path: root/parse-xml.c
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2013-01-09 16:14:21 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-01-09 16:38:21 -0800
commit1aa3c0d5147df7ef8846c955dffe7227257c5ca1 (patch)
tree43899c0a4a04e53c26bea707e7364035a7d0c3fb /parse-xml.c
parentec38d3708df24a23a46f19707f0f5afd44969c92 (diff)
downloadsubsurface-1aa3c0d5147df7ef8846c955dffe7227257c5ca1.tar.gz
Assemble the actual Suunto serial number
It turns out that the serial number returned by libdivecomputer isn't really the serial number as interpreted by the vendor. Those tend to be strings, but libdivecomputer gives us a 32bit number. Some experimenting showed that for the Suunto devies tested the serial number is encoded in that 32bit number: It so happens that the Suunto serial number strings are strings that have all numbers, but they aren't *one* number. They are four bytes representing two numbers each, and the "23500027" string is actually the four bytes 23 50 00 27 (0x17 0x32 0x00 0x1b). And libdivecomputer has incorrectly parsed those four bytes as one number, not as the encoded serial number string it is. So the value 389152795 is actually hex 0x1732001b, which is 0x17 0x32 0x00 0x1b, which is - 23 50 00 27. This should be done by libdivecomputer, but hey, in the meantime this at least shows the concept. And helps test the XML save/restore code. It depends on the two patches that create the whole "device.c" infrastructure, of course. With this, my dive file ends up having the settings section look like this: <divecomputerid model='Suunto Vyper Air' deviceid='d4629110' serial='01201094' firmware='1.1.22'/> <divecomputerid model='Suunto HelO2' deviceid='995dd566' serial='23500027' firmware='1.0.4'/> where the format of the firmware version is something I guessed at, but it was the obvious choice (again, it's byte-based, I'm ignoring the high byte that is zero for both of my Suuntos). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'parse-xml.c')
-rw-r--r--parse-xml.c23
1 files changed, 22 insertions, 1 deletions
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();
}