From 5d28a329129734c3cf930417bace35f1d584f811 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Wed, 6 Feb 2013 13:54:52 +0100 Subject: [PATCH 01/21] Post release version bump to 0.3.1. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 8c12ade..34310e0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # Versioning. m4_define([dc_version_major],[0]) m4_define([dc_version_minor],[3]) -m4_define([dc_version_micro],[0]) -m4_define([dc_version_suffix],[]) +m4_define([dc_version_micro],[1]) +m4_define([dc_version_suffix],[devel]) m4_define([dc_version],dc_version_major.dc_version_minor.dc_version_micro[]m4_ifset([dc_version_suffix],-[dc_version_suffix])) # Libtool versioning. From 5bea3156fd9acbbc24e2e16f6fba09d71b18671b Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 7 Feb 2013 13:11:18 +0100 Subject: [PATCH 02/21] Add support for the Aeris Elite. --- src/descriptor.c | 1 + src/oceanic_vtpro.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/descriptor.c b/src/descriptor.c index b550624..3e9a8f5 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -95,6 +95,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Aeris", "Atmos AI", DC_FAMILY_OCEANIC_VTPRO, 0x4244}, {"Oceanic", "VT Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4245}, {"Sherwood", "Wisdom", DC_FAMILY_OCEANIC_VTPRO, 0x4246}, + {"Aeris", "Elite", DC_FAMILY_OCEANIC_VTPRO, 0x424F}, /* Oceanic Veo 250 */ {"Genesis", "React Pro", DC_FAMILY_OCEANIC_VEO250, 0x4247}, {"Oceanic", "Veo 200", DC_FAMILY_OCEANIC_VEO250, 0x424B}, diff --git a/src/oceanic_vtpro.c b/src/oceanic_vtpro.c index e5fc93c..3eee27e 100644 --- a/src/oceanic_vtpro.c +++ b/src/oceanic_vtpro.c @@ -66,6 +66,7 @@ static const oceanic_common_version_t oceanic_vtpro_version[] = { {"PROPLUS2 \0\0 256K"}, {"ATMOSAIR \0\0 256K"}, {"VTPRO r\0\0 256K"}, + {"ELITE r\0\0 256K"}, }; static const oceanic_common_version_t oceanic_wisdom_version[] = { From 9fb5e1f566fde7bf2a7409d82e3d5bddba7c2d0b Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 3 Mar 2013 23:45:27 +0100 Subject: [PATCH 03/21] Add support for the Aeris Atmos 2. --- src/descriptor.c | 1 + src/oceanic_vtpro.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/descriptor.c b/src/descriptor.c index 3e9a8f5..8f5e9eb 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -91,6 +91,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Reefnet", "Sensus Ultra", DC_FAMILY_REEFNET_SENSUSULTRA, 3}, /* Oceanic VT Pro */ {"Oceanic", "Versa Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4155}, + {"Aeris", "Atmos 2", DC_FAMILY_OCEANIC_VTPRO, 0x4158}, {"Oceanic", "Pro Plus 2", DC_FAMILY_OCEANIC_VTPRO, 0x4159}, {"Aeris", "Atmos AI", DC_FAMILY_OCEANIC_VTPRO, 0x4244}, {"Oceanic", "VT Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4245}, diff --git a/src/oceanic_vtpro.c b/src/oceanic_vtpro.c index 3eee27e..6d5fcaf 100644 --- a/src/oceanic_vtpro.c +++ b/src/oceanic_vtpro.c @@ -63,6 +63,7 @@ static const device_backend_t oceanic_vtpro_device_backend = { static const oceanic_common_version_t oceanic_vtpro_version[] = { {"VERSAPRO \0\0 256K"}, + {"ATMOSTWO \0\0 256K"}, {"PROPLUS2 \0\0 256K"}, {"ATMOSAIR \0\0 256K"}, {"VTPRO r\0\0 256K"}, From 7323ba0f2d354e3abe6ad144ce36d4ea04de9b6b Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 10 Mar 2013 20:52:24 +0100 Subject: [PATCH 04/21] Re-order the decostop array to match the enum values. The enum values have been re-ordered a while ago, but the array was not updated to reflect those changes. --- examples/universal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/universal.c b/examples/universal.c index b305e29..b1aa2c2 100644 --- a/examples/universal.c +++ b/examples/universal.c @@ -243,7 +243,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) "OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning", "gaschange2"}; static const char *decostop[] = { - "ndl", "deco", "deep", "safety"}; + "ndl", "safety", "deco", "deep"}; sample_data_t *sampledata = (sample_data_t *) userdata; From 276be51a652848beae88112f2089ba693e6b04c3 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 16 Mar 2013 10:00:16 +0100 Subject: [PATCH 05/21] Fix the decoding of negative temperatures. Because temperatures can be negative, we should interpret the stored value as a signed integer, even for the absolute values. --- 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 035f508..8d0df3d 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -601,7 +601,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t break; case TEMPERATURE: if (table[id].absolute) { - temperature = value / 2.5; + temperature = svalue / 2.5; have_temperature = 1; } else { temperature += svalue / 2.5; From 4adac6f5c96c0bf811cc5c3d6617c68fb9a17c06 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 18 Mar 2013 09:24:28 +0100 Subject: [PATCH 06/21] Add support for the Oceanic Pro Plus 3. --- src/descriptor.c | 1 + src/oceanic_atom2.c | 1 + src/oceanic_atom2_parser.c | 9 +++++---- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 8f5e9eb..176f4e9 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -139,6 +139,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Oceanic", "Atom 3.1", DC_FAMILY_OCEANIC_ATOM2, 0x4456}, {"Aeris", "A300 AI", DC_FAMILY_OCEANIC_ATOM2, 0x4457}, {"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458}, + {"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548}, /* Mares Nemo */ {"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0}, {"Mares", "Nemo Excel", DC_FAMILY_MARES_NEMO, 17}, diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 8c18864..41bb94a 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -87,6 +87,7 @@ static const oceanic_common_version_t oceanic_atom2b_version[] = { {"ELEMENT2 \0\0 512K"}, {"OCEVEO20 \0\0 512K"}, {"TUSAZEN \0\0 512K"}, + {"PROPLUS3 \0\0 512K"}, }; static const oceanic_common_version_t oceanic_atom2c_version[] = { diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 01225e7..63ac3f3 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -53,6 +53,7 @@ #define EPICB 0x4453 #define ATOM31 0x4456 #define A300AI 0x4457 +#define PROPLUS3 0x4548 typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t; @@ -276,7 +277,7 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns if (parser->model == DATAMASK || parser->model == COMPUMASK || parser->model == GEO || parser->model == GEO20 || parser->model == VEO20 || parser->model == VEO30 || - parser->model == OCS) { + parser->model == OCS || parser->model == PROPLUS3) { headersize -= PAGESIZE; } else if (parser->model == VT4 || parser->model == VT41) { headersize += PAGESIZE; @@ -370,7 +371,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ if (parser->model == DATAMASK || parser->model == COMPUMASK || parser->model == GEO || parser->model == GEO20 || parser->model == VEO20 || parser->model == VEO30 || - parser->model == OCS) { + parser->model == OCS || parser->model == PROPLUS3) { headersize -= PAGESIZE; } else if (parser->model == VT4 || parser->model == VT41) { headersize += PAGESIZE; @@ -523,7 +524,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ temperature = ((data[offset + 7] & 0xF0) >> 4) | ((data[offset + 7] & 0x0C) << 2) | ((data[offset + 5] & 0x0C) << 4); } else { unsigned int sign; - if (parser->model == DG03) + if (parser->model == DG03 || parser->model == PROPLUS3) sign = (~data[offset + 5] & 0x04) >> 2; else if (parser->model == ATOM2 || parser->model == PROPLUS21 || parser->model == EPICA || parser->model == EPICB) @@ -546,7 +547,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ else if (parser->model == VT4 || parser->model == VT41|| parser->model == ATOM3 || parser->model == ATOM31 || parser->model == ZENAIR ||parser->model == A300AI || - parser->model == DG03) + parser->model == DG03 || parser->model == PROPLUS3) pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5; else pressure -= data[offset + 1]; From a9b7edfde30872ca21ee046f7c21ce04a3e04b25 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 19 Mar 2013 21:59:40 +0100 Subject: [PATCH 07/21] Add support for the Mares Nemo Steel and Titanium. These two models are simply a variant of the normal Mares Nemo with a different material on the outside. --- src/descriptor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/descriptor.c b/src/descriptor.c index 176f4e9..0ca81c3 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -142,6 +142,8 @@ static const dc_descriptor_t g_descriptors[] = { {"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548}, /* Mares Nemo */ {"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0}, + {"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0}, + {"Mares", "Nemo Titanium",DC_FAMILY_MARES_NEMO, 0}, {"Mares", "Nemo Excel", DC_FAMILY_MARES_NEMO, 17}, {"Mares", "Nemo Apneist", DC_FAMILY_MARES_NEMO, 18}, /* Mares Puck */ From 13950c0ca1783c4a958f80c96c35678c9dd4a21f Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 24 Mar 2013 19:44:10 -0700 Subject: [PATCH 08/21] Fix time conversion for Shearwater computers The time read from the Shearwater is already in localtime. Signed-off-by: Dirk Hohndel --- src/shearwater_predator_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index c0c6cec..6588584 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -122,7 +122,7 @@ shearwater_predator_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *d unsigned int ticks = array_uint32_be (data + 12); - if (!dc_datetime_localtime (datetime, ticks)) + if (!dc_datetime_gmtime (datetime, ticks)) return DC_STATUS_DATAFORMAT; return DC_STATUS_SUCCESS; From 7529ab8d5b7ce78598babb928c2e33d3819f4641 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 12 Mar 2013 22:25:30 +0100 Subject: [PATCH 09/21] Add additional descriptors for Uwatec devices. --- src/descriptor.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 0ca81c3..3d06e40 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -73,18 +73,30 @@ static const dc_descriptor_t g_descriptors[] = { {"Suunto", "D6i", DC_FAMILY_SUUNTO_D9, 0x1A}, {"Suunto", "D9tx", DC_FAMILY_SUUNTO_D9, 0x1B}, /* Uwatec Aladin */ - {"Uwatec", "Aladin", DC_FAMILY_UWATEC_ALADIN, 0}, + {"Uwatec", "Aladin Air Twin", DC_FAMILY_UWATEC_ALADIN, 0x1C}, + {"Uwatec", "Aladin Sport Plus", DC_FAMILY_UWATEC_ALADIN, 0x3E}, + {"Uwatec", "Aladin Pro", DC_FAMILY_UWATEC_ALADIN, 0x3F}, + {"Uwatec", "Aladin Air Z", DC_FAMILY_UWATEC_ALADIN, 0x44}, + {"Uwatec", "Aladin Air Z O2", DC_FAMILY_UWATEC_ALADIN, 0xA4}, + {"Uwatec", "Aladin Air Z Nitrox", DC_FAMILY_UWATEC_ALADIN, 0xF4}, + {"Uwatec", "Aladin Pro Ultra", DC_FAMILY_UWATEC_ALADIN, 0xFF}, /* Uwatec Memomouse */ {"Uwatec", "Memomouse", DC_FAMILY_UWATEC_MEMOMOUSE, 0}, /* Uwatec Smart */ {"Uwatec", "Smart Pro", DC_FAMILY_UWATEC_SMART, 0x10}, - {"Uwatec", "Galileo", DC_FAMILY_UWATEC_SMART, 0x11}, + {"Uwatec", "Galileo Sol", DC_FAMILY_UWATEC_SMART, 0x11}, + {"Uwatec", "Galileo Luna", DC_FAMILY_UWATEC_SMART, 0x11}, + {"Uwatec", "Galileo Terra", DC_FAMILY_UWATEC_SMART, 0x11}, {"Uwatec", "Aladin Tec", DC_FAMILY_UWATEC_SMART, 0x12}, + {"Uwatec", "Aladin Prime", DC_FAMILY_UWATEC_SMART, 0x12}, {"Uwatec", "Aladin Tec 2G", DC_FAMILY_UWATEC_SMART, 0x13}, + {"Uwatec", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x13}, + {"Subgear","XP-10", DC_FAMILY_UWATEC_SMART, 0x13}, {"Uwatec", "Smart Com", DC_FAMILY_UWATEC_SMART, 0x14}, {"Uwatec", "Smart Tec", DC_FAMILY_UWATEC_SMART, 0x18}, {"Uwatec", "Galileo Trimix",DC_FAMILY_UWATEC_SMART, 0x19}, {"Uwatec", "Smart Z", DC_FAMILY_UWATEC_SMART, 0x1C}, + {"Subgear","XP Air", DC_FAMILY_UWATEC_SMART, 0x1C}, /* Reefnet */ {"Reefnet", "Sensus", DC_FAMILY_REEFNET_SENSUS, 1}, {"Reefnet", "Sensus Pro", DC_FAMILY_REEFNET_SENSUSPRO, 2}, From c7cc955b29c3f7a8627a9f8940f733c8ea23eee1 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 20 Apr 2013 07:45:09 +0200 Subject: [PATCH 10/21] Use symbolic constants for the model numbers. --- src/oceanic_veo250_parser.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/oceanic_veo250_parser.c b/src/oceanic_veo250_parser.c index 910c393..bddcadd 100644 --- a/src/oceanic_veo250_parser.c +++ b/src/oceanic_veo250_parser.c @@ -29,6 +29,9 @@ #include "parser-private.h" #include "array.h" +#define VEO200 0x424B +#define VEO250 0x424C + typedef struct oceanic_veo250_parser_t oceanic_veo250_parser_t; struct oceanic_veo250_parser_t { @@ -142,7 +145,7 @@ oceanic_veo250_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dateti datetime->minute = p[2]; datetime->second = 0; - if (parser->model == 0x424B || parser->model == 0x424C) + if (parser->model == VEO200 || parser->model == VEO250) datetime->year += 3; } From 8a0efe2bfb0bd32a6ea38a4c9a6373f3fb287f3a Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 20 Apr 2013 07:48:10 +0200 Subject: [PATCH 11/21] Fix the sample rate for the Genesis React Pro. This model doesn't support a 2 second sample rate. It appears the possible sample rate values have been shifted by one to map the value zero to a 15 second sample rate. To avoid any trouble with possible out of range values, the index is shifted in a circular way. --- src/oceanic_veo250_parser.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/oceanic_veo250_parser.c b/src/oceanic_veo250_parser.c index bddcadd..8792a31 100644 --- a/src/oceanic_veo250_parser.c +++ b/src/oceanic_veo250_parser.c @@ -29,6 +29,7 @@ #include "parser-private.h" #include "array.h" +#define REACTPRO 0x4247 #define VEO200 0x424B #define VEO250 0x424C @@ -211,6 +212,8 @@ oceanic_veo250_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un static dc_status_t oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata) { + oceanic_veo250_parser_t *parser = (oceanic_veo250_parser_t *) abstract; + if (! parser_is_oceanic_veo250 (abstract)) return DC_STATUS_INVALIDARGS; @@ -222,7 +225,12 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback unsigned int time = 0; unsigned int interval = 0; - switch (data[0x27] & 0x03) { + unsigned int interval_idx = data[0x27] & 0x03; + if (parser->model == REACTPRO) { + interval_idx += 1; + interval_idx %= 4; + } + switch (interval_idx) { case 0: interval = 2; break; From b185c1f62a02a39fb16674ab2a4f4a8bfb2c220b Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 20 Apr 2013 08:09:55 +0200 Subject: [PATCH 12/21] Fix the temperature and year for the Genesis React Pro. --- src/oceanic_veo250_parser.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/oceanic_veo250_parser.c b/src/oceanic_veo250_parser.c index 8792a31..77d1370 100644 --- a/src/oceanic_veo250_parser.c +++ b/src/oceanic_veo250_parser.c @@ -148,6 +148,8 @@ oceanic_veo250_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dateti if (parser->model == VEO200 || parser->model == VEO250) datetime->year += 3; + else if (parser->model == REACTPRO) + datetime->year += 2; } return DC_STATUS_SUCCESS; @@ -272,7 +274,12 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata); // Temperature (°F) - unsigned int temperature = data[offset + 7]; + unsigned int temperature; + if (parser->model == REACTPRO) { + temperature = data[offset + 6]; + } else { + temperature = data[offset + 7]; + } sample.temperature = (temperature - 32.0) * (5.0 / 9.0); if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata); From f46e650a631f48b8909026768084772c4ceffd40 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 22 Apr 2013 06:57:07 +0200 Subject: [PATCH 13/21] Add support for the Genesis React Pro White The React Pro White appears to be a newer variant of the React Pro. For the communication it uses the newer atom2 protocol, but the data format remains (almost) the same as the older React Pro. --- src/descriptor.c | 1 + src/oceanic_atom2.c | 18 ++++++++++++++++++ src/oceanic_veo250_parser.c | 5 +++-- src/parser.c | 7 ++++++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 3d06e40..2061408 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -131,6 +131,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x434E}, {"Sherwood", "Wisdom 2", DC_FAMILY_OCEANIC_ATOM2, 0x4350}, {"Sherwood", "Insight 2", DC_FAMILY_OCEANIC_ATOM2, 0x4353}, + {"Genesis", "React Pro White", DC_FAMILY_OCEANIC_ATOM2, 0x4354}, {"Tusa", "Element II (IQ-750)", DC_FAMILY_OCEANIC_ATOM2, 0x4357}, {"Oceanic", "Veo 1.0", DC_FAMILY_OCEANIC_ATOM2, 0x4358}, {"Oceanic", "Veo 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4359}, diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 41bb94a..21f7954 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -123,6 +123,10 @@ static const oceanic_common_version_t oceanic_veo1_version[] = { {"OCEVEO10 \0\0 8K"}, }; +static const oceanic_common_version_t oceanic_reactpro_version[] = { + {"REACPRO2 \0\0 512K"}, +}; + static const oceanic_common_layout_t aeris_f10_layout = { 0x10000, /* memsize */ 0x0000, /* cf_devinfo */ @@ -240,6 +244,18 @@ static const oceanic_common_layout_t oceanic_veo1_layout = { 0 /* pt_mode_logbook */ }; +static const oceanic_common_layout_t oceanic_reactpro_layout = { + 0xFFF0, /* memsize */ + 0x0000, /* cf_devinfo */ + 0x0040, /* cf_pointers */ + 0x0400, /* rb_logbook_begin */ + 0x0600, /* rb_logbook_end */ + 8, /* rb_logbook_entry_size */ + 0x0600, /* rb_profile_begin */ + 0xFFF0, /* rb_profile_end */ + 1, /* pt_mode_global */ + 1 /* pt_mode_logbook */ +}; static int device_is_oceanic_atom2 (dc_device_t *abstract) @@ -427,6 +443,8 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char device->base.layout = &oceanic_oc1_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_veo1_version)) { device->base.layout = &oceanic_veo1_layout; + } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_reactpro_version)) { + device->base.layout = &oceanic_reactpro_layout; } else { device->base.layout = &oceanic_default_layout; } diff --git a/src/oceanic_veo250_parser.c b/src/oceanic_veo250_parser.c index 77d1370..a5c19b9 100644 --- a/src/oceanic_veo250_parser.c +++ b/src/oceanic_veo250_parser.c @@ -32,6 +32,7 @@ #define REACTPRO 0x4247 #define VEO200 0x424B #define VEO250 0x424C +#define REACTPROWHITE 0x4354 typedef struct oceanic_veo250_parser_t oceanic_veo250_parser_t; @@ -228,7 +229,7 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback unsigned int time = 0; unsigned int interval = 0; unsigned int interval_idx = data[0x27] & 0x03; - if (parser->model == REACTPRO) { + if (parser->model == REACTPRO || parser->model == REACTPROWHITE) { interval_idx += 1; interval_idx %= 4; } @@ -275,7 +276,7 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback // Temperature (°F) unsigned int temperature; - if (parser->model == REACTPRO) { + if (parser->model == REACTPRO || parser->model == REACTPROWHITE) { temperature = data[offset + 6]; } else { temperature = data[offset + 7]; diff --git a/src/parser.c b/src/parser.c index 310d13a..2c6c6ac 100644 --- a/src/parser.c +++ b/src/parser.c @@ -35,6 +35,8 @@ #include "parser-private.h" #include "device-private.h" +#define REACTPROWHITE 0x4354 + dc_status_t dc_parser_new (dc_parser_t **out, dc_device_t *device) { @@ -86,7 +88,10 @@ dc_parser_new (dc_parser_t **out, dc_device_t *device) rc = oceanic_veo250_parser_create (&parser, context, device->devinfo.model); break; case DC_FAMILY_OCEANIC_ATOM2: - rc = oceanic_atom2_parser_create (&parser, context, device->devinfo.model); + if (device->devinfo.model == REACTPROWHITE) + rc = oceanic_veo250_parser_create (&parser, context, device->devinfo.model); + else + rc = oceanic_atom2_parser_create (&parser, context, device->devinfo.model); break; case DC_FAMILY_MARES_NEMO: case DC_FAMILY_MARES_PUCK: From 20f813d5bc6a5d06c9407dc96c3cbc17e0d6af56 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 23 Apr 2013 17:12:59 +0200 Subject: [PATCH 14/21] Fix a potential NULL pointer dereference. --- src/cressi_leonardo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cressi_leonardo.c b/src/cressi_leonardo.c index c22fb85..f75d4bb 100644 --- a/src/cressi_leonardo.c +++ b/src/cressi_leonardo.c @@ -335,7 +335,7 @@ cressi_leonardo_extract_dives (dc_device_t *abstract, const unsigned char data[] if (header < RB_PROFILE_BEGIN || header + 2 > RB_PROFILE_END || footer < RB_PROFILE_BEGIN || footer + 2 > RB_PROFILE_END) { - ERROR (abstract->context, "Invalid ringbuffer pointer detected."); + ERROR (context, "Invalid ringbuffer pointer detected."); free (buffer); return DC_STATUS_DATAFORMAT; } @@ -344,7 +344,7 @@ cressi_leonardo_extract_dives (dc_device_t *abstract, const unsigned char data[] unsigned int header2 = array_uint16_le (data + footer); unsigned int footer2 = array_uint16_le (data + header); if (header2 != header || footer2 != footer) { - ERROR (abstract->context, "Invalid ringbuffer pointer detected."); + ERROR (context, "Invalid ringbuffer pointer detected."); free (buffer); return DC_STATUS_DATAFORMAT; } From 9297e390a8999897335ec7dea090262059936a28 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 29 Apr 2013 20:47:26 +0200 Subject: [PATCH 15/21] Flush the serial buffers after opening the port. Sometimes there are garbage bytes present after opening the serial port, which causes the communication to fail. Flushing the buffers after a small delay is all it takes to get rid of those bytes. --- src/cressi_leonardo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cressi_leonardo.c b/src/cressi_leonardo.c index f75d4bb..4411254 100644 --- a/src/cressi_leonardo.c +++ b/src/cressi_leonardo.c @@ -131,6 +131,9 @@ cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const cha return DC_STATUS_IO; } + serial_sleep (device->port, 100); + serial_flush (device->port, SERIAL_QUEUE_BOTH); + *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; From c429947f254a071a3855f3f4c57553dcb8ecc008 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 29 Apr 2013 20:56:52 +0200 Subject: [PATCH 16/21] Add a devinfo event containing the serial number. --- src/cressi_leonardo.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cressi_leonardo.c b/src/cressi_leonardo.c index 4411254..73d478a 100644 --- a/src/cressi_leonardo.c +++ b/src/cressi_leonardo.c @@ -278,6 +278,13 @@ cressi_leonardo_device_foreach (dc_device_t *abstract, dc_dive_callback_t callba return rc; } + unsigned char *data = dc_buffer_get_data (buffer); + dc_event_devinfo_t devinfo; + devinfo.model = 0; + devinfo.firmware = 0; + devinfo.serial = array_uint32_le (data + 1); + device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo); + rc = cressi_leonardo_extract_dives (abstract, dc_buffer_get_data (buffer), dc_buffer_get_size (buffer), callback, userdata); From 3ce237eee40910bedda86bb677a12ff97b6102ab Mon Sep 17 00:00:00 2001 From: Olivier Bussier Date: Wed, 1 May 2013 22:54:34 +0200 Subject: [PATCH 17/21] Fix the parsing of the gas mixes. If the gas model flag is set to air, the individual gas mix definitions are ignored, and a single mix with air is returned instead. For non-air dives, only the gas mixes marked as active are returned. --- src/mares_iconhd_parser.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 5ab70ca..b2500cb 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -163,6 +163,8 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi dc_gasmix_t *gasmix = (dc_gasmix_t *) value; + unsigned int air = (p[0] & 0x02) == 0; + if (value) { switch (type) { case DC_FIELD_DIVETIME: @@ -172,11 +174,27 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi *((double *) value) = array_uint16_le (p + 0x04) / 10.0; break; case DC_FIELD_GASMIX_COUNT: - *((unsigned int *) value) = 3; + if (air) { + *((unsigned int *) value) = 1; + } else { + // Count the number of active gas mixes. The active gas + // mixes are always first, so we stop counting as soon + // as the first gas marked as disabled is found. + unsigned int i = 0; + while (i < 3) { + if (p[0x14 + i * 4 + 1] & 0x80) + break; + i++; + } + *((unsigned int *) value) = i; + } break; case DC_FIELD_GASMIX: + if (air) + gasmix->oxygen = 0.21; + else + gasmix->oxygen = p[0x14 + flags * 4] / 100.0; gasmix->helium = 0.0; - gasmix->oxygen = p[0x14 + flags * 4] / 100.0; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; default: From 8f3eb48bfb5e74d278a551745dcb43a4cb4d5be3 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 18 Apr 2013 08:11:51 +0200 Subject: [PATCH 18/21] Prevent an infinite loop. When the number of parameters is zero, there are no sample values, and the offset variable is never increased. The result is an infinite loop. In practice this shouldn't happen because there should always be at least one sample value (e.g. depth). But if a new data format is available, which is not yet supported by the parser, we might be trying to interpret the wrong byte. --- src/suunto_d9_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c index 1334a3b..24de752 100644 --- a/src/suunto_d9_parser.c +++ b/src/suunto_d9_parser.c @@ -314,7 +314,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca // Number of parameters in the configuration data. unsigned int nparams = data[config]; - if (nparams > MAXPARAMS) + if (nparams == 0 || nparams > MAXPARAMS) return DC_STATUS_DATAFORMAT; // Available divisor values. From c195404920b32f177c8c2199b628bf71d22e9f97 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 18 Apr 2013 08:19:05 +0200 Subject: [PATCH 19/21] Add support for the Suunto DX. The Suunto DX has support for 8 gas mixes (OC) and 3 diluents (CC). Because it's still unknown how rebreather dives are stored, we simply return all 11 gas mixes. For the rest, the DX data format is very similar to that of the existing Suunto models, with only a few different offsets here and there. --- src/descriptor.c | 1 + src/suunto_d9.c | 14 +++++++++++++- src/suunto_d9_parser.c | 28 ++++++++++++++++++++++------ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 2061408..e45a286 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -72,6 +72,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Suunto", "D4i", DC_FAMILY_SUUNTO_D9, 0x19}, {"Suunto", "D6i", DC_FAMILY_SUUNTO_D9, 0x1A}, {"Suunto", "D9tx", DC_FAMILY_SUUNTO_D9, 0x1B}, + {"Suunto", "DX", DC_FAMILY_SUUNTO_D9, 0x1C}, /* Uwatec Aladin */ {"Uwatec", "Aladin Air Twin", DC_FAMILY_UWATEC_ALADIN, 0x1C}, {"Uwatec", "Aladin Sport Plus", DC_FAMILY_UWATEC_ALADIN, 0x3E}, diff --git a/src/suunto_d9.c b/src/suunto_d9.c index 259cbe9..cdd2961 100644 --- a/src/suunto_d9.c +++ b/src/suunto_d9.c @@ -41,6 +41,7 @@ #define D4i 0x19 #define D6i 0x1A #define D9tx 0x1B +#define DX 0x1C typedef struct suunto_d9_device_t { suunto_common2_device_t base; @@ -79,6 +80,15 @@ static const suunto_common2_layout_t suunto_d9tx_layout = { 0xEBF0 /* rb_profile_end */ }; +static const suunto_common2_layout_t suunto_dx_layout = { + 0x10000, /* memsize */ + 0x0017, /* fingerprint */ + 0x0024, /* serial */ + 0x019A, /* rb_profile_begin */ + 0xEBF0 /* rb_profile_end */ +}; + + static int device_is_suunto_d9 (dc_device_t *abstract) { @@ -100,7 +110,7 @@ suunto_d9_device_autodetect (suunto_d9_device_t *device, unsigned int model) // Use the model number as a hint to speedup the detection. unsigned int hint = 0; - if (model == D4i || model == D6i || model == D9tx) + if (model == D4i || model == D6i || model == D9tx || model == DX) hint = 1; for (unsigned int i = 0; i < C_ARRAY_SIZE(baudrates); ++i) { @@ -195,6 +205,8 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam model = device->base.version[0]; if (model == D4i || model == D6i || model == D9tx) device->base.layout = &suunto_d9tx_layout; + else if (model == DX) + device->base.layout = &suunto_dx_layout; else device->base.layout = &suunto_d9_layout; diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c index 24de752..d9d1ed2 100644 --- a/src/suunto_d9_parser.c +++ b/src/suunto_d9_parser.c @@ -41,6 +41,7 @@ #define D4i 0x19 #define D6i 0x1A #define D9tx 0x1B +#define DX 0x1C #define AIR 0 #define NITROX 1 @@ -146,7 +147,7 @@ suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime) suunto_d9_parser_t *parser = (suunto_d9_parser_t*) abstract; unsigned int offset = 0x11; - if (parser->model == HELO2) + if (parser->model == HELO2 || parser->model == DX) offset = 0x17; else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) offset = 0x13; @@ -157,7 +158,8 @@ suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime) const unsigned char *p = abstract->data + offset; if (datetime) { - if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) { + if (parser->model == D4i || parser->model == D6i || + parser->model == D9tx || parser->model == DX) { datetime->year = p[0] + (p[1] << 8); datetime->month = p[2]; datetime->day = p[3]; @@ -203,6 +205,9 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne } else if (parser->model == D9tx) { gasmix_offset = 0x87; gasmix_count = 8; + } else if (parser->model == DX) { + gasmix_offset = 0xC1; + gasmix_count = 11; } // Offset to the configuration data. @@ -210,7 +215,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne if (parser->model == D4) { config += 1; } else if (parser->model == HELO2 || parser->model == D4i || - parser->model == D6i || parser->model == D9tx) { + parser->model == D6i || parser->model == D9tx || + parser->model == DX) { config = gasmix_offset + gasmix_count * 6; } if (config + 1 > size) @@ -222,6 +228,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne gasmodel_offset = 0x1F; else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) gasmodel_offset = 0x1D; + else if (parser->model == DX) + gasmodel_offset = 0x21; unsigned int gasmodel = data[gasmodel_offset]; dc_gasmix_t *gasmix = (dc_gasmix_t *) value; @@ -231,7 +239,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne case DC_FIELD_DIVETIME: if (parser->model == D4) *((unsigned int *) value) = array_uint16_le (data + 0x0B); - else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) + else if (parser->model == D4i || parser->model == D6i || + parser->model == D9tx || parser->model == DX) *((unsigned int *) value) = array_uint16_le (data + 0x0D); else if (parser->model == HELO2) *((unsigned int *) value) = array_uint16_le (data + 0x0D) * 60; @@ -253,7 +262,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne gasmix->helium = 0.0; gasmix->oxygen = 0.21; } else if (parser->model == HELO2 || parser->model == D4i || - parser->model == D6i || parser->model == D9tx) { + parser->model == D6i || parser->model == D9tx || + parser->model == DX) { gasmix->helium = data[gasmix_offset + 6 * flags + 2] / 100.0; gasmix->oxygen = data[gasmix_offset + 6 * flags + 1] / 100.0; } else { @@ -299,6 +309,9 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca } else if (parser->model == D9tx) { gasmix_offset = 0x87; gasmix_count = 8; + } else if (parser->model == DX) { + gasmix_offset = 0xC1; + gasmix_count = 11; } // Offset to the configuration data. @@ -306,7 +319,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca if (parser->model == D4) { config += 1; } else if (parser->model == HELO2 || parser->model == D4i || - parser->model == D6i || parser->model == D9tx) { + parser->model == D6i || parser->model == D9tx || + parser->model == DX) { config = gasmix_offset + gasmix_count * 6; } if (config + 1 > size) @@ -357,6 +371,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca if (parser->model == HELO2 || parser->model == D4i || parser->model == D6i || parser->model == D9tx) interval_sample_offset = 0x1E; + else if (parser->model == DX) + interval_sample_offset = 0x22; unsigned int interval_sample = data[interval_sample_offset]; if (interval_sample == 0) return DC_STATUS_DATAFORMAT; From 1572a91f62befffaa1f1af83966ca02eba8bc149 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 9 May 2013 12:59:15 +0200 Subject: [PATCH 20/21] Add support for yet another Oceanic OC1 variant. The only difference with the two other Oceanic OC1 variants is the new model number. I have absolutely no idea what's the purpose of such a silly change. --- src/descriptor.c | 1 + src/oceanic_atom2_parser.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index e45a286..a1d3432 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -147,6 +147,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Oceanic", "Atom 3.0", DC_FAMILY_OCEANIC_ATOM2, 0x444C}, {"Hollis", "DG03", DC_FAMILY_OCEANIC_ATOM2, 0x444D}, {"Oceanic", "OCS", DC_FAMILY_OCEANIC_ATOM2, 0x4450}, + {"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x4451}, {"Oceanic", "VT 4.1", DC_FAMILY_OCEANIC_ATOM2, 0x4452}, {"Aeris", "Epic", DC_FAMILY_OCEANIC_ATOM2, 0x4453}, {"Aeris", "Elite T3", DC_FAMILY_OCEANIC_ATOM2, 0x4455}, diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 63ac3f3..af18c66 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -49,6 +49,7 @@ #define ATOM3 0x444C #define DG03 0x444D #define OCS 0x4450 +#define OC1C 0x4451 #define VT41 0x4452 #define EPICB 0x4453 #define ATOM31 0x4456 @@ -171,6 +172,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim switch (parser->model) { case OC1A: case OC1B: + case OC1C: case OCS: case VT4: case VT41: @@ -408,7 +410,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ } unsigned int samplesize = PAGESIZE / 2; - if (parser->model == OC1A || parser->model == OC1B) + if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C) samplesize = PAGESIZE; else if (parser->model == F10) samplesize = 2; @@ -516,7 +518,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ temperature = data[offset + 6]; } else if (parser->model == GEO20 || parser->model == VEO20 || parser->model == VEO30 || parser->model == OC1A || - parser->model == OC1B) { + parser->model == OC1B || parser->model == OC1C) { temperature = data[offset + 3]; } else if (parser->model == OCS) { temperature = data[offset + 1]; @@ -542,7 +544,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ // Tank Pressure (psi) if (have_pressure) { - if (parser->model == OC1A || parser->model == OC1B) + if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C) pressure = (data[offset + 10] + (data[offset + 11] << 8)) & 0x0FFF; else if (parser->model == VT4 || parser->model == VT41|| parser->model == ATOM3 || parser->model == ATOM31 || @@ -560,7 +562,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ unsigned int depth; if (parser->model == GEO20 || parser->model == VEO20 || parser->model == VEO30 || parser->model == OC1A || - parser->model == OC1B) + parser->model == OC1B || parser->model == OC1C) depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF; else if (parser->model == ATOM1) depth = data[offset + 3] * 16; From 1a3c919a8255cc35d05d3345a4e8531c38a583ca Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 11 May 2013 23:00:32 +0200 Subject: [PATCH 21/21] Fix temperature and tank pressure for the Tusa Element II. The Tusa Element II is a non air integrated model, and the temperature is stored at a different location. --- src/oceanic_atom2_parser.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index af18c66..6821a07 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -39,6 +39,7 @@ #define COMPUMASK 0x4348 #define OC1A 0x434E #define F10 0x434D +#define ELEMENT2 0x4357 #define VEO20 0x4359 #define VEO30 0x435A #define ZENAIR 0x4442 @@ -416,7 +417,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ samplesize = 2; unsigned int have_temperature = 1, have_pressure = 1; - if (parser->model == VEO30 || parser->model == OCS) { + if (parser->model == VEO30 || parser->model == OCS || + parser->model == ELEMENT2) { have_pressure = 0; } else if (parser->model == F10) { have_temperature = 0; @@ -514,7 +516,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ } else { // Temperature (°F) if (have_temperature) { - if (parser->model == GEO || parser->model == ATOM1) { + if (parser->model == GEO || parser->model == ATOM1 || + parser->model == ELEMENT2) { temperature = data[offset + 6]; } else if (parser->model == GEO20 || parser->model == VEO20 || parser->model == VEO30 || parser->model == OC1A ||