diff --git a/src/descriptor.c b/src/descriptor.c index a8ee301..d4e679a 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -220,6 +220,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Aqualung", "i450T", DC_FAMILY_OCEANIC_ATOM2, 0x4641, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i550", DC_FAMILY_OCEANIC_ATOM2, 0x4642, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i200", DC_FAMILY_OCEANIC_ATOM2, 0x4646, DC_TRANSPORT_SERIAL, NULL}, + {"Aqualung", "i300C", DC_FAMILY_OCEANIC_ATOM2, 0x4648, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, NULL}, {"Aqualung", "i100", DC_FAMILY_OCEANIC_ATOM2, 0x464E, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i770R", DC_FAMILY_OCEANIC_ATOM2, 0x4651, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, NULL}, /* Mares Nemo */ diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 6d07c0d..6d66613 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -122,6 +122,7 @@ static const oceanic_common_version_t oceanic_atom2b_version[] = { {"AQUAI300 \0\0 512K"}, {"HOLLDG03 \0\0 512K"}, {"AQUAI100 \0\0 512K"}, + {"AQUA300C \0\0 512K"}, }; static const oceanic_common_version_t oceanic_atom2c_version[] = { @@ -487,21 +488,6 @@ static const oceanic_common_layout_t oceanic_proplusx_layout = { 0, /* pt_mode_serial */ }; -static const oceanic_common_layout_t aeris_a300cs_layout = { - 0x40000, /* memsize */ - 0, /* highmem */ - 0x0000, /* cf_devinfo */ - 0x0040, /* cf_pointers */ - 0x0900, /* rb_logbook_begin */ - 0x1000, /* rb_logbook_end */ - 16, /* rb_logbook_entry_size */ - 0x1000, /* rb_profile_begin */ - 0x3FE00, /* rb_profile_end */ - 0, /* pt_mode_global */ - 1, /* pt_mode_logbook */ - 0, /* pt_mode_serial */ -}; - static const oceanic_common_layout_t aqualung_i770r_layout = { 0x440000, /* memsize */ 0x40000, /* highmem */ @@ -517,6 +503,21 @@ static const oceanic_common_layout_t aqualung_i770r_layout = { 0, /* pt_mode_serial */ }; +static const oceanic_common_layout_t aeris_a300cs_layout = { + 0x40000, /* memsize */ + 0, /* highmem */ + 0x0000, /* cf_devinfo */ + 0x0040, /* cf_pointers */ + 0x0900, /* rb_logbook_begin */ + 0x1000, /* rb_logbook_end */ + 16, /* rb_logbook_entry_size */ + 0x1000, /* rb_profile_begin */ + 0x3FE00, /* rb_profile_end */ + 0, /* pt_mode_global */ + 1, /* pt_mode_logbook */ + 0, /* pt_mode_serial */ +}; + static const oceanic_common_layout_t aqualung_i450t_layout = { 0x40000, /* memsize */ 0, /* highmem */ @@ -867,17 +868,9 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream memset(device->cache, 0, sizeof(device->cache)); // Get the correct baudrate. - unsigned int baudrate; - switch (model) { - case VTX: - case I750TC: - case PROPLUSX: - case I770R: + unsigned int baudrate = 38400; + if (model == VTX || model == I750TC || model == PROPLUSX || model == I770R) { baudrate = 115200; - break; - default: - baudrate = 38400; - break; } // Set the serial communication protocol (38400 8N1). @@ -979,12 +972,12 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_proplusx_version)) { device->base.layout = &oceanic_proplusx_layout; device->bigpage = 16; - } else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_a300cs_version)) { - device->base.layout = &aeris_a300cs_layout; - device->bigpage = 16; } else if (OCEANIC_COMMON_MATCH (device->base.version, aqualung_i770r_version)) { device->base.layout = &aqualung_i770r_layout; device->bigpage = 16; + } else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_a300cs_version)) { + device->base.layout = &aeris_a300cs_layout; + device->bigpage = 16; } else if (OCEANIC_COMMON_MATCH (device->base.version, aqualung_i450t_version)) { device->base.layout = &aqualung_i450t_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_default_version)) { diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 51df923..bb07237 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -88,6 +88,7 @@ #define I450T 0x4641 #define I550 0x4642 #define I200 0x4646 +#define I300C 0x4648 #define I100 0x464E #define I770R 0x4651 @@ -162,7 +163,7 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned model == A300 || model == MANTA || model == INSIGHT2 || model == ZEN || model == I300 || model == I550 || - model == I200) { + model == I200 || model == I300C) { parser->headersize -= PAGESIZE; } else if (model == VT4 || model == VT41) { parser->headersize += PAGESIZE; @@ -280,6 +281,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim case I300: case I200: case I100: + case I300C: datetime->year = ((p[3] & 0xE0) >> 1) + (p[4] & 0x0F) + 2000; datetime->month = (p[4] & 0xF0) >> 4; datetime->day = p[3] & 0x1F; @@ -424,7 +426,7 @@ oceanic_atom2_parser_cache (oceanic_atom2_parser_t *parser) unsigned int ngasmixes = 0; unsigned int o2_offset = 0; unsigned int he_offset = 0; - unsigned int pO2_offset = 1; + unsigned int o2_step = 1; if (mode == FREEDIVE) { ngasmixes = 0; } else if (parser->model == DATAMASK || parser->model == COMPUMASK) { @@ -466,7 +468,7 @@ oceanic_atom2_parser_cache (oceanic_atom2_parser_t *parser) } else if (parser->model == I770R) { o2_offset = 0x30; ngasmixes = 4; - pO2_offset = 2; + o2_step = 2; } else { o2_offset = header + 4; ngasmixes = 3; @@ -478,8 +480,8 @@ oceanic_atom2_parser_cache (oceanic_atom2_parser_t *parser) parser->mode = mode; parser->ngasmixes = ngasmixes; for (unsigned int i = 0; i < ngasmixes; ++i) { - if (data[o2_offset + i*pO2_offset]) { - parser->oxygen[i] = data[o2_offset + i*pO2_offset]; + if (data[o2_offset + i * o2_step]) { + parser->oxygen[i] = data[o2_offset + i * o2_step]; } else { parser->oxygen[i] = 21; } @@ -728,7 +730,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == A300 || parser->model == ZEN || parser->model == GEO || parser->model == GEO20 || parser->model == MANTA || parser->model == I300 || - parser->model == I200 || parser->model == I100) { + parser->model == I200 || parser->model == I100 || + parser->model == I300C) { have_pressure = 0; } @@ -883,7 +886,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == OC1B || parser->model == OC1C || parser->model == OCI || parser->model == A300 || parser->model == I450T || parser->model == I300 || - parser->model == I200 || parser->model == I100) { + parser->model == I200 || parser->model == I100 || + parser->model == I300C) { temperature = data[offset + 3]; } else if (parser->model == OCS || parser->model == TX1) { temperature = data[offset + 1]; @@ -953,7 +957,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == OC1B || parser->model == OC1C || parser->model == OCI || parser->model == A300 || parser->model == I450T || parser->model == I300 || - parser->model == I200 || parser->model == I100) + parser->model == I200 || parser->model == I100 || + parser->model == I300C) depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF; else if (parser->model == ATOM1) depth = data[offset + 3] * 16; @@ -1004,7 +1009,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ } else if (parser->model == I200 || parser->model == I300 || parser->model == OC1A || parser->model == OC1B || parser->model == OC1C || parser->model == OCI || - parser->model == I100) { + parser->model == I100 || parser->model == I300C) { decostop = (data[offset + 7] & 0xF0) >> 4; decotime = array_uint16_le(data + offset + 6) & 0x0FFF; have_deco = 1; @@ -1028,7 +1033,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ have_rbt = 1; } else if (parser->model == I450T || parser->model == OC1A || parser->model == OC1B || parser->model == OC1C || - parser->model == OCI || parser->model == PROPLUSX) { + parser->model == OCI || parser->model == PROPLUSX || + parser->model == I770R) { rbt = array_uint16_le(data + offset + 8) & 0x01FF; have_rbt = 1; } else if (parser->model == VISION || parser->model == XPAIR || diff --git a/src/suunto_common2.c b/src/suunto_common2.c index 4aa1699..fd56562 100644 --- a/src/suunto_common2.c +++ b/src/suunto_common2.c @@ -287,16 +287,22 @@ suunto_common2_device_foreach (dc_device_t *abstract, dc_dive_callback_t callbac if (last < layout->rb_profile_begin || last >= layout->rb_profile_end || end < layout->rb_profile_begin || - end >= layout->rb_profile_end || - begin < layout->rb_profile_begin || - begin >= layout->rb_profile_end) + end >= layout->rb_profile_end) { ERROR (abstract->context, "Invalid ringbuffer pointer detected (0x%04x 0x%04x 0x%04x %u).", begin, last, end, count); return DC_STATUS_DATAFORMAT; } // Calculate the total amount of bytes. - unsigned int remaining = RB_PROFILE_DISTANCE (layout, begin, end, count != 0); + unsigned int remaining = 0; + if (begin < layout->rb_profile_begin || begin >= layout->rb_profile_end) { + // Fall back to downloading the entire ringbuffer as workaround + // for an invalid begin pointer! + ERROR (abstract->context, "Invalid ringbuffer pointer detected (0x%04x 0x%04x 0x%04x %u).", begin, last, end, count); + remaining = layout->rb_profile_end - layout->rb_profile_begin; + } else { + remaining = RB_PROFILE_DISTANCE (layout, begin, end, count != 0); + } // Update and emit a progress event. progress.maximum -= (layout->rb_profile_end - layout->rb_profile_begin) - remaining;