From d8bc4910b79cd4113fedcb2ee507d17bfa184601 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 16 May 2013 19:39:24 +0200 Subject: [PATCH 01/30] Post release version bump to 0.4.1. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index eac2682..3e183f7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # Versioning. m4_define([dc_version_major],[0]) m4_define([dc_version_minor],[4]) -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 890f5f0b5beee1839c83200675b9519e19f72456 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 16 May 2013 20:16:03 +0200 Subject: [PATCH 02/30] Fix the temperature for the Aeris Atmos AI 2. The temperature sign bit is reversed for this model. --- src/oceanic_atom2_parser.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index de5e116..f579619 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -45,6 +45,7 @@ #define VEO20 0x4359 #define VEO30 0x435A #define ZENAIR 0x4442 +#define ATMOSAI2 0x4443 #define PROPLUS21 0x4444 #define GEO20 0x4446 #define VT4 0x4447 @@ -515,7 +516,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ 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) + parser->model == EPICA || parser->model == EPICB || + parser->model == ATMOSAI2) sign = (data[offset + 0] & 0x80) >> 7; else sign = (~data[offset + 0] & 0x80) >> 7; From d7c59dff58a91096a34bbd7e31d17ab935d55fbb Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 25 May 2013 21:50:16 +0200 Subject: [PATCH 03/30] Adjust the length based on the firmware version. The OSTC 3 dataformat does contain the profile length twice: once in the main 256 byte header, and again in the small profile header. However due to a firmware bug, both values are not identical. The value in the main header is wrong and 3 bytes larger than the value in the small profile header. This bug was fixed in firmware version 0.93. Unfortunately we rely on the length in the main header to calculate the number of bytes to read when downloading the dive. The consequence is that for all dives recorded with firmware 0.93 or later, the length is calculated incorrectly, and the download fails. Luckily the firmware version is stored in the main header too, and we can adjust the length calculation accordingly. --- src/hw_ostc3.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index 3b19c03..f0067f4 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -392,8 +392,13 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi unsigned int idx = (latest + RB_LOGBOOK_COUNT - i) % RB_LOGBOOK_COUNT; unsigned int offset = idx * RB_LOGBOOK_SIZE; + // Get the firmware version. + unsigned int firmware = array_uint16_be (header + offset + 0x30); + // Calculate the profile length. unsigned int length = RB_LOGBOOK_SIZE + array_uint24_le (header + offset + 9) - 6; + if (firmware >= 93) + length += 3; // Check the fingerprint data. if (memcmp (header + offset + 12, device->fingerprint, sizeof (device->fingerprint)) == 0) @@ -428,8 +433,13 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi unsigned int idx = (latest + RB_LOGBOOK_COUNT - i) % RB_LOGBOOK_COUNT; unsigned int offset = idx * RB_LOGBOOK_SIZE; + // Get the firmware version. + unsigned int firmware = array_uint16_be (header + offset + 0x30); + // Calculate the profile length. unsigned int length = RB_LOGBOOK_SIZE + array_uint24_le (header + offset + 9) - 6; + if (firmware >= 93) + length += 3; // Download the dive. unsigned char number[1] = {idx}; From 6ad8d61253fa4e69e032df8367befe48b83ad9aa Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 15 Jun 2013 07:58:59 +0200 Subject: [PATCH 04/30] Fix the date/time for the Oceanic Geo 2.0. --- src/oceanic_atom2_parser.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index f579619..34d5222 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -176,7 +176,6 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim case VT3: case VEO20: case VEO30: - case GEO20: case DG03: datetime->year = ((p[3] & 0xE0) >> 1) + (p[4] & 0x0F) + 2000; datetime->month = (p[4] & 0xF0) >> 4; @@ -202,7 +201,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim default: datetime->year = bcd2dec (((p[3] & 0xC0) >> 2) + (p[4] & 0x0F)) + 2000; datetime->month = (p[4] & 0xF0) >> 4; - if (parser->model == T3) + if (parser->model == T3 || parser->model == GEO20) datetime->day = p[3] & 0x3F; else datetime->day = bcd2dec (p[3] & 0x3F); From b1574848b2c3ffcf7f0a8080c853453f5750ce2c Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 17 Jun 2013 22:09:28 +0200 Subject: [PATCH 05/30] Interpret the 7th bit of the event byte correctly. In the OSTC3 data format, the 7th bit of the event byte is used to indicate whether another event byte is present or not. For the OSTC2, this 7th bit remained unused, and I assumed it would eventually get used in the same way as the OSTC3 does. But that assumption turns out to be wrong. Starting with firmware v2.66 the 7th bit is used for a new bailout event. This patch leaves the existing logic intact, but except for the OSTC3 format (version 0x23), the maximum number of events bytes is now limited to just one byte. --- src/hw_ostc_parser.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index 576afdf..73f7fc3 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -482,6 +482,8 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call unsigned int nbits = 0; unsigned int events = 0; while (data[offset - 1] & 0x80) { + if (nbits && version != 0x23) + break; if (offset + 1 > size) return DC_STATUS_DATAFORMAT; events |= data[offset] << nbits; From bed4d19acacdaba50a2c4d80f1c827aad0c406a9 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 18 Jun 2013 22:17:38 +0200 Subject: [PATCH 06/30] Add support for the new bailout event. The new bailout event is reported to the application as a normal gas change event. --- src/hw_ostc_parser.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index 73f7fc3..b007377 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -596,13 +596,27 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call } } - // SetPoint Change - if ((events & 0x40) && (version != 0x23)) { - if (offset + 1 > size) - return DC_STATUS_DATAFORMAT; - sample.setpoint = data[offset] / 100.0; - if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata); - offset++; + if (version != 0x23) { + // SetPoint Change + if (events & 0x40) { + if (offset + 1 > size) + return DC_STATUS_DATAFORMAT; + sample.setpoint = data[offset] / 100.0; + if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata); + offset++; + } + + // Bailout Event + if (events & 0x80) { + if (offset + 2 > size) + return DC_STATUS_DATAFORMAT; + sample.event.type = SAMPLE_EVENT_GASCHANGE2; + sample.event.time = 0; + sample.event.flags = 0; + sample.event.value = data[offset] | (data[offset + 1] << 16); + if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); + offset += 2; + } } } From 2d3e7078394f128d08b676e3d59e0f9f3e02963e Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 1 Jul 2013 21:35:38 +0200 Subject: [PATCH 07/30] Release version 0.4.1. --- NEWS | 13 +++++++++++++ configure.ac | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ec4d0ce..0748263 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,16 @@ +Version 0.4.1 (2013-07-01) +========================== + +The v0.4.1 release is a bugfix release. + +Bug fixes: + + * [ostc] Add support for the new bailout event. + * [ostc] Interpret the 7th bit of the event byte correctly. + * [atom2] Fix the date/time for the Oceanic Geo 2.0. + * [ostc3] Adjust the length based on the firmware version. + * [atom2] Fix the temperature for the Aeris Atmos AI 2. + Version 0.4.0 (2013-05-13) ========================== diff --git a/configure.ac b/configure.ac index 3e183f7..fd5cbd8 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([dc_version_major],[0]) m4_define([dc_version_minor],[4]) m4_define([dc_version_micro],[1]) -m4_define([dc_version_suffix],[devel]) +m4_define([dc_version_suffix],[]) m4_define([dc_version],dc_version_major.dc_version_minor.dc_version_micro[]m4_ifset([dc_version_suffix],-[dc_version_suffix])) # Libtool versioning. From b4250ef74db39262e79ba8daed6fa38c94941145 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 1 Jul 2013 21:44:05 +0200 Subject: [PATCH 08/30] Post release version bump to 0.4.2. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index fd5cbd8..dd08484 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # Versioning. m4_define([dc_version_major],[0]) m4_define([dc_version_minor],[4]) -m4_define([dc_version_micro],[1]) -m4_define([dc_version_suffix],[]) +m4_define([dc_version_micro],[2]) +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 5c16b28fb9437135f3d7f49c5b584cb220be3bbd Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 16 Jul 2013 08:46:49 +0200 Subject: [PATCH 09/30] Use only 12 bits for the temperature. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using all 16 bits for the temperature, the resulting values are clearly wrong in some cases. Most likely the upper 4 bits are used to store something else. Even with only 12 bits, the resulting temperature range (0-409.5°C) should still be more than sufficient. --- src/mares_iconhd_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 0c8668a..28c5c92 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -237,7 +237,7 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata); // Temperature (1/10 °C). - unsigned int temperature = array_uint16_le (data + offset + 2); + unsigned int temperature = array_uint16_le (data + offset + 2) & 0x0FFF; sample.temperature = temperature / 10.0; if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata); From 5f8da384e63536c418743d833d7f9f10c8b363db Mon Sep 17 00:00:00 2001 From: Michael Andreen Date: Mon, 5 Aug 2013 16:03:59 +0200 Subject: [PATCH 10/30] Identify event 0x07 on Suunto d9-style computers as Below Floor. This event is on when accumulating deco time. Once you reach the floor deco time will start decreasing and the event will stop. Going below the floor again will re-activate the event. Signed-off-by: Michael Andreen --- examples/universal.c | 2 +- include/libdivecomputer/parser.h | 5 ++++- src/suunto_d9_parser.c | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/universal.c b/examples/universal.c index 4eef0c5..48be0de 100644 --- a/examples/universal.c +++ b/examples/universal.c @@ -241,7 +241,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata) "none", "deco", "rbt", "ascent", "ceiling", "workload", "transmitter", "violation", "bookmark", "surface", "safety stop", "gaschange", "safety stop (voluntary)", "safety stop (mandatory)", "deepstop", - "ceiling (safety stop)", "unknown", "divetime", "maxdepth", + "ceiling (safety stop)", "floor", "divetime", "maxdepth", "OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning", "gaschange2"}; static const char *decostop[] = { diff --git a/include/libdivecomputer/parser.h b/include/libdivecomputer/parser.h index a92e653..16ca2b3 100644 --- a/include/libdivecomputer/parser.h +++ b/include/libdivecomputer/parser.h @@ -73,7 +73,7 @@ typedef enum parser_sample_event_t { SAMPLE_EVENT_SAFETYSTOP_MANDATORY, SAMPLE_EVENT_DEEPSTOP, SAMPLE_EVENT_CEILING_SAFETYSTOP, - SAMPLE_EVENT_UNKNOWN, + SAMPLE_EVENT_FLOOR, SAMPLE_EVENT_DIVETIME, SAMPLE_EVENT_MAXDEPTH, SAMPLE_EVENT_OLF, @@ -87,6 +87,9 @@ typedef enum parser_sample_event_t { respectively the low and high part. */ } parser_sample_event_t; +/* For backwards compatibility */ +#define SAMPLE_EVENT_UNKNOWN SAMPLE_EVENT_FLOOR + typedef enum parser_sample_flags_t { SAMPLE_FLAGS_NONE = 0, SAMPLE_FLAGS_BEGIN = (1 << 0), diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c index 11c7d0f..65e7e87 100644 --- a/src/suunto_d9_parser.c +++ b/src/suunto_d9_parser.c @@ -482,8 +482,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca case 0x06: // Mandatory Safety Stop Ceiling Error sample.event.type = SAMPLE_EVENT_CEILING_SAFETYSTOP; break; - case 0x07: // Unknown (Deco related) - sample.event.type = SAMPLE_EVENT_UNKNOWN; + case 0x07: // Below Deco Floor + sample.event.type = SAMPLE_EVENT_FLOOR; break; case 0x08: // Dive Time sample.event.type = SAMPLE_EVENT_DIVETIME; From 37cb54c37680489efdd902ccdaa63e8291765be5 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 11 Aug 2013 22:56:03 +0200 Subject: [PATCH 11/30] Add Mares Puck 2 dive computer This dive computer has the same enclosure as the Mares Puck, but the wire protocol is that of the Puck Pro. The original software identifies it as a "Mares Puck 2", and the handshake string also contains the sequence "PUCK 2", so this string is used to identify the device. --- src/descriptor.c | 1 + src/mares_iconhd.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 9190abc..1ffc408 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -183,6 +183,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Mares", "Icon HD Net Ready", DC_FAMILY_MARES_ICONHD , 0x15}, {"Mares", "Puck Pro", DC_FAMILY_MARES_ICONHD , 0x18}, {"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19}, + {"Mares", "Puck 2", DC_FAMILY_MARES_ICONHD , 0x1F}, /* Heinrichs Weikamp */ {"Heinrichs Weikamp", "OSTC", DC_FAMILY_HW_OSTC, 0}, {"Heinrichs Weikamp", "OSTC Mk2", DC_FAMILY_HW_OSTC, 1}, diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index af628ed..6a00e0d 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -48,6 +48,7 @@ #define ICONHDNET 0x15 #define PUCKPRO 0x18 #define NEMOWIDE2 0x19 +#define PUCK2 0x1F #define ACK 0xAA #define EOF 0xEA @@ -261,7 +262,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * device->port = NULL; memset (device->fingerprint, 0, sizeof (device->fingerprint)); memset (device->version, 0, sizeof (device->version)); - if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO) { + if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO || model == PUCK2) { device->layout = &mares_matrix_layout; device->packetsize = 64; } else { @@ -278,7 +279,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * } // Set the serial communication protocol (256000 8N1). - if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO) { + if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO || model == PUCK2) { rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_EVEN, 1, SERIAL_FLOWCONTROL_NONE); } else { rc = serial_configure (device->port, BAUDRATE, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); From 888b6ab03fd28d3d063569d1b77baf131e361eea Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 2 Sep 2013 20:25:29 +0200 Subject: [PATCH 12/30] Disable the cancellation callback during shutdown. Several backends require a shutdown command to be send before closing the connection. If such a command gets cancelled, that might result in an unclean shutdown. Backends where this is problematic can always ignore cancellation requests internally, but it's less error-prone (and much easier) to simply disable the cancellation callback for all backends, before closing the connection. --- src/device.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/device.c b/src/device.c index 0fa4e7e..2aa6289 100644 --- a/src/device.c +++ b/src/device.c @@ -315,6 +315,10 @@ dc_device_close (dc_device_t *device) if (device->vtable->close == NULL) return DC_STATUS_UNSUPPORTED; + // Disable the cancellation callback. + device->cancel_callback = NULL; + device->cancel_userdata = NULL; + return device->vtable->close (device); } From b35e07b71bfa3e3ff943a82f9629357c40c29270 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 2 Sep 2013 23:28:48 +0200 Subject: [PATCH 13/30] Add cancellation support to several backends. Some backends are technically capable of supporting cancellation, but still lacked the necessary code to enable it. --- src/cressi_edy.c | 3 +++ src/hw_frog.c | 3 +++ src/hw_ostc3.c | 3 +++ src/mares_iconhd.c | 3 +++ src/shearwater_common.c | 3 +++ src/zeagle_n2ition3.c | 3 +++ 6 files changed, 18 insertions(+) diff --git a/src/cressi_edy.c b/src/cressi_edy.c index 0de977a..d5c5482 100644 --- a/src/cressi_edy.c +++ b/src/cressi_edy.c @@ -83,6 +83,9 @@ cressi_edy_transfer (cressi_edy_device_t *device, const unsigned char command[], assert (asize >= csize); + if (device_is_cancelled (abstract)) + return DC_STATUS_CANCELLED; + // Flush the serial input buffer. int rc = serial_flush (device->port, SERIAL_QUEUE_INPUT); if (rc == -1) { diff --git a/src/hw_frog.c b/src/hw_frog.c index bda09b7..ec760ac 100644 --- a/src/hw_frog.c +++ b/src/hw_frog.c @@ -111,6 +111,9 @@ hw_frog_transfer (hw_frog_device_t *device, { dc_device_t *abstract = (dc_device_t *) device; + if (device_is_cancelled (abstract)) + return DC_STATUS_CANCELLED; + // Send the command. unsigned char command[1] = {cmd}; int n = serial_write (device->port, command, sizeof (command)); diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index f0067f4..1bcc73f 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -108,6 +108,9 @@ hw_ostc3_transfer (hw_ostc3_device_t *device, { dc_device_t *abstract = (dc_device_t *) device; + if (device_is_cancelled (abstract)) + return DC_STATUS_CANCELLED; + // Send the command. unsigned char command[1] = {cmd}; int n = serial_write (device->port, command, sizeof (command)); diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index 6a00e0d..0189d32 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -122,6 +122,9 @@ mares_iconhd_transfer (mares_iconhd_device_t *device, assert (csize >= 2); + if (device_is_cancelled (abstract)) + return DC_STATUS_CANCELLED; + // Send the command header to the dive computer. int n = serial_write (device->port, command, 2); if (n != 2) { diff --git a/src/shearwater_common.c b/src/shearwater_common.c index 8e4f493..e712312 100644 --- a/src/shearwater_common.c +++ b/src/shearwater_common.c @@ -266,6 +266,9 @@ shearwater_common_transfer (shearwater_common_device_t *device, const unsigned c if (isize > SZ_PACKET || osize > SZ_PACKET) return DC_STATUS_INVALIDARGS; + if (device_is_cancelled (abstract)) + return DC_STATUS_CANCELLED; + // Setup the request packet. packet[0] = 0xFF; packet[1] = 0x01; diff --git a/src/zeagle_n2ition3.c b/src/zeagle_n2ition3.c index 4d6db49..1e19d49 100644 --- a/src/zeagle_n2ition3.c +++ b/src/zeagle_n2ition3.c @@ -79,6 +79,9 @@ zeagle_n2ition3_packet (zeagle_n2ition3_device_t *device, const unsigned char co assert (asize >= csize + 5); + if (device_is_cancelled (abstract)) + return DC_STATUS_CANCELLED; + // Send the command to the device. int n = serial_write (device->port, command, csize); if (n != csize) { From 1331db75cb6d20b14b27f444599ee1bce25987c8 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 3 Sep 2013 22:01:12 +0200 Subject: [PATCH 14/30] Fix the memory layout for the Atom 3.x and VT4.x. The logbook ringbuffer appears to start at offset 0x400 instead of 0x240. Since these ringbuffer boundaries have to be taken taken into account only once the ringbuffer has been filled completely, this bug affects users with more than 200 dives only. Thus, no surprise it didn't get noticed earlier. --- src/oceanic_atom2.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index e58ae34..a2106b3 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -112,10 +112,13 @@ static const oceanic_common_version_t tusa_zenair_version[] = { static const oceanic_common_version_t oceanic_oc1_version[] = { {"OCWATCH R\0\0 1024"}, - {"OCEANVT4 \0\0 1024"}, {"OC1WATCH \0\0 1024"}, - {"OCEATOM3 \0\0 1024"}, {"OCSWATCH \0\0 1024"}, +}; + +static const oceanic_common_version_t oceanic_atom3_version[] = { + {"OCEANVT4 \0\0 1024"}, + {"OCEATOM3 \0\0 1024"}, {"OCEAVT41 \0\0 1024"}, {"ATOM31 \0\0 1024"}, {"AERISAIR \0\0 1024"}, @@ -233,6 +236,19 @@ static const oceanic_common_layout_t oceanic_oc1_layout = { 1 /* pt_mode_logbook */ }; +static const oceanic_common_layout_t oceanic_atom3_layout = { + 0x20000, /* memsize */ + 0x0000, /* cf_devinfo */ + 0x0040, /* cf_pointers */ + 0x0400, /* rb_logbook_begin */ + 0x0A40, /* rb_logbook_end */ + 8, /* rb_logbook_entry_size */ + 0x0A40, /* rb_profile_begin */ + 0x1FE00, /* rb_profile_end */ + 0, /* pt_mode_global */ + 1 /* pt_mode_logbook */ +}; + static const oceanic_common_layout_t oceanic_veo1_layout = { 0x0400, /* memsize */ 0x0000, /* cf_devinfo */ @@ -433,6 +449,8 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char device->base.layout = &tusa_zenair_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_oc1_version)) { device->base.layout = &oceanic_oc1_layout; + } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom3_version)) { + device->base.layout = &oceanic_atom3_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)) { From 1bfcb8c3c149cf50d9665341e7c20716dda5a5dd Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 5 Sep 2013 20:40:01 +0200 Subject: [PATCH 15/30] Mark the Oceanic Veo 2.0 as a non air integrated model. --- src/oceanic_atom2_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 34d5222..1cc7d4a 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -401,7 +401,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ unsigned int have_temperature = 1, have_pressure = 1; if (parser->model == VEO30 || parser->model == OCS || - parser->model == ELEMENT2) { + parser->model == ELEMENT2 || parser->model == VEO20) { have_pressure = 0; } else if (parser->model == F10) { have_temperature = 0; From 85fd0c524fa100af9022b1c082c1fd48fe19ee71 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Fri, 6 Sep 2013 22:24:47 +0200 Subject: [PATCH 16/30] Fix the memory layout descriptors. The profile ringbuffer appears to be slightly smaller than expected for some models. For the Mares Matrix (and all compatible devices) it ends earlier, while for the Icon HD Net Ready it starts later. This bug resulted in missing dives, because all remaining dives were getting dropped once a dive that crossed the ringbuffer boundary was reached. --- src/mares_iconhd.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index 0189d32..5e09ea3 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -90,10 +90,16 @@ static const mares_iconhd_layout_t mares_iconhd_layout = { 0x100000, /* rb_profile_end */ }; +static const mares_iconhd_layout_t mares_iconhdnet_layout = { + 0x100000, /* memsize */ + 0x00E000, /* rb_profile_begin */ + 0x100000, /* rb_profile_end */ +}; + static const mares_iconhd_layout_t mares_matrix_layout = { 0x40000, /* memsize */ 0x0A000, /* rb_profile_begin */ - 0x40000, /* rb_profile_end */ + 0x3E000, /* rb_profile_end */ }; static unsigned int @@ -268,6 +274,9 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO || model == PUCK2) { device->layout = &mares_matrix_layout; device->packetsize = 64; + } else if (model == ICONHDNET) { + device->layout = &mares_iconhdnet_layout; + device->packetsize = 0; } else { device->layout = &mares_iconhd_layout; device->packetsize = 0; From b96780ce75b9166375f670f072476ae3cf8c837d Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 14 Sep 2013 00:16:30 +0200 Subject: [PATCH 17/30] Add support for the Sherwood Amphos. --- src/descriptor.c | 1 + src/oceanic_atom2.c | 1 + src/oceanic_atom2_parser.c | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/descriptor.c b/src/descriptor.c index 1ffc408..8c0f38f 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -160,6 +160,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}, + {"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545}, {"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548}, /* Mares Nemo */ {"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0}, diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index a2106b3..845c4d3 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -108,6 +108,7 @@ static const oceanic_common_version_t oceanic_default_version[] = { static const oceanic_common_version_t tusa_zenair_version[] = { {"TUZENAIR \0\0 512K"}, + {"AMPHOSSW \0\0 512K"}, }; static const oceanic_common_version_t oceanic_oc1_version[] = { diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 1cc7d4a..ebd0a25 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -58,6 +58,7 @@ #define EPICB 0x4453 #define ATOM31 0x4456 #define A300AI 0x4457 +#define AMPHOS 0x4545 #define PROPLUS3 0x4548 typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t; @@ -184,6 +185,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim datetime->minute = bcd2dec (p[0]); break; case ZENAIR: + case AMPHOS: datetime->year = (p[3] & 0x0F) + 2000; datetime->month = (p[7] & 0xF0) >> 4; datetime->day = ((p[3] & 0x80) >> 3) + ((p[5] & 0xF0) >> 4); @@ -516,7 +518,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ sign = (~data[offset + 5] & 0x04) >> 2; else if (parser->model == ATOM2 || parser->model == PROPLUS21 || parser->model == EPICA || parser->model == EPICB || - parser->model == ATMOSAI2) + parser->model == ATMOSAI2 || parser->model == AMPHOS) sign = (data[offset + 0] & 0x80) >> 7; else sign = (~data[offset + 0] & 0x80) >> 7; From 043fc4166c91572e3b4c0458865de5ffc8f71992 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 8 Sep 2013 09:12:13 +0200 Subject: [PATCH 18/30] Add support for the Oceanic OCi. The new Oceanic OCi appears to be almost identical to the already supported Oceanic OC1. The most important change is the different location for the logbook ringbuffer. --- src/descriptor.c | 1 + src/oceanic_atom2.c | 19 +++++++++++++++++++ src/oceanic_atom2_parser.c | 14 ++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 8c0f38f..ce5379a 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -162,6 +162,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458}, {"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545}, {"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548}, + {"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B}, /* Mares Nemo */ {"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0}, {"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0}, diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 845c4d3..f31b130 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -117,6 +117,10 @@ static const oceanic_common_version_t oceanic_oc1_version[] = { {"OCSWATCH \0\0 1024"}, }; +static const oceanic_common_version_t oceanic_oci_version[] = { + {"OCEANOCI \0\0 1024"}, +}; + static const oceanic_common_version_t oceanic_atom3_version[] = { {"OCEANVT4 \0\0 1024"}, {"OCEATOM3 \0\0 1024"}, @@ -237,6 +241,19 @@ static const oceanic_common_layout_t oceanic_oc1_layout = { 1 /* pt_mode_logbook */ }; +static const oceanic_common_layout_t oceanic_oci_layout = { + 0x20000, /* memsize */ + 0x0000, /* cf_devinfo */ + 0x0040, /* cf_pointers */ + 0x10C0, /* rb_logbook_begin */ + 0x1400, /* rb_logbook_end */ + 8, /* rb_logbook_entry_size */ + 0x1400, /* rb_profile_begin */ + 0x1FE00, /* rb_profile_end */ + 0, /* pt_mode_global */ + 1 /* pt_mode_logbook */ +}; + static const oceanic_common_layout_t oceanic_atom3_layout = { 0x20000, /* memsize */ 0x0000, /* cf_devinfo */ @@ -450,6 +467,8 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char device->base.layout = &tusa_zenair_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_oc1_version)) { device->base.layout = &oceanic_oc1_layout; + } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_oci_version)) { + device->base.layout = &oceanic_oci_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom3_version)) { device->base.layout = &oceanic_atom3_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_veo1_version)) { diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index ebd0a25..a3cd39c 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -60,6 +60,7 @@ #define A300AI 0x4457 #define AMPHOS 0x4545 #define PROPLUS3 0x4548 +#define OCI 0x454B typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t; @@ -168,6 +169,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim case ATOM3: case ATOM31: case A300AI: + case OCI: datetime->year = ((p[5] & 0xE0) >> 5) + ((p[7] & 0xE0) >> 2) + 2000; datetime->month = (p[3] & 0x0F); datetime->day = ((p[0] & 0x80) >> 3) + ((p[3] & 0xF0) >> 4); @@ -396,7 +398,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ } unsigned int samplesize = PAGESIZE / 2; - if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C) + if (parser->model == OC1A || parser->model == OC1B || + parser->model == OC1C || parser->model == OCI) samplesize = PAGESIZE; else if (parser->model == F10) samplesize = 2; @@ -506,7 +509,8 @@ 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 == OC1C) { + parser->model == OC1B || parser->model == OC1C || + parser->model == OCI) { temperature = data[offset + 3]; } else if (parser->model == OCS) { temperature = data[offset + 1]; @@ -533,7 +537,8 @@ 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 || parser->model == OC1C) + if (parser->model == OC1A || parser->model == OC1B || + parser->model == OC1C || parser->model == OCI) pressure = (data[offset + 10] + (data[offset + 11] << 8)) & 0x0FFF; else if (parser->model == VT4 || parser->model == VT41|| parser->model == ATOM3 || parser->model == ATOM31 || @@ -551,7 +556,8 @@ 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 == OC1C) + parser->model == OC1B || parser->model == OC1C || + parser->model == OCI) depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF; else if (parser->model == ATOM1) depth = data[offset + 3] * 16; From 6f7495dd3ebeacca18c48506ceb9d94a2bcd3c73 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 17 Sep 2013 11:44:33 +0200 Subject: [PATCH 19/30] Add support for a new Uwatec Aladin 2G variant. This new variant has a different model number and has switched to the Uwatec Galileo data format. --- src/descriptor.c | 1 + src/uwatec_smart_parser.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/descriptor.c b/src/descriptor.c index ce5379a..2df5574 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -99,6 +99,7 @@ static const dc_descriptor_t g_descriptors[] = { {"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", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x15}, {"Uwatec", "Smart Tec", DC_FAMILY_UWATEC_SMART, 0x18}, {"Uwatec", "Galileo Trimix",DC_FAMILY_UWATEC_SMART, 0x19}, {"Uwatec", "Smart Z", DC_FAMILY_UWATEC_SMART, 0x1C}, diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index 60cbfa4..9fd9a44 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -39,6 +39,7 @@ #define ALADINTEC 0x12 #define ALADINTEC2G 0x13 #define SMARTCOM 0x14 +#define ALADIN2G 0x15 #define SMARTTEC 0x18 #define GALILEOTRIMIX 0x19 #define SMARTZ 0x1C @@ -206,6 +207,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi break; case GALILEO: case GALILEOTRIMIX: + case ALADIN2G: header = 152; if (data[43] & 0x80) { header = 0xB1; @@ -454,6 +456,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t break; case GALILEO: case GALILEOTRIMIX: + case ALADIN2G: header = 152; if (data[43] & 0x80) { header = 0xB1; @@ -519,7 +522,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t // Process the type bits in the bitstream. unsigned int id = 0; - if (parser->model == GALILEO || parser->model == GALILEOTRIMIX) { + if (parser->model == GALILEO || parser->model == GALILEOTRIMIX || parser->model == ALADIN2G) { // Uwatec Galileo id = uwatec_galileo_identify (data[offset]); } else { From 8e0355c354b4d5578be6b1980bc55668f4c317c4 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Fri, 20 Sep 2013 21:58:50 +0200 Subject: [PATCH 20/30] Buffer the slip packet before sending. On Mac OS X, sending the slip packet byte by byte results in an abysmal performance. The first byte takes up to 160ms to send, and each next byte approximately 250ms. The packet to request a data block is typically 7 bytes large, and therefore takes about 1660ms to send. Because a dive is transmitted as multiple smaller packets (typically 144 bytes without protocol overhead), downloading a single dive can easily take several seconds. However, when sending the entire slip packet at once, the time remains roughly identical to sending just the first byte. The result is that the time for sending a packet reduces significantly, proportional to the length of the packet. Under the hood, the slip packet is now internally buffered, and the buffer is send only when the entire packet is complete, or whenever the buffer gets full. But in practice, the buffer is large enough to always store an entire packet. In the original bug report, downloading 57 dives took about 40 minutes. After applying the patch, that time reduced to only 5 minutes! --- src/shearwater_common.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/shearwater_common.c b/src/shearwater_common.c index e712312..b809a3c 100644 --- a/src/shearwater_common.c +++ b/src/shearwater_common.c @@ -148,6 +148,8 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned const unsigned char end[] = {END}; const unsigned char esc_end[] = {ESC, ESC_END}; const unsigned char esc_esc[] = {ESC, ESC_ESC}; + unsigned char buffer[32]; + unsigned int nbytes = 0; #if 0 // Send an initial END character to flush out any data that may have @@ -179,15 +181,28 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned break; } - n = serial_write (device->port, seq, len); - if (n != len) { - return EXITCODE(n); + // Flush the buffer if necessary. + if (nbytes + len + sizeof(end) > sizeof(buffer)) { + n = serial_write (device->port, buffer, nbytes); + if (n != nbytes) { + return EXITCODE(n); + } + + nbytes = 0; } + + // Append the escaped character. + memcpy(buffer + nbytes, seq, len); + nbytes += len; } - // Send the END character to indicate the end of the packet. - n = serial_write (device->port, end, sizeof (end)); - if (n != sizeof (end)) { + // Append the END character to indicate the end of the packet. + memcpy(buffer + nbytes, end, sizeof(end)); + nbytes += sizeof(end); + + // Flush the buffer. + n = serial_write (device->port, buffer, nbytes); + if (n != nbytes) { return EXITCODE(n); } From 8edbceaa4d5b919b8a19db066a4bdef798eefd02 Mon Sep 17 00:00:00 2001 From: Patrick Valsecchi Date: Thu, 10 Oct 2013 13:11:17 +0200 Subject: [PATCH 21/30] Use the correct vtable for the Shearwater Petrel. That was an harmless copy&paste error. Signed-off-by: Patrick Valsecchi --- 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 43c44b5..320a00c 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -88,7 +88,7 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig // Initialize the base class. parser->petrel = petrel; if (petrel) { - parser_init (&parser->base, context, &shearwater_predator_parser_vtable); + parser_init (&parser->base, context, &shearwater_petrel_parser_vtable); } else { parser_init (&parser->base, context, &shearwater_predator_parser_vtable); } From 2af365cfb704932e5604cda416ef6da831617294 Mon Sep 17 00:00:00 2001 From: Tim Wootton Date: Fri, 11 Oct 2013 23:04:29 +0100 Subject: [PATCH 22/30] Adds support for DC_FIELD_ATMOSPHERIC to the iconhd parser Signed-off-by: Tim Wootton --- src/mares_iconhd_parser.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 28c5c92..9419f47 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -186,6 +186,9 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi gasmix->helium = 0.0; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; + case DC_FIELD_ATMOSPHERIC: + *((double *) value) = array_uint16_le (p + 0x26) / 8; + break; default: return DC_STATUS_UNSUPPORTED; } From 734533e4d1cc4dbd4f4e38cc6f33d2b4cef7c5c0 Mon Sep 17 00:00:00 2001 From: Tim Wootton Date: Tue, 15 Oct 2013 08:46:12 +0100 Subject: [PATCH 23/30] Fix units for atmospheric pressure for iconhd type Was returning mbar, should have been bar. Signed-off-by: Tim Wootton --- src/mares_iconhd_parser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 9419f47..0d48945 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -187,7 +187,8 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; case DC_FIELD_ATMOSPHERIC: - *((double *) value) = array_uint16_le (p + 0x26) / 8; + // Pressure (1/8 millibar) + *((double *) value) = array_uint16_le (p + 0x26) / 8000.0; break; default: return DC_STATUS_UNSUPPORTED; From 938839e694d18c20cff51a45fe0ddeccbb56e7b5 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Fri, 18 Oct 2013 20:10:28 +0200 Subject: [PATCH 24/30] Add support for the Scubapro XTender 5. The XTender 5 is identical to the other models in the Zeagle N2iTiON3 family, and can be added to the list of supported devices without any further changes. --- src/descriptor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/descriptor.c b/src/descriptor.c index 2df5574..2db5236 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -201,6 +201,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Zeagle", "N2iTiON3", DC_FAMILY_ZEAGLE_N2ITION3, 0}, {"Apeks", "Quantum X", DC_FAMILY_ZEAGLE_N2ITION3, 0}, {"DiveRite", "NiTek Trio", DC_FAMILY_ZEAGLE_N2ITION3, 0}, + {"Scubapro", "XTender 5", DC_FAMILY_ZEAGLE_N2ITION3, 0}, /* Atomic Aquatics Cobalt */ #ifdef HAVE_LIBUSB {"Atomic Aquatics", "Cobalt", DC_FAMILY_ATOMICS_COBALT, 0}, From 4c94460831e15e0ad53fe697a25ed87e8ec71289 Mon Sep 17 00:00:00 2001 From: Stephane Bensoussan Date: Sun, 20 Oct 2013 22:08:56 +0200 Subject: [PATCH 25/30] Use only 11 bits for the depth. When using up to 14 bits for the depth, the resulting values are too large in some cases. Most likely the upper bits are used to store something else. Even with only 11 bits, the resulting depth range (0-204.7m) should still be more than sufficient. --- src/cressi_leonardo_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cressi_leonardo_parser.c b/src/cressi_leonardo_parser.c index 0291366..470a4fa 100644 --- a/src/cressi_leonardo_parser.c +++ b/src/cressi_leonardo_parser.c @@ -162,7 +162,7 @@ cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac dc_sample_value_t sample = {0}; unsigned int value = array_uint16_le (data + offset); - unsigned int depth = value & 0x3FFF; + unsigned int depth = value & 0x07FF; // Time (seconds). time += interval; From 459b1574b869b23ed4b263518ccdad76162862c4 Mon Sep 17 00:00:00 2001 From: Tim Wootton Date: Fri, 25 Oct 2013 23:12:07 +0100 Subject: [PATCH 26/30] Add iconhd gas change event Signed-off-by: Tim Wootton --- src/mares_iconhd_parser.c | 63 ++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 0d48945..078d14f 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -55,6 +55,27 @@ static const dc_parser_vtable_t mares_iconhd_parser_vtable = { }; +/* Find how many gas mixes are in use */ +static unsigned int +mares_iconhd_parser_count_active_gas_mixes (const unsigned char *p, unsigned int air) +{ + if (air) { + return 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++; + } + return i; + } +} + + dc_status_t mares_iconhd_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model) { @@ -163,20 +184,7 @@ 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: - 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; - } + *((unsigned int *) value) = mares_iconhd_parser_count_active_gas_mixes (p, air); break; case DC_FIELD_GASMIX: if (air) @@ -219,6 +227,10 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t if (abstract->size < length || length < header + 4) return DC_STATUS_DATAFORMAT; + const unsigned char *p = abstract->data + length - header; + + unsigned int air = (p[0] & 0x02) == 0; + const unsigned char *data = abstract->data; unsigned int size = length - header; @@ -227,6 +239,11 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t unsigned int offset = 4; unsigned int nsamples = 0; + + // Previous gas mix - initialize with impossible value + unsigned int gasmix_previous = 0xFFFFFFFF; + unsigned int ngasmixes = mares_iconhd_parser_count_active_gas_mixes (p, air); + while (offset + samplesize <= size) { dc_sample_value_t sample = {0}; @@ -245,6 +262,24 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t sample.temperature = temperature / 10.0; if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata); + // Current gas mix + unsigned int gasmix = (data[offset + 3] & 0xF0) >> 4; + if (gasmix >= ngasmixes) { + return DC_STATUS_DATAFORMAT; + } + if (gasmix != gasmix_previous) { + unsigned int o2 = 0; + if (air) + o2 = 21; + else + o2 = p[0x14 + gasmix * 4]; + sample.event.type = SAMPLE_EVENT_GASCHANGE; + sample.event.time = 0; + sample.event.value = o2; + if (callback) callback (DC_SAMPLE_EVENT, sample, userdata); + gasmix_previous = gasmix; + } + offset += samplesize; nsamples++; From 914e740087956a39ef1523ad2097e87f9a815912 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 22 Dec 2013 22:53:27 +0100 Subject: [PATCH 27/30] Fix the memory layout for the VT4.x. The VT4.x memory layout appears to be slightly different from the Atom 3.x memory layout. The logbook ringbuffer does start at offset 0x420 instead of 0x400. --- src/oceanic_atom2.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index f31b130..d845c91 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -122,10 +122,13 @@ static const oceanic_common_version_t oceanic_oci_version[] = { }; static const oceanic_common_version_t oceanic_atom3_version[] = { - {"OCEANVT4 \0\0 1024"}, {"OCEATOM3 \0\0 1024"}, - {"OCEAVT41 \0\0 1024"}, {"ATOM31 \0\0 1024"}, +}; + +static const oceanic_common_version_t oceanic_vt4_version[] = { + {"OCEANVT4 \0\0 1024"}, + {"OCEAVT41 \0\0 1024"}, {"AERISAIR \0\0 1024"}, }; @@ -267,6 +270,19 @@ static const oceanic_common_layout_t oceanic_atom3_layout = { 1 /* pt_mode_logbook */ }; +static const oceanic_common_layout_t oceanic_vt4_layout = { + 0x20000, /* memsize */ + 0x0000, /* cf_devinfo */ + 0x0040, /* cf_pointers */ + 0x0420, /* rb_logbook_begin */ + 0x0A40, /* rb_logbook_end */ + 8, /* rb_logbook_entry_size */ + 0x0A40, /* rb_profile_begin */ + 0x1FE00, /* rb_profile_end */ + 0, /* pt_mode_global */ + 1 /* pt_mode_logbook */ +}; + static const oceanic_common_layout_t oceanic_veo1_layout = { 0x0400, /* memsize */ 0x0000, /* cf_devinfo */ @@ -471,6 +487,8 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char device->base.layout = &oceanic_oci_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom3_version)) { device->base.layout = &oceanic_atom3_layout; + } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_vt4_version)) { + device->base.layout = &oceanic_vt4_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)) { From 4ae3a4f3ab8b3b8a673b1a8637893b3ca45e8e62 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 21 Nov 2013 16:16:45 +0100 Subject: [PATCH 28/30] Remove the infinite timeout. An infinite timeout causes major problems, because if the device doesn't respond at all, the read call will block forever. With the eon serial line settings (1200 8N2), the total time to read the 2305 byte packet is about 21.129 seconds. A timeout of 30 seconds should be plenty of time. --- src/suunto_eon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/suunto_eon.c b/src/suunto_eon.c index 31a1eda..5cb2d51 100644 --- a/src/suunto_eon.c +++ b/src/suunto_eon.c @@ -104,8 +104,8 @@ suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *na return DC_STATUS_IO; } - // Set the timeout for receiving data (1000ms). - if (serial_set_timeout (device->port, -1) == -1) { + // Set the timeout for receiving data (30s). + if (serial_set_timeout (device->port, 30000) == -1) { ERROR (context, "Failed to set the timeout."); serial_close (device->port); free (device); From 040679f76aaedc8e5272455e4b94dad5ab1b2a54 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Fri, 22 Nov 2013 09:30:46 +0100 Subject: [PATCH 29/30] Improve the progress events. Reading the data packet in multiple smaller chunks greatly improves the progress events. Instead of just two events, before and after the download, there are now many intermediate events. This change also allows to significantly reduce the timeout, from 30 seconds to just one second, which avoids blocking for too long in case the device doesn't respond at all. --- src/suunto_eon.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/suunto_eon.c b/src/suunto_eon.c index 5cb2d51..de7d2aa 100644 --- a/src/suunto_eon.c +++ b/src/suunto_eon.c @@ -104,8 +104,8 @@ suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *na return DC_STATUS_IO; } - // Set the timeout for receiving data (30s). - if (serial_set_timeout (device->port, 30000) == -1) { + // Set the timeout for receiving data (1000ms). + if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); serial_close (device->port); free (device); @@ -170,16 +170,34 @@ suunto_eon_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) } // Receive the answer. + unsigned int nbytes = 0; unsigned char answer[SZ_MEMORY + 1] = {0}; - rc = serial_read (device->port, answer, sizeof (answer)); - if (rc != sizeof (answer)) { - ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (rc); - } + while (nbytes < sizeof(answer)) { + // Set the minimum packet size. + unsigned int len = 64; - // Update and emit a progress event. - progress.current += sizeof (answer); - device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); + // Increase the packet size if more data is immediately available. + int available = serial_get_received (device->port); + if (available > len) + len = available; + + // Limit the packet size to the total size. + if (nbytes + len > sizeof(answer)) + len = sizeof(answer) - nbytes; + + // Read the packet. + int n = serial_read (device->port, answer + nbytes, len); + if (n != len) { + ERROR (abstract->context, "Failed to receive the answer."); + return EXITCODE (n); + } + + // Update and emit a progress event. + progress.current += len; + device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); + + nbytes += len; + } // Verify the checksum of the package. unsigned char crc = answer[sizeof (answer) - 1]; From 9f42f6b87d89b9957b266896e75aea3b16d86ab2 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 6 Feb 2014 20:22:19 +0100 Subject: [PATCH 30/30] Release version 0.4.2. --- NEWS | 29 +++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 0748263..2208dae 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,32 @@ +Version 0.4.2 (2014-02-06) +========================== + +The v0.4.2 release is a bugfix release. + +Bug fixes: + + * [iconhd] Use only 12 bits for the temperature. + * [d9] Identify event 0x07 on Suunto d9-style computers as Below Floor. + * [iconhd] Add Mares Puck 2 dive computer + * [misc] Disable the cancellation callback during shutdown. + * [misc] Add cancellation support to several backends. + * [atom2] Fix the memory layout for the Atom 3.x and VT4.x. + * [atom2] Mark the Oceanic Veo 2.0 as a non air integrated model. + * [iconhd] Fix the memory layout descriptors. + * [atom2] Add support for the Sherwood Amphos. + * [atom2] Add support for the Oceanic OCi. + * [smart] Add support for a new Uwatec Aladin 2G variant. + * [shearwater] Buffer the slip packet before sending. + * [shearwater] Use the correct vtable for the Shearwater Petrel. + * [iconhd] Adds support for DC_FIELD_ATMOSPHERIC to the iconhd parser + * [iconhd] Fix units for atmospheric pressure for iconhd type + * [n2ition3] Add support for the Scubapro XTender 5. + * [leonardo] Use only 11 bits for the depth. + * [iconhd] Add iconhd gas change event + * [atom2] Fix the memory layout for the VT4.x. + * [eon] Remove the infinite timeout. + * [eon] Improve the progress events. + Version 0.4.1 (2013-07-01) ========================== diff --git a/configure.ac b/configure.ac index dd08484..872f797 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ m4_define([dc_version_major],[0]) m4_define([dc_version_minor],[4]) m4_define([dc_version_micro],[2]) -m4_define([dc_version_suffix],[devel]) +m4_define([dc_version_suffix],[]) m4_define([dc_version],dc_version_major.dc_version_minor.dc_version_micro[]m4_ifset([dc_version_suffix],-[dc_version_suffix])) # Libtool versioning.