From: Linus Torvalds torvalds@linux-foundation.org Date: Sat, 3 Jan 2015 16:25:19 -0800 Subject: [PATCH 4/4] Add EON Steel bookmarks, warnings and alarm events
I'd missed these because I'm blind. But mostly because they aren't as common.
Signed-off-by: Linus Torvalds torvalds@linux-foundation.org ---
There is no really good way to distinguish between "notification", "warning" and "alarm" in libdivecomputer. Sometimes there are sane middle grounds (ie a "notification" of a safety stop is would be the "voluntary" version, while a warning would be a "mandatory" one). But how to distinguish between a deep stop ceiling violation notification vs warning vs alarm?
Anyway, these translations really aren't wonderful, and some things aren'ty translated at all (ie they translate to SAMPLE_EVENT_NONE). But they make *some* amount of sense.
As usual, I'd be happier with a string-based model, rather than the crazy enumeration constants that don't make any sense and are too limited anyway.
But now I think I *really* have all the core EON Steel data translated.
src/suunto_eonsteel_parser.c | 101 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 3 deletions(-)
diff --git a/src/suunto_eonsteel_parser.c b/src/suunto_eonsteel_parser.c index a31c1a7e9b68..d5fe9f8ca7f2 100644 --- a/src/suunto_eonsteel_parser.c +++ b/src/suunto_eonsteel_parser.c @@ -229,6 +229,7 @@ struct sample_data { void *userdata; unsigned int time; unsigned char state_type, notify_type; + unsigned char warning_type, alarm_type; };
static void sample_time(struct sample_data *info, unsigned short time_delta) @@ -292,6 +293,17 @@ static void sample_cylinder_pressure(struct sample_data *info, unsigned char idx if (info->callback) info->callback(DC_SAMPLE_PRESSURE, sample, info->userdata); }
+static void sample_bookmark_event(struct sample_data *info, unsigned short idx) +{ + suunto_eonsteel_parser_t *eon = info->eon; + dc_sample_value_t sample = {0}; + + sample.event.type = SAMPLE_EVENT_BOOKMARK; + sample.event.value = idx; + + if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata); +} + static void sample_gas_switch_event(struct sample_data *info, unsigned short idx) { suunto_eonsteel_parser_t *eon = info->eon; @@ -312,8 +324,8 @@ static void sample_gas_switch_event(struct sample_data *info, unsigned short idx }
/* - * The EON Steel has two different sample events: "state" and "notification". - * Both end up having two fields: type and a boolean value. + * The EON Steel has four different sample events: "state", "notification", + * "warning" and "alarm". All end up having two fields: type and a boolean value. * * The type enumerations are available as part of the type descriptor, and we * *should* probably parse them dynamically, but this hardcodes the different @@ -363,7 +375,7 @@ static void sample_event_notify_value(struct sample_data *info, unsigned char va SAMPLE_EVENT_TISSUELEVEL, // 3=Tissue Level SAMPLE_EVENT_NONE, // 4=Deco SAMPLE_EVENT_NONE, // 5=Deco Window - SAMPLE_EVENT_SAFETYSTOP_MANDATORY, // 6=Safety Stop Ahead + SAMPLE_EVENT_SAFETYSTOP_VOLUNTARY, // 6=Safety Stop Ahead SAMPLE_EVENT_SAFETYSTOP, // 7=Safety Stop SAMPLE_EVENT_CEILING_SAFETYSTOP, // 8=Safety Stop Broken SAMPLE_EVENT_NONE, // 9=Deep Stop Ahead @@ -387,6 +399,74 @@ static void sample_event_notify_value(struct sample_data *info, unsigned char va }
+static void sample_event_warning_type(struct sample_data *info, unsigned char type) +{ + info->warning_type = type; +} + + +static void sample_event_warning_value(struct sample_data *info, unsigned char value) +{ + dc_sample_value_t sample = {0}; + static const enum parser_sample_event_t translate_warning[] = { + SAMPLE_EVENT_NONE, // 0=ICD Penalty ("Isobaric counterdiffusion") + SAMPLE_EVENT_VIOLATION, // 1=Deep Stop Penalty + SAMPLE_EVENT_SAFETYSTOP_MANDATORY, // 2=Mandatory Safety Stop + SAMPLE_EVENT_NONE, // 3=OTU250 + SAMPLE_EVENT_NONE, // 4=OTU300 + SAMPLE_EVENT_NONE, // 5=CNS80% + SAMPLE_EVENT_NONE, // 6=CNS100% + SAMPLE_EVENT_AIRTIME, // 7=Air Time + SAMPLE_EVENT_MAXDEPTH, // 8=Max.Depth + SAMPLE_EVENT_AIRTIME, // 9=Tank Pressure + SAMPLE_EVENT_CEILING_SAFETYSTOP, // 10=Safety Stop Broken + SAMPLE_EVENT_CEILING_SAFETYSTOP, // 11=Deep Stop Broken + SAMPLE_EVENT_CEILING, // 12=Ceiling Broken + SAMPLE_EVENT_PO2, // 13=PO2 High + }; + + if (info->warning_type > 13) + return; + + sample.event.type = translate_warning[info->warning_type]; + if (sample.event.type == SAMPLE_EVENT_NONE) + return; + + sample.event.value = value ? SAMPLE_FLAGS_BEGIN : SAMPLE_FLAGS_END; + if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata); +} + +static void sample_event_alarm_type(struct sample_data *info, unsigned char type) +{ + info->alarm_type = type; +} + + +static void sample_event_alarm_value(struct sample_data *info, unsigned char value) +{ + dc_sample_value_t sample = {0}; + static const enum parser_sample_event_t translate_alarm[] = { + SAMPLE_EVENT_CEILING_SAFETYSTOP, // 0=Mandatory Safety Stop Broken + SAMPLE_EVENT_ASCENT, // 1=Ascent Speed + SAMPLE_EVENT_NONE, // 2=Diluent Hyperoxia + SAMPLE_EVENT_VIOLATION, // 3=Violated Deep Stop + SAMPLE_EVENT_CEILING, // 4=Ceiling Broken + SAMPLE_EVENT_PO2, // 5=PO2 High + SAMPLE_EVENT_PO2, // 6=PO2 Low + }; + + if (info->alarm_type > 6) + return; + + sample.event.type = translate_alarm[info->alarm_type]; + if (sample.event.type == SAMPLE_EVENT_NONE) + return; + + sample.event.value = value ? SAMPLE_FLAGS_BEGIN : SAMPLE_FLAGS_END; + if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata); +} + + static int traverse_samples(unsigned short type, const struct type_desc *desc, const unsigned char *data, int len, void *user) { struct sample_data *info = (struct sample_data *) user; @@ -419,6 +499,21 @@ static int traverse_samples(unsigned short type, const struct type_desc *desc, c case 0x0016: sample_event_notify_value(info, data[0]); break; + case 0x0017: + sample_event_warning_type(info, data[0]); + break; + case 0x0018: + sample_event_warning_value(info, data[0]); + break; + case 0x0019: + sample_event_warning_type(info, data[0]); + break; + case 0x001a: + sample_event_warning_value(info, data[0]); + break; + case 0x001c: + sample_bookmark_event(info, array_uint16_le(data)); + break; case 0x001d: sample_gas_switch_event(info, array_uint16_le(data)); break;