Add support for Cressi Goa gauge and freedives
The gauge and freedives have a slightly different data format compared to scuba dives. The main difference is the size of the header and two new sample types.
This commit is contained in:
parent
57cd11fffe
commit
c77a311a89
@ -28,9 +28,16 @@
|
||||
|
||||
#define ISINSTANCE(parser) dc_device_isinstance((parser), &cressi_goa_parser_vtable)
|
||||
|
||||
#define SZ_HEADER 0x61
|
||||
#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
|
||||
@ -63,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)
|
||||
{
|
||||
@ -102,7 +116,19 @@ 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;
|
||||
|
||||
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;
|
||||
@ -125,11 +151,19 @@ cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
|
||||
{
|
||||
cressi_goa_parser_t *parser = (cressi_goa_parser_t *) abstract;
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = abstract->size;
|
||||
|
||||
if (abstract->size < SZ_HEADER)
|
||||
if (size < SZ_HEADER)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
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;
|
||||
@ -153,7 +187,7 @@ cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
|
||||
*((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;
|
||||
@ -190,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};
|
||||
|
||||
@ -204,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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user