diff --git a/msvc/libdivecomputer.vcproj b/msvc/libdivecomputer.vcproj
index f7b7883..c194f9f 100644
--- a/msvc/libdivecomputer.vcproj
+++ b/msvc/libdivecomputer.vcproj
@@ -478,6 +478,10 @@
RelativePath="..\src\uwatec_aladin.c"
>
+
+
@@ -796,6 +800,10 @@
RelativePath="..\src\uwatec_aladin.h"
>
+
+
diff --git a/src/divesystem_idive_parser.c b/src/divesystem_idive_parser.c
index ff9f480..f37d142 100644
--- a/src/divesystem_idive_parser.c
+++ b/src/divesystem_idive_parser.c
@@ -307,6 +307,13 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
divemode = mode;
}
+ // Setpoint
+ if (mode == SCR || mode == CCR) {
+ unsigned int setpoint = array_uint16_le (data + offset + 19);
+ sample.setpoint = setpoint / 1000.0;
+ if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
+ }
+
// Gaschange.
unsigned int o2 = data[offset + 10];
unsigned int he = data[offset + 11];
diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c
index f527c7e..444ed1e 100644
--- a/src/oceanic_atom2_parser.c
+++ b/src/oceanic_atom2_parser.c
@@ -979,7 +979,9 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
decostop = (data[offset + 5] & 0xF0) >> 4;
decotime = array_uint16_le(data + offset + 4) & 0x03FF;
have_deco = 1;
- } else if (parser->model == I200) {
+ } else if (parser->model == I200 || parser->model == I300 ||
+ parser->model == OC1A || parser->model == OC1B ||
+ parser->model == OC1C || parser->model == OCI) {
decostop = (data[offset + 7] & 0xF0) >> 4;
decotime = array_uint16_le(data + offset + 6) & 0x0FFF;
have_deco = 1;
@@ -1001,7 +1003,9 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
if (parser->model == ATOM31) {
rbt = array_uint16_le(data + offset + 6) & 0x01FF;
have_rbt = 1;
- } else if (parser->model == I450T) {
+ } else if (parser->model == I450T || parser->model == OC1A ||
+ parser->model == OC1B || parser->model == OC1C ||
+ parser->model == OCI) {
rbt = array_uint16_le(data + offset + 8) & 0x01FF;
have_rbt = 1;
} else if (parser->model == VISION || parser->model == XPAIR ||
@@ -1014,6 +1018,20 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
if (callback) callback (DC_SAMPLE_RBT, sample, userdata);
}
+ // Bookmarks
+ unsigned int have_bookmark = 0;
+ if (parser->model == OC1A || parser->model == OC1B ||
+ parser->model == OC1C || parser->model == OCI) {
+ have_bookmark = data[offset + 12] & 0x80;
+ }
+ if (have_bookmark) {
+ sample.event.type = SAMPLE_EVENT_BOOKMARK;
+ sample.event.time = 0;
+ sample.event.flags = 0;
+ sample.event.value = 0;
+ if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ }
+
count++;
complete = 1;
}
diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c
index 54bdee5..639d0e4 100644
--- a/src/uwatec_smart_parser.c
+++ b/src/uwatec_smart_parser.c
@@ -74,8 +74,8 @@ typedef enum {
BEARING,
ALARMS,
TIME,
- UNKNOWN1,
- UNKNOWN2,
+ APNEA,
+ MISC,
} uwatec_smart_sample_t;
typedef enum {
@@ -142,9 +142,9 @@ struct uwatec_smart_parser_t {
unsigned int nsamples;
const uwatec_smart_event_info_t *events[NEVENTS];
unsigned int nevents[NEVENTS];
+ unsigned int trimix;
// Cached fields.
unsigned int cached;
- unsigned int trimix;
unsigned int ngasmixes;
uwatec_smart_gasmix_t gasmix[NGASMIXES];
unsigned int ntanks;
@@ -158,6 +158,8 @@ static dc_status_t uwatec_smart_parser_get_datetime (dc_parser_t *abstract, dc_d
static dc_status_t uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
+static dc_status_t uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback, void *userdata);
+
static const dc_parser_vtable_t uwatec_smart_parser_vtable = {
sizeof(uwatec_smart_parser_t),
DC_FAMILY_UWATEC_SMART,
@@ -194,6 +196,19 @@ uwatec_smart_header_info_t uwatec_smart_galileo_header = {
92, /* settings */
};
+static const
+uwatec_smart_header_info_t uwatec_smart_trimix_header = {
+ 22, /* maxdepth */
+ 26, /* divetime */
+ UNSUPPORTED, 0, /* gasmixes */
+ 30, /* temp_minimum */
+ 28, /* temp_maximum */
+ 32, /* temp_surface */
+ UNSUPPORTED, /* tankpressure */
+ 16, /* timezone */
+ 68, /* settings */
+};
+
static const
uwatec_smart_header_info_t uwatec_smart_aladin_tec_header = {
22,
@@ -277,8 +292,8 @@ uwatec_smart_sample_info_t uwatec_smart_galileo_samples[] = {
{HEARTRATE, 1, 0, 8, 0, 1}, // 1111 0111 dddddddd
{BEARING, 1, 0, 8, 0, 2}, // 1111 1000 dddddddd dddddddd
{ALARMS, 1, 2, 8, 0, 1}, // 1111 1001 dddddddd
- {UNKNOWN1, 1, 0, 8, 0, 0}, // 1111 1010 (8 bytes)
- {UNKNOWN2, 1, 0, 8, 0, 1}, // 1111 1011 dddddddd (n-1 bytes)
+ {APNEA, 1, 0, 8, 0, 0}, // 1111 1010 (8 bytes)
+ {MISC, 1, 0, 8, 0, 1}, // 1111 1011 dddddddd (n-1 bytes)
};
@@ -418,32 +433,32 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser)
{
const unsigned char *data = parser->base.data;
unsigned int size = parser->base.size;
- const uwatec_smart_header_info_t *header = parser->header;
if (parser->cached) {
return DC_STATUS_SUCCESS;
}
- unsigned int trimix = 0;
if (parser->model == GALILEO || parser->model == GALILEOTRIMIX) {
if (size < 44)
return DC_STATUS_DATAFORMAT;
if (data[43] & 0x80) {
- trimix = 1;
- }
-
- if (trimix) {
+ parser->trimix = 1;
+ parser->headersize = 84;
+ parser->header = &uwatec_smart_trimix_header;
parser->events[2] = uwatec_smart_trimix_events_2;
parser->nevents[2] = C_ARRAY_SIZE (uwatec_smart_trimix_events_2);
} else {
+ parser->trimix = 0;
+ parser->headersize = 152;
+ parser->header = &uwatec_smart_galileo_header;
parser->events[2] = uwatec_smart_galileo_events_2;
parser->nevents[2] = C_ARRAY_SIZE (uwatec_smart_galileo_events_2);
}
- } else if (parser->model == G2) {
- trimix = 1;
}
+ const uwatec_smart_header_info_t *header = parser->header;
+
// Get the settings.
dc_divemode_t divemode = DC_DIVEMODE_OC;
dc_water_t watertype = DC_WATER_FRESH;
@@ -479,7 +494,7 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser)
unsigned int ngasmixes = 0;
uwatec_smart_tank_t tank[NGASMIXES] = {{0}};
uwatec_smart_gasmix_t gasmix[NGASMIXES] = {{0}};
- if (!trimix) {
+ if (header->gasmix != UNSUPPORTED) {
for (unsigned int i = 0; i < header->ngases; ++i) {
unsigned int idx = DC_GASMIX_UNKNOWN;
unsigned int o2 = 0;
@@ -526,7 +541,6 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser)
}
// Cache the data for later use.
- parser->trimix = trimix;
parser->ngasmixes = ngasmixes;
for (unsigned int i = 0; i < ngasmixes; ++i) {
parser->gasmix[i] = gasmix[i];
@@ -563,6 +577,7 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
parser->model = model;
parser->devtime = devtime;
parser->systime = systime;
+ parser->trimix = 0;
for (unsigned int i = 0; i < NEVENTS; ++i) {
parser->events[i] = NULL;
parser->nevents[i] = 0;
@@ -582,7 +597,6 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
case MERIDIAN:
case CHROMIS:
case MANTIS2:
- case G2:
parser->headersize = 152;
parser->header = &uwatec_smart_galileo_header;
parser->samples = uwatec_smart_galileo_samples;
@@ -594,6 +608,19 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
parser->nevents[1] = C_ARRAY_SIZE (uwatec_smart_galileo_events_1);
parser->nevents[2] = C_ARRAY_SIZE (uwatec_smart_galileo_events_2);
break;
+ case G2:
+ parser->headersize = 84;
+ parser->header = &uwatec_smart_trimix_header;
+ parser->samples = uwatec_smart_galileo_samples;
+ parser->nsamples = C_ARRAY_SIZE (uwatec_smart_galileo_samples);
+ parser->events[0] = uwatec_smart_galileo_events_0;
+ parser->events[1] = uwatec_smart_galileo_events_1;
+ parser->events[2] = uwatec_smart_trimix_events_2;
+ parser->nevents[0] = C_ARRAY_SIZE (uwatec_smart_galileo_events_0);
+ parser->nevents[1] = C_ARRAY_SIZE (uwatec_smart_galileo_events_1);
+ parser->nevents[2] = C_ARRAY_SIZE (uwatec_smart_trimix_events_2);
+ parser->trimix = 1;
+ break;
case ALADINTEC:
parser->headersize = 108;
parser->header = &uwatec_smart_aladin_tec_header;
@@ -635,7 +662,6 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
}
parser->cached = 0;
- parser->trimix = 0;
parser->ngasmixes = 0;
parser->ntanks = 0;
for (unsigned int i = 0; i < NGASMIXES; ++i) {
@@ -667,7 +693,6 @@ uwatec_smart_parser_set_data (dc_parser_t *abstract, const unsigned char *data,
// Reset the cache.
parser->cached = 0;
- parser->trimix = 0;
parser->ngasmixes = 0;
parser->ntanks = 0;
for (unsigned int i = 0; i < NGASMIXES; ++i) {
@@ -728,9 +753,6 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
{
uwatec_smart_parser_t *parser = (uwatec_smart_parser_t *) abstract;
- const unsigned char *data = abstract->data;
- const uwatec_smart_header_info_t *table = parser->header;
-
// Cache the parser data.
dc_status_t rc = uwatec_smart_parser_cache (parser);
if (rc != DC_STATUS_SUCCESS)
@@ -738,11 +760,14 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
// Cache the profile data.
if (parser->cached < PROFILE) {
- rc = uwatec_smart_parser_samples_foreach (abstract, NULL, NULL);
+ rc = uwatec_smart_parse (parser, NULL, NULL);
if (rc != DC_STATUS_SUCCESS)
return rc;
}
+ const uwatec_smart_header_info_t *table = parser->header;
+ const unsigned char *data = abstract->data;
+
double salinity = (parser->watertype == DC_WATER_SALT ? SALT : FRESH);
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
@@ -766,13 +791,9 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
break;
case DC_FIELD_TANK_COUNT:
- if (table->tankpressure == UNSUPPORTED)
- return DC_STATUS_UNSUPPORTED;
*((unsigned int *) value) = parser->ntanks;
break;
case DC_FIELD_TANK:
- if (table->tankpressure == UNSUPPORTED)
- return DC_STATUS_UNSUPPORTED;
tank->type = DC_TANKVOLUME_NONE;
tank->volume = 0.0;
tank->workpressure = 0.0;
@@ -871,24 +892,15 @@ uwatec_smart_fixsignbit (unsigned int x, unsigned int n)
static dc_status_t
-uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
+uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback, void *userdata)
{
- uwatec_smart_parser_t *parser = (uwatec_smart_parser_t*) abstract;
+ dc_parser_t *abstract = (dc_parser_t *) parser;
const unsigned char *data = abstract->data;
unsigned int size = abstract->size;
- // Cache the parser data.
- dc_status_t rc = uwatec_smart_parser_cache (parser);
- if (rc != DC_STATUS_SUCCESS)
- return rc;
-
const uwatec_smart_sample_info_t *table = parser->samples;
unsigned int entries = parser->nsamples;
- unsigned int header = parser->headersize;
- if (parser->trimix) {
- header = 0xB1;
- }
// Get the maximum number of alarm bytes.
unsigned int nalarms = 0;
@@ -927,7 +939,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
int have_depth = 0, have_temperature = 0, have_pressure = 0, have_rbt = 0,
have_heartrate = 0, have_bearing = 0;
- unsigned int offset = header;
+ unsigned int offset = parser->headersize;
while (offset < size) {
dc_sample_value_t sample = {0};
@@ -1079,14 +1091,14 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
case TIME:
complete = value;
break;
- case UNKNOWN1:
+ case APNEA:
if (offset + 8 > size) {
ERROR (abstract->context, "Incomplete sample data.");
return DC_STATUS_DATAFORMAT;
}
offset += 8;
break;
- case UNKNOWN2:
+ case MISC:
if (value < 1 || offset + value - 1 > size) {
ERROR (abstract->context, "Incomplete sample data.");
return DC_STATUS_DATAFORMAT;
@@ -1211,3 +1223,24 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
return DC_STATUS_SUCCESS;
}
+
+
+static dc_status_t
+uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
+{
+ uwatec_smart_parser_t *parser = (uwatec_smart_parser_t *) abstract;
+
+ // Cache the parser data.
+ dc_status_t rc = uwatec_smart_parser_cache (parser);
+ if (rc != DC_STATUS_SUCCESS)
+ return rc;
+
+ // Cache the profile data.
+ if (parser->cached < PROFILE) {
+ rc = uwatec_smart_parse (parser, NULL, NULL);
+ if (rc != DC_STATUS_SUCCESS)
+ return rc;
+ }
+
+ return uwatec_smart_parse (parser, callback, userdata);
+}