Merge branch 'release-0.3'

Integrate the bugfixes from the stable branch.
This commit is contained in:
Jef Driesen 2013-05-13 22:46:30 +02:00
commit ee8b4e36ad
13 changed files with 156 additions and 31 deletions

View File

@ -245,7 +245,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
"OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning",
"gaschange2"};
static const char *decostop[] = {
"ndl", "deco", "deep", "safety"};
"ndl", "safety", "deco", "deep"};
sample_data_t *sampledata = (sample_data_t *) userdata;

View File

@ -124,6 +124,9 @@ cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const cha
return DC_STATUS_IO;
}
serial_sleep (device->port, 100);
serial_flush (device->port, SERIAL_QUEUE_BOTH);
*out = (dc_device_t *) device;
return DC_STATUS_SUCCESS;
@ -268,6 +271,13 @@ cressi_leonardo_device_foreach (dc_device_t *abstract, dc_dive_callback_t callba
return rc;
}
unsigned char *data = dc_buffer_get_data (buffer);
dc_event_devinfo_t devinfo;
devinfo.model = 0;
devinfo.firmware = 0;
devinfo.serial = array_uint32_le (data + 1);
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
rc = cressi_leonardo_extract_dives (abstract, dc_buffer_get_data (buffer),
dc_buffer_get_size (buffer), callback, userdata);
@ -328,7 +338,7 @@ cressi_leonardo_extract_dives (dc_device_t *abstract, const unsigned char data[]
if (header < RB_PROFILE_BEGIN || header + 2 > RB_PROFILE_END ||
footer < RB_PROFILE_BEGIN || footer + 2 > RB_PROFILE_END)
{
ERROR (abstract->context, "Invalid ringbuffer pointer detected.");
ERROR (context, "Invalid ringbuffer pointer detected.");
free (buffer);
return DC_STATUS_DATAFORMAT;
}
@ -337,7 +347,7 @@ cressi_leonardo_extract_dives (dc_device_t *abstract, const unsigned char data[]
unsigned int header2 = array_uint16_le (data + footer);
unsigned int footer2 = array_uint16_le (data + header);
if (header2 != header || footer2 != footer) {
ERROR (abstract->context, "Invalid ringbuffer pointer detected.");
ERROR (context, "Invalid ringbuffer pointer detected.");
free (buffer);
return DC_STATUS_DATAFORMAT;
}

View File

@ -76,20 +76,33 @@ static const dc_descriptor_t g_descriptors[] = {
{"Suunto", "D4i", DC_FAMILY_SUUNTO_D9, 0x19},
{"Suunto", "D6i", DC_FAMILY_SUUNTO_D9, 0x1A},
{"Suunto", "D9tx", DC_FAMILY_SUUNTO_D9, 0x1B},
{"Suunto", "DX", DC_FAMILY_SUUNTO_D9, 0x1C},
/* Uwatec Aladin */
{"Uwatec", "Aladin", DC_FAMILY_UWATEC_ALADIN, 0},
{"Uwatec", "Aladin Air Twin", DC_FAMILY_UWATEC_ALADIN, 0x1C},
{"Uwatec", "Aladin Sport Plus", DC_FAMILY_UWATEC_ALADIN, 0x3E},
{"Uwatec", "Aladin Pro", DC_FAMILY_UWATEC_ALADIN, 0x3F},
{"Uwatec", "Aladin Air Z", DC_FAMILY_UWATEC_ALADIN, 0x44},
{"Uwatec", "Aladin Air Z O2", DC_FAMILY_UWATEC_ALADIN, 0xA4},
{"Uwatec", "Aladin Air Z Nitrox", DC_FAMILY_UWATEC_ALADIN, 0xF4},
{"Uwatec", "Aladin Pro Ultra", DC_FAMILY_UWATEC_ALADIN, 0xFF},
/* Uwatec Memomouse */
{"Uwatec", "Memomouse", DC_FAMILY_UWATEC_MEMOMOUSE, 0},
/* Uwatec Smart */
#ifdef HAVE_IRDA
{"Uwatec", "Smart Pro", DC_FAMILY_UWATEC_SMART, 0x10},
{"Uwatec", "Galileo", DC_FAMILY_UWATEC_SMART, 0x11},
{"Uwatec", "Galileo Sol", DC_FAMILY_UWATEC_SMART, 0x11},
{"Uwatec", "Galileo Luna", DC_FAMILY_UWATEC_SMART, 0x11},
{"Uwatec", "Galileo Terra", DC_FAMILY_UWATEC_SMART, 0x11},
{"Uwatec", "Aladin Tec", DC_FAMILY_UWATEC_SMART, 0x12},
{"Uwatec", "Aladin Prime", DC_FAMILY_UWATEC_SMART, 0x12},
{"Uwatec", "Aladin Tec 2G", DC_FAMILY_UWATEC_SMART, 0x13},
{"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", "Smart Tec", DC_FAMILY_UWATEC_SMART, 0x18},
{"Uwatec", "Galileo Trimix",DC_FAMILY_UWATEC_SMART, 0x19},
{"Uwatec", "Smart Z", DC_FAMILY_UWATEC_SMART, 0x1C},
{"Subgear","XP Air", DC_FAMILY_UWATEC_SMART, 0x1C},
#endif
/* Reefnet */
{"Reefnet", "Sensus", DC_FAMILY_REEFNET_SENSUS, 1},
@ -97,10 +110,12 @@ static const dc_descriptor_t g_descriptors[] = {
{"Reefnet", "Sensus Ultra", DC_FAMILY_REEFNET_SENSUSULTRA, 3},
/* Oceanic VT Pro */
{"Oceanic", "Versa Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4155},
{"Aeris", "Atmos 2", DC_FAMILY_OCEANIC_VTPRO, 0x4158},
{"Oceanic", "Pro Plus 2", DC_FAMILY_OCEANIC_VTPRO, 0x4159},
{"Aeris", "Atmos AI", DC_FAMILY_OCEANIC_VTPRO, 0x4244},
{"Oceanic", "VT Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4245},
{"Sherwood", "Wisdom", DC_FAMILY_OCEANIC_VTPRO, 0x4246},
{"Aeris", "Elite", DC_FAMILY_OCEANIC_VTPRO, 0x424F},
/* Oceanic Veo 250 */
{"Genesis", "React Pro", DC_FAMILY_OCEANIC_VEO250, 0x4247},
{"Oceanic", "Veo 200", DC_FAMILY_OCEANIC_VEO250, 0x424B},
@ -123,6 +138,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x434E},
{"Sherwood", "Wisdom 2", DC_FAMILY_OCEANIC_ATOM2, 0x4350},
{"Sherwood", "Insight 2", DC_FAMILY_OCEANIC_ATOM2, 0x4353},
{"Genesis", "React Pro White", DC_FAMILY_OCEANIC_ATOM2, 0x4354},
{"Tusa", "Element II (IQ-750)", DC_FAMILY_OCEANIC_ATOM2, 0x4357},
{"Oceanic", "Veo 1.0", DC_FAMILY_OCEANIC_ATOM2, 0x4358},
{"Oceanic", "Veo 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4359},
@ -137,14 +153,18 @@ static const dc_descriptor_t g_descriptors[] = {
{"Oceanic", "Atom 3.0", DC_FAMILY_OCEANIC_ATOM2, 0x444C},
{"Hollis", "DG03", DC_FAMILY_OCEANIC_ATOM2, 0x444D},
{"Oceanic", "OCS", DC_FAMILY_OCEANIC_ATOM2, 0x4450},
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x4451},
{"Oceanic", "VT 4.1", DC_FAMILY_OCEANIC_ATOM2, 0x4452},
{"Aeris", "Epic", DC_FAMILY_OCEANIC_ATOM2, 0x4453},
{"Aeris", "Elite T3", DC_FAMILY_OCEANIC_ATOM2, 0x4455},
{"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},
{"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548},
/* Mares Nemo */
{"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0},
{"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0},
{"Mares", "Nemo Titanium",DC_FAMILY_MARES_NEMO, 0},
{"Mares", "Nemo Excel", DC_FAMILY_MARES_NEMO, 17},
{"Mares", "Nemo Apneist", DC_FAMILY_MARES_NEMO, 18},
/* Mares Puck */

View File

@ -152,6 +152,8 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
unsigned int air = (p[0] & 0x02) == 0;
if (value) {
switch (type) {
case DC_FIELD_DIVETIME:
@ -161,11 +163,27 @@ 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:
*((unsigned int *) value) = 3;
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;
}
break;
case DC_FIELD_GASMIX:
if (air)
gasmix->oxygen = 0.21;
else
gasmix->oxygen = p[0x14 + flags * 4] / 100.0;
gasmix->helium = 0.0;
gasmix->oxygen = p[0x14 + flags * 4] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
break;
default:

View File

@ -89,6 +89,7 @@ static const oceanic_common_version_t oceanic_atom2b_version[] = {
{"ELEMENT2 \0\0 512K"},
{"OCEVEO20 \0\0 512K"},
{"TUSAZEN \0\0 512K"},
{"PROPLUS3 \0\0 512K"},
};
static const oceanic_common_version_t oceanic_atom2c_version[] = {
@ -124,6 +125,10 @@ static const oceanic_common_version_t oceanic_veo1_version[] = {
{"OCEVEO10 \0\0 8K"},
};
static const oceanic_common_version_t oceanic_reactpro_version[] = {
{"REACPRO2 \0\0 512K"},
};
static const oceanic_common_layout_t aeris_f10_layout = {
0x10000, /* memsize */
0x0000, /* cf_devinfo */
@ -241,6 +246,18 @@ static const oceanic_common_layout_t oceanic_veo1_layout = {
0 /* pt_mode_logbook */
};
static const oceanic_common_layout_t oceanic_reactpro_layout = {
0xFFF0, /* memsize */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0400, /* rb_logbook_begin */
0x0600, /* rb_logbook_end */
8, /* rb_logbook_entry_size */
0x0600, /* rb_profile_begin */
0xFFF0, /* rb_profile_end */
1, /* pt_mode_global */
1 /* pt_mode_logbook */
};
static dc_status_t
oceanic_atom2_send (oceanic_atom2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char ack)
@ -418,6 +435,8 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char
device->base.layout = &oceanic_oc1_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 {
device->base.layout = &oceanic_default_layout;
}

View File

@ -41,6 +41,7 @@
#define COMPUMASK 0x4348
#define OC1A 0x434E
#define F10 0x434D
#define ELEMENT2 0x4357
#define VEO20 0x4359
#define VEO30 0x435A
#define ZENAIR 0x4442
@ -51,10 +52,12 @@
#define ATOM3 0x444C
#define DG03 0x444D
#define OCS 0x4450
#define OC1C 0x4451
#define VT41 0x4452
#define EPICB 0x4453
#define ATOM31 0x4456
#define A300AI 0x4457
#define PROPLUS3 0x4548
typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t;
@ -156,6 +159,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
switch (parser->model) {
case OC1A:
case OC1B:
case OC1C:
case OCS:
case VT4:
case VT41:
@ -262,7 +266,7 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
if (parser->model == DATAMASK || parser->model == COMPUMASK ||
parser->model == GEO || parser->model == GEO20 ||
parser->model == VEO20 || parser->model == VEO30 ||
parser->model == OCS) {
parser->model == OCS || parser->model == PROPLUS3) {
headersize -= PAGESIZE;
} else if (parser->model == VT4 || parser->model == VT41) {
headersize += PAGESIZE;
@ -353,7 +357,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
if (parser->model == DATAMASK || parser->model == COMPUMASK ||
parser->model == GEO || parser->model == GEO20 ||
parser->model == VEO20 || parser->model == VEO30 ||
parser->model == OCS) {
parser->model == OCS || parser->model == PROPLUS3) {
headersize -= PAGESIZE;
} else if (parser->model == VT4 || parser->model == VT41) {
headersize += PAGESIZE;
@ -390,13 +394,14 @@ 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 (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C)
samplesize = PAGESIZE;
else if (parser->model == F10)
samplesize = 2;
unsigned int have_temperature = 1, have_pressure = 1;
if (parser->model == VEO30 || parser->model == OCS) {
if (parser->model == VEO30 || parser->model == OCS ||
parser->model == ELEMENT2) {
have_pressure = 0;
} else if (parser->model == F10) {
have_temperature = 0;
@ -494,11 +499,12 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
} else {
// Temperature (°F)
if (have_temperature) {
if (parser->model == GEO || parser->model == ATOM1) {
if (parser->model == GEO || parser->model == ATOM1 ||
parser->model == ELEMENT2) {
temperature = data[offset + 6];
} else if (parser->model == GEO20 || parser->model == VEO20 ||
parser->model == VEO30 || parser->model == OC1A ||
parser->model == OC1B) {
parser->model == OC1B || parser->model == OC1C) {
temperature = data[offset + 3];
} else if (parser->model == OCS) {
temperature = data[offset + 1];
@ -506,7 +512,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
temperature = ((data[offset + 7] & 0xF0) >> 4) | ((data[offset + 7] & 0x0C) << 2) | ((data[offset + 5] & 0x0C) << 4);
} else {
unsigned int sign;
if (parser->model == DG03)
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)
@ -524,12 +530,12 @@ 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)
if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C)
pressure = (data[offset + 10] + (data[offset + 11] << 8)) & 0x0FFF;
else if (parser->model == VT4 || parser->model == VT41||
parser->model == ATOM3 || parser->model == ATOM31 ||
parser->model == ZENAIR ||parser->model == A300AI ||
parser->model == DG03)
parser->model == DG03 || parser->model == PROPLUS3)
pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5;
else
pressure -= data[offset + 1];
@ -542,7 +548,7 @@ 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 == OC1B || parser->model == OC1C)
depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF;
else if (parser->model == ATOM1)
depth = data[offset + 3] * 16;

View File

@ -31,6 +31,11 @@
#define ISINSTANCE(parser) dc_parser_isinstance((parser), &oceanic_veo250_parser_vtable)
#define REACTPRO 0x4247
#define VEO200 0x424B
#define VEO250 0x424C
#define REACTPROWHITE 0x4354
typedef struct oceanic_veo250_parser_t oceanic_veo250_parser_t;
struct oceanic_veo250_parser_t {
@ -128,8 +133,10 @@ oceanic_veo250_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dateti
datetime->minute = p[2];
datetime->second = 0;
if (parser->model == 0x424B || parser->model == 0x424C)
if (parser->model == VEO200 || parser->model == VEO250)
datetime->year += 3;
else if (parser->model == REACTPRO)
datetime->year += 2;
}
return DC_STATUS_SUCCESS;
@ -194,6 +201,7 @@ oceanic_veo250_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
static dc_status_t
oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
{
oceanic_veo250_parser_t *parser = (oceanic_veo250_parser_t *) abstract;
const unsigned char *data = abstract->data;
unsigned int size = abstract->size;
@ -202,7 +210,12 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
unsigned int time = 0;
unsigned int interval = 0;
switch (data[0x27] & 0x03) {
unsigned int interval_idx = data[0x27] & 0x03;
if (parser->model == REACTPRO || parser->model == REACTPROWHITE) {
interval_idx += 1;
interval_idx %= 4;
}
switch (interval_idx) {
case 0:
interval = 2;
break;
@ -244,7 +257,12 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
// Temperature (°F)
unsigned int temperature = data[offset + 7];
unsigned int temperature;
if (parser->model == REACTPRO || parser->model == REACTPROWHITE) {
temperature = data[offset + 6];
} else {
temperature = data[offset + 7];
}
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);

View File

@ -65,9 +65,11 @@ static const dc_device_vtable_t oceanic_vtpro_device_vtable = {
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[] = {

View File

@ -35,6 +35,8 @@
#include "parser-private.h"
#include "device-private.h"
#define REACTPROWHITE 0x4354
dc_status_t
dc_parser_new (dc_parser_t **out, dc_device_t *device)
{
@ -86,7 +88,10 @@ dc_parser_new (dc_parser_t **out, dc_device_t *device)
rc = oceanic_veo250_parser_create (&parser, context, device->devinfo.model);
break;
case DC_FAMILY_OCEANIC_ATOM2:
rc = oceanic_atom2_parser_create (&parser, context, device->devinfo.model);
if (device->devinfo.model == REACTPROWHITE)
rc = oceanic_veo250_parser_create (&parser, context, device->devinfo.model);
else
rc = oceanic_atom2_parser_create (&parser, context, device->devinfo.model);
break;
case DC_FAMILY_MARES_NEMO:
case DC_FAMILY_MARES_PUCK:

View File

@ -141,7 +141,7 @@ shearwater_predator_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *d
unsigned int ticks = array_uint32_be (data + 12);
if (!dc_datetime_localtime (datetime, ticks))
if (!dc_datetime_gmtime (datetime, ticks))
return DC_STATUS_DATAFORMAT;
return DC_STATUS_SUCCESS;

View File

@ -43,6 +43,7 @@
#define D4i 0x19
#define D6i 0x1A
#define D9tx 0x1B
#define DX 0x1C
typedef struct suunto_d9_device_t {
suunto_common2_device_t base;
@ -81,6 +82,14 @@ static const suunto_common2_layout_t suunto_d9tx_layout = {
0xEBF0 /* rb_profile_end */
};
static const suunto_common2_layout_t suunto_dx_layout = {
0x10000, /* memsize */
0x0017, /* fingerprint */
0x0024, /* serial */
0x019A, /* rb_profile_begin */
0xEBF0 /* rb_profile_end */
};
static dc_status_t
suunto_d9_device_autodetect (suunto_d9_device_t *device, unsigned int model)
@ -93,7 +102,7 @@ suunto_d9_device_autodetect (suunto_d9_device_t *device, unsigned int model)
// Use the model number as a hint to speedup the detection.
unsigned int hint = 0;
if (model == D4i || model == D6i || model == D9tx)
if (model == D4i || model == D6i || model == D9tx || model == DX)
hint = 1;
for (unsigned int i = 0; i < C_ARRAY_SIZE(baudrates); ++i) {
@ -188,6 +197,8 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam
model = device->base.version[0];
if (model == D4i || model == D6i || model == D9tx)
device->base.layout = &suunto_d9tx_layout;
else if (model == DX)
device->base.layout = &suunto_dx_layout;
else
device->base.layout = &suunto_d9_layout;

View File

@ -43,6 +43,7 @@
#define D4i 0x19
#define D6i 0x1A
#define D9tx 0x1B
#define DX 0x1C
#define AIR 0
#define NITROX 1
@ -132,7 +133,7 @@ suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
suunto_d9_parser_t *parser = (suunto_d9_parser_t*) abstract;
unsigned int offset = 0x11;
if (parser->model == HELO2)
if (parser->model == HELO2 || parser->model == DX)
offset = 0x17;
else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx)
offset = 0x13;
@ -143,7 +144,8 @@ suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
const unsigned char *p = abstract->data + offset;
if (datetime) {
if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) {
if (parser->model == D4i || parser->model == D6i ||
parser->model == D9tx || parser->model == DX) {
datetime->year = p[0] + (p[1] << 8);
datetime->month = p[2];
datetime->day = p[3];
@ -189,6 +191,9 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
} else if (parser->model == D9tx) {
gasmix_offset = 0x87;
gasmix_count = 8;
} else if (parser->model == DX) {
gasmix_offset = 0xC1;
gasmix_count = 11;
}
// Offset to the configuration data.
@ -196,7 +201,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
if (parser->model == D4) {
config += 1;
} else if (parser->model == HELO2 || parser->model == D4i ||
parser->model == D6i || parser->model == D9tx) {
parser->model == D6i || parser->model == D9tx ||
parser->model == DX) {
config = gasmix_offset + gasmix_count * 6;
}
if (config + 1 > size)
@ -208,6 +214,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
gasmodel_offset = 0x1F;
else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx)
gasmodel_offset = 0x1D;
else if (parser->model == DX)
gasmodel_offset = 0x21;
unsigned int gasmodel = data[gasmodel_offset];
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
@ -217,7 +225,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
case DC_FIELD_DIVETIME:
if (parser->model == D4)
*((unsigned int *) value) = array_uint16_le (data + 0x0B);
else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx)
else if (parser->model == D4i || parser->model == D6i ||
parser->model == D9tx || parser->model == DX)
*((unsigned int *) value) = array_uint16_le (data + 0x0D);
else if (parser->model == HELO2)
*((unsigned int *) value) = array_uint16_le (data + 0x0D) * 60;
@ -239,7 +248,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
gasmix->helium = 0.0;
gasmix->oxygen = 0.21;
} else if (parser->model == HELO2 || parser->model == D4i ||
parser->model == D6i || parser->model == D9tx) {
parser->model == D6i || parser->model == D9tx ||
parser->model == DX) {
gasmix->helium = data[gasmix_offset + 6 * flags + 2] / 100.0;
gasmix->oxygen = data[gasmix_offset + 6 * flags + 1] / 100.0;
} else {
@ -282,6 +292,9 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
} else if (parser->model == D9tx) {
gasmix_offset = 0x87;
gasmix_count = 8;
} else if (parser->model == DX) {
gasmix_offset = 0xC1;
gasmix_count = 11;
}
// Offset to the configuration data.
@ -289,7 +302,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
if (parser->model == D4) {
config += 1;
} else if (parser->model == HELO2 || parser->model == D4i ||
parser->model == D6i || parser->model == D9tx) {
parser->model == D6i || parser->model == D9tx ||
parser->model == DX) {
config = gasmix_offset + gasmix_count * 6;
}
if (config + 1 > size)
@ -297,7 +311,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
// Number of parameters in the configuration data.
unsigned int nparams = data[config];
if (nparams > MAXPARAMS)
if (nparams == 0 || nparams > MAXPARAMS)
return DC_STATUS_DATAFORMAT;
// Available divisor values.
@ -340,6 +354,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
if (parser->model == HELO2 || parser->model == D4i ||
parser->model == D6i || parser->model == D9tx)
interval_sample_offset = 0x1E;
else if (parser->model == DX)
interval_sample_offset = 0x22;
unsigned int interval_sample = data[interval_sample_offset];
if (interval_sample == 0)
return DC_STATUS_DATAFORMAT;

View File

@ -584,7 +584,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
break;
case TEMPERATURE:
if (table[id].absolute) {
temperature = value / 2.5;
temperature = svalue / 2.5;
have_temperature = 1;
} else {
temperature += svalue / 2.5;