From 1226b47c6d3ead53c2cf97303398dcc70f37043b Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 15 Aug 2016 08:30:43 +0200 Subject: [PATCH 1/4] Add the salinity field for the Aladin Tec. --- src/uwatec_smart_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index d0ed765..cf5b03d 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -197,7 +197,7 @@ uwatec_smart_header_info_t uwatec_smart_aladin_tec_header = { 28, /* temp_maximum */ 32, /* temp_surface */ UNSUPPORTED, /* tankpressure */ - UNSUPPORTED, /* salinity */ + 54, /* salinity */ 16, /* timezone */ }; From 8b0a04817568602970e58e8d191e68e1295471b8 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 15 Aug 2016 10:46:32 +0200 Subject: [PATCH 2/4] Detect the gauge and freedive mode correctly. The gauge and freedive mode bits are stored in the settings field. The location of the gauge bit appears to be the same for all models. For the freedive bit it depends on the model, and also not all models support it. --- src/uwatec_smart_parser.c | 50 +++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index cf5b03d..2524314 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -59,6 +59,10 @@ #define FRESH 1.000 #define SALT 1.025 +#define FREEDIVE1 0x00000080 +#define FREEDIVE2 0x00000200 +#define GAUGE 0x00001000 + typedef enum { PRESSURE_DEPTH, RBT, @@ -94,6 +98,7 @@ typedef struct uwatec_smart_header_info_t { unsigned int tankpressure; unsigned int salinity; unsigned int timezone; + unsigned int settings; } uwatec_smart_header_info_t; typedef struct uwatec_smart_sample_info_t { @@ -145,6 +150,7 @@ struct uwatec_smart_parser_t { unsigned int ntanks; uwatec_smart_tank_t tank[NGASMIXES]; dc_water_t watertype; + dc_divemode_t divemode; }; static dc_status_t uwatec_smart_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size); @@ -173,6 +179,7 @@ uwatec_smart_header_info_t uwatec_smart_pro_header = { UNSUPPORTED, /* tankpressure */ UNSUPPORTED, /* salinity */ UNSUPPORTED, /* timezone */ + UNSUPPORTED, /* settings */ }; static const @@ -186,6 +193,7 @@ uwatec_smart_header_info_t uwatec_smart_galileo_header = { 50, /* tankpressure */ 94, /* salinity */ 16, /* timezone */ + 92, /* settings */ }; static const @@ -199,6 +207,7 @@ uwatec_smart_header_info_t uwatec_smart_aladin_tec_header = { UNSUPPORTED, /* tankpressure */ 54, /* salinity */ 16, /* timezone */ + 52, /* settings */ }; static const @@ -212,6 +221,7 @@ uwatec_smart_header_info_t uwatec_smart_aladin_tec2g_header = { UNSUPPORTED, /* tankpressure */ 62, /* salinity */ 16, /* timezone */ + 60, /* settings */ }; static const @@ -225,6 +235,7 @@ uwatec_smart_header_info_t uwatec_smart_com_header = { 30, /* tankpressure */ UNSUPPORTED, /* salinity */ UNSUPPORTED, /* timezone */ + UNSUPPORTED, /* settings */ }; static const @@ -238,6 +249,7 @@ uwatec_smart_header_info_t uwatec_smart_tec_header = { 34, /* tankpressure */ UNSUPPORTED, /* salinity */ UNSUPPORTED, /* timezone */ + UNSUPPORTED, /* settings */ }; static const @@ -436,6 +448,34 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) } } + // Get the settings. + dc_divemode_t divemode = DC_DIVEMODE_OC; + if (header->settings != UNSUPPORTED) { + unsigned int settings = array_uint32_le (data + header->settings); + + // Get the freedive/gauge bits. + unsigned int freedive = 0; + unsigned int gauge = (settings & GAUGE) != 0; + if (parser->model == ALADINTEC) { + freedive = 0; + } else if (parser->model == ALADINTEC2G) { + freedive = (settings & FREEDIVE2) != 0; + } else { + freedive = (settings & FREEDIVE1) != 0; + } + + // Get the dive mode. The freedive bit needs to be checked + // first, because freedives have both the freedive and gauge + // bits set. + if (freedive) { + divemode = DC_DIVEMODE_FREEDIVE; + } else if (gauge) { + divemode = DC_DIVEMODE_GAUGE; + } else { + divemode = DC_DIVEMODE_OC; + } + } + // Get the gas mixes and tanks. unsigned int ntanks = 0; unsigned int ngasmixes = 0; @@ -504,6 +544,7 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) parser->tank[i] = tank[i]; } parser->watertype = watertype; + parser->divemode = divemode; parser->cached = HEADER; return DC_STATUS_SUCCESS; @@ -614,6 +655,7 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i parser->tank[i].gasmix = 0; } parser->watertype = DC_WATER_FRESH; + parser->divemode = DC_DIVEMODE_OC; *out = (dc_parser_t*) parser; @@ -645,6 +687,7 @@ uwatec_smart_parser_set_data (dc_parser_t *abstract, const unsigned char *data, parser->tank[i].gasmix = 0; } parser->watertype = DC_WATER_FRESH; + parser->divemode = DC_DIVEMODE_OC; return DC_STATUS_SUCCESS; } @@ -756,10 +799,9 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi *((double *) value) = (signed short) array_uint16_le (data + table->temp_surface) / 10.0; break; case DC_FIELD_DIVEMODE: - if (parser->ngasmixes) - *((dc_divemode_t *) value) = DC_DIVEMODE_OC; - else - *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + if (table->settings == UNSUPPORTED) + return DC_STATUS_UNSUPPORTED; + *((dc_divemode_t *) value) = parser->divemode; break; case DC_FIELD_SALINITY: if (table->salinity == UNSUPPORTED) From bfcd707889c5ba9a19d1f99d586a68937db42fb0 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 25 Jul 2016 10:26:26 +0200 Subject: [PATCH 3/4] Fix the parsing of freedives. In freedive mode the sample rate is only 1 second instead of 4 seconds. The tank pressure fields appear to be re-used for some other (unknown) purposes, and should be ignored. --- src/uwatec_smart_parser.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index 2524314..48c5163 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -501,7 +501,8 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) unsigned int beginpressure = 0; unsigned int endpressure = 0; - if (header->tankpressure != UNSUPPORTED) { + if (header->tankpressure != UNSUPPORTED && + divemode != DC_DIVEMODE_FREEDIVE) { if (parser->model == GALILEO || parser->model == GALILEOTRIMIX || parser->model == ALADIN2G || parser->model == MERIDIAN || parser->model == CHROMIS || parser->model == MANTIS2) { @@ -924,6 +925,11 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t double salinity = (parser->watertype == DC_WATER_SALT ? SALT : FRESH); + unsigned int interval = 4; + if (parser->divemode == DC_DIVEMODE_FREEDIVE) { + interval = 1; + } + int have_depth = 0, have_temperature = 0, have_pressure = 0, have_rbt = 0, have_heartrate = 0, have_bearing = 0; @@ -1210,7 +1216,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata); } - time += 4; + time += interval; complete--; } } From 0ab2d8ccda12bd410a88520a15d63573234eef51 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 15 Aug 2016 10:56:04 +0200 Subject: [PATCH 4/4] Use the new settings field for the salinity. Since the salinity bit is stored in the settings, there is no need for a separate salinity entry in the header tables. --- src/uwatec_smart_parser.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index 48c5163..feb4844 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -62,6 +62,7 @@ #define FREEDIVE1 0x00000080 #define FREEDIVE2 0x00000200 #define GAUGE 0x00001000 +#define SALINITY 0x00100000 typedef enum { PRESSURE_DEPTH, @@ -96,7 +97,6 @@ typedef struct uwatec_smart_header_info_t { unsigned int temp_maximum; unsigned int temp_surface; unsigned int tankpressure; - unsigned int salinity; unsigned int timezone; unsigned int settings; } uwatec_smart_header_info_t; @@ -177,7 +177,6 @@ uwatec_smart_header_info_t uwatec_smart_pro_header = { UNSUPPORTED, /* temp_maximum */ UNSUPPORTED, /* temp_surface */ UNSUPPORTED, /* tankpressure */ - UNSUPPORTED, /* salinity */ UNSUPPORTED, /* timezone */ UNSUPPORTED, /* settings */ }; @@ -191,7 +190,6 @@ uwatec_smart_header_info_t uwatec_smart_galileo_header = { 28, /* temp_maximum */ 32, /* temp_surface */ 50, /* tankpressure */ - 94, /* salinity */ 16, /* timezone */ 92, /* settings */ }; @@ -205,7 +203,6 @@ uwatec_smart_header_info_t uwatec_smart_aladin_tec_header = { 28, /* temp_maximum */ 32, /* temp_surface */ UNSUPPORTED, /* tankpressure */ - 54, /* salinity */ 16, /* timezone */ 52, /* settings */ }; @@ -219,7 +216,6 @@ uwatec_smart_header_info_t uwatec_smart_aladin_tec2g_header = { 28, /* temp_maximum */ 32, /* temp_surface */ UNSUPPORTED, /* tankpressure */ - 62, /* salinity */ 16, /* timezone */ 60, /* settings */ }; @@ -233,7 +229,6 @@ uwatec_smart_header_info_t uwatec_smart_com_header = { UNSUPPORTED, /* temp_maximum */ UNSUPPORTED, /* temp_surface */ 30, /* tankpressure */ - UNSUPPORTED, /* salinity */ UNSUPPORTED, /* timezone */ UNSUPPORTED, /* settings */ }; @@ -247,7 +242,6 @@ uwatec_smart_header_info_t uwatec_smart_tec_header = { UNSUPPORTED, /* temp_maximum */ UNSUPPORTED, /* temp_surface */ 34, /* tankpressure */ - UNSUPPORTED, /* salinity */ UNSUPPORTED, /* timezone */ UNSUPPORTED, /* settings */ }; @@ -450,6 +444,7 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) // Get the settings. dc_divemode_t divemode = DC_DIVEMODE_OC; + dc_water_t watertype = DC_WATER_FRESH; if (header->settings != UNSUPPORTED) { unsigned int settings = array_uint32_le (data + header->settings); @@ -474,6 +469,11 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) } else { divemode = DC_DIVEMODE_OC; } + + // Get the water type. + if (settings & SALINITY) { + watertype = DC_WATER_SALT; + } } // Get the gas mixes and tanks. @@ -526,14 +526,6 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser) } } - // Get the water type. - dc_water_t watertype = DC_WATER_FRESH; - if (header->salinity != UNSUPPORTED) { - if (data[header->salinity] & 0x10) { - watertype = DC_WATER_SALT; - } - } - // Cache the data for later use. parser->trimix = trimix; parser->ngasmixes = ngasmixes; @@ -805,7 +797,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi *((dc_divemode_t *) value) = parser->divemode; break; case DC_FIELD_SALINITY: - if (table->salinity == UNSUPPORTED) + if (table->settings == UNSUPPORTED) return DC_STATUS_UNSUPPORTED; water->type = parser->watertype; water->density = salinity * 1000.0;