Merge git://github.com/libdivecomputer/libdivecomputer into Subsurface-DS9
Merge upstream libdivecomputer from Jef: - support the Scubapro Aladin A2 - improve Cressi Goa support - parse and report Oceanic firmware versions * 'master' of git://github.com/libdivecomputer/libdivecomputer: Report the firmware version in the devinfo event Refactor the version string matching to use one table Parse the firmware version Add support for Cressi Goa gauge and freedives Add the extra 5 bytes containing the divemode Add a function to insert data anywhere in the buffer Add support for the Scubapro Aladin A2
This commit is contained in:
commit
e58a5866bb
@ -51,6 +51,9 @@ dc_buffer_append (dc_buffer_t *buffer, const unsigned char data[], size_t size);
|
||||
int
|
||||
dc_buffer_prepend (dc_buffer_t *buffer, const unsigned char data[], size_t size);
|
||||
|
||||
int
|
||||
dc_buffer_insert (dc_buffer_t *buffer, size_t offset, const unsigned char data[], size_t size);
|
||||
|
||||
int
|
||||
dc_buffer_slice (dc_buffer_t *buffer, size_t offset, size_t size);
|
||||
|
||||
|
||||
66
src/buffer.c
66
src/buffer.c
@ -231,6 +231,72 @@ dc_buffer_prepend (dc_buffer_t *buffer, const unsigned char data[], size_t size)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dc_buffer_insert (dc_buffer_t *buffer, size_t offset, const unsigned char data[], size_t size)
|
||||
{
|
||||
if (buffer == NULL)
|
||||
return 0;
|
||||
|
||||
if (offset > buffer->size)
|
||||
return 0;
|
||||
|
||||
size_t head = buffer->offset;
|
||||
size_t tail = buffer->capacity - (buffer->offset + buffer->size);
|
||||
|
||||
unsigned char *ptr = buffer->data + buffer->offset;
|
||||
|
||||
if (size <= head) {
|
||||
if (buffer->size)
|
||||
memmove (ptr - size, ptr, offset);
|
||||
buffer->offset -= size;
|
||||
} else if (size <= tail) {
|
||||
if (buffer->size)
|
||||
memmove (ptr + offset + size, ptr + offset, buffer->size - offset);
|
||||
} else if (size <= tail + head) {
|
||||
size_t n = buffer->size + size;
|
||||
size_t available = buffer->capacity - n;
|
||||
|
||||
size_t tmp_offset = head > tail ? available : 0;
|
||||
|
||||
unsigned char *tmp = buffer->data;
|
||||
|
||||
if (buffer->size) {
|
||||
memmove (tmp + tmp_offset, ptr, offset);
|
||||
memmove (tmp + tmp_offset + offset + size, ptr + offset, buffer->size - offset);
|
||||
}
|
||||
|
||||
buffer->offset = tmp_offset;
|
||||
} else {
|
||||
size_t n = buffer->size + size;
|
||||
size_t capacity = dc_buffer_expand_calc (buffer, n);
|
||||
size_t available = capacity - n;
|
||||
|
||||
size_t tmp_offset = head > tail ? available : 0;
|
||||
|
||||
unsigned char *tmp = (unsigned char *) malloc (capacity);
|
||||
if (tmp == NULL)
|
||||
return 0;
|
||||
|
||||
if (buffer->size) {
|
||||
memcpy (tmp + tmp_offset, ptr, offset);
|
||||
memcpy (tmp + tmp_offset + offset + size, ptr + offset, buffer->size - offset);
|
||||
}
|
||||
|
||||
free (buffer->data);
|
||||
buffer->data = tmp;
|
||||
buffer->capacity = capacity;
|
||||
buffer->offset = tmp_offset;
|
||||
}
|
||||
|
||||
if (size)
|
||||
memcpy (buffer->data + buffer->offset + offset, data, size);
|
||||
|
||||
buffer->size += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dc_buffer_slice (dc_buffer_t *buffer, size_t offset, size_t size)
|
||||
{
|
||||
|
||||
@ -485,7 +485,19 @@ cressi_goa_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v
|
||||
goto error_free_dive;
|
||||
}
|
||||
|
||||
if (callback && !callback(dive_data, dive_size, dive_data + FP_OFFSET - 5, sizeof(device->fingerprint), userdata))
|
||||
// Those 5 extra bytes contain the dive mode, which is required for
|
||||
// parsing the dive data. Therefore, insert all 5 bytes again. The
|
||||
// remaining 4 bytes appear to be some 32 bit address.
|
||||
if (!dc_buffer_insert (dive, 2, logbook_data + offset + 2, 5)) {
|
||||
ERROR (abstract->context, "Out of memory.");
|
||||
status = DC_STATUS_NOMEMORY;
|
||||
goto error_free_dive;
|
||||
}
|
||||
|
||||
dive_data = dc_buffer_get_data (dive);
|
||||
dive_size = dc_buffer_get_size (dive);
|
||||
|
||||
if (callback && !callback(dive_data, dive_size, dive_data + FP_OFFSET, sizeof(device->fingerprint), userdata))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -28,11 +28,23 @@
|
||||
|
||||
#define ISINSTANCE(parser) dc_device_isinstance((parser), &cressi_goa_parser_vtable)
|
||||
|
||||
#define SZ_HEADER 0x5C
|
||||
#define C_ARRAY_SIZE(array) (sizeof (array) / sizeof *(array))
|
||||
|
||||
#define SZ_HEADER 23
|
||||
#define SZ_HEADER_SCUBA 0x61
|
||||
#define SZ_HEADER_FREEDIVE 0x2B
|
||||
#define SZ_HEADER_GAUGE 0x2D
|
||||
|
||||
#define DEPTH 0
|
||||
#define DEPTH2 1
|
||||
#define TIME 2
|
||||
#define TEMPERATURE 3
|
||||
|
||||
#define SCUBA 0
|
||||
#define NITROX 1
|
||||
#define FREEDIVE 2
|
||||
#define GAUGE 3
|
||||
|
||||
typedef struct cressi_goa_parser_t cressi_goa_parser_t;
|
||||
|
||||
struct cressi_goa_parser_t {
|
||||
@ -58,6 +70,13 @@ static const dc_parser_vtable_t cressi_goa_parser_vtable = {
|
||||
NULL /* destroy */
|
||||
};
|
||||
|
||||
static const unsigned int headersizes[] = {
|
||||
SZ_HEADER_SCUBA,
|
||||
SZ_HEADER_SCUBA,
|
||||
SZ_HEADER_FREEDIVE,
|
||||
SZ_HEADER_GAUGE,
|
||||
};
|
||||
|
||||
dc_status_t
|
||||
cressi_goa_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
|
||||
{
|
||||
@ -97,17 +116,29 @@ cressi_goa_parser_set_data (dc_parser_t *abstract, const unsigned char *data, un
|
||||
static dc_status_t
|
||||
cressi_goa_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
||||
{
|
||||
if (abstract->size < SZ_HEADER)
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = abstract->size;
|
||||
|
||||
if (size < SZ_HEADER)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
const unsigned char *p = abstract->data;
|
||||
unsigned int divemode = data[2];
|
||||
if (divemode >= C_ARRAY_SIZE(headersizes)) {
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
|
||||
unsigned int headersize = headersizes[divemode];
|
||||
if (size < headersize)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
const unsigned char *p = abstract->data + 0x11;
|
||||
|
||||
if (datetime) {
|
||||
datetime->year = array_uint16_le(p + 0x0C);
|
||||
datetime->month = p[0x0E];
|
||||
datetime->day = p[0x0F];
|
||||
datetime->hour = p[0x10];
|
||||
datetime->minute = p[0x11];
|
||||
datetime->year = array_uint16_le(p);
|
||||
datetime->month = p[2];
|
||||
datetime->day = p[3];
|
||||
datetime->hour = p[4];
|
||||
datetime->minute = p[5];
|
||||
datetime->second = 0;
|
||||
datetime->timezone = DC_TIMEZONE_NONE;
|
||||
}
|
||||
@ -119,10 +150,20 @@ static dc_status_t
|
||||
cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value)
|
||||
{
|
||||
cressi_goa_parser_t *parser = (cressi_goa_parser_t *) abstract;
|
||||
if (abstract->size < SZ_HEADER)
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = abstract->size;
|
||||
|
||||
if (size < SZ_HEADER)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int divemode = data[2];
|
||||
if (divemode >= C_ARRAY_SIZE(headersizes)) {
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
|
||||
unsigned int headersize = headersizes[divemode];
|
||||
if (size < headersize)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
if (!parser->cached) {
|
||||
sample_statistics_t statistics = SAMPLE_STATISTICS_INITIALIZER;
|
||||
@ -140,19 +181,35 @@ cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
|
||||
if (value) {
|
||||
switch (type) {
|
||||
case DC_FIELD_DIVETIME:
|
||||
*((unsigned int *) value) = array_uint16_le (data + 0x14);
|
||||
*((unsigned int *) value) = array_uint16_le (data + 0x19);
|
||||
break;
|
||||
case DC_FIELD_MAXDEPTH:
|
||||
*((double *) value) = parser->maxdepth;
|
||||
break;
|
||||
case DC_FIELD_GASMIX_COUNT:
|
||||
*((unsigned int *) value) = 2;
|
||||
*((unsigned int *) value) = divemode == SCUBA || divemode == NITROX ? 2 : 0;
|
||||
break;
|
||||
case DC_FIELD_GASMIX:
|
||||
gasmix->helium = 0.0;
|
||||
gasmix->oxygen = data[0x1B + 2 * flags] / 100.0;
|
||||
gasmix->oxygen = data[0x20 + 2 * flags] / 100.0;
|
||||
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
|
||||
break;
|
||||
case DC_FIELD_DIVEMODE:
|
||||
switch (divemode) {
|
||||
case SCUBA:
|
||||
case NITROX:
|
||||
*((dc_divemode_t *) value) = DC_DIVEMODE_OC;
|
||||
break;
|
||||
case GAUGE:
|
||||
*((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE;
|
||||
break;
|
||||
case FREEDIVE:
|
||||
*((dc_divemode_t *) value) = DC_DIVEMODE_FREEDIVE;
|
||||
break;
|
||||
default:
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
@ -167,12 +224,28 @@ cressi_goa_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = abstract->size;
|
||||
|
||||
unsigned int time = 0;
|
||||
unsigned int interval = 5;
|
||||
unsigned int complete = 1;
|
||||
unsigned int gasmix_previous = 0xFFFFFFFF;
|
||||
if (size < SZ_HEADER)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
unsigned int offset = SZ_HEADER;
|
||||
unsigned int divemode = data[2];
|
||||
if (divemode >= C_ARRAY_SIZE(headersizes)) {
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
|
||||
unsigned int headersize = headersizes[divemode];
|
||||
if (size < headersize)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
unsigned int interval = divemode == FREEDIVE ? 2 : 5;
|
||||
|
||||
unsigned int time = 0;
|
||||
unsigned int depth = 0;
|
||||
unsigned int gasmix = 0, gasmix_previous = 0xFFFFFFFF;
|
||||
unsigned int temperature = 0;
|
||||
unsigned int have_temperature = 0;
|
||||
unsigned int complete = 0;
|
||||
|
||||
unsigned int offset = headersize;
|
||||
while (offset + 2 <= size) {
|
||||
dc_sample_value_t sample = {0};
|
||||
|
||||
@ -181,35 +254,44 @@ cressi_goa_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
|
||||
unsigned int type = (raw & 0x0003);
|
||||
unsigned int value = (raw & 0xFFFC) >> 2;
|
||||
|
||||
if (complete) {
|
||||
// Time (seconds).
|
||||
if (type == DEPTH || type == DEPTH2) {
|
||||
depth = (value & 0x07FF);
|
||||
gasmix = (value & 0x0800) >> 11;
|
||||
time += interval;
|
||||
sample.time = time;
|
||||
if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
|
||||
complete = 0;
|
||||
complete = 1;
|
||||
} else if (type == TEMPERATURE) {
|
||||
temperature = value;
|
||||
have_temperature = 1;
|
||||
} else if (type == TIME) {
|
||||
time += value;
|
||||
}
|
||||
|
||||
if (type == DEPTH) {
|
||||
if (complete) {
|
||||
// Time (seconds).
|
||||
sample.time = time;
|
||||
if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
|
||||
|
||||
// Temperature (1/10 °C).
|
||||
if (have_temperature) {
|
||||
sample.temperature = temperature / 10.0;
|
||||
if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
|
||||
have_temperature = 0;
|
||||
}
|
||||
|
||||
// Depth (1/10 m).
|
||||
unsigned int depth = value & 0x07FF;
|
||||
sample.depth = depth / 10.0;
|
||||
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
|
||||
|
||||
// Gas change.
|
||||
unsigned int gasmix = (value & 0x0800) >> 11;
|
||||
if (gasmix != gasmix_previous) {
|
||||
sample.gasmix = gasmix;
|
||||
if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
|
||||
gasmix_previous = gasmix;
|
||||
// Gas change
|
||||
if (divemode == SCUBA || divemode == NITROX) {
|
||||
if (gasmix != gasmix_previous) {
|
||||
sample.gasmix = gasmix;
|
||||
if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
|
||||
gasmix_previous = gasmix;
|
||||
}
|
||||
}
|
||||
|
||||
complete = 1;
|
||||
} else if (type == TEMPERATURE) {
|
||||
// Temperature (1/10 °C).
|
||||
sample.temperature = value / 10.0;
|
||||
if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
|
||||
} else {
|
||||
WARNING(abstract->context, "Unknown sample type %u.", type);
|
||||
complete = 0;
|
||||
}
|
||||
|
||||
offset += 2;
|
||||
|
||||
@ -172,6 +172,7 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"Scubapro", "Chromis", DC_FAMILY_UWATEC_SMART, 0x24, DC_TRANSPORT_SERIAL, NULL},
|
||||
{"Scubapro", "Aladin A1", DC_FAMILY_UWATEC_SMART, 0x25, DC_TRANSPORT_BLE, dc_filter_uwatec},
|
||||
{"Scubapro", "Mantis 2", DC_FAMILY_UWATEC_SMART, 0x26, DC_TRANSPORT_SERIAL, NULL},
|
||||
{"Scubapro", "Aladin A2", DC_FAMILY_UWATEC_SMART, 0x28, DC_TRANSPORT_BLE, dc_filter_uwatec},
|
||||
{"Scubapro", "G2", DC_FAMILY_UWATEC_SMART, 0x32, DC_TRANSPORT_USBHID | DC_TRANSPORT_BLE, dc_filter_uwatec},
|
||||
{"Scubapro", "G2 Console", DC_FAMILY_UWATEC_SMART, 0x32, DC_TRANSPORT_USBHID | DC_TRANSPORT_BLE, dc_filter_uwatec},
|
||||
{"Scubapro", "G2 HUD", DC_FAMILY_UWATEC_SMART, 0x42, DC_TRANSPORT_USBHID | DC_TRANSPORT_BLE, dc_filter_uwatec},
|
||||
@ -536,6 +537,7 @@ static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, voi
|
||||
"Aladin",
|
||||
"HUD",
|
||||
"A1",
|
||||
"A2",
|
||||
};
|
||||
|
||||
if (transport == DC_TRANSPORT_IRDA) {
|
||||
|
||||
@ -8,6 +8,7 @@ dc_buffer_reserve
|
||||
dc_buffer_resize
|
||||
dc_buffer_append
|
||||
dc_buffer_prepend
|
||||
dc_buffer_insert
|
||||
dc_buffer_slice
|
||||
dc_buffer_get_size
|
||||
dc_buffer_get_data
|
||||
|
||||
@ -92,141 +92,6 @@ static const oceanic_common_device_vtable_t oceanic_atom2_device_vtable = {
|
||||
oceanic_common_device_profile,
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t aeris_f10_version[] = {
|
||||
{"FREEWAER \0\0 512K"},
|
||||
{"OCEANF10 \0\0 512K"},
|
||||
{"MUNDIAL R\0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t aeris_f11_version[] = {
|
||||
{"AERISF11 \0\0 1024"},
|
||||
{"OCEANF11 \0\0 1024"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t aeris_manta_version[] = {
|
||||
{"MANTA R\0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_atom1_version[] = {
|
||||
{"ATOM rev\0\0 256K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_atom2_version[] = {
|
||||
{"2M ATOM r\0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_atom2a_version[] = {
|
||||
{"INSIGHT2 \0\0 512K"},
|
||||
{"OCEVEO30 \0\0 512K"},
|
||||
{"ATMOSAI R\0\0 512K"},
|
||||
{"PROPLUS2 \0\0 512K"},
|
||||
{"OCEGEO20 \0\0 512K"},
|
||||
{"OCE GEO R\0\0 512K"},
|
||||
{"AQUAI200 \0\0 512K"},
|
||||
{"AQUA200C \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_atom2b_version[] = {
|
||||
{"ELEMENT2 \0\0 512K"},
|
||||
{"OCEVEO20 \0\0 512K"},
|
||||
{"TUSAZEN \0\0 512K"},
|
||||
{"AQUAI300 \0\0 512K"},
|
||||
{"HOLLDG03 \0\0 512K"},
|
||||
{"AQUAI100 \0\0 512K"},
|
||||
{"AQUA300C \0\0 512K"},
|
||||
{"OCEGEO40 \0\0 512K"},
|
||||
{"VEOSMART \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_atom2c_version[] = {
|
||||
{"2M EPIC r\0\0 512K"},
|
||||
{"EPIC1 R\0\0 512K"},
|
||||
{"AERIA300 \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_default_version[] = {
|
||||
{"OCE VT3 R\0\0 512K"},
|
||||
{"ELITET3 R\0\0 512K"},
|
||||
{"ELITET31 \0\0 512K"},
|
||||
{"DATAMASK \0\0 512K"},
|
||||
{"COMPMASK \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t sherwood_wisdom_version[] = {
|
||||
{"WISDOM R\0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_proplus3_version[] = {
|
||||
{"PROPLUS3 \0\0 512K"},
|
||||
{"PROPLUS4 \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t tusa_zenair_version[] = {
|
||||
{"TUZENAIR \0\0 512K"},
|
||||
{"AMPHOSSW \0\0 512K"},
|
||||
{"AMPHOAIR \0\0 512K"},
|
||||
{"VOYAGE2G \0\0 512K"},
|
||||
{"TUSTALIS \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_oc1_version[] = {
|
||||
{"OCWATCH R\0\0 1024"},
|
||||
{"OC1WATCH \0\0 1024"},
|
||||
{"OCSWATCH \0\0 1024"},
|
||||
{"AQUAI550 \0\0 1024"},
|
||||
{"AQUA550C \0\0 1024"},
|
||||
{"WISDOM04 \0\0 1024"},
|
||||
{"AQUA470C \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[] = {
|
||||
{"OCEATOM3 \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"},
|
||||
{"SWVISION \0\0 1024"},
|
||||
{"XPSUBAIR \0\0 1024"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t hollis_tx1_version[] = {
|
||||
{"HOLLDG04 \0\0 2048"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_veo1_version[] = {
|
||||
{"OCEVEO10 \0\0 8K"},
|
||||
{"AERIS XR1 NX R\0\0"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_reactpro_version[] = {
|
||||
{"REACPRO2 \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_proplusx_version[] = {
|
||||
{"OCEANOCX \0\0 \0\0\0\0"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t aqualung_i770r_version[] = {
|
||||
{"AQUA770R \0\0 \0\0\0\0"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t aeris_a300cs_version[] = {
|
||||
{"AER300CS \0\0 2048"},
|
||||
{"OCEANVTX \0\0 2048"},
|
||||
{"AQUAI750 \0\0 2048"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t aqualung_i450t_version[] = {
|
||||
{"AQUAI450 \0\0 2048"},
|
||||
};
|
||||
|
||||
static const oceanic_common_layout_t aeris_f10_layout = {
|
||||
0x10000, /* memsize */
|
||||
0, /* highmem */
|
||||
@ -542,6 +407,98 @@ static const oceanic_common_layout_t aqualung_i450t_layout = {
|
||||
0, /* pt_mode_serial */
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t versions[] = {
|
||||
{"OCEVEO10 \0\0 8K", 0, &oceanic_veo1_layout},
|
||||
{"AERIS XR1 NX R\0\0", 0, &oceanic_veo1_layout},
|
||||
|
||||
{"ATOM rev\0\0 256K", 0, &oceanic_atom1_layout},
|
||||
|
||||
{"MANTA R\0\0 512K", 0x3242, &oceanic_atom2a_layout},
|
||||
{"MANTA R\0\0 512K", 0, &oceanic_atom2c_layout},
|
||||
{"2M ATOM r\0\0 512K", 0x3349, &oceanic_atom2a_layout},
|
||||
{"2M ATOM r\0\0 512K", 0, &oceanic_atom2c_layout},
|
||||
|
||||
{"INSIGHT2 \0\0 512K", 0, &oceanic_atom2a_layout},
|
||||
{"OCEVEO30 \0\0 512K", 0, &oceanic_atom2a_layout},
|
||||
{"ATMOSAI R\0\0 512K", 0, &oceanic_atom2a_layout},
|
||||
{"PROPLUS2 \0\0 512K", 0, &oceanic_atom2a_layout},
|
||||
{"OCEGEO20 \0\0 512K", 0, &oceanic_atom2a_layout},
|
||||
{"OCE GEO R\0\0 512K", 0, &oceanic_atom2a_layout},
|
||||
{"AQUAI200 \0\0 512K", 0, &oceanic_atom2a_layout},
|
||||
{"AQUA200C \0\0 512K", 0, &oceanic_atom2a_layout},
|
||||
|
||||
{"ELEMENT2 \0\0 512K", 0, &oceanic_atom2b_layout},
|
||||
{"OCEVEO20 \0\0 512K", 0, &oceanic_atom2b_layout},
|
||||
{"TUSAZEN \0\0 512K", 0, &oceanic_atom2b_layout},
|
||||
{"AQUAI300 \0\0 512K", 0, &oceanic_atom2b_layout},
|
||||
{"HOLLDG03 \0\0 512K", 0, &oceanic_atom2b_layout},
|
||||
{"AQUAI100 \0\0 512K", 0, &oceanic_atom2b_layout},
|
||||
{"AQUA300C \0\0 512K", 0, &oceanic_atom2b_layout},
|
||||
{"OCEGEO40 \0\0 512K", 0, &oceanic_atom2b_layout},
|
||||
{"VEOSMART \0\0 512K", 0, &oceanic_atom2b_layout},
|
||||
|
||||
{"2M EPIC r\0\0 512K", 0, &oceanic_atom2c_layout},
|
||||
{"EPIC1 R\0\0 512K", 0, &oceanic_atom2c_layout},
|
||||
{"AERIA300 \0\0 512K", 0, &oceanic_atom2c_layout},
|
||||
|
||||
{"OCE VT3 R\0\0 512K", 0, &oceanic_default_layout},
|
||||
{"ELITET3 R\0\0 512K", 0, &oceanic_default_layout},
|
||||
{"ELITET31 \0\0 512K", 0, &oceanic_default_layout},
|
||||
{"DATAMASK \0\0 512K", 0, &oceanic_default_layout},
|
||||
{"COMPMASK \0\0 512K", 0, &oceanic_default_layout},
|
||||
|
||||
{"WISDOM R\0\0 512K", 0, &sherwood_wisdom_layout},
|
||||
|
||||
{"PROPLUS3 \0\0 512K", 0, &oceanic_proplus3_layout},
|
||||
{"PROPLUS4 \0\0 512K", 0, &oceanic_proplus3_layout},
|
||||
|
||||
{"TUZENAIR \0\0 512K", 0, &tusa_zenair_layout},
|
||||
{"AMPHOSSW \0\0 512K", 0, &tusa_zenair_layout},
|
||||
{"AMPHOAIR \0\0 512K", 0, &tusa_zenair_layout},
|
||||
{"VOYAGE2G \0\0 512K", 0, &tusa_zenair_layout},
|
||||
{"TUSTALIS \0\0 512K", 0, &tusa_zenair_layout},
|
||||
|
||||
{"REACPRO2 \0\0 512K", 0, &oceanic_reactpro_layout},
|
||||
|
||||
{"FREEWAER \0\0 512K", 0, &aeris_f10_layout},
|
||||
{"OCEANF10 \0\0 512K", 0, &aeris_f10_layout},
|
||||
{"MUNDIAL R\0\0 512K", 0, &aeris_f10_layout},
|
||||
|
||||
{"AERISF11 \0\0 1024", 0, &aeris_f11_layout},
|
||||
{"OCEANF11 \0\0 1024", 0, &aeris_f11_layout},
|
||||
|
||||
{"OCWATCH R\0\0 1024", 0, &oceanic_oc1_layout},
|
||||
{"OC1WATCH \0\0 1024", 0, &oceanic_oc1_layout},
|
||||
{"OCSWATCH \0\0 1024", 0, &oceanic_oc1_layout},
|
||||
{"AQUAI550 \0\0 1024", 0, &oceanic_oc1_layout},
|
||||
{"AQUA550C \0\0 1024", 0, &oceanic_oc1_layout},
|
||||
{"WISDOM04 \0\0 1024", 0, &oceanic_oc1_layout},
|
||||
{"AQUA470C \0\0 1024", 0, &oceanic_oc1_layout},
|
||||
|
||||
{"OCEANOCI \0\0 1024", 0, &oceanic_oci_layout},
|
||||
|
||||
{"OCEATOM3 \0\0 1024", 0, &oceanic_atom3_layout},
|
||||
{"ATOM31 \0\0 1024", 0, &oceanic_atom3_layout},
|
||||
|
||||
{"OCEANVT4 \0\0 1024", 0, &oceanic_vt4_layout},
|
||||
{"OCEAVT41 \0\0 1024", 0, &oceanic_vt4_layout},
|
||||
{"AERISAIR \0\0 1024", 0, &oceanic_vt4_layout},
|
||||
{"SWVISION \0\0 1024", 0, &oceanic_vt4_layout},
|
||||
{"XPSUBAIR \0\0 1024", 0, &oceanic_vt4_layout},
|
||||
|
||||
{"HOLLDG04 \0\0 2048", 0, &hollis_tx1_layout},
|
||||
|
||||
{"AER300CS \0\0 2048", 0, &aeris_a300cs_layout},
|
||||
{"OCEANVTX \0\0 2048", 0, &aeris_a300cs_layout},
|
||||
{"AQUAI750 \0\0 2048", 0, &aeris_a300cs_layout},
|
||||
|
||||
{"AQUAI450 \0\0 2048", 0, &aqualung_i450t_layout},
|
||||
|
||||
{"OCEANOCX \0\0 \0\0\0\0", 0, &oceanic_proplusx_layout},
|
||||
|
||||
{"AQUA770R \0\0 \0\0\0\0", 0, &aqualung_i770r_layout},
|
||||
};
|
||||
|
||||
/*
|
||||
* The BLE GATT packet size is up to 20 bytes and the format is:
|
||||
*
|
||||
@ -952,68 +909,10 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream
|
||||
}
|
||||
}
|
||||
|
||||
// Override the base class values.
|
||||
if (OCEANIC_COMMON_MATCH (device->base.version, aeris_f10_version)) {
|
||||
device->base.layout = &aeris_f10_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_f11_version)) {
|
||||
device->base.layout = &aeris_f11_layout;
|
||||
device->bigpage = 8;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_manta_version)) {
|
||||
if (array_uint16_be (device->base.version + 0x08) >= 0x3242) {
|
||||
device->base.layout = &oceanic_atom2a_layout;
|
||||
} else {
|
||||
device->base.layout = &oceanic_atom2c_layout;
|
||||
}
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom1_version)) {
|
||||
device->base.layout = &oceanic_atom1_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom2_version)) {
|
||||
if (array_uint16_be (device->base.version + 0x09) >= 0x3349) {
|
||||
device->base.layout = &oceanic_atom2a_layout;
|
||||
} else {
|
||||
device->base.layout = &oceanic_atom2c_layout;
|
||||
}
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom2a_version)) {
|
||||
device->base.layout = &oceanic_atom2a_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom2b_version)) {
|
||||
device->base.layout = &oceanic_atom2b_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom2c_version)) {
|
||||
device->base.layout = &oceanic_atom2c_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, sherwood_wisdom_version)) {
|
||||
device->base.layout = &sherwood_wisdom_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_proplus3_version)) {
|
||||
device->base.layout = &oceanic_proplus3_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, tusa_zenair_version)) {
|
||||
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_vt4_version)) {
|
||||
device->base.layout = &oceanic_vt4_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, hollis_tx1_version)) {
|
||||
device->base.layout = &hollis_tx1_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 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, 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)) {
|
||||
device->base.layout = &oceanic_default_layout;
|
||||
} else {
|
||||
// Detect the memory layout.
|
||||
device->base.layout = OCEANIC_COMMON_MATCH(device->base.version, versions, &device->base.firmware);
|
||||
if (device->base.layout == NULL) {
|
||||
WARNING (context, "Unsupported device detected (%s)!", device->base.version);
|
||||
device->base.layout = &oceanic_default_layout;
|
||||
if (memcmp(device->base.version + 12, "256K", 4) == 0) {
|
||||
device->base.layout = &oceanic_atom1_layout;
|
||||
} else if (memcmp(device->base.version + 12, "512K", 4) == 0) {
|
||||
@ -1027,6 +926,15 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream
|
||||
}
|
||||
}
|
||||
|
||||
// Set the big page support.
|
||||
if (device->base.layout == &aeris_f11_layout) {
|
||||
device->bigpage = 8;
|
||||
} else if (device->base.layout == &oceanic_proplusx_layout ||
|
||||
device->base.layout == &aqualung_i770r_layout ||
|
||||
device->base.layout == &aeris_a300cs_layout) {
|
||||
device->bigpage = 16;
|
||||
}
|
||||
|
||||
*out = (dc_device_t*) device;
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
|
||||
@ -99,26 +99,52 @@ get_profile_last (const unsigned char data[], const oceanic_common_layout_t *lay
|
||||
|
||||
|
||||
static int
|
||||
oceanic_common_match_pattern (const unsigned char *string, const unsigned char *pattern)
|
||||
oceanic_common_match_pattern (const unsigned char *string, const unsigned char *pattern, unsigned int *firmware)
|
||||
{
|
||||
unsigned int value = 0;
|
||||
unsigned int count = 0;
|
||||
|
||||
for (unsigned int i = 0; i < PAGESIZE; ++i, ++pattern, ++string) {
|
||||
if (*pattern != '\0' && *pattern != *string)
|
||||
return 0;
|
||||
if (*pattern != '\0') {
|
||||
// Compare the pattern.
|
||||
if (*pattern != *string)
|
||||
return 0;
|
||||
} else {
|
||||
// Extract the firmware version.
|
||||
// This is based on the assumption that (only) the first block of
|
||||
// zeros in the pattern contains the firmware version.
|
||||
if (i == 0 || *(pattern - 1) != '\0')
|
||||
count++;
|
||||
if (count == 1) {
|
||||
value <<= 8;
|
||||
value |= *string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firmware) {
|
||||
*firmware = value;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
oceanic_common_match (const unsigned char *version, const oceanic_common_version_t patterns[], unsigned int n)
|
||||
const oceanic_common_layout_t *
|
||||
oceanic_common_match (const unsigned char *version, const oceanic_common_version_t patterns[], size_t n, unsigned int *firmware)
|
||||
{
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
if (oceanic_common_match_pattern (version, patterns[i]))
|
||||
return 1;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
unsigned int fw = 0;
|
||||
if (oceanic_common_match_pattern (version, patterns[i].pattern, &fw) &&
|
||||
fw >= patterns[i].firmware)
|
||||
{
|
||||
if (firmware) {
|
||||
*firmware = fw;
|
||||
}
|
||||
return patterns[i].layout;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -128,6 +154,7 @@ oceanic_common_device_init (oceanic_common_device_t *device)
|
||||
assert (device != NULL);
|
||||
|
||||
// Set the default values.
|
||||
device->firmware = 0;
|
||||
memset (device->version, 0, sizeof (device->version));
|
||||
memset (device->fingerprint, 0, sizeof (device->fingerprint));
|
||||
device->layout = NULL;
|
||||
@ -585,7 +612,7 @@ oceanic_common_device_foreach (dc_device_t *abstract, dc_dive_callback_t callbac
|
||||
// Emit a device info event.
|
||||
dc_event_devinfo_t devinfo;
|
||||
devinfo.model = array_uint16_be (id + 8);
|
||||
devinfo.firmware = 0;
|
||||
devinfo.firmware = device->firmware;
|
||||
if (layout->pt_mode_serial == 0)
|
||||
devinfo.serial = bcd2dec (id[10]) * 10000 + bcd2dec (id[11]) * 100 + bcd2dec (id[12]);
|
||||
else if (layout->pt_mode_serial == 1)
|
||||
|
||||
@ -31,9 +31,9 @@ extern "C" {
|
||||
#define PAGESIZE 0x10
|
||||
#define FPMAXSIZE 0x20
|
||||
|
||||
#define OCEANIC_COMMON_MATCH(version,patterns) \
|
||||
#define OCEANIC_COMMON_MATCH(version,patterns,firmware) \
|
||||
oceanic_common_match ((version), (patterns), \
|
||||
sizeof (patterns) / sizeof *(patterns))
|
||||
sizeof (patterns) / sizeof *(patterns), (firmware))
|
||||
|
||||
typedef struct oceanic_common_layout_t {
|
||||
// Memory size.
|
||||
@ -61,6 +61,7 @@ typedef struct oceanic_common_layout_t {
|
||||
|
||||
typedef struct oceanic_common_device_t {
|
||||
dc_device_t base;
|
||||
unsigned int firmware;
|
||||
unsigned char version[PAGESIZE];
|
||||
unsigned char fingerprint[FPMAXSIZE];
|
||||
const oceanic_common_layout_t *layout;
|
||||
@ -73,10 +74,14 @@ typedef struct oceanic_common_device_vtable_t {
|
||||
dc_status_t (*profile) (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook, dc_dive_callback_t callback, void *userdata);
|
||||
} oceanic_common_device_vtable_t;
|
||||
|
||||
typedef unsigned char oceanic_common_version_t[PAGESIZE + 1];
|
||||
typedef struct oceanic_common_version_t {
|
||||
unsigned char pattern[PAGESIZE + 1];
|
||||
unsigned int firmware;
|
||||
const oceanic_common_layout_t *layout;
|
||||
} oceanic_common_version_t;
|
||||
|
||||
int
|
||||
oceanic_common_match (const unsigned char *version, const oceanic_common_version_t patterns[], unsigned int n);
|
||||
const oceanic_common_layout_t *
|
||||
oceanic_common_match (const unsigned char *version, const oceanic_common_version_t patterns[], size_t n, unsigned int *firmware);
|
||||
|
||||
void
|
||||
oceanic_common_device_init (oceanic_common_device_t *device);
|
||||
|
||||
@ -62,17 +62,6 @@ static const oceanic_common_device_vtable_t oceanic_veo250_device_vtable = {
|
||||
oceanic_common_device_profile,
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_veo250_version[] = {
|
||||
{"GENREACT \0\0 256K"},
|
||||
{"VEO 200 R\0\0 256K"},
|
||||
{"VEO 250 R\0\0 256K"},
|
||||
{"SEEMANN R\0\0 256K"},
|
||||
{"VEO 180 R\0\0 256K"},
|
||||
{"AERISXR2 \0\0 256K"},
|
||||
{"INSIGHT R\0\0 256K"},
|
||||
{"HO DGO2 R\0\0 256K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_layout_t oceanic_veo250_layout = {
|
||||
0x8000, /* memsize */
|
||||
0, /* highmem */
|
||||
@ -88,6 +77,16 @@ static const oceanic_common_layout_t oceanic_veo250_layout = {
|
||||
1, /* pt_mode_serial */
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t versions[] = {
|
||||
{"GENREACT \0\0 256K", 0, &oceanic_veo250_layout},
|
||||
{"VEO 200 R\0\0 256K", 0, &oceanic_veo250_layout},
|
||||
{"VEO 250 R\0\0 256K", 0, &oceanic_veo250_layout},
|
||||
{"SEEMANN R\0\0 256K", 0, &oceanic_veo250_layout},
|
||||
{"VEO 180 R\0\0 256K", 0, &oceanic_veo250_layout},
|
||||
{"AERISXR2 \0\0 256K", 0, &oceanic_veo250_layout},
|
||||
{"INSIGHT R\0\0 256K", 0, &oceanic_veo250_layout},
|
||||
{"HO DGO2 R\0\0 256K", 0, &oceanic_veo250_layout},
|
||||
};
|
||||
|
||||
static dc_status_t
|
||||
oceanic_veo250_send (oceanic_veo250_device_t *device, const unsigned char command[], unsigned int csize)
|
||||
@ -316,10 +315,9 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, dc_iostrea
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
// Override the base class values.
|
||||
if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_veo250_version)) {
|
||||
device->base.layout = &oceanic_veo250_layout;
|
||||
} else {
|
||||
// Detect the memory layout.
|
||||
device->base.layout = OCEANIC_COMMON_MATCH(device->base.version, versions, &device->base.firmware);
|
||||
if (device->base.layout == NULL) {
|
||||
WARNING (context, "Unsupported device detected!");
|
||||
device->base.layout = &oceanic_veo250_layout;
|
||||
}
|
||||
|
||||
@ -74,19 +74,6 @@ static const oceanic_common_device_vtable_t oceanic_vtpro_device_vtable = {
|
||||
oceanic_common_device_profile,
|
||||
};
|
||||
|
||||
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"},
|
||||
{"ELITE r\0\0 256K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_wisdom_version[] = {
|
||||
{"WISDOM r\0\0 256K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_layout_t oceanic_vtpro_layout = {
|
||||
0x8000, /* memsize */
|
||||
0, /* highmem */
|
||||
@ -132,6 +119,17 @@ static const oceanic_common_layout_t aeris_500ai_layout = {
|
||||
2, /* pt_mode_serial */
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t versions[] = {
|
||||
{"VERSAPRO \0\0 256K", 0, &oceanic_vtpro_layout},
|
||||
{"ATMOSTWO \0\0 256K", 0, &oceanic_vtpro_layout},
|
||||
{"PROPLUS2 \0\0 256K", 0, &oceanic_vtpro_layout},
|
||||
{"ATMOSAIR \0\0 256K", 0, &oceanic_vtpro_layout},
|
||||
{"VTPRO r\0\0 256K", 0, &oceanic_vtpro_layout},
|
||||
{"ELITE r\0\0 256K", 0, &oceanic_vtpro_layout},
|
||||
|
||||
{"WISDOM r\0\0 256K", 0, &oceanic_wisdom_layout},
|
||||
};
|
||||
|
||||
static dc_status_t
|
||||
oceanic_vtpro_send (oceanic_vtpro_device_t *device, const unsigned char command[], unsigned int csize)
|
||||
{
|
||||
@ -491,16 +489,15 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, dc_iostream
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
// Override the base class values.
|
||||
// Detect the memory layout.
|
||||
if (model == AERIS500AI) {
|
||||
device->base.layout = &aeris_500ai_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_wisdom_version)) {
|
||||
device->base.layout = &oceanic_wisdom_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_vtpro_version)) {
|
||||
device->base.layout = &oceanic_vtpro_layout;
|
||||
} else {
|
||||
WARNING (context, "Unsupported device detected!");
|
||||
device->base.layout = &oceanic_vtpro_layout;
|
||||
device->base.layout = OCEANIC_COMMON_MATCH(device->base.version, versions, &device->base.firmware);
|
||||
if (device->base.layout == NULL) {
|
||||
WARNING (context, "Unsupported device detected!");
|
||||
device->base.layout = &oceanic_vtpro_layout;
|
||||
}
|
||||
}
|
||||
|
||||
*out = (dc_device_t*) device;
|
||||
|
||||
@ -50,6 +50,7 @@
|
||||
#define CHROMIS 0x24
|
||||
#define ALADINA1 0x25
|
||||
#define MANTIS2 0x26
|
||||
#define ALADINA2 0x28
|
||||
#define G2 0x32
|
||||
#define G2HUD 0x42
|
||||
|
||||
@ -532,7 +533,7 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser)
|
||||
parser->model == CHROMIS || parser->model == MANTIS2 ||
|
||||
parser->model == G2 || parser->model == ALADINSPORTMATRIX ||
|
||||
parser->model == ALADINSQUARE || parser->model == G2HUD ||
|
||||
parser->model == ALADINA1) {
|
||||
parser->model == ALADINA1 || parser->model == ALADINA2 ) {
|
||||
unsigned int offset = header->tankpressure + 2 * i;
|
||||
endpressure = array_uint16_le(data + offset);
|
||||
beginpressure = array_uint16_le(data + offset + 2 * header->ngases);
|
||||
@ -626,6 +627,7 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
|
||||
case G2HUD:
|
||||
case ALADINSPORTMATRIX:
|
||||
case ALADINA1:
|
||||
case ALADINA2:
|
||||
parser->headersize = 84;
|
||||
parser->header = &uwatec_smart_trimix_header;
|
||||
parser->samples = uwatec_smart_galileo_samples;
|
||||
@ -969,7 +971,7 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback
|
||||
parser->model == CHROMIS || parser->model == MANTIS2 ||
|
||||
parser->model == G2 || parser->model == ALADINSPORTMATRIX ||
|
||||
parser->model == ALADINSQUARE || parser->model == G2HUD ||
|
||||
parser->model == ALADINA1) {
|
||||
parser->model == ALADINA1 || parser->model == ALADINA2 ) {
|
||||
// Uwatec Galileo
|
||||
id = uwatec_galileo_identify (data[offset]);
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user