From b17f432635f883dcd35ae04c46c2d6eaa008c31f Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 4 Jun 2015 14:31:45 +0200 Subject: [PATCH] Fix the logic to skip disabled gas mixes. Originally I assumed it's not possible to enable a gas mix if the previous gas mix has already been disabled. However, this assumption turns out to be wrong. For devices with support for 3 gas mixes, it's possible to enable only the first and the third gas mix, and leave the second gas mix disabled. This is fixed by checking all gas mixes, instead of aborting once the first disabled gas mix has been found. Due to this change the uwatec gas mix id's are no longer sequential and need to remapped to the corresponding internal array index. --- src/uwatec_smart_parser.c | 110 ++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index 664f635..d72ff1a 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -90,9 +90,16 @@ typedef struct uwatec_smart_sample_info_t { unsigned int extrabytes; } uwatec_smart_sample_info_t; +typedef struct uwatec_smart_gasmix_t { + unsigned int id; + unsigned int oxygen; +} uwatec_smart_gasmix_t; + typedef struct uwatec_smart_tank_t { + unsigned int id; unsigned int beginpressure; unsigned int endpressure; + unsigned int gasmix; } uwatec_smart_tank_t; typedef struct uwatec_smart_parser_t uwatec_smart_parser_t; @@ -110,7 +117,7 @@ struct uwatec_smart_parser_t { unsigned int cached; unsigned int trimix; unsigned int ngasmixes; - unsigned int oxygen[NGASMIXES]; + uwatec_smart_gasmix_t gasmix[NGASMIXES]; unsigned int ntanks; uwatec_smart_tank_t tank[NGASMIXES]; dc_water_t watertype; @@ -293,6 +300,20 @@ uwatec_smart_sample_info_t uwatec_smart_tec_samples[] = { }; +static unsigned int +uwatec_smart_find_gasmix (uwatec_smart_parser_t *parser, unsigned int id) +{ + unsigned int i = 0; + while (i < parser->ngasmixes) { + if (id == parser->gasmix[i].id) + break; + i++; + } + + return i; +} + + static dc_status_t uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) { @@ -314,42 +335,45 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) } } - // Get the gas mixes. - unsigned int ngasmixes = 0; - unsigned int oxygen[NGASMIXES] = {0}; - if (!trimix) { - for (unsigned int i = 0; i < parser->header->ngases; ++i) { - unsigned int o2 = data[parser->header->gasmix + i * 2]; - if (o2 == 0) - break; // Skip disabled gas mixes. - oxygen[ngasmixes] = o2; - ngasmixes++; - } - } - - // Get the tanks. + // Get the gas mixes and tanks. unsigned int ntanks = 0; + unsigned int ngasmixes = 0; uwatec_smart_tank_t tank[NGASMIXES] = {{0}}; - if (!trimix && header->tankpressure != UNSUPPORTED) { + uwatec_smart_gasmix_t gasmix[NGASMIXES] = {{0}}; + if (!trimix) { for (unsigned int i = 0; i < header->ngases; ++i) { + unsigned int idx = DC_GASMIX_UNKNOWN; + + unsigned int o2 = data[header->gasmix + i * 2]; + if (o2 != 0) { + idx = ngasmixes; + gasmix[ngasmixes].id = i; + gasmix[ngasmixes].oxygen = o2; + ngasmixes++; + } + unsigned int beginpressure = 0; unsigned int endpressure = 0; - if (parser->model == GALILEO || parser->model == GALILEOTRIMIX || - parser->model == ALADIN2G || parser->model == MERIDIAN || - parser->model == CHROMIS) { - unsigned int idx = header->tankpressure + 2 * i; - endpressure = array_uint16_le(data + idx); - beginpressure = array_uint16_le(data + idx + 2 * header->ngases); - } else { - unsigned int idx = header->tankpressure + 4 * i; - beginpressure = array_uint16_le(data + idx); - endpressure = array_uint16_le(data + idx + 2); + if (header->tankpressure != UNSUPPORTED) { + if (parser->model == GALILEO || parser->model == GALILEOTRIMIX || + parser->model == ALADIN2G || parser->model == MERIDIAN || + parser->model == CHROMIS) { + unsigned int offset = header->tankpressure + 2 * i; + endpressure = array_uint16_le(data + offset); + beginpressure = array_uint16_le(data + offset + 2 * header->ngases); + } else { + unsigned int offset = header->tankpressure + 4 * i; + beginpressure = array_uint16_le(data + offset); + endpressure = array_uint16_le(data + offset + 2); + } + } + if (beginpressure != 0 || endpressure != 0) { + tank[ntanks].id = i; + tank[ntanks].beginpressure = beginpressure; + tank[ntanks].endpressure = endpressure; + tank[ntanks].gasmix = idx; + ntanks++; } - if (beginpressure == 0 && endpressure == 0) - break; // Skip unused tanks. - tank[ntanks].beginpressure = beginpressure; - tank[ntanks].endpressure = endpressure; - ntanks++; } } @@ -365,7 +389,7 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) parser->trimix = trimix; parser->ngasmixes = ngasmixes; for (unsigned int i = 0; i < ngasmixes; ++i) { - parser->oxygen[i] = oxygen[i]; + parser->gasmix[i] = gasmix[i]; } parser->ntanks = ntanks; for (unsigned int i = 0; i < ntanks; ++i) { @@ -450,9 +474,12 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i parser->ngasmixes = 0; parser->ntanks = 0; for (unsigned int i = 0; i < NGASMIXES; ++i) { - parser->oxygen[i] = 0; + parser->gasmix[i].id = 0; + parser->gasmix[i].oxygen = 0; + parser->tank[i].id = 0; parser->tank[i].beginpressure = 0; parser->tank[i].endpressure = 0; + parser->tank[i].gasmix = 0; } parser->watertype = DC_WATER_FRESH; @@ -483,9 +510,12 @@ uwatec_smart_parser_set_data (dc_parser_t *abstract, const unsigned char *data, parser->ngasmixes = 0; parser->ntanks = 0; for (unsigned int i = 0; i < NGASMIXES; ++i) { - parser->oxygen[i] = 0; + parser->gasmix[i].id = 0; + parser->gasmix[i].oxygen = 0; + parser->tank[i].id = 0; parser->tank[i].beginpressure = 0; parser->tank[i].endpressure = 0; + parser->tank[i].gasmix = 0; } parser->watertype = DC_WATER_FRESH; @@ -564,7 +594,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi if (parser->trimix) return DC_STATUS_UNSUPPORTED; gasmix->helium = 0.0; - gasmix->oxygen = parser->oxygen[flags] / 100.0; + gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; case DC_FIELD_TANK_COUNT: @@ -578,12 +608,9 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi tank->type = DC_TANKVOLUME_NONE; tank->volume = 0.0; tank->workpressure = 0.0; - if (flags < parser->ngasmixes) - tank->gasmix = flags; - else - tank->gasmix = DC_GASMIX_UNKNOWN; tank->beginpressure = parser->tank[flags].beginpressure / 128.0; tank->endpressure = parser->tank[flags].endpressure / 128.0; + tank->gasmix = parser->tank[flags].gasmix; break; case DC_FIELD_TEMPERATURE_MINIMUM: *((double *) value) = (signed short) array_uint16_le (data + table->temp_minimum) / 10.0; @@ -885,14 +912,15 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t if (callback) callback (DC_SAMPLE_TIME, sample, userdata); if (parser->ngasmixes && gasmix != gasmix_previous) { - if (gasmix >= parser->ngasmixes) { + unsigned int idx = uwatec_smart_find_gasmix (parser, gasmix); + if (idx >= parser->ngasmixes) { ERROR (abstract->context, "Invalid gas mix index."); return DC_STATUS_DATAFORMAT; } sample.event.type = SAMPLE_EVENT_GASCHANGE; sample.event.time = 0; sample.event.flags = 0; - sample.event.value = parser->oxygen[gasmix]; + sample.event.value = parser->gasmix[idx].oxygen; if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); gasmix_previous = gasmix; }