Suunto EON Steel: populate various string data

The EON Steel saves the dive computer firmware versions etc per dive,
which is really nice for upgrades: old dives done with older firmware
still show the firmware at the time of the dive.  That, in turn, is nice
because we can use it for a reliable dive ID - dive time with serial
number etc.

This uses the new DC_FIELD_STRING model to feed the hw/sw information to
the application, since we need the parser to access it.  It also returns
battery state and deco model information.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Linus Torvalds 2014-10-27 17:19:48 -07:00 committed by Dirk Hohndel
parent 0c8886ce70
commit c39dda89bc

View File

@ -68,6 +68,7 @@ struct type_desc {
#define MAXTYPE 512 #define MAXTYPE 512
#define MAXGASES 16 #define MAXGASES 16
#define MAXSTRINGS 16
typedef struct suunto_eonsteel_parser_t { typedef struct suunto_eonsteel_parser_t {
dc_parser_t base; dc_parser_t base;
@ -82,6 +83,7 @@ typedef struct suunto_eonsteel_parser_t {
dc_gasmix_t gasmix[MAXGASES]; dc_gasmix_t gasmix[MAXGASES];
dc_salinity_t salinity; dc_salinity_t salinity;
double surface_pressure; double surface_pressure;
dc_field_string_t strings[MAXSTRINGS];
} cache; } cache;
} suunto_eonsteel_parser_t; } suunto_eonsteel_parser_t;
@ -868,6 +870,19 @@ suunto_eonsteel_parser_samples_foreach(dc_parser_t *abstract, dc_sample_callback
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
} }
static dc_status_t get_string_field(suunto_eonsteel_parser_t *eon, unsigned idx, dc_field_string_t *value)
{
if (idx < MAXSTRINGS) {
dc_field_string_t *res = eon->cache.strings+idx;
if (res->desc && res->value) {
*value = *res;
return DC_STATUS_SUCCESS;
}
}
return DC_STATUS_UNSUPPORTED;
}
// Ugly define thing makes the code much easier to read // Ugly define thing makes the code much easier to read
// I'd love to use __typeof__, but that's a gcc'ism // I'd love to use __typeof__, but that's a gcc'ism
#define field_value(p, set) \ #define field_value(p, set) \
@ -905,6 +920,8 @@ suunto_eonsteel_parser_get_field(dc_parser_t *parser, dc_field_type_t type, unsi
case DC_FIELD_ATMOSPHERIC: case DC_FIELD_ATMOSPHERIC:
field_value(value, eon->cache.surface_pressure); field_value(value, eon->cache.surface_pressure);
break; break;
case DC_FIELD_STRING:
return get_string_field(eon, flags, (dc_field_string_t *)value);
default: default:
return DC_STATUS_UNSUPPORTED; return DC_STATUS_UNSUPPORTED;
} }
@ -980,6 +997,22 @@ static int add_gas_he(suunto_eonsteel_parser_t *eon, unsigned char he)
return 0; return 0;
} }
static int add_string(suunto_eonsteel_parser_t *eon, const char *desc, const char *value)
{
int i;
eon->cache.initialized |= 1 << DC_FIELD_STRING;
for (i = 0; i < MAXSTRINGS; i++) {
dc_field_string_t *str = eon->cache.strings+i;
if (str->desc)
continue;
str->desc = desc;
str->value = strdup(value);
break;
}
return 0;
}
static float get_le32_float(const unsigned char *src) static float get_le32_float(const unsigned char *src)
{ {
union { union {
@ -1003,7 +1036,16 @@ static int traverse_device_fields(suunto_eonsteel_parser_t *eon, const struct ty
const unsigned char *data, int len) const unsigned char *data, int len)
{ {
const char *name = desc->desc + strlen("sml.DeviceLog.Device."); const char *name = desc->desc + strlen("sml.DeviceLog.Device.");
if (!strcmp(name, "SerialNumber"))
return add_string(eon, "Serial", data);
if (!strcmp(name, "Info.HW"))
return add_string(eon, "HW Version", data);
if (!strcmp(name, "Info.SW"))
return add_string(eon, "FW Version", data);
if (!strcmp(name, "Info.BatteryAtStart"))
return add_string(eon, "Battery at start", data);
if (!strcmp(name, "Info.BatteryAtEnd"))
return add_string(eon, "Battery at end", data);
return 0; return 0;
} }
@ -1070,6 +1112,9 @@ static int traverse_diving_fields(suunto_eonsteel_parser_t *eon, const struct ty
return 0; return 0;
} }
if (!strcmp(name, "Algorithm"))
return add_string(eon, "Deco algorithm", data);
return 0; return 0;
} }
@ -1096,6 +1141,8 @@ static int traverse_header_fields(suunto_eonsteel_parser_t *eon, const struct ty
eon->cache.maxdepth = d; eon->cache.maxdepth = d;
return 0; return 0;
} }
if (!strcmp(name, "DateTime"))
return add_string(eon, "Dive ID", data);
return 0; return 0;
} }