diff --git a/include/libdivecomputer/hw_ostc.h b/include/libdivecomputer/hw_ostc.h index 4dfb523..2b293e2 100644 --- a/include/libdivecomputer/hw_ostc.h +++ b/include/libdivecomputer/hw_ostc.h @@ -65,7 +65,7 @@ dc_status_t hw_ostc_extract_dives (dc_device_t *device, const unsigned char data[], unsigned int size, dc_dive_callback_t callback, void *userdata); dc_status_t -hw_ostc_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int frog); +hw_ostc_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int hwos); dc_status_t hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename); diff --git a/include/libdivecomputer/hw_ostc3.h b/include/libdivecomputer/hw_ostc3.h index c60dc63..56244ed 100644 --- a/include/libdivecomputer/hw_ostc3.h +++ b/include/libdivecomputer/hw_ostc3.h @@ -64,6 +64,9 @@ hw_ostc3_device_config_reset (dc_device_t *abstract); dc_status_t hw_ostc3_device_fwupdate (dc_device_t *abstract, const char *filename); +dc_status_t +hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index 0ed1874..2f88bf0 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -595,7 +595,11 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi // Emit a device info event. dc_event_devinfo_t devinfo; - devinfo.firmware = array_uint16_be (id + 2); + if (device->hardware == OSTC4) { + devinfo.firmware = array_uint16_le (id + 2); + } else { + devinfo.firmware = array_uint16_be (id + 2); + } devinfo.serial = array_uint16_le (id + 0); if (device->hardware != UNKNOWN) { devinfo.model = device->hardware; diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index b6a6989..7401bc3 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -59,6 +59,8 @@ #define OSTC3_GAUGE 2 #define OSTC3_APNEA 3 +#define OSTC4 0x3B + typedef struct hw_ostc_sample_info_t { unsigned int type; unsigned int divisor; @@ -74,6 +76,7 @@ typedef struct hw_ostc_layout_t { unsigned int salinity; unsigned int duration; unsigned int temperature; + unsigned int firmware; } hw_ostc_layout_t; typedef struct hw_ostc_gasmix_t { @@ -83,7 +86,8 @@ typedef struct hw_ostc_gasmix_t { typedef struct hw_ostc_parser_t { dc_parser_t base; - unsigned int frog; + unsigned int hwos; + unsigned int model; // Cached fields. unsigned int cached; unsigned int version; @@ -119,6 +123,7 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc = { 43, /* salinity */ 47, /* duration */ 13, /* temperature */ + 32, /* firmware */ }; static const hw_ostc_layout_t hw_ostc_layout_frog = { @@ -130,6 +135,7 @@ static const hw_ostc_layout_t hw_ostc_layout_frog = { 43, /* salinity */ 47, /* duration */ 19, /* temperature */ + 34, /* firmware */ }; static const hw_ostc_layout_t hw_ostc_layout_ostc3 = { @@ -141,6 +147,7 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc3 = { 70, /* salinity */ 75, /* duration */ 22, /* temperature */ + 48, /* firmware */ }; static unsigned int @@ -181,7 +188,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser) } // Check the profile version - unsigned int version = data[parser->frog ? 8 : 2]; + unsigned int version = data[parser->hwos ? 8 : 2]; const hw_ostc_layout_t *layout = NULL; unsigned int header = 0; switch (version) { @@ -267,7 +274,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser) } dc_status_t -hw_ostc_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int frog) +hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, unsigned int hwos, unsigned int model) { hw_ostc_parser_t *parser = NULL; @@ -282,7 +289,8 @@ hw_ostc_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int fr } // Set the default values. - parser->frog = frog; + parser->hwos = hwos; + parser->model = model; parser->cached = 0; parser->version = 0; parser->header = 0; @@ -301,6 +309,18 @@ hw_ostc_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int fr } +dc_status_t +hw_ostc_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int hwos) +{ + return hw_ostc_parser_create_internal (out, context, hwos, 0); +} + +dc_status_t +hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model) +{ + return hw_ostc_parser_create_internal (out, context, 1, model); +} + static dc_status_t hw_ostc_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size) { @@ -589,6 +609,14 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call } } + // Get the firmware version. + unsigned int firmware = 0; + if (parser->model == OSTC4) { + firmware = array_uint16_le (data + layout->firmware); + } else { + firmware = array_uint16_be (data + layout->firmware); + } + unsigned int time = 0; unsigned int nsamples = 0; @@ -809,6 +837,10 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata); break; case 1: // Deco / NDL + // Due to a firmware bug, the deco/ndl info is incorrect for + // all OSTC4 dives with a firmware older than version 1.0.8. + if (parser->model == OSTC4 && firmware < 0x0810) + break; if (data[offset]) { sample.deco.type = DC_DECO_DECOSTOP; sample.deco.depth = data[offset]; diff --git a/src/libdivecomputer.symbols b/src/libdivecomputer.symbols index 8f83c9b..347db27 100644 --- a/src/libdivecomputer.symbols +++ b/src/libdivecomputer.symbols @@ -63,6 +63,7 @@ oceanic_vtpro_parser_create2 oceanic_veo250_parser_create oceanic_atom2_parser_create hw_ostc_parser_create +hw_ostc3_parser_create cressi_edy_parser_create cressi_leonardo_parser_create atomics_cobalt_parser_create diff --git a/src/parser.c b/src/parser.c index 505270e..bb3eb7a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -116,7 +116,7 @@ dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, dc_family_t fa break; case DC_FAMILY_HW_FROG: case DC_FAMILY_HW_OSTC3: - rc = hw_ostc_parser_create (&parser, context, 1); + rc = hw_ostc3_parser_create (&parser, context, model); break; case DC_FAMILY_CRESSI_EDY: case DC_FAMILY_ZEAGLE_N2ITION3: