diff --git a/examples/output_xml.c b/examples/output_xml.c
index 854646b..7d76cb1 100644
--- a/examples/output_xml.c
+++ b/examples/output_xml.c
@@ -386,6 +386,30 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
names[divemode]);
}
+ // Parse the deco model.
+ message ("Parsing the deco model.\n");
+ dc_decomodel_t decomodel = {DC_DECOMODEL_NONE};
+ status = dc_parser_get_field (parser, DC_FIELD_DECOMODEL, 0, &decomodel);
+ if (status != DC_STATUS_SUCCESS && status != DC_STATUS_UNSUPPORTED) {
+ ERROR ("Error parsing the deco model.");
+ goto cleanup;
+ }
+
+ if (status != DC_STATUS_UNSUPPORTED) {
+ const char *names[] = {"none", "buhlmann", "vpm", "rgbm", "dciem"};
+ fprintf (output->ostream, "%s\n",
+ names[decomodel.type]);
+ if (decomodel.type == DC_DECOMODEL_BUHLMANN &&
+ (decomodel.params.gf.low != 0 || decomodel.params.gf.high != 0)) {
+ fprintf (output->ostream, "%u/%u\n",
+ decomodel.params.gf.low, decomodel.params.gf.high);
+ }
+ if (decomodel.conservatism) {
+ fprintf (output->ostream, "%d\n",
+ decomodel.conservatism);
+ }
+ }
+
// Parse the salinity.
message ("Parsing the salinity.\n");
dc_salinity_t salinity = {DC_WATER_FRESH, 0.0};
diff --git a/include/libdivecomputer/parser.h b/include/libdivecomputer/parser.h
index 1b53fd3..dc81317 100644
--- a/include/libdivecomputer/parser.h
+++ b/include/libdivecomputer/parser.h
@@ -62,7 +62,8 @@ typedef enum dc_field_type_t {
DC_FIELD_TEMPERATURE_MAXIMUM,
DC_FIELD_TANK_COUNT,
DC_FIELD_TANK,
- DC_FIELD_DIVEMODE
+ DC_FIELD_DIVEMODE,
+ DC_FIELD_DECOMODEL,
} dc_field_type_t;
typedef enum parser_sample_event_t {
@@ -186,6 +187,43 @@ typedef struct dc_tank_t {
double endpressure; /* End pressure (bar) */
} dc_tank_t;
+typedef enum dc_decomodel_type_t {
+ DC_DECOMODEL_NONE,
+ DC_DECOMODEL_BUHLMANN,
+ DC_DECOMODEL_VPM,
+ DC_DECOMODEL_RGBM,
+ DC_DECOMODEL_DCIEM,
+} dc_decomodel_type_t;
+
+/*
+ * Decompression model
+ *
+ * The type field contains the decompression algorithm.
+ *
+ * The (optional) conservatism field contains the personal adjustment
+ * setting of the algorithm. The exact interpretation depends on the
+ * dive computer, but the default value (zero) will typically correspond
+ * to the neutral setting, while a positive value is more conservative
+ * and a negative value more aggressive.
+ *
+ * The (optional) params field contains the parameters of the algorithm:
+ *
+ * DC_DECOMODEL_BUHLMANN: The Gradient Factor (GF) parameters low and
+ * high. For a pure Buhlmann algorithm (e.g. without GF enabled), both
+ * values are 100. If GF are enabled, but the actual parameter values
+ * are not available from the dive computer, both values are zero.
+ */
+typedef struct dc_decomodel_t {
+ dc_decomodel_type_t type;
+ int conservatism;
+ union {
+ struct {
+ unsigned int high;
+ unsigned int low;
+ } gf;
+ } params;
+} dc_decomodel_t;
+
typedef union dc_sample_value_t {
unsigned int time;
double depth;
diff --git a/src/divesystem_idive_parser.c b/src/divesystem_idive_parser.c
index 5ace8f4..f0d7700 100644
--- a/src/divesystem_idive_parser.c
+++ b/src/divesystem_idive_parser.c
@@ -48,6 +48,9 @@
#define FREEDIVE 4
#define INVALID 0xFFFFFFFF
+#define BUHLMANN 0
+#define VPM 1
+
typedef struct divesystem_idive_parser_t divesystem_idive_parser_t;
typedef struct divesystem_idive_gasmix_t {
@@ -74,6 +77,9 @@ struct divesystem_idive_parser_t {
unsigned int ntanks;
divesystem_idive_gasmix_t gasmix[NGASMIXES];
divesystem_idive_tank_t tank[NTANKS];
+ unsigned int algorithm;
+ unsigned int gf_low;
+ unsigned int gf_high;
};
static dc_status_t divesystem_idive_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
@@ -129,6 +135,10 @@ divesystem_idive_parser_create (dc_parser_t **out, dc_context_t *context, unsign
parser->tank[i].beginpressure = 0;
parser->tank[i].endpressure = 0;
}
+ parser->algorithm = INVALID;
+ parser->gf_low = INVALID;
+ parser->gf_high = INVALID;
+
*out = (dc_parser_t*) parser;
@@ -157,6 +167,9 @@ divesystem_idive_parser_set_data (dc_parser_t *abstract, const unsigned char *da
parser->tank[i].beginpressure = 0;
parser->tank[i].endpressure = 0;
}
+ parser->algorithm = INVALID;
+ parser->gf_low = INVALID;
+ parser->gf_high = INVALID;
return DC_STATUS_SUCCESS;
}
@@ -280,6 +293,7 @@ divesystem_idive_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
dc_tank_t *tank = (dc_tank_t *) value;
dc_salinity_t *water = (dc_salinity_t *) value;
+ dc_decomodel_t *decomodel = (dc_decomodel_t *) value;
if (value) {
switch (type) {
@@ -343,6 +357,25 @@ divesystem_idive_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
return DC_STATUS_DATAFORMAT;
}
break;
+ case DC_FIELD_DECOMODEL:
+ if (parser->algorithm == INVALID)
+ return DC_STATUS_UNSUPPORTED;
+ switch (parser->algorithm) {
+ case BUHLMANN:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->conservatism = 0;
+ decomodel->params.gf.low = parser->gf_low;
+ decomodel->params.gf.high = parser->gf_high;
+ break;
+ case VPM:
+ decomodel->type = DC_DECOMODEL_VPM;
+ decomodel->conservatism = 0;
+ break;
+ default:
+ ERROR (abstract->context, "Unknown deco algorithm %02x.", parser->algorithm);
+ return DC_STATUS_DATAFORMAT;
+ }
+ break;
default:
return DC_STATUS_UNSUPPORTED;
}
@@ -371,6 +404,10 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
unsigned int divemode = INVALID;
unsigned int tank_previous = INVALID;
unsigned int tank_idx = INVALID;
+ unsigned int algorithm = INVALID;
+ unsigned int algorithm_previous = INVALID;
+ unsigned int gf_low = INVALID;
+ unsigned int gf_high = INVALID;
unsigned int firmware = 0;
unsigned int apos4 = 0;
@@ -433,6 +470,22 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
divemode = mode;
}
+ // Deco model
+ unsigned int s_algorithm = data[offset + 14];
+ unsigned int s_gf_high = data[offset + 15];
+ unsigned int s_gf_low = data[offset + 16];
+ if (s_algorithm != algorithm_previous) {
+ if (algorithm_previous != INVALID) {
+ WARNING (abstract->context, "Deco algorithm changed from %02x to %02x.", algorithm_previous, s_algorithm);
+ }
+ algorithm_previous = s_algorithm;
+ }
+ if (algorithm == INVALID) {
+ algorithm = s_algorithm;
+ gf_low = s_gf_low;
+ gf_high = s_gf_high;
+ }
+
// Setpoint
if (mode == SCR || mode == CCR) {
unsigned int setpoint = array_uint16_le (data + offset + 19);
@@ -560,6 +613,9 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
parser->maxdepth = maxdepth;
parser->divetime = time;
parser->divemode = divemode;
+ parser->algorithm = algorithm;
+ parser->gf_low = gf_low;
+ parser->gf_high = gf_high;
parser->cached = 1;
return DC_STATUS_SUCCESS;
diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c
index f1092c0..06470d7 100644
--- a/src/hw_ostc_parser.c
+++ b/src/hw_ostc_parser.c
@@ -69,6 +69,10 @@
#define OSTC3_APNEA 3
#define OSTC3_PSCR 4
+#define OSTC3_ZHL16 0
+#define OSTC3_ZHL16_GF 1
+#define OSTC4_VPM 2
+
#define OSTC4 0x3B
#define OSTC3FW(major,minor) ( \
@@ -97,6 +101,8 @@ typedef struct hw_ostc_layout_t {
unsigned int salinity;
unsigned int avgdepth;
unsigned int duration;
+ unsigned int gf;
+ unsigned int decomodel;
unsigned int divemode;
} hw_ostc_layout_t;
@@ -147,6 +153,8 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc = {
43, /* salinity */
45, /* avgdepth */
47, /* duration */
+ 49, /* gf */
+ UNDEFINED, /* decomodel */
51, /* divemode */
};
@@ -160,6 +168,8 @@ static const hw_ostc_layout_t hw_ostc_layout_frog = {
43, /* salinity */
45, /* avgdepth */
47, /* duration */
+ 49, /* gf */
+ UNDEFINED, /* decomodel */
51, /* divemode */
};
@@ -173,6 +183,8 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc3 = {
70, /* salinity */
73, /* avgdepth */
75, /* duration */
+ 77, /* gf */
+ 79, /* decomodel */
82, /* divemode */
};
@@ -472,6 +484,8 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
dc_salinity_t *water = (dc_salinity_t *) value;
+ dc_decomodel_t *decomodel = (dc_decomodel_t *) value;
+
unsigned int salinity = data[layout->salinity];
if (version == 0x23 || version == 0x24)
salinity += 100;
@@ -572,6 +586,70 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
return DC_STATUS_UNSUPPORTED;
}
break;
+ case DC_FIELD_DECOMODEL:
+ if (version == 0x21) {
+ switch (data[layout->divemode]) {
+ case OSTC_APNEA:
+ case OSTC_GAUGE:
+ decomodel->type = DC_DECOMODEL_NONE;
+ break;
+ case OSTC_ZHL16_OC:
+ case OSTC_ZHL16_CC:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->params.gf.low = 100;
+ decomodel->params.gf.high = 100;
+ break;
+ case OSTC_ZHL16_OC_GF:
+ case OSTC_ZHL16_CC_GF:
+ case OSTC_PSCR_GF:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->params.gf.low = data[layout->gf + 0];
+ decomodel->params.gf.high = data[layout->gf + 1];
+ break;
+ default:
+ return DC_STATUS_DATAFORMAT;
+ }
+ } else if (version == 0x22) {
+ switch (data[layout->divemode]) {
+ case FROG_ZHL16:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->params.gf.low = 100;
+ decomodel->params.gf.high = 100;
+ break;
+ case FROG_ZHL16_GF:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->params.gf.low = data[layout->gf + 0];
+ decomodel->params.gf.high = data[layout->gf + 1];
+ break;
+ case FROG_APNEA:
+ decomodel->type = DC_DECOMODEL_NONE;
+ break;
+ default:
+ return DC_STATUS_DATAFORMAT;
+ }
+ } else if (version == 0x23 || version == 0x24) {
+ switch (data[layout->decomodel]) {
+ case OSTC3_ZHL16:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->params.gf.low = 100;
+ decomodel->params.gf.high = 100;
+ break;
+ case OSTC3_ZHL16_GF:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->params.gf.low = data[layout->gf + 0];
+ decomodel->params.gf.high = data[layout->gf + 1];
+ break;
+ case OSTC4_VPM:
+ decomodel->type = DC_DECOMODEL_VPM;
+ break;
+ default:
+ return DC_STATUS_DATAFORMAT;
+ }
+ } else {
+ return DC_STATUS_UNSUPPORTED;
+ }
+ decomodel->conservatism = 0;
+ break;
default:
return DC_STATUS_UNSUPPORTED;
}
diff --git a/src/liquivision_lynx_parser.c b/src/liquivision_lynx_parser.c
index c4272d8..2ff52cb 100644
--- a/src/liquivision_lynx_parser.c
+++ b/src/liquivision_lynx_parser.c
@@ -66,6 +66,9 @@
#define TEC 2
#define REC 3
+#define ZHL16GF 0
+#define RGBM 1
+
#define NORMAL 0
#define BOOKMARK 1
#define ALARM_DEPTH 2
@@ -231,6 +234,7 @@ liquivision_lynx_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
dc_tank_t *tank = (dc_tank_t *) value;
dc_salinity_t *water = (dc_salinity_t *) value;
+ dc_decomodel_t *decomodel = (dc_decomodel_t *) value;
if (value) {
switch (type) {
@@ -288,6 +292,22 @@ liquivision_lynx_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
}
}
break;
+ case DC_FIELD_DECOMODEL:
+ switch (abstract->data[93]) {
+ case ZHL16GF:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->conservatism = 0;
+ decomodel->params.gf.low = 0;
+ decomodel->params.gf.high = 0;
+ break;
+ case RGBM:
+ decomodel->type = DC_DECOMODEL_RGBM;
+ decomodel->conservatism = 0;
+ break;
+ default:
+ return DC_STATUS_DATAFORMAT;
+ }
+ break;
case DC_FIELD_GASMIX_COUNT:
*((unsigned int *) value) = parser->ngasmixes;
break;
diff --git a/src/seac_screen_parser.c b/src/seac_screen_parser.c
index 28988e4..46e3303 100644
--- a/src/seac_screen_parser.c
+++ b/src/seac_screen_parser.c
@@ -44,6 +44,8 @@ struct seac_screen_parser_t {
unsigned int cached;
unsigned int ngasmixes;
unsigned int oxygen[NGASMIXES];
+ unsigned int gf_low;
+ unsigned int gf_high;
};
static dc_status_t seac_screen_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
@@ -82,6 +84,8 @@ seac_screen_parser_create (dc_parser_t **out, dc_context_t *context)
for (unsigned int i = 0; i < NGASMIXES; ++i) {
parser->oxygen[i] = 0;
}
+ parser->gf_low = 0;
+ parser->gf_high = 0;
*out = (dc_parser_t *) parser;
@@ -99,6 +103,8 @@ seac_screen_parser_set_data (dc_parser_t *abstract, const unsigned char *data, u
for (unsigned int i = 0; i < NGASMIXES; ++i) {
parser->oxygen[i] = 0;
}
+ parser->gf_low = 0;
+ parser->gf_high = 0;
return DC_STATUS_SUCCESS;
}
@@ -207,6 +213,7 @@ seac_screen_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsig
}
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
+ dc_decomodel_t *decomodel = (dc_decomodel_t *) value;
if (value) {
switch (type) {
@@ -249,6 +256,12 @@ seac_screen_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsig
return DC_STATUS_DATAFORMAT;
}
break;
+ case DC_FIELD_DECOMODEL:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->conservatism = 0;
+ decomodel->params.gf.low = parser->gf_low;
+ decomodel->params.gf.high = parser->gf_high;
+ break;
default:
return DC_STATUS_UNSUPPORTED;
}
@@ -279,6 +292,9 @@ seac_screen_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
unsigned int oxygen[NGASMIXES] = {0};
unsigned int o2_previous = INVALID;
+ unsigned int gf_low = 0;
+ unsigned int gf_high = 0;
+
unsigned int time = 0;
unsigned int offset = SZ_HEADER;
while (offset + SZ_SAMPLE <= size) {
@@ -298,6 +314,8 @@ seac_screen_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
unsigned int decotime = array_uint16_le (data + offset + 0x10);
unsigned int ndl_tts = array_uint16_le (data + offset + 0x12);
unsigned int cns = array_uint16_le (data + offset + 0x16);
+ unsigned int gf_hi = data[offset + 0x3B];
+ unsigned int gf_lo = data[offset + 0x3C];
if (id != dive_id) {
ERROR (abstract->context, "Unexpected sample id (%u %u).", dive_id, id);
@@ -362,6 +380,12 @@ seac_screen_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
sample.cns = cns / 100.0;
if (callback) callback (DC_SAMPLE_CNS, sample, userdata);
+ // Deco model
+ if (gf_low == 0 && gf_high == 0) {
+ gf_low = gf_lo;
+ gf_high = gf_hi;
+ }
+
offset += SZ_SAMPLE;
}
@@ -370,6 +394,8 @@ seac_screen_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
parser->oxygen[i] = oxygen[i];
}
parser->ngasmixes = ngasmixes;
+ parser->gf_low = gf_low;
+ parser->gf_high = gf_high;
parser->cached = 1;
return DC_STATUS_SUCCESS;
diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c
index 28c4915..5113f75 100644
--- a/src/shearwater_predator_parser.c
+++ b/src/shearwater_predator_parser.c
@@ -78,6 +78,11 @@
#define M_OC_REC 6
#define M_FREEDIVE 7
+#define GF 0
+#define VPMB 1
+#define VPMB_GFS 2
+#define DCIEM 3
+
#define METRIC 0
#define IMPERIAL 1
@@ -669,9 +674,13 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
if (rc != DC_STATUS_SUCCESS)
return rc;
+ unsigned int decomodel_idx = parser->pnf ? parser->opening[2] + 18 : 67;
+ unsigned int gf_idx = parser->pnf ? parser->opening[0] + 4 : 4;
+
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
dc_tank_t *tank = (dc_tank_t *) value;
dc_salinity_t *water = (dc_salinity_t *) value;
+ dc_decomodel_t *decomodel = (dc_decomodel_t *) value;
if (value) {
switch (type) {
@@ -742,6 +751,27 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
return DC_STATUS_DATAFORMAT;
}
break;
+ case DC_FIELD_DECOMODEL:
+ switch (data[decomodel_idx]) {
+ case GF:
+ decomodel->type = DC_DECOMODEL_BUHLMANN;
+ decomodel->conservatism = 0;
+ decomodel->params.gf.low = data[gf_idx + 0];
+ decomodel->params.gf.high = data[gf_idx + 1];
+ break;
+ case VPMB:
+ case VPMB_GFS:
+ decomodel->type = DC_DECOMODEL_VPM;
+ decomodel->conservatism = data[decomodel_idx + 1];
+ break;
+ case DCIEM:
+ decomodel->type = DC_DECOMODEL_DCIEM;
+ decomodel->conservatism = 0;
+ break;
+ default:
+ return DC_STATUS_DATAFORMAT;
+ }
+ break;
default:
return DC_STATUS_UNSUPPORTED;
}
diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c
index 7fc05fd..32e28ea 100644
--- a/src/suunto_d9_parser.c
+++ b/src/suunto_d9_parser.c
@@ -361,6 +361,7 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
return rc;
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
+ dc_decomodel_t *decomodel = (dc_decomodel_t *) value;
if (value) {
switch (type) {
@@ -408,6 +409,20 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
return DC_STATUS_DATAFORMAT;
}
break;
+ case DC_FIELD_DECOMODEL:
+ decomodel->type = DC_DECOMODEL_RGBM;
+ if (parser->model == D4i ||parser->model == D6i ||
+ parser->model == D9tx || parser->model == ZOOPNOVO_A ||
+ parser->model == ZOOPNOVO_B || parser->model == VYPERNOVO ||
+ parser->model == D4F)
+ decomodel->conservatism = data[0x21] - 2;
+ else if (parser->model == HELO2)
+ decomodel->conservatism = data[0x23] - 2;
+ else if (parser->model == DX)
+ decomodel->conservatism = data[0x25] - 2;
+ else
+ decomodel->conservatism = data[0x1E];
+ break;
default:
return DC_STATUS_UNSUPPORTED;
}
diff --git a/src/suunto_eonsteel_parser.c b/src/suunto_eonsteel_parser.c
index de00001..cc9276a 100644
--- a/src/suunto_eonsteel_parser.c
+++ b/src/suunto_eonsteel_parser.c
@@ -90,6 +90,7 @@ typedef struct suunto_eonsteel_parser_t {
dc_tankvolume_t tankinfo[MAXGASES];
double tanksize[MAXGASES];
double tankworkingpressure[MAXGASES];
+ dc_decomodel_t decomodel;
} cache;
} suunto_eonsteel_parser_t;
@@ -1095,6 +1096,9 @@ suunto_eonsteel_parser_get_field(dc_parser_t *parser, dc_field_type_t type, unsi
tank->type = DC_TANKVOLUME_IMPERIAL;
}
break;
+ case DC_FIELD_DECOMODEL:
+ field_value(value, eon->cache.decomodel);
+ break;
default:
return DC_STATUS_UNSUPPORTED;
}
@@ -1341,6 +1345,20 @@ static int traverse_diving_fields(suunto_eonsteel_parser_t *eon, const struct ty
return 0;
}
+ if (!strcmp(name, "Algorithm")) {
+ if (!strcmp((const char *)data, "Suunto Fused RGBM")) {
+ eon->cache.decomodel.type = DC_DECOMODEL_RGBM;
+ eon->cache.initialized |= 1 << DC_FIELD_DECOMODEL;
+ }
+ return 0;
+ }
+
+ if (!strcmp(name, "Conservatism")) {
+ eon->cache.decomodel.conservatism = *(const signed char *)data;
+ eon->cache.initialized |= 1 << DC_FIELD_DECOMODEL;
+ return 0;
+ }
+
if (!strcmp(name, "LowSetPoint")) {
unsigned int pressure = array_uint32_le(data); // in SI units - Pascal
eon->cache.lowsetpoint = pressure / 100000.0; // bar
diff --git a/src/suunto_vyper_parser.c b/src/suunto_vyper_parser.c
index 369ad5c..d7af05c 100644
--- a/src/suunto_vyper_parser.c
+++ b/src/suunto_vyper_parser.c
@@ -238,6 +238,7 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
dc_gasmix_t *gas = (dc_gasmix_t *) value;
dc_tank_t *tank = (dc_tank_t *) value;
+ dc_decomodel_t *decomodel = (dc_decomodel_t *) value;
// Cache the data.
dc_status_t rc = suunto_vyper_parser_cache (parser);
@@ -297,6 +298,10 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
*((dc_divemode_t *) value) = DC_DIVEMODE_OC;
}
break;
+ case DC_FIELD_DECOMODEL:
+ decomodel->type = DC_DECOMODEL_RGBM;
+ decomodel->conservatism = (data[4] & 0x0F) / 3;
+ break;
default:
return DC_STATUS_UNSUPPORTED;
}