From ce82829284ea0888008c89ce082c7512c8d663ee Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 23 Feb 2016 22:13:25 +0100 Subject: [PATCH 1/9] Fix a memory leak. A new buffer is allocated for each dive, but only the last one is freed. Since the code is already prepared to simply re-use the same buffer, there is no need to allocate those extra buffers. --- src/suunto_eonsteel.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index ec7cfe3..e1c9846 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -672,9 +672,6 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac break; if (!callback(dc_buffer_get_data(file), dc_buffer_get_size(file), NULL, 0, userdata)) skip = 1; - - // We've used up the buffer, so create a new one - file = dc_buffer_new(0); } progress.current++; device_event_emit(abstract, DC_EVENT_PROGRESS, &progress); From 76c52b582a6298b66bdba742eae987b27dca0e40 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 23 Feb 2016 22:52:31 +0100 Subject: [PATCH 2/9] Add support for the fingerprint feature. --- src/suunto_eonsteel.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index e1c9846..9debc6a 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -52,6 +52,7 @@ typedef struct suunto_eonsteel_device_t { libusb_device_handle *handle; unsigned int magic; unsigned short seq; + unsigned char fingerprint[4]; } suunto_eonsteel_device_t; // The EON Steel implements a small filesystem @@ -81,13 +82,14 @@ struct directory_entry { #define READDIR_CMD 0x0910 #define DIR_CLOSE_CMD 0x0a10 +static dc_status_t suunto_eonsteel_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size); static dc_status_t suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callback, void *userdata); static dc_status_t suunto_eonsteel_device_close(dc_device_t *abstract); static const dc_device_vtable_t suunto_eonsteel_device_vtable = { sizeof(suunto_eonsteel_device_t), DC_FAMILY_SUUNTO_EONSTEEL, - NULL, /* set_fingerprint */ + suunto_eonsteel_device_set_fingerprint, /* set_fingerprint */ NULL, /* read */ NULL, /* write */ NULL, /* dump */ @@ -570,6 +572,7 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char // Set up the magic handshake fields eon->magic = INIT_MAGIC; eon->seq = INIT_SEQ; + memset (eon->fingerprint, 0, sizeof (eon->fingerprint)); if (libusb_init(&eon->ctx)) { ERROR(context, "libusb_init() failed"); @@ -619,6 +622,22 @@ static int count_dir_entries(struct directory_entry *de) return count; } +static dc_status_t +suunto_eonsteel_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size) +{ + suunto_eonsteel_device_t *device = (suunto_eonsteel_device_t *) abstract; + + if (size && size != sizeof (device->fingerprint)) + return DC_STATUS_INVALIDARGS; + + if (size) + memcpy (device->fingerprint, data, sizeof (device->fingerprint)); + else + memset (device->fingerprint, 0, sizeof (device->fingerprint)); + + return DC_STATUS_SUCCESS; +} + static dc_status_t suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callback, void *userdata) { @@ -642,6 +661,8 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac int len; struct directory_entry *next = de->next; unsigned char buf[4]; + const unsigned char *data = NULL; + unsigned int size = 0; if (device_is_cancelled(abstract)) skip = 1; @@ -668,9 +689,16 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac rc = read_file(eon, pathname, file); if (rc < 0) break; - if (!callback) + + data = dc_buffer_get_data(file); + size = dc_buffer_get_size(file); + + if (memcmp (data, eon->fingerprint, sizeof (eon->fingerprint)) == 0) { + skip = 1; break; - if (!callback(dc_buffer_get_data(file), dc_buffer_get_size(file), NULL, 0, userdata)) + } + + if (callback && !callback(data, size, data, sizeof(eon->fingerprint), userdata)) skip = 1; } progress.current++; From d40cdb4755ee478530a09f297836f310d7423678 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 24 Apr 2016 19:14:52 +0200 Subject: [PATCH 3/9] Add the devinfo event. The devinfo event with the device serial number is required for the fingerprint feature. Without this event, applications won't be able to load (or save) the correct fingerprint. All necessary information is already available in the initial handshake packet. --- src/array.c | 14 ++++++++++++++ src/array.h | 3 +++ src/suunto_eonsteel.c | 11 ++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/array.c b/src/array.c index 26a6c1b..13a73e5 100644 --- a/src/array.c +++ b/src/array.c @@ -146,6 +146,20 @@ array_convert_hex2bin (const unsigned char input[], unsigned int isize, unsigned return 0; } +unsigned int +array_convert_str2num (const unsigned char data[], unsigned int size) +{ + unsigned int value = 0; + for (unsigned int i = 0; i < size; ++i) { + if (data[i] < '0' || data[i] > '9') + break; + value *= 10; + value += data[i] - '0'; + } + + return value; +} + unsigned int array_uint_be (const unsigned char data[], unsigned int n) { diff --git a/src/array.h b/src/array.h index 49e8ab1..cd0a3a1 100644 --- a/src/array.h +++ b/src/array.h @@ -49,6 +49,9 @@ array_convert_bin2hex (const unsigned char input[], unsigned int isize, unsigned int array_convert_hex2bin (const unsigned char input[], unsigned int isize, unsigned char output[], unsigned int osize); +unsigned int +array_convert_str2num (const unsigned char data[], unsigned int size); + unsigned int array_uint_be (const unsigned char data[], unsigned int n); diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index 9debc6a..079c353 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -52,6 +52,7 @@ typedef struct suunto_eonsteel_device_t { libusb_device_handle *handle; unsigned int magic; unsigned short seq; + unsigned char version[0x30]; unsigned char fingerprint[4]; } suunto_eonsteel_device_t; @@ -544,7 +545,7 @@ static int initialize_eonsteel(suunto_eonsteel_device_t *eon) ERROR(eon->base.context, "Failed to send initialization command"); return -1; } - if (receive_header(eon, &hdr, buf, sizeof(buf)) < 0) { + if (receive_header(eon, &hdr, eon->version, sizeof(eon->version)) < 0) { ERROR(eon->base.context, "Failed to receive initial reply"); return -1; } @@ -572,6 +573,7 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char // Set up the magic handshake fields eon->magic = INIT_MAGIC; eon->seq = INIT_SEQ; + memset (eon->version, 0, sizeof (eon->version)); memset (eon->fingerprint, 0, sizeof (eon->fingerprint)); if (libusb_init(&eon->ctx)) { @@ -652,6 +654,13 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac if (get_file_list(eon, &de) < 0) return DC_STATUS_IO; + // Emit a device info event. + dc_event_devinfo_t devinfo; + devinfo.model = 0; + devinfo.firmware = array_uint32_be (eon->version + 0x20); + devinfo.serial = array_convert_str2num(eon->version + 0x10, 16); + device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo); + file = dc_buffer_new(0); progress.maximum = count_dir_entries(de); progress.current = 0; From 33f5206f79e4b96aa7767f182792ffb6a0167622 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 26 Apr 2016 21:06:45 +0200 Subject: [PATCH 4/9] Add support for the Beuchat Mundial 2 and 3. These two models use the same memory layout and data format as the Oceanic F10. Reported-By: Nick Shore --- src/descriptor.c | 2 ++ src/oceanic_atom2.c | 1 + src/oceanic_atom2_parser.c | 21 +++++++++++++++------ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index af15103..446bbd4 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -176,12 +176,14 @@ static const dc_descriptor_t g_descriptors[] = { {"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458}, {"Aeris", "A300", DC_FAMILY_OCEANIC_ATOM2, 0x445A}, {"Hollis", "TX1", DC_FAMILY_OCEANIC_ATOM2, 0x4542}, + {"Beuchat", "Mundial 2", DC_FAMILY_OCEANIC_ATOM2, 0x4543}, {"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545}, {"Sherwood", "Amphos Air", DC_FAMILY_OCEANIC_ATOM2, 0x4546}, {"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548}, {"Aeris", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4549}, {"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B}, {"Aeris", "A300CS", DC_FAMILY_OCEANIC_ATOM2, 0x454C}, + {"Beuchat", "Mundial 3", DC_FAMILY_OCEANIC_ATOM2, 0x4550}, {"Oceanic", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4554}, {"Oceanic", "VTX", DC_FAMILY_OCEANIC_ATOM2, 0x4557}, {"Aqualung", "i450T", DC_FAMILY_OCEANIC_ATOM2, 0x4641}, diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 3bd81db..bc93387 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -83,6 +83,7 @@ static const dc_device_vtable_t oceanic_atom2_device_vtable = { static const oceanic_common_version_t aeris_f10_version[] = { {"FREEWAER \0\0 512K"}, + {"MUNDIAL R\0\0 512K"}, }; static const oceanic_common_version_t aeris_f11_version[] = { diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index f431628..26ad9b3 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -67,12 +67,14 @@ #define WISDOM3 0x4458 #define A300 0x445A #define TX1 0x4542 +#define MUNDIAL2 0x4543 #define AMPHOS 0x4545 #define AMPHOSAIR 0x4546 #define PROPLUS3 0x4548 #define F11A 0x4549 #define OCI 0x454B #define A300CS 0x454C +#define MUNDIAL3 0x4550 #define F11B 0x4554 #define VTX 0x4557 #define I450T 0x4641 @@ -153,7 +155,7 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned parser->headersize += 2 * PAGESIZE; } else if (model == ATOM1) { parser->headersize -= 2 * PAGESIZE; - } else if (model == F10) { + } else if (model == F10 || model == MUNDIAL2 || model == MUNDIAL3) { parser->headersize = 3 * PAGESIZE; parser->footersize = 0; } else if (model == F11A || model == F11B) { @@ -210,7 +212,8 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim unsigned int header = 8; if (parser->model == F10 || parser->model == F11A || - parser->model == F11B) + parser->model == F11B || parser->model == MUNDIAL2 || + parser->model == MUNDIAL3) header = 32; if (abstract->size < header) @@ -268,6 +271,8 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim case F10: case F11A: case F11B: + case MUNDIAL2: + case MUNDIAL3: datetime->year = bcd2dec (p[6]) + 2000; datetime->month = bcd2dec (p[7]); datetime->day = bcd2dec (p[8]); @@ -369,7 +374,8 @@ oceanic_atom2_parser_cache (oceanic_atom2_parser_t *parser) // Get the dive mode. unsigned int mode = NORMAL; if (parser->model == F10 || parser->model == F11A || - parser->model == F11B) { + parser->model == F11B || parser->model == MUNDIAL2 || + parser->model == MUNDIAL3) { mode = FREEDIVE; } else if (parser->model == T3B || parser->model == VT3 || parser->model == DG03) { @@ -474,14 +480,16 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns switch (type) { case DC_FIELD_DIVETIME: if (parser->model == F10 || parser->model == F11A || - parser->model == F11B) + parser->model == F11B || parser->model == MUNDIAL2 || + parser->model == MUNDIAL3) *((unsigned int *) value) = bcd2dec (data[2]) + bcd2dec (data[3]) * 60; else *((unsigned int *) value) = parser->divetime; break; case DC_FIELD_MAXDEPTH: if (parser->model == F10 || parser->model == F11A || - parser->model == F11B) + parser->model == F11B || parser->model == MUNDIAL2 || + parser->model == MUNDIAL3) *((double *) value) = array_uint16_le (data + 4) / 16.0 * FEET; else *((double *) value) = array_uint16_le (data + parser->footer + 4) / 16.0 * FEET; @@ -594,7 +602,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ unsigned int samplesize = PAGESIZE / 2; if (parser->mode == FREEDIVE) { if (parser->model == F10 || parser->model == F11A || - parser->model == F11B) { + parser->model == F11B || parser->model == MUNDIAL2 || + parser->model == MUNDIAL3) { samplesize = 2; } else { samplesize = 4; From dbba7f32726687b504133a63aefb9ef32ba63ef8 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Wed, 27 Apr 2016 08:56:51 +0200 Subject: [PATCH 5/9] Fix the date for the Sherwood Insight 2. --- src/oceanic_atom2_parser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 26ad9b3..7d8bb19 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -252,6 +252,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim case PROPLUS3: case DATAMASK: case COMPUMASK: + case INSIGHT2: datetime->year = ((p[3] & 0xE0) >> 1) + (p[4] & 0x0F) + 2000; datetime->month = (p[4] & 0xF0) >> 4; datetime->day = p[3] & 0x1F; From f67bdcd0800654b04c16e12a2b71d1bd30abe7af Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Wed, 11 May 2016 08:30:41 +0200 Subject: [PATCH 6/9] Add support for the Aqualung i300. --- src/descriptor.c | 1 + src/oceanic_atom2.c | 1 + src/oceanic_atom2_parser.c | 11 +++++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 446bbd4..b774062 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -186,6 +186,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Beuchat", "Mundial 3", DC_FAMILY_OCEANIC_ATOM2, 0x4550}, {"Oceanic", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4554}, {"Oceanic", "VTX", DC_FAMILY_OCEANIC_ATOM2, 0x4557}, + {"Aqualung", "i300", DC_FAMILY_OCEANIC_ATOM2, 0x4559}, {"Aqualung", "i450T", DC_FAMILY_OCEANIC_ATOM2, 0x4641}, /* Mares Nemo */ {"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0}, diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index bc93387..9904131 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -129,6 +129,7 @@ static const oceanic_common_version_t oceanic_default_version[] = { {"DATAMASK \0\0 512K"}, {"COMPMASK \0\0 512K"}, {"HOLLDG03 \0\0 512K"}, + {"AQUAI300 \0\0 512K"}, }; static const oceanic_common_version_t oceanic_proplus3_version[] = { diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 7d8bb19..23745e3 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -77,6 +77,7 @@ #define MUNDIAL3 0x4550 #define F11B 0x4554 #define VTX 0x4557 +#define I300 0x4559 #define I450T 0x4641 #define NORMAL 0 @@ -147,7 +148,8 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned model == VEO20 || model == VEO30 || model == OCS || model == PROPLUS3 || model == A300 || model == MANTA || - model == INSIGHT2 || model == ZEN) { + model == INSIGHT2 || model == ZEN || + model == I300) { parser->headersize -= PAGESIZE; } else if (model == VT4 || model == VT41) { parser->headersize += PAGESIZE; @@ -253,6 +255,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim case DATAMASK: case COMPUMASK: case INSIGHT2: + case I300: datetime->year = ((p[3] & 0xE0) >> 1) + (p[4] & 0x0F) + 2000; datetime->month = (p[4] & 0xF0) >> 4; datetime->day = p[3] & 0x1F; @@ -624,7 +627,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == ELEMENT2 || parser->model == VEO20 || parser->model == A300 || parser->model == ZEN || parser->model == GEO || parser->model == GEO20 || - parser->model == MANTA) { + parser->model == MANTA || parser->model == I300) { have_pressure = 0; } @@ -738,7 +741,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == VEO30 || parser->model == OC1A || parser->model == OC1B || parser->model == OC1C || parser->model == OCI || parser->model == A300 || - parser->model == I450T) { + parser->model == I450T || parser->model == I300) { temperature = data[offset + 3]; } else if (parser->model == OCS || parser->model == TX1) { temperature = data[offset + 1]; @@ -798,7 +801,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == VEO30 || parser->model == OC1A || parser->model == OC1B || parser->model == OC1C || parser->model == OCI || parser->model == A300 || - parser->model == I450T) + parser->model == I450T || parser->model == I300) depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF; else if (parser->model == ATOM1) depth = data[offset + 3] * 16; From bdc1c1349ec7baa433c541e0e1c2961f82815a52 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Wed, 1 Jun 2016 19:25:24 +0200 Subject: [PATCH 7/9] Fix the length of the Vyper Novo gas change event. Just like the Suunto DX, the Vyper Novo uses 5 bytes for the 0x06 gas change event. --- src/suunto_d9_parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c index f534051..427fd3d 100644 --- a/src/suunto_d9_parser.c +++ b/src/suunto_d9_parser.c @@ -724,7 +724,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca offset += 2; break; case 0x06: // Gas Change - if (parser->model == DX) + if (parser->model == DX || parser->model == VYPERNOVO) length = 5; else length = 4; @@ -735,7 +735,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca unknown = data[offset + 0]; he = data[offset + 1]; o2 = data[offset + 2]; - if (parser->model == DX) { + if (parser->model == DX || parser->model == VYPERNOVO) { seconds = data[offset + 4]; } else { seconds = data[offset + 3]; From 87facc940b677e312b391f8091db03a4dc437ef7 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 2 Jun 2016 23:40:17 +0200 Subject: [PATCH 8/9] Add support for the dive mode field. --- src/mares_darwin_parser.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/mares_darwin_parser.c b/src/mares_darwin_parser.c index 42cccb4..cad3d6b 100644 --- a/src/mares_darwin_parser.c +++ b/src/mares_darwin_parser.c @@ -34,6 +34,10 @@ #define DARWIN 0 #define DARWINAIR 1 +#define AIR 0 +#define GAUGE 1 +#define NITROX 2 + typedef struct mares_darwin_parser_t mares_darwin_parser_t; struct mares_darwin_parser_t { @@ -133,6 +137,8 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi dc_gasmix_t *gasmix = (dc_gasmix_t *) value; dc_tank_t *tank = (dc_tank_t *) value; + unsigned int mode = p[0x0C] & 0x03; + if (value) { switch (type) { case DC_FIELD_DIVETIME: @@ -142,7 +148,11 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi *((double *) value) = array_uint16_be (p + 0x08) / 10.0; break; case DC_FIELD_GASMIX_COUNT: - *((unsigned int *) value) = 1; + if (mode == GAUGE) { + *((unsigned int *) value) = 0; + } else { + *((unsigned int *) value) = 1; + } break; case DC_FIELD_GASMIX: gasmix->helium = 0.0; @@ -171,6 +181,19 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi return DC_STATUS_UNSUPPORTED; } break; + case DC_FIELD_DIVEMODE: + switch (mode) { + case AIR: + case NITROX: + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + break; + case GAUGE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; + default: + return DC_STATUS_DATAFORMAT; + } + break; default: return DC_STATUS_UNSUPPORTED; } From 5361bc06bdd37b4dbcd89edaa3d4dcaed93eefde Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Wed, 11 May 2016 10:49:15 +0200 Subject: [PATCH 9/9] Fix the nitrox gas mix parsing. Mares Darwin compatible devices support a nitrox mode. The nitrogen percentage should only be taken into account when the dive mode is set to nitrox, because the last used value remains in place for air dives. --- src/mares_darwin_parser.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mares_darwin_parser.c b/src/mares_darwin_parser.c index cad3d6b..d4d13da 100644 --- a/src/mares_darwin_parser.c +++ b/src/mares_darwin_parser.c @@ -156,7 +156,11 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi break; case DC_FIELD_GASMIX: gasmix->helium = 0.0; - gasmix->oxygen = 0.21; + if (mode == NITROX) { + gasmix->oxygen = p[0x0E] / 100.0; + } else { + gasmix->oxygen = 0.21; + } gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; case DC_FIELD_TEMPERATURE_MINIMUM: