Parse the profile to retrieve the manual gas mixes.
The DC_FIELD_GASMIX api doesn't support the 6th manual gas very well. Manual gas mixes are either not taken into account at all (OSTC3), or only the last value is returned (OSTC2). We now parse the profile data in order to retrieve all the manual gas mixes too. Note that manual gas mixes are only included when they are actively used during the dive. This is a small change in behaviour for the OSTC2. To simplify the implementation, there is an upper limit of 10 manual gas mixes (or 15 gas mixes in total). This is an arbitrary choice, which should be more than sufficient in practice. If it turns out to be too small, we can always increase the number, or even make it truely unlimited.
This commit is contained in:
parent
ac48210f4a
commit
f24b93cd82
@ -31,7 +31,14 @@
|
||||
#define ISINSTANCE(parser) dc_parser_isinstance((parser), &hw_ostc_parser_vtable)
|
||||
|
||||
#define MAXCONFIG 7
|
||||
#define NGASMIXES 6
|
||||
#define NGASMIXES 15
|
||||
|
||||
#define ALL 0
|
||||
#define FIXED 1
|
||||
#define MANUAL 2
|
||||
|
||||
#define HEADER 1
|
||||
#define PROFILE 2
|
||||
|
||||
#define OSTC_ZHL16_OC 0
|
||||
#define OSTC_GAUGE 1
|
||||
@ -81,6 +88,7 @@ typedef struct hw_ostc_parser_t {
|
||||
unsigned int header;
|
||||
const hw_ostc_layout_t *layout;
|
||||
unsigned int ngasmixes;
|
||||
unsigned int nfixed;
|
||||
unsigned int initial;
|
||||
hw_ostc_gasmix_t gasmix[NGASMIXES];
|
||||
} hw_ostc_parser_t;
|
||||
@ -133,6 +141,27 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc3 = {
|
||||
22, /* temperature */
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
hw_ostc_find_gasmix (hw_ostc_parser_t *parser, unsigned int o2, unsigned int he, unsigned int type)
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
unsigned int count = parser->ngasmixes;
|
||||
if (type == FIXED) {
|
||||
count = parser->nfixed;
|
||||
} else if (type == MANUAL) {
|
||||
offset = parser->nfixed;
|
||||
}
|
||||
|
||||
unsigned int i = offset;
|
||||
while (i < count) {
|
||||
if (o2 == parser->gasmix[i].oxygen && he == parser->gasmix[i].helium)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static dc_status_t
|
||||
hw_ostc_parser_cache (hw_ostc_parser_t *parser)
|
||||
{
|
||||
@ -202,7 +231,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ngasmixes = 6;
|
||||
ngasmixes = 5;
|
||||
initial = data[31];
|
||||
for (unsigned int i = 0; i < ngasmixes; ++i) {
|
||||
gasmix[i].oxygen = data[19 + 2 * i + 0];
|
||||
@ -220,11 +249,12 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
|
||||
parser->header = header;
|
||||
parser->layout = layout;
|
||||
parser->ngasmixes = ngasmixes;
|
||||
parser->nfixed = ngasmixes;
|
||||
parser->initial = initial;
|
||||
for (unsigned int i = 0; i < ngasmixes; ++i) {
|
||||
parser->gasmix[i] = gasmix[i];
|
||||
}
|
||||
parser->cached = 1;
|
||||
parser->cached = HEADER;
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
@ -252,6 +282,7 @@ hw_ostc_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int fr
|
||||
parser->header = 0;
|
||||
parser->layout = NULL;
|
||||
parser->ngasmixes = 0;
|
||||
parser->nfixed = 0;
|
||||
parser->initial = 0;
|
||||
for (unsigned int i = 0; i < NGASMIXES; ++i) {
|
||||
parser->gasmix[i].oxygen = 0;
|
||||
@ -285,6 +316,7 @@ hw_ostc_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsig
|
||||
parser->header = 0;
|
||||
parser->layout = NULL;
|
||||
parser->ngasmixes = 0;
|
||||
parser->nfixed = 0;
|
||||
parser->initial = 0;
|
||||
for (unsigned int i = 0; i < NGASMIXES; ++i) {
|
||||
parser->gasmix[i].oxygen = 0;
|
||||
@ -360,6 +392,13 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
|
||||
// Cache the profile data.
|
||||
if (parser->cached < PROFILE) {
|
||||
rc = hw_ostc_parser_samples_foreach (abstract, NULL, NULL);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
}
|
||||
|
||||
unsigned int version = parser->version;
|
||||
const hw_ostc_layout_t *layout = parser->layout;
|
||||
|
||||
@ -641,10 +680,22 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
||||
ERROR (abstract->context, "Buffer overflow detected!");
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
unsigned int o2 = data[offset];
|
||||
unsigned int he = data[offset + 1];
|
||||
unsigned int idx = hw_ostc_find_gasmix (parser, o2, he, MANUAL);
|
||||
if (idx >= parser->ngasmixes) {
|
||||
if (idx >= NGASMIXES) {
|
||||
ERROR (abstract->context, "Maximum number of gas mixes reached.");
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
parser->gasmix[idx].oxygen = o2;
|
||||
parser->gasmix[idx].helium = he;
|
||||
parser->ngasmixes = idx + 1;
|
||||
}
|
||||
sample.event.type = SAMPLE_EVENT_GASCHANGE2;
|
||||
sample.event.time = 0;
|
||||
sample.event.flags = 0;
|
||||
sample.event.value = data[offset] | (data[offset + 1] << 16);
|
||||
sample.event.value = o2 | (he << 16);
|
||||
if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
|
||||
offset += 2;
|
||||
length -= 2;
|
||||
@ -785,5 +836,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
|
||||
parser->cached = PROFILE;
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user