EON Steel: look up enum descriptor strings
It turns out you can't hardcode the enum numbers either, since they change from dive to dive (or possibly firmware version to firmware version). So do it right, and actually parse the string descriptor for the enum. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
1b5ccf5983
commit
3547c72111
@ -457,8 +457,8 @@ struct sample_data {
|
||||
dc_sample_callback_t callback;
|
||||
void *userdata;
|
||||
unsigned int time;
|
||||
unsigned char state_type, notify_type;
|
||||
unsigned char warning_type, alarm_type;
|
||||
const char *state_type, *notify_type;
|
||||
const char *warning_type, *alarm_type;
|
||||
|
||||
/* We gather up deco and cylinder pressure information */
|
||||
int gasnr;
|
||||
@ -609,6 +609,70 @@ static void sample_gas_switch_event(struct sample_data *info, unsigned short idx
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the string from an enumeration.
|
||||
*
|
||||
* Enumerations have the enum values in the "format" string,
|
||||
* and all start with "enum:" followed by a comma-separated list
|
||||
* of enumeration values and strings. Example:
|
||||
*
|
||||
* "enum:0=NoFly Time,1=Depth,2=Surface Time,3=..."
|
||||
*/
|
||||
static const char *lookup_enum(const struct type_desc *desc, unsigned char value)
|
||||
{
|
||||
const char *str = desc->format;
|
||||
unsigned char c;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
if (strncmp(str, "enum:", 5))
|
||||
return NULL;
|
||||
str += 5;
|
||||
|
||||
while ((c = *str) != 0) {
|
||||
unsigned char n;
|
||||
const char *begin, *end;
|
||||
char *ret;
|
||||
|
||||
str++;
|
||||
if (!isdigit(c))
|
||||
continue;
|
||||
n = c - '0';
|
||||
|
||||
// We only handle one or two digits
|
||||
if (isdigit(*str)) {
|
||||
n = n*10 + *str - '0';
|
||||
str++;
|
||||
}
|
||||
|
||||
begin = end = str;
|
||||
while ((c = *str) != 0) {
|
||||
str++;
|
||||
if (c == ',')
|
||||
break;
|
||||
end = str;
|
||||
}
|
||||
|
||||
// Verify that it has the 'n=string' format and skip the equals sign
|
||||
if (*begin != '=')
|
||||
continue;
|
||||
begin++;
|
||||
|
||||
// Is it the value we're looking for?
|
||||
if (n != value)
|
||||
continue;
|
||||
|
||||
ret = malloc(end - begin + 1);
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
memcpy(ret, begin, end-begin);
|
||||
ret[end-begin] = 0;
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The EON Steel has four different sample events: "state", "notification",
|
||||
* "warning" and "alarm". All end up having two fields: type and a boolean value.
|
||||
@ -630,11 +694,17 @@ static void sample_gas_switch_event(struct sample_data *info, unsigned short idx
|
||||
*/
|
||||
static void sample_event_state_type(const struct type_desc *desc, struct sample_data *info, unsigned char type)
|
||||
{
|
||||
info->state_type = type;
|
||||
info->state_type = lookup_enum(desc, type);
|
||||
}
|
||||
|
||||
static void sample_event_state_value(const struct type_desc *desc, struct sample_data *info, unsigned char value)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = info->state_type;
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
/*
|
||||
* We could turn these into sample events, but they don't actually
|
||||
* match any libdivecomputer events.
|
||||
@ -649,7 +719,7 @@ static void sample_event_state_value(const struct type_desc *desc, struct sample
|
||||
|
||||
static void sample_event_notify_type(const struct type_desc *desc, struct sample_data *info, unsigned char type)
|
||||
{
|
||||
info->notify_type = type;
|
||||
info->notify_type = lookup_enum(desc, type);
|
||||
}
|
||||
|
||||
|
||||
@ -657,31 +727,14 @@ static void sample_event_notify_type(const struct type_desc *desc, struct sample
|
||||
static void sample_event_notify_value(const struct type_desc *desc, struct sample_data *info, unsigned char value)
|
||||
{
|
||||
dc_sample_value_t sample = {0};
|
||||
static const enum parser_sample_event_t translate_notification[] = {
|
||||
SAMPLE_EVENT_NONE, // 0=NoFly Time
|
||||
SAMPLE_EVENT_NONE, // 1=Depth
|
||||
SAMPLE_EVENT_NONE, // 2=Surface Time
|
||||
SAMPLE_EVENT_TISSUELEVEL, // 3=Tissue Level
|
||||
SAMPLE_EVENT_NONE, // 4=Deco
|
||||
SAMPLE_EVENT_NONE, // 5=Deco Window
|
||||
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
|
||||
SAMPLE_EVENT_DEEPSTOP, // 10=Deep Stop
|
||||
SAMPLE_EVENT_DIVETIME, // 11=Dive Time
|
||||
SAMPLE_EVENT_NONE, // 12=Gas Available
|
||||
SAMPLE_EVENT_NONE, // 13=SetPoint Switch
|
||||
SAMPLE_EVENT_NONE, // 14=Diluent Hypoxia
|
||||
SAMPLE_EVENT_NONE, // 15=Tank Pressure
|
||||
};
|
||||
const char *name;
|
||||
|
||||
if (info->notify_type > 15)
|
||||
name = info->notify_type;
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
sample.event.type = translate_notification[info->notify_type];
|
||||
if (sample.event.type == SAMPLE_EVENT_NONE)
|
||||
return;
|
||||
sample.event.type = SAMPLE_EVENT_STRING;
|
||||
sample.event.name = name;
|
||||
|
||||
sample.event.value = value ? SAMPLE_FLAGS_BEGIN : SAMPLE_FLAGS_END;
|
||||
if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
|
||||
@ -690,36 +743,20 @@ static void sample_event_notify_value(const struct type_desc *desc, struct sampl
|
||||
|
||||
static void sample_event_warning_type(const struct type_desc *desc, struct sample_data *info, unsigned char type)
|
||||
{
|
||||
info->warning_type = type;
|
||||
info->warning_type = lookup_enum(desc, type);
|
||||
}
|
||||
|
||||
|
||||
static void sample_event_warning_value(const struct type_desc *desc, 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
|
||||
};
|
||||
const char *name;
|
||||
|
||||
if (info->warning_type > 13)
|
||||
name = info->warning_type;
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
sample.event.type = translate_warning[info->warning_type];
|
||||
if (sample.event.type == SAMPLE_EVENT_NONE)
|
||||
return;
|
||||
sample.event.type = SAMPLE_EVENT_STRING;
|
||||
sample.event.name = name;
|
||||
|
||||
sample.event.value = value ? SAMPLE_FLAGS_BEGIN : SAMPLE_FLAGS_END;
|
||||
if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
|
||||
@ -727,31 +764,22 @@ static void sample_event_warning_value(const struct type_desc *desc, struct samp
|
||||
|
||||
static void sample_event_alarm_type(const struct type_desc *desc, struct sample_data *info, unsigned char type)
|
||||
{
|
||||
info->alarm_type = type;
|
||||
info->alarm_type = lookup_enum(desc, type);
|
||||
}
|
||||
|
||||
|
||||
// FIXME! This needs to parse the actual type descriptor enum
|
||||
static void sample_event_alarm_value(const struct type_desc *desc, struct sample_data *info, unsigned char value)
|
||||
{
|
||||
const char *name;
|
||||
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)
|
||||
name = info->alarm_type;
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
sample.event.type = SAMPLE_EVENT_STRING;
|
||||
sample.event.name = name;
|
||||
sample.event.value = value ? SAMPLE_FLAGS_BEGIN : SAMPLE_FLAGS_END;
|
||||
if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user