diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 3748221..fc68ecb 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -73,6 +73,10 @@ #define OCI 0x454B #define A300CS 0x454C +#define NORMAL 0 +#define GAUGE 1 +#define FREEDIVE 2 + typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t; struct oceanic_atom2_parser_t { @@ -327,6 +331,14 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns header = 3 * PAGESIZE; } + // Get the dive mode. + unsigned int mode = NORMAL; + if (parser->model == F10 || parser->model == F11) { + mode = FREEDIVE; + } else if (parser->model == T3B) { + mode = (data[2] & 0xC0) >> 6; + } + if (!parser->cached) { sample_statistics_t statistics = SAMPLE_STATISTICS_INITIALIZER; dc_status_t rc = oceanic_atom2_parser_samples_foreach ( @@ -360,7 +372,9 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns *((double *) value) = array_uint16_le (data + footer + 4) / 16.0 * FEET; break; case DC_FIELD_GASMIX_COUNT: - if (parser->model == DATAMASK || parser->model == COMPUMASK) { + if (mode == FREEDIVE) { + *((unsigned int *) value) = 0; + } else if (parser->model == DATAMASK || parser->model == COMPUMASK) { *((unsigned int *) value) = 1; } else if (parser->model == VT4 || parser->model == VT41 || parser->model == OCI || parser->model == A300AI) { @@ -410,6 +424,21 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns return DC_STATUS_UNSUPPORTED; } break; + case DC_FIELD_DIVEMODE: + switch (mode) { + case NORMAL: + *((unsigned int *) value) = DC_DIVEMODE_OC; + break; + case GAUGE: + *((unsigned int *) value) = DC_DIVEMODE_GAUGE; + break; + case FREEDIVE: + *((unsigned int *) value) = DC_DIVEMODE_FREEDIVE; + break; + default: + return DC_STATUS_DATAFORMAT; + } + break; default: return DC_STATUS_UNSUPPORTED; } @@ -463,9 +492,17 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ header = 3 * PAGESIZE; } + // Get the dive mode. + unsigned int mode = NORMAL; + if (parser->model == F10 || parser->model == F11) { + mode = FREEDIVE; + } else if (parser->model == T3B) { + mode = (data[2] & 0xC0) >> 6; + } + unsigned int time = 0; unsigned int interval = 1; - if (parser->model != F10 && parser->model != F11) { + if (mode != FREEDIVE) { unsigned int idx = 0x17; if (parser->model == A300CS) idx = 0x1f; @@ -486,22 +523,27 @@ 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 (mode == FREEDIVE) { + if (parser->model == F10 || parser->model == F11) { + samplesize = 2; + } else { + samplesize = 4; + } + } else if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C || parser->model == OCI || - parser->model == TX1 || parser->model == A300CS) + parser->model == TX1 || parser->model == A300CS) { samplesize = PAGESIZE; - else if (parser->model == F10 || parser->model == F11) - samplesize = 2; + } unsigned int have_temperature = 1, have_pressure = 1; - if (parser->model == VEO30 || parser->model == OCS || + if (mode == FREEDIVE) { + have_temperature = 0; + have_pressure = 0; + } else if (parser->model == VEO30 || parser->model == OCS || parser->model == ELEMENT2 || parser->model == VEO20 || parser->model == A300 || parser->model == ZEN || parser->model == GEO || parser->model == GEO20) { have_pressure = 0; - } else if (parser->model == F10 || parser->model == F11) { - have_temperature = 0; - have_pressure = 0; } // Initial temperature. @@ -545,7 +587,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ // Get the sample type. unsigned int sampletype = data[offset + 0]; - if (parser->model == F10 || parser->model == F11) + if (mode == FREEDIVE) sampletype = 0; // The sample size is usually fixed, but some sample types have a @@ -659,15 +701,15 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ // Depth (1/16 ft) unsigned int depth; - if (parser->model == GEO20 || parser->model == VEO20 || + if (mode == FREEDIVE) + depth = array_uint16_le (data + offset); + else if (parser->model == GEO20 || parser->model == VEO20 || parser->model == VEO30 || parser->model == OC1A || parser->model == OC1B || parser->model == OC1C || parser->model == OCI || parser->model == A300) depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF; else if (parser->model == ATOM1) depth = data[offset + 3] * 16; - else if (parser->model == F10 || parser->model == F11) - depth = array_uint16_le (data + offset); else depth = (data[offset + 2] + (data[offset + 3] << 8)) & 0x0FFF; sample.depth = depth / 16.0 * FEET;