From ff1ee12770a6c63bb7217a965bdf02f14d49c8a6 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 12 Aug 2018 19:42:27 +0200 Subject: [PATCH] Add support for the Mares Smart Air The Smart Air uses almost the same data format as the Quad Air. Only the 4 bytes containing the dive mode and number of samples moved from the beginning of the header to the end. This is a change adopted from the regular Smart. --- src/descriptor.c | 1 + src/mares_iconhd.c | 13 ++++++++++--- src/mares_iconhd_parser.c | 20 ++++++++++++-------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 72db49a..0fad0e2 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -246,6 +246,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19, DC_TRANSPORT_SERIAL, NULL}, {"Mares", "Puck 2", DC_FAMILY_MARES_ICONHD , 0x1F, DC_TRANSPORT_SERIAL, NULL}, {"Mares", "Quad Air", DC_FAMILY_MARES_ICONHD , 0x23, DC_TRANSPORT_SERIAL, NULL}, + {"Mares", "Smart Air", DC_FAMILY_MARES_ICONHD , 0x24, DC_TRANSPORT_SERIAL, NULL}, {"Mares", "Quad", DC_FAMILY_MARES_ICONHD , 0x29, DC_TRANSPORT_SERIAL, NULL}, /* Heinrichs Weikamp */ {"Heinrichs Weikamp", "OSTC", DC_FAMILY_HW_OSTC, 0, DC_TRANSPORT_SERIAL, NULL}, diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index 450245e..d5f0ede 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -42,6 +42,7 @@ #define NEMOWIDE2 0x19 #define PUCK2 0x1F #define QUADAIR 0x23 +#define SMARTAIR 0x24 #define QUAD 0x29 #define ACK 0xAA @@ -127,6 +128,7 @@ mares_iconhd_get_model (mares_iconhd_device_t *device) {"Nemo Wide 2", NEMOWIDE2}, {"Puck 2", PUCK2}, {"Quad Air", QUADAIR}, + {"Smart Air", SMARTAIR}, {"Quad", QUAD}, }; @@ -293,6 +295,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_ device->packetsize = 256; break; case QUADAIR: + case SMARTAIR: device->layout = &mares_iconhdnet_layout; device->packetsize = 256; break; @@ -442,7 +445,7 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, header = 0x80; else if (model == QUADAIR) header = 0x84; - else if (model == SMART) + else if (model == SMART || model == SMARTAIR) header = 4; // Type and number of samples only! else if (model == SMARTAPNEA) header = 6; // Type and number of samples only! @@ -504,7 +507,7 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, // Get the number of samples in the profile data. unsigned int type = 0, nsamples = 0; - if (model == SMART || model == SMARTAPNEA) { + if (model == SMART || model == SMARTAPNEA || model == SMARTAIR) { type = array_uint16_le (buffer + offset - header + 2); nsamples = array_uint16_le (buffer + offset - header + 0); } else { @@ -541,6 +544,10 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, headersize = 0x50; samplesize = 14; fingerprint = 0x40; + } else if (model == SMARTAIR) { + headersize = 0x84; + samplesize = 12; + fingerprint = 2; } if (offset < headersize) break; @@ -559,7 +566,7 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, // end of the ringbuffer. The current dive is incomplete (partially // overwritten with newer data), and processing should stop. unsigned int nbytes = 4 + headersize + nsamples * samplesize; - if (model == ICONHDNET || model == QUADAIR) { + if (model == ICONHDNET || model == QUADAIR || model == SMARTAIR) { nbytes += (nsamples / 4) * 8; } else if (model == SMARTAPNEA) { unsigned int settings = array_uint16_le (buffer + offset - headersize + 0x1C); diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 0c48a22..aa44ace 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -35,6 +35,7 @@ #define ICONHD 0x14 #define ICONHDNET 0x15 #define QUADAIR 0x23 +#define SMARTAIR 0x24 #define NGASMIXES 3 #define NTANKS NGASMIXES @@ -94,7 +95,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser) header = 0x80; else if (parser->model == QUADAIR) header = 0x84; - else if (parser->model == SMART) + else if (parser->model == SMART || parser->model == SMARTAIR) header = 4; // Type and number of samples only! else if (parser->model == SMARTAPNEA) header = 6; // Type and number of samples only! @@ -112,7 +113,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser) // Get the number of samples in the profile data. unsigned int type = 0, nsamples = 0; - if (parser->model == SMART || parser->model == SMARTAPNEA) { + if (parser->model == SMART || parser->model == SMARTAPNEA || parser->model == SMARTAIR) { type = array_uint16_le (data + length - header + 2); nsamples = array_uint16_le (data + length - header + 0); } else { @@ -129,7 +130,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser) if (parser->model == ICONHDNET) { headersize = 0x80; samplesize = 12; - } else if (parser->model == QUADAIR) { + } else if (parser->model == QUADAIR || parser->model == SMARTAIR) { headersize = 0x84; samplesize = 12; } else if (parser->model == SMART) { @@ -151,7 +152,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser) } const unsigned char *p = data + length - headersize; - if (parser->model != SMART && parser->model != SMARTAPNEA) { + if (parser->model != SMART && parser->model != SMARTAPNEA && parser->model != SMARTAIR) { p += 4; } @@ -181,7 +182,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser) // Calculate the total number of bytes for this dive. unsigned int nbytes = 4 + headersize + nsamples * samplesize; - if (parser->model == ICONHDNET || parser->model == QUADAIR) { + if (parser->model == ICONHDNET || parser->model == QUADAIR || parser->model == SMARTAIR) { nbytes += (nsamples / 4) * 8; } else if (parser->model == SMARTAPNEA) { unsigned int divetime = array_uint32_le (p + 0x24); @@ -215,7 +216,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser) // Tanks unsigned int ntanks = 0; - if (parser->model == ICONHDNET || parser->model == QUADAIR) { + if (parser->model == ICONHDNET || parser->model == QUADAIR || parser->model == SMARTAIR) { unsigned int tankoffset = (parser->model == ICONHDNET) ? 0x58 : 0x5C; while (ntanks < NTANKS) { unsigned int beginpressure = array_uint16_le (p + tankoffset + ntanks * 4 + 0); @@ -325,6 +326,8 @@ mares_iconhd_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime } } else if (parser->model == SMARTAPNEA) { p += 0x40; + } else if (parser->model == SMARTAIR) { + p += 2; } else { p += 6; } @@ -354,7 +357,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi return rc; const unsigned char *p = abstract->data + parser->footer; - if (parser->model != SMART && parser->model != SMARTAPNEA) { + if (parser->model != SMART && parser->model != SMARTAPNEA && parser->model != SMARTAIR) { p += 4; } @@ -611,7 +614,8 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t nsamples++; // Some extra data. - if ((parser->model == ICONHDNET || parser->model == QUADAIR) && (nsamples % 4) == 0) { + if ((parser->model == ICONHDNET || parser->model == QUADAIR || parser->model == SMARTAIR) && + (nsamples % 4) == 0) { // Pressure (1/100 bar). unsigned int pressure = array_uint16_le(data + offset); if (gasmix < parser->ntanks) {