Merge branch 'release-0.4'

Integrate the bugfixes from the stable branch.
This commit is contained in:
Jef Driesen 2014-02-06 20:31:27 +01:00
commit 56aa3b6669
19 changed files with 265 additions and 58 deletions

View File

@ -243,7 +243,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
"none", "deco", "rbt", "ascent", "ceiling", "workload", "transmitter",
"violation", "bookmark", "surface", "safety stop", "gaschange",
"safety stop (voluntary)", "safety stop (mandatory)", "deepstop",
"ceiling (safety stop)", "unknown", "divetime", "maxdepth",
"ceiling (safety stop)", "floor", "divetime", "maxdepth",
"OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning",
"gaschange2"};
static const char *decostop[] = {

View File

@ -73,7 +73,7 @@ typedef enum parser_sample_event_t {
SAMPLE_EVENT_SAFETYSTOP_MANDATORY,
SAMPLE_EVENT_DEEPSTOP,
SAMPLE_EVENT_CEILING_SAFETYSTOP,
SAMPLE_EVENT_UNKNOWN,
SAMPLE_EVENT_FLOOR,
SAMPLE_EVENT_DIVETIME,
SAMPLE_EVENT_MAXDEPTH,
SAMPLE_EVENT_OLF,
@ -87,6 +87,9 @@ typedef enum parser_sample_event_t {
respectively the low and high part. */
} parser_sample_event_t;
/* For backwards compatibility */
#define SAMPLE_EVENT_UNKNOWN SAMPLE_EVENT_FLOOR
typedef enum parser_sample_flags_t {
SAMPLE_FLAGS_NONE = 0,
SAMPLE_FLAGS_BEGIN = (1 << 0),

View File

@ -83,6 +83,9 @@ cressi_edy_transfer (cressi_edy_device_t *device, const unsigned char command[],
assert (asize >= csize);
if (device_is_cancelled (abstract))
return DC_STATUS_CANCELLED;
// Flush the serial input buffer.
int rc = serial_flush (device->port, SERIAL_QUEUE_INPUT);
if (rc == -1) {

View File

@ -162,7 +162,7 @@ cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
dc_sample_value_t sample = {0};
unsigned int value = array_uint16_le (data + offset);
unsigned int depth = value & 0x3FFF;
unsigned int depth = value & 0x07FF;
// Time (seconds).
time += interval;

View File

@ -99,6 +99,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Uwatec", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x13},
{"Subgear","XP-10", DC_FAMILY_UWATEC_SMART, 0x13},
{"Uwatec", "Smart Com", DC_FAMILY_UWATEC_SMART, 0x14},
{"Uwatec", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x15},
{"Uwatec", "Smart Tec", DC_FAMILY_UWATEC_SMART, 0x18},
{"Uwatec", "Galileo Trimix",DC_FAMILY_UWATEC_SMART, 0x19},
{"Uwatec", "Smart Z", DC_FAMILY_UWATEC_SMART, 0x1C},
@ -163,7 +164,9 @@ static const dc_descriptor_t g_descriptors[] = {
{"Oceanic", "Atom 3.1", DC_FAMILY_OCEANIC_ATOM2, 0x4456},
{"Aeris", "A300 AI", DC_FAMILY_OCEANIC_ATOM2, 0x4457},
{"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458},
{"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545},
{"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548},
{"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B},
/* Mares Nemo */
{"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0},
{"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0},
@ -186,6 +189,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Mares", "Icon HD Net Ready", DC_FAMILY_MARES_ICONHD , 0x15},
{"Mares", "Puck Pro", DC_FAMILY_MARES_ICONHD , 0x18},
{"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19},
{"Mares", "Puck 2", DC_FAMILY_MARES_ICONHD , 0x1F},
/* Heinrichs Weikamp */
{"Heinrichs Weikamp", "OSTC", DC_FAMILY_HW_OSTC, 0},
{"Heinrichs Weikamp", "OSTC Mk2", DC_FAMILY_HW_OSTC, 1},
@ -201,6 +205,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Zeagle", "N2iTiON3", DC_FAMILY_ZEAGLE_N2ITION3, 0},
{"Apeks", "Quantum X", DC_FAMILY_ZEAGLE_N2ITION3, 0},
{"Dive Rite", "NiTek Trio", DC_FAMILY_ZEAGLE_N2ITION3, 0},
{"Scubapro", "XTender 5", DC_FAMILY_ZEAGLE_N2ITION3, 0},
/* Atomic Aquatics Cobalt */
#ifdef HAVE_LIBUSB
{"Atomic Aquatics", "Cobalt", DC_FAMILY_ATOMICS_COBALT, 0},

View File

@ -322,6 +322,10 @@ dc_device_close (dc_device_t *device)
if (device->vtable->close == NULL)
return DC_STATUS_UNSUPPORTED;
// Disable the cancellation callback.
device->cancel_callback = NULL;
device->cancel_userdata = NULL;
return device->vtable->close (device);
}

View File

@ -111,6 +111,9 @@ hw_frog_transfer (hw_frog_device_t *device,
{
dc_device_t *abstract = (dc_device_t *) device;
if (device_is_cancelled (abstract))
return DC_STATUS_CANCELLED;
// Send the command.
unsigned char command[1] = {cmd};
int n = serial_write (device->port, command, sizeof (command));

View File

@ -108,6 +108,9 @@ hw_ostc3_transfer (hw_ostc3_device_t *device,
{
dc_device_t *abstract = (dc_device_t *) device;
if (device_is_cancelled (abstract))
return DC_STATUS_CANCELLED;
// Send the command.
unsigned char command[1] = {cmd};
int n = serial_write (device->port, command, sizeof (command));
@ -392,8 +395,13 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi
unsigned int idx = (latest + RB_LOGBOOK_COUNT - i) % RB_LOGBOOK_COUNT;
unsigned int offset = idx * RB_LOGBOOK_SIZE;
// Get the firmware version.
unsigned int firmware = array_uint16_be (header + offset + 0x30);
// Calculate the profile length.
unsigned int length = RB_LOGBOOK_SIZE + array_uint24_le (header + offset + 9) - 6;
if (firmware >= 93)
length += 3;
// Check the fingerprint data.
if (memcmp (header + offset + 12, device->fingerprint, sizeof (device->fingerprint)) == 0)
@ -428,8 +436,13 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi
unsigned int idx = (latest + RB_LOGBOOK_COUNT - i) % RB_LOGBOOK_COUNT;
unsigned int offset = idx * RB_LOGBOOK_SIZE;
// Get the firmware version.
unsigned int firmware = array_uint16_be (header + offset + 0x30);
// Calculate the profile length.
unsigned int length = RB_LOGBOOK_SIZE + array_uint24_le (header + offset + 9) - 6;
if (firmware >= 93)
length += 3;
// Download the dive.
unsigned char number[1] = {idx};

View File

@ -482,6 +482,8 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
unsigned int nbits = 0;
unsigned int events = 0;
while (data[offset - 1] & 0x80) {
if (nbits && version != 0x23)
break;
if (offset + 1 > size)
return DC_STATUS_DATAFORMAT;
events |= data[offset] << nbits;
@ -594,13 +596,27 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
}
}
// SetPoint Change
if ((events & 0x40) && (version != 0x23)) {
if (offset + 1 > size)
return DC_STATUS_DATAFORMAT;
sample.setpoint = data[offset] / 100.0;
if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
offset++;
if (version != 0x23) {
// SetPoint Change
if (events & 0x40) {
if (offset + 1 > size)
return DC_STATUS_DATAFORMAT;
sample.setpoint = data[offset] / 100.0;
if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
offset++;
}
// Bailout Event
if (events & 0x80) {
if (offset + 2 > size)
return DC_STATUS_DATAFORMAT;
sample.event.type = SAMPLE_EVENT_GASCHANGE2;
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = data[offset] | (data[offset + 1] << 16);
if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
offset += 2;
}
}
}

View File

@ -48,6 +48,7 @@
#define ICONHDNET 0x15
#define PUCKPRO 0x18
#define NEMOWIDE2 0x19
#define PUCK2 0x1F
#define ACK 0xAA
#define EOF 0xEA
@ -89,10 +90,16 @@ static const mares_iconhd_layout_t mares_iconhd_layout = {
0x100000, /* rb_profile_end */
};
static const mares_iconhd_layout_t mares_iconhdnet_layout = {
0x100000, /* memsize */
0x00E000, /* rb_profile_begin */
0x100000, /* rb_profile_end */
};
static const mares_iconhd_layout_t mares_matrix_layout = {
0x40000, /* memsize */
0x0A000, /* rb_profile_begin */
0x40000, /* rb_profile_end */
0x3E000, /* rb_profile_end */
};
static unsigned int
@ -121,6 +128,9 @@ mares_iconhd_transfer (mares_iconhd_device_t *device,
assert (csize >= 2);
if (device_is_cancelled (abstract))
return DC_STATUS_CANCELLED;
// Send the command header to the dive computer.
int n = serial_write (device->port, command, 2);
if (n != 2) {
@ -261,9 +271,12 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
device->port = NULL;
memset (device->fingerprint, 0, sizeof (device->fingerprint));
memset (device->version, 0, sizeof (device->version));
if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO) {
if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO || model == PUCK2) {
device->layout = &mares_matrix_layout;
device->packetsize = 64;
} else if (model == ICONHDNET) {
device->layout = &mares_iconhdnet_layout;
device->packetsize = 0;
} else {
device->layout = &mares_iconhd_layout;
device->packetsize = 0;
@ -278,7 +291,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
}
// Set the serial communication protocol (256000 8N1).
if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO) {
if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO || model == PUCK2) {
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_EVEN, 1, SERIAL_FLOWCONTROL_NONE);
} else {
rc = serial_configure (device->port, BAUDRATE, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);

View File

@ -55,6 +55,27 @@ static const dc_parser_vtable_t mares_iconhd_parser_vtable = {
};
/* Find how many gas mixes are in use */
static unsigned int
mares_iconhd_parser_count_active_gas_mixes (const unsigned char *p, unsigned int air)
{
if (air) {
return 1;
} else {
// Count the number of active gas mixes. The active gas
// mixes are always first, so we stop counting as soon
// as the first gas marked as disabled is found.
unsigned int i = 0;
while (i < 3) {
if (p[0x14 + i * 4 + 1] & 0x80)
break;
i++;
}
return i;
}
}
dc_status_t
mares_iconhd_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
{
@ -163,20 +184,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
*((double *) value) = array_uint16_le (p + 0x04) / 10.0;
break;
case DC_FIELD_GASMIX_COUNT:
if (air) {
*((unsigned int *) value) = 1;
} else {
// Count the number of active gas mixes. The active gas
// mixes are always first, so we stop counting as soon
// as the first gas marked as disabled is found.
unsigned int i = 0;
while (i < 3) {
if (p[0x14 + i * 4 + 1] & 0x80)
break;
i++;
}
*((unsigned int *) value) = i;
}
*((unsigned int *) value) = mares_iconhd_parser_count_active_gas_mixes (p, air);
break;
case DC_FIELD_GASMIX:
if (air)
@ -186,6 +194,10 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
gasmix->helium = 0.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
break;
case DC_FIELD_ATMOSPHERIC:
// Pressure (1/8 millibar)
*((double *) value) = array_uint16_le (p + 0x26) / 8000.0;
break;
default:
return DC_STATUS_UNSUPPORTED;
}
@ -215,6 +227,10 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
if (abstract->size < length || length < header + 4)
return DC_STATUS_DATAFORMAT;
const unsigned char *p = abstract->data + length - header;
unsigned int air = (p[0] & 0x02) == 0;
const unsigned char *data = abstract->data;
unsigned int size = length - header;
@ -223,6 +239,11 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
unsigned int offset = 4;
unsigned int nsamples = 0;
// Previous gas mix - initialize with impossible value
unsigned int gasmix_previous = 0xFFFFFFFF;
unsigned int ngasmixes = mares_iconhd_parser_count_active_gas_mixes (p, air);
while (offset + samplesize <= size) {
dc_sample_value_t sample = {0};
@ -237,10 +258,28 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
// Temperature (1/10 °C).
unsigned int temperature = array_uint16_le (data + offset + 2);
unsigned int temperature = array_uint16_le (data + offset + 2) & 0x0FFF;
sample.temperature = temperature / 10.0;
if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
// Current gas mix
unsigned int gasmix = (data[offset + 3] & 0xF0) >> 4;
if (gasmix >= ngasmixes) {
return DC_STATUS_DATAFORMAT;
}
if (gasmix != gasmix_previous) {
unsigned int o2 = 0;
if (air)
o2 = 21;
else
o2 = p[0x14 + gasmix * 4];
sample.event.type = SAMPLE_EVENT_GASCHANGE;
sample.event.time = 0;
sample.event.value = o2;
if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
gasmix_previous = gasmix;
}
offset += samplesize;
nsamples++;

View File

@ -108,16 +108,27 @@ static const oceanic_common_version_t oceanic_default_version[] = {
static const oceanic_common_version_t tusa_zenair_version[] = {
{"TUZENAIR \0\0 512K"},
{"AMPHOSSW \0\0 512K"},
};
static const oceanic_common_version_t oceanic_oc1_version[] = {
{"OCWATCH R\0\0 1024"},
{"OCEANVT4 \0\0 1024"},
{"OC1WATCH \0\0 1024"},
{"OCEATOM3 \0\0 1024"},
{"OCSWATCH \0\0 1024"},
{"OCEAVT41 \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"},
};
@ -234,6 +245,45 @@ static const oceanic_common_layout_t oceanic_oc1_layout = {
1 /* pt_mode_logbook */
};
static const oceanic_common_layout_t oceanic_oci_layout = {
0x20000, /* memsize */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x10C0, /* rb_logbook_begin */
0x1400, /* rb_logbook_end */
8, /* rb_logbook_entry_size */
0x1400, /* rb_profile_begin */
0x1FE00, /* rb_profile_end */
0, /* pt_mode_global */
1 /* pt_mode_logbook */
};
static const oceanic_common_layout_t oceanic_atom3_layout = {
0x20000, /* memsize */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0400, /* rb_logbook_begin */
0x0A40, /* rb_logbook_end */
8, /* rb_logbook_entry_size */
0x0A40, /* rb_profile_begin */
0x1FE00, /* rb_profile_end */
0, /* pt_mode_global */
1 /* pt_mode_logbook */
};
static const oceanic_common_layout_t oceanic_vt4_layout = {
0x20000, /* memsize */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0420, /* rb_logbook_begin */
0x0A40, /* rb_logbook_end */
8, /* rb_logbook_entry_size */
0x0A40, /* rb_profile_begin */
0x1FE00, /* rb_profile_end */
0, /* pt_mode_global */
1 /* pt_mode_logbook */
};
static const oceanic_common_layout_t oceanic_veo1_layout = {
0x0400, /* memsize */
0x0000, /* cf_devinfo */
@ -434,6 +484,12 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char
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, oceanic_veo1_version)) {
device->base.layout = &oceanic_veo1_layout;
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_reactpro_version)) {

View File

@ -45,6 +45,7 @@
#define VEO20 0x4359
#define VEO30 0x435A
#define ZENAIR 0x4442
#define ATMOSAI2 0x4443
#define PROPLUS21 0x4444
#define GEO20 0x4446
#define VT4 0x4447
@ -57,7 +58,9 @@
#define EPICB 0x4453
#define ATOM31 0x4456
#define A300AI 0x4457
#define AMPHOS 0x4545
#define PROPLUS3 0x4548
#define OCI 0x454B
typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t;
@ -166,6 +169,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
case ATOM3:
case ATOM31:
case A300AI:
case OCI:
datetime->year = ((p[5] & 0xE0) >> 5) + ((p[7] & 0xE0) >> 2) + 2000;
datetime->month = (p[3] & 0x0F);
datetime->day = ((p[0] & 0x80) >> 3) + ((p[3] & 0xF0) >> 4);
@ -175,7 +179,6 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
case VT3:
case VEO20:
case VEO30:
case GEO20:
case DG03:
datetime->year = ((p[3] & 0xE0) >> 1) + (p[4] & 0x0F) + 2000;
datetime->month = (p[4] & 0xF0) >> 4;
@ -184,6 +187,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
datetime->minute = bcd2dec (p[0]);
break;
case ZENAIR:
case AMPHOS:
datetime->year = (p[3] & 0x0F) + 2000;
datetime->month = (p[7] & 0xF0) >> 4;
datetime->day = ((p[3] & 0x80) >> 3) + ((p[5] & 0xF0) >> 4);
@ -201,7 +205,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
default:
datetime->year = bcd2dec (((p[3] & 0xC0) >> 2) + (p[4] & 0x0F)) + 2000;
datetime->month = (p[4] & 0xF0) >> 4;
if (parser->model == T3)
if (parser->model == T3 || parser->model == GEO20)
datetime->day = p[3] & 0x3F;
else
datetime->day = bcd2dec (p[3] & 0x3F);
@ -394,14 +398,15 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
}
unsigned int samplesize = PAGESIZE / 2;
if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C)
if (parser->model == OC1A || parser->model == OC1B ||
parser->model == OC1C || parser->model == OCI)
samplesize = PAGESIZE;
else if (parser->model == F10)
samplesize = 2;
unsigned int have_temperature = 1, have_pressure = 1;
if (parser->model == VEO30 || parser->model == OCS ||
parser->model == ELEMENT2) {
parser->model == ELEMENT2 || parser->model == VEO20) {
have_pressure = 0;
} else if (parser->model == F10) {
have_temperature = 0;
@ -504,7 +509,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
temperature = data[offset + 6];
} else if (parser->model == GEO20 || parser->model == VEO20 ||
parser->model == VEO30 || parser->model == OC1A ||
parser->model == OC1B || parser->model == OC1C) {
parser->model == OC1B || parser->model == OC1C ||
parser->model == OCI) {
temperature = data[offset + 3];
} else if (parser->model == OCS) {
temperature = data[offset + 1];
@ -515,7 +521,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
if (parser->model == DG03 || parser->model == PROPLUS3)
sign = (~data[offset + 5] & 0x04) >> 2;
else if (parser->model == ATOM2 || parser->model == PROPLUS21 ||
parser->model == EPICA || parser->model == EPICB)
parser->model == EPICA || parser->model == EPICB ||
parser->model == ATMOSAI2 || parser->model == AMPHOS)
sign = (data[offset + 0] & 0x80) >> 7;
else
sign = (~data[offset + 0] & 0x80) >> 7;
@ -530,7 +537,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
// Tank Pressure (psi)
if (have_pressure) {
if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C)
if (parser->model == OC1A || parser->model == OC1B ||
parser->model == OC1C || parser->model == OCI)
pressure = (data[offset + 10] + (data[offset + 11] << 8)) & 0x0FFF;
else if (parser->model == VT4 || parser->model == VT41||
parser->model == ATOM3 || parser->model == ATOM31 ||
@ -548,7 +556,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
unsigned int depth;
if (parser->model == GEO20 || parser->model == VEO20 ||
parser->model == VEO30 || parser->model == OC1A ||
parser->model == OC1B || parser->model == OC1C)
parser->model == OC1B || parser->model == OC1C ||
parser->model == OCI)
depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF;
else if (parser->model == ATOM1)
depth = data[offset + 3] * 16;

View File

@ -148,6 +148,8 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned
const unsigned char end[] = {END};
const unsigned char esc_end[] = {ESC, ESC_END};
const unsigned char esc_esc[] = {ESC, ESC_ESC};
unsigned char buffer[32];
unsigned int nbytes = 0;
#if 0
// Send an initial END character to flush out any data that may have
@ -179,15 +181,28 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned
break;
}
n = serial_write (device->port, seq, len);
if (n != len) {
return EXITCODE(n);
// Flush the buffer if necessary.
if (nbytes + len + sizeof(end) > sizeof(buffer)) {
n = serial_write (device->port, buffer, nbytes);
if (n != nbytes) {
return EXITCODE(n);
}
nbytes = 0;
}
// Append the escaped character.
memcpy(buffer + nbytes, seq, len);
nbytes += len;
}
// Send the END character to indicate the end of the packet.
n = serial_write (device->port, end, sizeof (end));
if (n != sizeof (end)) {
// Append the END character to indicate the end of the packet.
memcpy(buffer + nbytes, end, sizeof(end));
nbytes += sizeof(end);
// Flush the buffer.
n = serial_write (device->port, buffer, nbytes);
if (n != nbytes) {
return EXITCODE(n);
}
@ -266,6 +281,9 @@ shearwater_common_transfer (shearwater_common_device_t *device, const unsigned c
if (isize > SZ_PACKET || osize > SZ_PACKET)
return DC_STATUS_INVALIDARGS;
if (device_is_cancelled (abstract))
return DC_STATUS_CANCELLED;
// Setup the request packet.
packet[0] = 0xFF;
packet[1] = 0x01;

View File

@ -88,7 +88,7 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig
// Initialize the base class.
parser->petrel = petrel;
if (petrel) {
parser_init (&parser->base, context, &shearwater_predator_parser_vtable);
parser_init (&parser->base, context, &shearwater_petrel_parser_vtable);
} else {
parser_init (&parser->base, context, &shearwater_predator_parser_vtable);
}

View File

@ -482,8 +482,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
case 0x06: // Mandatory Safety Stop Ceiling Error
sample.event.type = SAMPLE_EVENT_CEILING_SAFETYSTOP;
break;
case 0x07: // Unknown (Deco related)
sample.event.type = SAMPLE_EVENT_UNKNOWN;
case 0x07: // Below Deco Floor
sample.event.type = SAMPLE_EVENT_FLOOR;
break;
case 0x08: // Dive Time
sample.event.type = SAMPLE_EVENT_DIVETIME;

View File

@ -105,7 +105,7 @@ suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *na
}
// Set the timeout for receiving data (1000ms).
if (serial_set_timeout (device->port, -1) == -1) {
if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout.");
serial_close (device->port);
free (device);
@ -170,16 +170,34 @@ suunto_eon_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
}
// Receive the answer.
unsigned int nbytes = 0;
unsigned char answer[SZ_MEMORY + 1] = {0};
rc = serial_read (device->port, answer, sizeof (answer));
if (rc != sizeof (answer)) {
ERROR (abstract->context, "Failed to receive the answer.");
return EXITCODE (rc);
}
while (nbytes < sizeof(answer)) {
// Set the minimum packet size.
unsigned int len = 64;
// Update and emit a progress event.
progress.current += sizeof (answer);
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
// Increase the packet size if more data is immediately available.
int available = serial_get_received (device->port);
if (available > len)
len = available;
// Limit the packet size to the total size.
if (nbytes + len > sizeof(answer))
len = sizeof(answer) - nbytes;
// Read the packet.
int n = serial_read (device->port, answer + nbytes, len);
if (n != len) {
ERROR (abstract->context, "Failed to receive the answer.");
return EXITCODE (n);
}
// Update and emit a progress event.
progress.current += len;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
nbytes += len;
}
// Verify the checksum of the package.
unsigned char crc = answer[sizeof (answer) - 1];

View File

@ -39,6 +39,7 @@
#define ALADINTEC 0x12
#define ALADINTEC2G 0x13
#define SMARTCOM 0x14
#define ALADIN2G 0x15
#define SMARTTEC 0x18
#define GALILEOTRIMIX 0x19
#define SMARTZ 0x1C
@ -207,6 +208,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
break;
case GALILEO:
case GALILEOTRIMIX:
case ALADIN2G:
case MERIDIAN:
header = 152;
if (data[43] & 0x80) {
@ -456,6 +458,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
break;
case GALILEO:
case GALILEOTRIMIX:
case ALADIN2G:
case MERIDIAN:
header = 152;
if (data[43] & 0x80) {
@ -522,7 +525,8 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
// Process the type bits in the bitstream.
unsigned int id = 0;
if (parser->model == GALILEO || parser->model == GALILEOTRIMIX || parser->model == MERIDIAN) {
if (parser->model == GALILEO || parser->model == GALILEOTRIMIX ||
parser->model == ALADIN2G || parser->model == MERIDIAN) {
// Uwatec Galileo
id = uwatec_galileo_identify (data[offset]);
} else {

View File

@ -79,6 +79,9 @@ zeagle_n2ition3_packet (zeagle_n2ition3_device_t *device, const unsigned char co
assert (asize >= csize + 5);
if (device_is_cancelled (abstract))
return DC_STATUS_CANCELLED;
// Send the command to the device.
int n = serial_write (device->port, command, csize);
if (n != csize) {