Merge branch 'partsOfMaster' into Subsurface-branch
This commit is contained in:
commit
26b027cad8
14
src/array.c
14
src/array.c
@ -146,6 +146,20 @@ array_convert_hex2bin (const unsigned char input[], unsigned int isize, unsigned
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
array_convert_str2num (const unsigned char data[], unsigned int size)
|
||||
{
|
||||
unsigned int value = 0;
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
if (data[i] < '0' || data[i] > '9')
|
||||
break;
|
||||
value *= 10;
|
||||
value += data[i] - '0';
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
array_uint_be (const unsigned char data[], unsigned int n)
|
||||
{
|
||||
|
||||
@ -49,6 +49,9 @@ array_convert_bin2hex (const unsigned char input[], unsigned int isize, unsigned
|
||||
int
|
||||
array_convert_hex2bin (const unsigned char input[], unsigned int isize, unsigned char output[], unsigned int osize);
|
||||
|
||||
unsigned int
|
||||
array_convert_str2num (const unsigned char data[], unsigned int size);
|
||||
|
||||
unsigned int
|
||||
array_uint_be (const unsigned char data[], unsigned int n);
|
||||
|
||||
|
||||
@ -176,14 +176,17 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458},
|
||||
{"Aeris", "A300", DC_FAMILY_OCEANIC_ATOM2, 0x445A},
|
||||
{"Hollis", "TX1", DC_FAMILY_OCEANIC_ATOM2, 0x4542},
|
||||
{"Beuchat", "Mundial 2", DC_FAMILY_OCEANIC_ATOM2, 0x4543},
|
||||
{"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545},
|
||||
{"Sherwood", "Amphos Air", DC_FAMILY_OCEANIC_ATOM2, 0x4546},
|
||||
{"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548},
|
||||
{"Aeris", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4549},
|
||||
{"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B},
|
||||
{"Aeris", "A300CS", DC_FAMILY_OCEANIC_ATOM2, 0x454C},
|
||||
{"Beuchat", "Mundial 3", DC_FAMILY_OCEANIC_ATOM2, 0x4550},
|
||||
{"Oceanic", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4554},
|
||||
{"Oceanic", "VTX", DC_FAMILY_OCEANIC_ATOM2, 0x4557},
|
||||
{"Aqualung", "i300", DC_FAMILY_OCEANIC_ATOM2, 0x4559},
|
||||
{"Aqualung", "i450T", DC_FAMILY_OCEANIC_ATOM2, 0x4641},
|
||||
/* Mares Nemo */
|
||||
{"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0},
|
||||
|
||||
@ -34,6 +34,10 @@
|
||||
#define DARWIN 0
|
||||
#define DARWINAIR 1
|
||||
|
||||
#define AIR 0
|
||||
#define GAUGE 1
|
||||
#define NITROX 2
|
||||
|
||||
typedef struct mares_darwin_parser_t mares_darwin_parser_t;
|
||||
|
||||
struct mares_darwin_parser_t {
|
||||
@ -133,6 +137,8 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
|
||||
dc_tank_t *tank = (dc_tank_t *) value;
|
||||
|
||||
unsigned int mode = p[0x0C] & 0x03;
|
||||
|
||||
if (value) {
|
||||
switch (type) {
|
||||
case DC_FIELD_DIVETIME:
|
||||
@ -142,11 +148,19 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
*((double *) value) = array_uint16_be (p + 0x08) / 10.0;
|
||||
break;
|
||||
case DC_FIELD_GASMIX_COUNT:
|
||||
*((unsigned int *) value) = 1;
|
||||
if (mode == GAUGE) {
|
||||
*((unsigned int *) value) = 0;
|
||||
} else {
|
||||
*((unsigned int *) value) = 1;
|
||||
}
|
||||
break;
|
||||
case DC_FIELD_GASMIX:
|
||||
gasmix->helium = 0.0;
|
||||
gasmix->oxygen = 0.21;
|
||||
if (mode == NITROX) {
|
||||
gasmix->oxygen = p[0x0E] / 100.0;
|
||||
} else {
|
||||
gasmix->oxygen = 0.21;
|
||||
}
|
||||
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
|
||||
break;
|
||||
case DC_FIELD_TEMPERATURE_MINIMUM:
|
||||
@ -171,6 +185,19 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
break;
|
||||
case DC_FIELD_DIVEMODE:
|
||||
switch (mode) {
|
||||
case AIR:
|
||||
case NITROX:
|
||||
*((dc_divemode_t *) value) = DC_DIVEMODE_OC;
|
||||
break;
|
||||
case GAUGE:
|
||||
*((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE;
|
||||
break;
|
||||
default:
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -83,6 +83,7 @@ static const dc_device_vtable_t oceanic_atom2_device_vtable = {
|
||||
|
||||
static const oceanic_common_version_t aeris_f10_version[] = {
|
||||
{"FREEWAER \0\0 512K"},
|
||||
{"MUNDIAL R\0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t aeris_f11_version[] = {
|
||||
@ -128,6 +129,7 @@ static const oceanic_common_version_t oceanic_default_version[] = {
|
||||
{"DATAMASK \0\0 512K"},
|
||||
{"COMPMASK \0\0 512K"},
|
||||
{"HOLLDG03 \0\0 512K"},
|
||||
{"AQUAI300 \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_proplus3_version[] = {
|
||||
|
||||
@ -69,14 +69,17 @@
|
||||
#define WISDOM3 0x4458
|
||||
#define A300 0x445A
|
||||
#define TX1 0x4542
|
||||
#define MUNDIAL2 0x4543
|
||||
#define AMPHOS 0x4545
|
||||
#define AMPHOSAIR 0x4546
|
||||
#define PROPLUS3 0x4548
|
||||
#define F11A 0x4549
|
||||
#define OCI 0x454B
|
||||
#define A300CS 0x454C
|
||||
#define MUNDIAL3 0x4550
|
||||
#define F11B 0x4554
|
||||
#define VTX 0x4557
|
||||
#define I300 0x4559
|
||||
#define I450T 0x4641
|
||||
|
||||
#define NORMAL 0
|
||||
@ -148,7 +151,8 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
|
||||
model == VEO20 || model == VEO30 ||
|
||||
model == OCS || model == PROPLUS3 ||
|
||||
model == A300 || model == MANTA ||
|
||||
model == INSIGHT2 || model == ZEN) {
|
||||
model == INSIGHT2 || model == ZEN ||
|
||||
model == I300) {
|
||||
parser->headersize -= PAGESIZE;
|
||||
} else if (model == VT4 || model == VT41) {
|
||||
parser->headersize += PAGESIZE;
|
||||
@ -156,7 +160,7 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
|
||||
parser->headersize += 2 * PAGESIZE;
|
||||
} else if (model == ATOM1) {
|
||||
parser->headersize -= 2 * PAGESIZE;
|
||||
} else if (model == F10) {
|
||||
} else if (model == F10 || model == MUNDIAL2 || model == MUNDIAL3) {
|
||||
parser->headersize = 3 * PAGESIZE;
|
||||
parser->footersize = 0;
|
||||
} else if (model == F11A || model == F11B) {
|
||||
@ -214,7 +218,8 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
||||
|
||||
unsigned int header = 8;
|
||||
if (parser->model == F10 || parser->model == F11A ||
|
||||
parser->model == F11B)
|
||||
parser->model == F11B || parser->model == MUNDIAL2 ||
|
||||
parser->model == MUNDIAL3)
|
||||
header = 32;
|
||||
|
||||
if (abstract->size < header)
|
||||
@ -253,6 +258,8 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
||||
case PROPLUS3:
|
||||
case DATAMASK:
|
||||
case COMPUMASK:
|
||||
case INSIGHT2:
|
||||
case I300:
|
||||
datetime->year = ((p[3] & 0xE0) >> 1) + (p[4] & 0x0F) + 2000;
|
||||
datetime->month = (p[4] & 0xF0) >> 4;
|
||||
datetime->day = p[3] & 0x1F;
|
||||
@ -272,6 +279,8 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
||||
case F10:
|
||||
case F11A:
|
||||
case F11B:
|
||||
case MUNDIAL2:
|
||||
case MUNDIAL3:
|
||||
datetime->year = bcd2dec (p[6]) + 2000;
|
||||
datetime->month = bcd2dec (p[7]);
|
||||
datetime->day = bcd2dec (p[8]);
|
||||
@ -374,7 +383,8 @@ oceanic_atom2_parser_cache (oceanic_atom2_parser_t *parser)
|
||||
// Get the dive mode.
|
||||
unsigned int mode = NORMAL;
|
||||
if (parser->model == F10 || parser->model == F11A ||
|
||||
parser->model == F11B) {
|
||||
parser->model == F11B || parser->model == MUNDIAL2 ||
|
||||
parser->model == MUNDIAL3) {
|
||||
mode = FREEDIVE;
|
||||
} else if (parser->model == T3B || parser->model == VT3 ||
|
||||
parser->model == DG03) {
|
||||
@ -482,14 +492,16 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
|
||||
switch (type) {
|
||||
case DC_FIELD_DIVETIME:
|
||||
if (parser->model == F10 || parser->model == F11A ||
|
||||
parser->model == F11B)
|
||||
parser->model == F11B || parser->model == MUNDIAL2 ||
|
||||
parser->model == MUNDIAL3)
|
||||
*((unsigned int *) value) = bcd2dec (data[2]) + bcd2dec (data[3]) * 60;
|
||||
else
|
||||
*((unsigned int *) value) = parser->divetime;
|
||||
break;
|
||||
case DC_FIELD_MAXDEPTH:
|
||||
if (parser->model == F10 || parser->model == F11A ||
|
||||
parser->model == F11B)
|
||||
parser->model == F11B || parser->model == MUNDIAL2 ||
|
||||
parser->model == MUNDIAL3)
|
||||
*((double *) value) = array_uint16_le (data + 4) / 16.0 * FEET;
|
||||
else
|
||||
*((double *) value) = array_uint16_le (data + parser->footer + 4) / 16.0 * FEET;
|
||||
@ -613,7 +625,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
unsigned int samplesize = PAGESIZE / 2;
|
||||
if (parser->mode == FREEDIVE) {
|
||||
if (parser->model == F10 || parser->model == F11A ||
|
||||
parser->model == F11B) {
|
||||
parser->model == F11B || parser->model == MUNDIAL2 ||
|
||||
parser->model == MUNDIAL3) {
|
||||
samplesize = 2;
|
||||
} else {
|
||||
samplesize = 4;
|
||||
@ -633,7 +646,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
parser->model == ELEMENT2 || parser->model == VEO20 ||
|
||||
parser->model == A300 || parser->model == ZEN ||
|
||||
parser->model == GEO || parser->model == GEO20 ||
|
||||
parser->model == MANTA) {
|
||||
parser->model == MANTA || parser->model == I300) {
|
||||
have_pressure = 0;
|
||||
}
|
||||
|
||||
@ -747,7 +760,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
parser->model == VEO30 || parser->model == OC1A ||
|
||||
parser->model == OC1B || parser->model == OC1C ||
|
||||
parser->model == OCI || parser->model == A300 ||
|
||||
parser->model == I450T) {
|
||||
parser->model == I450T || parser->model == I300) {
|
||||
temperature = data[offset + 3];
|
||||
} else if (parser->model == OCS || parser->model == TX1) {
|
||||
temperature = data[offset + 1];
|
||||
@ -807,7 +820,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
parser->model == VEO30 || parser->model == OC1A ||
|
||||
parser->model == OC1B || parser->model == OC1C ||
|
||||
parser->model == OCI || parser->model == A300 ||
|
||||
parser->model == I450T)
|
||||
parser->model == I450T || parser->model == I300)
|
||||
depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF;
|
||||
else if (parser->model == ATOM1)
|
||||
depth = data[offset + 3] * 16;
|
||||
|
||||
@ -742,7 +742,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
|
||||
offset += 2;
|
||||
break;
|
||||
case 0x06: // Gas Change
|
||||
if (parser->model == DX)
|
||||
if (parser->model == DX || parser->model == VYPERNOVO)
|
||||
length = 5;
|
||||
else
|
||||
length = 4;
|
||||
@ -753,7 +753,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
|
||||
unknown = data[offset + 0];
|
||||
he = data[offset + 1];
|
||||
o2 = data[offset + 2];
|
||||
if (parser->model == DX) {
|
||||
if (parser->model == DX || parser->model == VYPERNOVO) {
|
||||
seconds = data[offset + 4];
|
||||
} else {
|
||||
seconds = data[offset + 3];
|
||||
|
||||
@ -59,6 +59,8 @@ typedef struct suunto_eonsteel_device_t {
|
||||
#endif
|
||||
unsigned int magic;
|
||||
unsigned short seq;
|
||||
unsigned char version[0x30];
|
||||
unsigned char fingerprint[4];
|
||||
} suunto_eonsteel_device_t;
|
||||
|
||||
// The EON Steel implements a small filesystem
|
||||
@ -88,13 +90,14 @@ struct directory_entry {
|
||||
#define READDIR_CMD 0x0910
|
||||
#define DIR_CLOSE_CMD 0x0a10
|
||||
|
||||
static dc_status_t suunto_eonsteel_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
||||
static dc_status_t suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
||||
static dc_status_t suunto_eonsteel_device_close(dc_device_t *abstract);
|
||||
|
||||
static const dc_device_vtable_t suunto_eonsteel_device_vtable = {
|
||||
sizeof(suunto_eonsteel_device_t),
|
||||
DC_FAMILY_SUUNTO_EONSTEEL,
|
||||
NULL, /* set_fingerprint */
|
||||
suunto_eonsteel_device_set_fingerprint, /* set_fingerprint */
|
||||
NULL, /* read */
|
||||
NULL, /* write */
|
||||
NULL, /* dump */
|
||||
@ -565,7 +568,7 @@ static int initialize_eonsteel(suunto_eonsteel_device_t *eon)
|
||||
ERROR(eon->base.context, "Failed to send initialization command");
|
||||
return -1;
|
||||
}
|
||||
if (receive_header(eon, &hdr, buf, sizeof(buf)) < 0) {
|
||||
if (receive_header(eon, &hdr, eon->version, sizeof(eon->version)) < 0) {
|
||||
ERROR(eon->base.context, "Failed to receive initial reply");
|
||||
return -1;
|
||||
}
|
||||
@ -593,6 +596,8 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char
|
||||
// Set up the magic handshake fields
|
||||
eon->magic = INIT_MAGIC;
|
||||
eon->seq = INIT_SEQ;
|
||||
memset (eon->version, 0, sizeof (eon->version));
|
||||
memset (eon->fingerprint, 0, sizeof (eon->fingerprint));
|
||||
|
||||
#if __APPLE__ && HAVE_HIDAPI
|
||||
|
||||
@ -670,6 +675,22 @@ static int count_dir_entries(struct directory_entry *de)
|
||||
return count;
|
||||
}
|
||||
|
||||
static dc_status_t
|
||||
suunto_eonsteel_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size)
|
||||
{
|
||||
suunto_eonsteel_device_t *device = (suunto_eonsteel_device_t *) abstract;
|
||||
|
||||
if (size && size != sizeof (device->fingerprint))
|
||||
return DC_STATUS_INVALIDARGS;
|
||||
|
||||
if (size)
|
||||
memcpy (device->fingerprint, data, sizeof (device->fingerprint));
|
||||
else
|
||||
memset (device->fingerprint, 0, sizeof (device->fingerprint));
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static dc_status_t
|
||||
suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callback, void *userdata)
|
||||
{
|
||||
@ -684,6 +705,13 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac
|
||||
if (get_file_list(eon, &de) < 0)
|
||||
return DC_STATUS_IO;
|
||||
|
||||
// Emit a device info event.
|
||||
dc_event_devinfo_t devinfo;
|
||||
devinfo.model = 0;
|
||||
devinfo.firmware = array_uint32_be (eon->version + 0x20);
|
||||
devinfo.serial = array_convert_str2num(eon->version + 0x10, 16);
|
||||
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
||||
|
||||
file = dc_buffer_new(0);
|
||||
progress.maximum = count_dir_entries(de);
|
||||
progress.current = 0;
|
||||
@ -693,6 +721,8 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac
|
||||
int len;
|
||||
struct directory_entry *next = de->next;
|
||||
unsigned char buf[4];
|
||||
const unsigned char *data = NULL;
|
||||
unsigned int size = 0;
|
||||
|
||||
if (device_is_cancelled(abstract))
|
||||
skip = 1;
|
||||
@ -719,13 +749,17 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac
|
||||
rc = read_file(eon, pathname, file);
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (!callback)
|
||||
break;
|
||||
if (!callback(dc_buffer_get_data(file), dc_buffer_get_size(file), NULL, 0, userdata))
|
||||
skip = 1;
|
||||
|
||||
// We've used up the buffer, so create a new one
|
||||
file = dc_buffer_new(0);
|
||||
data = dc_buffer_get_data(file);
|
||||
size = dc_buffer_get_size(file);
|
||||
|
||||
if (memcmp (data, eon->fingerprint, sizeof (eon->fingerprint)) == 0) {
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (callback && !callback(data, size, data, sizeof(eon->fingerprint), userdata))
|
||||
skip = 1;
|
||||
}
|
||||
progress.current++;
|
||||
device_event_emit(abstract, DC_EVENT_PROGRESS, &progress);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user