Implement the new field api for the Oceanic devices.
This commit is contained in:
parent
643c04eca3
commit
061e647ecf
@ -46,10 +46,15 @@ typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t;
|
||||
struct oceanic_atom2_parser_t {
|
||||
parser_t base;
|
||||
unsigned int model;
|
||||
// Cached fields.
|
||||
unsigned int cached;
|
||||
unsigned int divetime;
|
||||
double maxdepth;
|
||||
};
|
||||
|
||||
static parser_status_t oceanic_atom2_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size);
|
||||
static parser_status_t oceanic_atom2_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime);
|
||||
static parser_status_t oceanic_atom2_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value);
|
||||
static parser_status_t oceanic_atom2_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata);
|
||||
static parser_status_t oceanic_atom2_parser_destroy (parser_t *abstract);
|
||||
|
||||
@ -57,7 +62,7 @@ static const parser_backend_t oceanic_atom2_parser_backend = {
|
||||
PARSER_TYPE_OCEANIC_ATOM2,
|
||||
oceanic_atom2_parser_set_data, /* set_data */
|
||||
oceanic_atom2_parser_get_datetime, /* datetime */
|
||||
NULL, /* fields */
|
||||
oceanic_atom2_parser_get_field, /* fields */
|
||||
oceanic_atom2_parser_samples_foreach, /* samples_foreach */
|
||||
oceanic_atom2_parser_destroy /* destroy */
|
||||
};
|
||||
@ -91,6 +96,9 @@ oceanic_atom2_parser_create (parser_t **out, unsigned int model)
|
||||
|
||||
// Set the default values.
|
||||
parser->model = model;
|
||||
parser->cached = 0;
|
||||
parser->divetime = 0;
|
||||
parser->maxdepth = 0.0;
|
||||
|
||||
*out = (parser_t*) parser;
|
||||
|
||||
@ -114,9 +122,16 @@ oceanic_atom2_parser_destroy (parser_t *abstract)
|
||||
static parser_status_t
|
||||
oceanic_atom2_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size)
|
||||
{
|
||||
oceanic_atom2_parser_t *parser = (oceanic_atom2_parser_t *) abstract;
|
||||
|
||||
if (! parser_is_oceanic_atom2 (abstract))
|
||||
return PARSER_STATUS_TYPE_MISMATCH;
|
||||
|
||||
// Reset the cache.
|
||||
parser->cached = 0;
|
||||
parser->divetime = 0;
|
||||
parser->maxdepth = 0.0;
|
||||
|
||||
return PARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -208,6 +223,76 @@ oceanic_atom2_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime)
|
||||
}
|
||||
|
||||
|
||||
static parser_status_t
|
||||
oceanic_atom2_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value)
|
||||
{
|
||||
oceanic_atom2_parser_t *parser = (oceanic_atom2_parser_t *) abstract;
|
||||
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = abstract->size;
|
||||
|
||||
unsigned int length = 11 * PAGESIZE / 2;
|
||||
unsigned int header = 4 * PAGESIZE;
|
||||
unsigned int footer = size - PAGESIZE;
|
||||
if (parser->model == GEO || parser->model == DATAMASK ||
|
||||
parser->model == GEO20 || parser->model == VEO20 ||
|
||||
parser->model == VEO30)
|
||||
{
|
||||
length -= PAGESIZE;
|
||||
header -= PAGESIZE;
|
||||
}
|
||||
|
||||
if (size < length)
|
||||
return PARSER_STATUS_ERROR;
|
||||
|
||||
if (!parser->cached) {
|
||||
sample_statistics_t statistics = SAMPLE_STATISTICS_INITIALIZER;
|
||||
parser_status_t rc = oceanic_atom2_parser_samples_foreach (
|
||||
abstract, sample_statistics_cb, &statistics);
|
||||
if (rc != PARSER_STATUS_SUCCESS)
|
||||
return rc;
|
||||
|
||||
parser->cached = 1;
|
||||
parser->divetime = statistics.divetime;
|
||||
parser->maxdepth = statistics.maxdepth;
|
||||
}
|
||||
|
||||
gasmix_t *gasmix = (gasmix_t *) value;
|
||||
|
||||
unsigned int nitrox = 0;
|
||||
|
||||
if (value) {
|
||||
switch (type) {
|
||||
case FIELD_TYPE_DIVETIME:
|
||||
*((unsigned int *) value) = parser->divetime;
|
||||
break;
|
||||
case FIELD_TYPE_MAXDEPTH:
|
||||
*((double *) value) = array_uint16_le (data + footer + 4) / 16.0 * FEET;
|
||||
break;
|
||||
case FIELD_TYPE_GASMIX_COUNT:
|
||||
if (parser->model == DATAMASK)
|
||||
*((unsigned int *) value) = 1;
|
||||
else
|
||||
*((unsigned int *) value) = 3;
|
||||
break;
|
||||
case FIELD_TYPE_GASMIX:
|
||||
if (parser->model == DATAMASK)
|
||||
nitrox = data[header + 3];
|
||||
else
|
||||
nitrox = data[header + 4 + flags];
|
||||
gasmix->helium = 0.0;
|
||||
gasmix->oxygen = (nitrox ? nitrox / 100.0 : 0.21);
|
||||
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
|
||||
break;
|
||||
default:
|
||||
return PARSER_STATUS_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
return PARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static parser_status_t
|
||||
oceanic_atom2_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata)
|
||||
{
|
||||
|
||||
@ -33,10 +33,15 @@ typedef struct oceanic_veo250_parser_t oceanic_veo250_parser_t;
|
||||
struct oceanic_veo250_parser_t {
|
||||
parser_t base;
|
||||
unsigned int model;
|
||||
// Cached fields.
|
||||
unsigned int cached;
|
||||
unsigned int divetime;
|
||||
double maxdepth;
|
||||
};
|
||||
|
||||
static parser_status_t oceanic_veo250_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size);
|
||||
static parser_status_t oceanic_veo250_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime);
|
||||
static parser_status_t oceanic_veo250_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value);
|
||||
static parser_status_t oceanic_veo250_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata);
|
||||
static parser_status_t oceanic_veo250_parser_destroy (parser_t *abstract);
|
||||
|
||||
@ -44,7 +49,7 @@ static const parser_backend_t oceanic_veo250_parser_backend = {
|
||||
PARSER_TYPE_OCEANIC_VEO250,
|
||||
oceanic_veo250_parser_set_data, /* set_data */
|
||||
oceanic_veo250_parser_get_datetime, /* datetime */
|
||||
NULL, /* fields */
|
||||
oceanic_veo250_parser_get_field, /* fields */
|
||||
oceanic_veo250_parser_samples_foreach, /* samples_foreach */
|
||||
oceanic_veo250_parser_destroy /* destroy */
|
||||
};
|
||||
@ -78,6 +83,9 @@ oceanic_veo250_parser_create (parser_t **out, unsigned int model)
|
||||
|
||||
// Set the default values.
|
||||
parser->model = model;
|
||||
parser->cached = 0;
|
||||
parser->divetime = 0;
|
||||
parser->maxdepth = 0.0;
|
||||
|
||||
*out = (parser_t*) parser;
|
||||
|
||||
@ -101,9 +109,16 @@ oceanic_veo250_parser_destroy (parser_t *abstract)
|
||||
static parser_status_t
|
||||
oceanic_veo250_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size)
|
||||
{
|
||||
oceanic_veo250_parser_t *parser = (oceanic_veo250_parser_t *) abstract;
|
||||
|
||||
if (! parser_is_oceanic_veo250 (abstract))
|
||||
return PARSER_STATUS_TYPE_MISMATCH;
|
||||
|
||||
// Reset the cache.
|
||||
parser->cached = 0;
|
||||
parser->divetime = 0;
|
||||
parser->maxdepth = 0.0;
|
||||
|
||||
return PARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -133,6 +148,62 @@ oceanic_veo250_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime)
|
||||
return PARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static parser_status_t
|
||||
oceanic_veo250_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value)
|
||||
{
|
||||
oceanic_veo250_parser_t *parser = (oceanic_veo250_parser_t *) abstract;
|
||||
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = abstract->size;
|
||||
|
||||
if (size < 7 * PAGESIZE / 2)
|
||||
return PARSER_STATUS_ERROR;
|
||||
|
||||
if (!parser->cached) {
|
||||
sample_statistics_t statistics = SAMPLE_STATISTICS_INITIALIZER;
|
||||
parser_status_t rc = oceanic_veo250_parser_samples_foreach (
|
||||
abstract, sample_statistics_cb, &statistics);
|
||||
if (rc != PARSER_STATUS_SUCCESS)
|
||||
return rc;
|
||||
|
||||
parser->cached = 1;
|
||||
parser->divetime = statistics.divetime;
|
||||
parser->maxdepth = statistics.maxdepth;
|
||||
}
|
||||
|
||||
unsigned int footer = size - PAGESIZE;
|
||||
|
||||
gasmix_t *gasmix = (gasmix_t *) value;
|
||||
|
||||
if (value) {
|
||||
switch (type) {
|
||||
case FIELD_TYPE_DIVETIME:
|
||||
*((unsigned int *) value) = data[footer + 3] * 60;
|
||||
break;
|
||||
case FIELD_TYPE_MAXDEPTH:
|
||||
*((double *) value) = parser->maxdepth;
|
||||
break;
|
||||
case FIELD_TYPE_GASMIX_COUNT:
|
||||
*((unsigned int *) value) = 1;
|
||||
break;
|
||||
case FIELD_TYPE_GASMIX:
|
||||
gasmix->helium = 0.0;
|
||||
if (data[footer + 6])
|
||||
gasmix->oxygen = data[footer + 6] / 100.0;
|
||||
else
|
||||
gasmix->oxygen = 0.21;
|
||||
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
|
||||
break;
|
||||
default:
|
||||
return PARSER_STATUS_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
return PARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static parser_status_t
|
||||
oceanic_veo250_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata)
|
||||
{
|
||||
|
||||
@ -32,10 +32,15 @@ typedef struct oceanic_vtpro_parser_t oceanic_vtpro_parser_t;
|
||||
|
||||
struct oceanic_vtpro_parser_t {
|
||||
parser_t base;
|
||||
// Cached fields.
|
||||
unsigned int cached;
|
||||
unsigned int divetime;
|
||||
double maxdepth;
|
||||
};
|
||||
|
||||
static parser_status_t oceanic_vtpro_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size);
|
||||
static parser_status_t oceanic_vtpro_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime);
|
||||
static parser_status_t oceanic_vtpro_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value);
|
||||
static parser_status_t oceanic_vtpro_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata);
|
||||
static parser_status_t oceanic_vtpro_parser_destroy (parser_t *abstract);
|
||||
|
||||
@ -43,7 +48,7 @@ static const parser_backend_t oceanic_vtpro_parser_backend = {
|
||||
PARSER_TYPE_OCEANIC_VTPRO,
|
||||
oceanic_vtpro_parser_set_data, /* set_data */
|
||||
oceanic_vtpro_parser_get_datetime, /* datetime */
|
||||
NULL, /* fields */
|
||||
oceanic_vtpro_parser_get_field, /* fields */
|
||||
oceanic_vtpro_parser_samples_foreach, /* samples_foreach */
|
||||
oceanic_vtpro_parser_destroy /* destroy */
|
||||
};
|
||||
@ -75,6 +80,11 @@ oceanic_vtpro_parser_create (parser_t **out)
|
||||
// Initialize the base class.
|
||||
parser_init (&parser->base, &oceanic_vtpro_parser_backend);
|
||||
|
||||
// Set the default values.
|
||||
parser->cached = 0;
|
||||
parser->divetime = 0;
|
||||
parser->maxdepth = 0.0;
|
||||
|
||||
*out = (parser_t*) parser;
|
||||
|
||||
return PARSER_STATUS_SUCCESS;
|
||||
@ -97,9 +107,16 @@ oceanic_vtpro_parser_destroy (parser_t *abstract)
|
||||
static parser_status_t
|
||||
oceanic_vtpro_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size)
|
||||
{
|
||||
oceanic_vtpro_parser_t *parser = (oceanic_vtpro_parser_t *) abstract;
|
||||
|
||||
if (! parser_is_oceanic_vtpro (abstract))
|
||||
return PARSER_STATUS_TYPE_MISMATCH;
|
||||
|
||||
// Reset the cache.
|
||||
parser->cached = 0;
|
||||
parser->divetime = 0;
|
||||
parser->maxdepth = 0.0;
|
||||
|
||||
return PARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -135,6 +152,61 @@ oceanic_vtpro_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime)
|
||||
}
|
||||
|
||||
|
||||
static parser_status_t
|
||||
oceanic_vtpro_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value)
|
||||
{
|
||||
oceanic_vtpro_parser_t *parser = (oceanic_vtpro_parser_t *) abstract;
|
||||
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = abstract->size;
|
||||
|
||||
if (size < 7 * PAGESIZE / 2)
|
||||
return PARSER_STATUS_ERROR;
|
||||
|
||||
if (!parser->cached) {
|
||||
sample_statistics_t statistics = SAMPLE_STATISTICS_INITIALIZER;
|
||||
parser_status_t rc = oceanic_vtpro_parser_samples_foreach (
|
||||
abstract, sample_statistics_cb, &statistics);
|
||||
if (rc != PARSER_STATUS_SUCCESS)
|
||||
return rc;
|
||||
|
||||
parser->cached = 1;
|
||||
parser->divetime = statistics.divetime;
|
||||
parser->maxdepth = statistics.maxdepth;
|
||||
}
|
||||
|
||||
unsigned int footer = size - PAGESIZE;
|
||||
|
||||
gasmix_t *gasmix = (gasmix_t *) value;
|
||||
|
||||
if (value) {
|
||||
switch (type) {
|
||||
case FIELD_TYPE_DIVETIME:
|
||||
*((unsigned int *) value) = parser->divetime;
|
||||
break;
|
||||
case FIELD_TYPE_MAXDEPTH:
|
||||
*((double *) value) = (data[footer + 0] + ((data[footer + 1] & 0x0F) << 8)) * 1;
|
||||
break;
|
||||
case FIELD_TYPE_GASMIX_COUNT:
|
||||
*((unsigned int *) value) = 1;
|
||||
break;
|
||||
case FIELD_TYPE_GASMIX:
|
||||
gasmix->helium = 0.0;
|
||||
if (data[footer + 3])
|
||||
gasmix->oxygen = data[footer + 3] / 100.0;
|
||||
else
|
||||
gasmix->oxygen = 0.21;
|
||||
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
|
||||
break;
|
||||
default:
|
||||
return PARSER_STATUS_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
return PARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static parser_status_t
|
||||
oceanic_vtpro_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata)
|
||||
{
|
||||
|
||||
@ -56,6 +56,16 @@ struct parser_backend_t {
|
||||
void
|
||||
parser_init (parser_t *parser, const parser_backend_t *backend);
|
||||
|
||||
typedef struct sample_statistics_t {
|
||||
unsigned int divetime;
|
||||
double maxdepth;
|
||||
} sample_statistics_t;
|
||||
|
||||
#define SAMPLE_STATISTICS_INITIALIZER {0, 0.0}
|
||||
|
||||
void
|
||||
sample_statistics_cb (parser_sample_type_t type, parser_sample_value_t value, void *userdata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
19
src/parser.c
19
src/parser.c
@ -108,3 +108,22 @@ parser_destroy (parser_t *parser)
|
||||
|
||||
return parser->backend->destroy (parser);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sample_statistics_cb (parser_sample_type_t type, parser_sample_value_t value, void *userdata)
|
||||
{
|
||||
sample_statistics_t *statistics = (sample_statistics_t *) userdata;
|
||||
|
||||
switch (type) {
|
||||
case SAMPLE_TYPE_TIME:
|
||||
statistics->divetime = value.time;
|
||||
break;
|
||||
case SAMPLE_TYPE_DEPTH:
|
||||
if (statistics->maxdepth < value.depth)
|
||||
statistics->maxdepth = value.depth;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user