diff --git a/configure.ac b/configure.ac
index f580dbc1..fbb20734 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
# Versioning.
m4_define([dc_version_major],[0])
-m4_define([dc_version_minor],[8])
+m4_define([dc_version_minor],[9])
m4_define([dc_version_micro],[0])
m4_define([dc_version_suffix],[devel-Subsurface-NG])
m4_define([dc_version],dc_version_major.dc_version_minor.dc_version_micro[]m4_ifset([dc_version_suffix],-[dc_version_suffix]))
diff --git a/contrib/msvc/libdivecomputer.vcxproj b/contrib/msvc/libdivecomputer.vcxproj
index 7f1335c7..704ef8b7 100644
--- a/contrib/msvc/libdivecomputer.vcxproj
+++ b/contrib/msvc/libdivecomputer.vcxproj
@@ -331,7 +331,6 @@
-
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
index 63f9e855..4ea44de2 100644
--- a/doc/man/Makefile.am
+++ b/doc/man/Makefile.am
@@ -32,7 +32,6 @@ MANPAGES = \
dc_parser_get_field.3 \
dc_parser_new.3 \
dc_parser_samples_foreach.3 \
- dc_parser_set_data.3 \
dc_bluetooth_open.3 \
dc_bluetooth_iterator_new.3 \
dc_bluetooth_device_get_address.3 \
diff --git a/doc/man/dc_device_foreach.3 b/doc/man/dc_device_foreach.3
index a349a728..86782f84 100644
--- a/doc/man/dc_device_foreach.3
+++ b/doc/man/dc_device_foreach.3
@@ -53,7 +53,7 @@ with
Each dive invokes
.Fa callback
with the dive data, which should be parsed with
-.Xr dc_parser_set_data 3 ,
+.Xr dc_parser_new 3 ,
and the binary fingerprint of the dive.
The fingerprint can be used to record the newest dive and stop
processing (on subsequent invocations) when the same dive fingerprint is
@@ -72,7 +72,7 @@ If
returns zero, this will not be reflected in the return value (usually
.Dv DC_STATUS_SUCCESS ) .
.Sh SEE ALSO
-.Xr dc_parser_set_data 3
+.Xr dc_parser_new 3
.Sh AUTHORS
The
.Lb libdivecomputer
diff --git a/doc/man/dc_parser_get_datetime.3 b/doc/man/dc_parser_get_datetime.3
index ba1f365d..0b7b707c 100644
--- a/doc/man/dc_parser_get_datetime.3
+++ b/doc/man/dc_parser_get_datetime.3
@@ -37,7 +37,7 @@
Extract the date and time of a dive,
.Fa parser ,
previously initialised with
-.Xr dc_parser_set_data 3 .
+.Xr dc_parser_new 3 .
This returns the broken-down time-stamp of the dive in the local time of
the dive.
.Pp
@@ -57,7 +57,7 @@ messages on further failure.
.Sh SEE ALSO
.Xr dc_datetime_gmtime 3 ,
.Xr dc_datetime_localtime 3 ,
-.Xr dc_parser_set_data 3
+.Xr dc_parser_new 3
.Sh AUTHORS
The
.Lb libdivecomputer
diff --git a/doc/man/dc_parser_get_field.3 b/doc/man/dc_parser_get_field.3
index a4c33f2e..0f6455dc 100644
--- a/doc/man/dc_parser_get_field.3
+++ b/doc/man/dc_parser_get_field.3
@@ -39,7 +39,7 @@
Extract a field from a dive,
.Fa parser ,
previously initialised with
-.Xr dc_parser_set_data 3 .
+.Xr dc_parser_new 3 .
The
.Fa value
field type depends upon the
@@ -187,7 +187,7 @@ if the field was retrieved,
if the field is not supported by the device, or other error messages on
further failure.
.Sh SEE ALSO
-.Xr dc_parser_set_data 3
+.Xr dc_parser_new 3
.Sh AUTHORS
The
.Lb libdivecomputer
diff --git a/doc/man/dc_parser_new.3 b/doc/man/dc_parser_new.3
index 9f879cdf..e5340f0c 100644
--- a/doc/man/dc_parser_new.3
+++ b/doc/man/dc_parser_new.3
@@ -39,8 +39,6 @@
.Fa "dc_parser_t **parser"
.Fa "dc_context_t *context"
.Fa "dc_descriptor_t *descriptor"
-.Fa "unsigned int devtime"
-.Fa "dc_ticks_t systime"
.Fc
.Sh DESCRIPTION
Creates a parser for a single dive extracted from the dive computer with
@@ -55,10 +53,6 @@ parameter; and
.Nm dc_parser_new2 ,
which is given device values (model, etc.) directly.
.Pp
-After filling in the
-.Fa parser
-parameter, one usually sets parser data with
-.Xr dc_parser_set_data 3 .
The pointer must later be freed with
.Xr dc_parser_destroy 3 .
.Sh RETURN VALUES
diff --git a/doc/man/dc_parser_samples_foreach.3 b/doc/man/dc_parser_samples_foreach.3
index 5ac55549..69a637f2 100644
--- a/doc/man/dc_parser_samples_foreach.3
+++ b/doc/man/dc_parser_samples_foreach.3
@@ -31,7 +31,7 @@
.Ft "typedef void"
.Fo "(*dc_sample_callback_t)"
.Fa "dc_sample_type_t type"
-.Fa "dc_sample_value_t value"
+.Fa "const dc_sample_value_t *value"
.Fa "void *userdata"
.Fc
.Ft dc_status_t
@@ -42,7 +42,7 @@
.Fc
.Sh DESCRIPTION
Extract the samples taken during a dive as previously initialised with
-.Xr dc_parser_set_data 3 .
+.Xr dc_parser_new 3 .
Each sample is passed to
.Fa callback
with the
@@ -63,7 +63,7 @@ closed.
The following sample types may be raised:
.Bl -tag -width Ds
.It Dv DC_SAMPLE_TIME
-The time of the sample taken in seconds after the dive began.
+The time of the sample taken in milliseconds after the dive began.
Set in the
.Fa time
field.
@@ -184,7 +184,7 @@ Returns
.Dv DC_STATUS_OK
on success and another code on failure.
.Sh SEE ALSO
-.Xr dc_parser_set_data 3
+.Xr dc_parser_new 3
.Sh AUTHORS
The
.Lb libdivecomputer
diff --git a/doc/man/dc_parser_set_data.3 b/doc/man/dc_parser_set_data.3
deleted file mode 100644
index 39af43b7..00000000
--- a/doc/man/dc_parser_set_data.3
+++ /dev/null
@@ -1,65 +0,0 @@
-.\"
-.\" libdivecomputer
-.\"
-.\" Copyright (C) 2017 Kristaps Dzonsons
-.\"
-.\" This library is free software; you can redistribute it and/or
-.\" modify it under the terms of the GNU Lesser General Public
-.\" License as published by the Free Software Foundation; either
-.\" version 2.1 of the License, or (at your option) any later version.
-.\"
-.\" This library is distributed in the hope that it will be useful,
-.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
-.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-.\" Lesser General Public License for more details.
-.\"
-.\" You should have received a copy of the GNU Lesser General Public
-.\" License along with this library; if not, write to the Free Software
-.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-.\" MA 02110-1301 USA
-.\"
-.Dd January 5, 2017
-.Dt DC_PARSER_SET_DATA 3
-.Os
-.Sh NAME
-.Nm dc_parser_set_data
-.Nd assigns parse data to a dive parser
-.Sh LIBRARY
-.Lb libdivecomputer
-.Sh SYNOPSIS
-.In libdivecomputer/parser.h
-.Ft dc_status_t
-.Fo dc_parser_set_data
-.Fa "dc_parser_t *parser"
-.Fa "const unsigned char *data"
-.Fa "unsigned int size"
-.Fc
-.Sh DESCRIPTION
-Assigns the binary sequence
-.Fa data
-of length
-.Fa size
-bytes to
-.Fa parser ,
-which was created with
-.Xr dc_parser_new 3 .
-How the data is parsed depends upon the values provided to
-.Xr dc_parser_new 3 .
-The data usually comes from the callback assigned to
-.Xr dc_device_foreach 3 .
-.Sh RETURN VALUES
-Returns
-.Dv DC_STATUS_OK
-on success and another code on failure.
-.Sh SEE ALSO
-.Xr dc_device_foreach 3 ,
-.Xr dc_parser_new 3
-.Sh AUTHORS
-The
-.Lb libdivecomputer
-library was written by
-.An Jef Driesen ,
-.Mt jef@libdivecomputer.org .
-The manpages were written by
-.An Kristaps Dzonsons ,
-.Mt kristaps@bsd.lv .
diff --git a/doc/man/libdivecomputer.3 b/doc/man/libdivecomputer.3
index 4e1f6013..cbe22eb9 100644
--- a/doc/man/libdivecomputer.3
+++ b/doc/man/libdivecomputer.3
@@ -82,9 +82,7 @@ Iterate over all dives with
.Xr dc_device_foreach 3 .
.It
For each iterated dive, create a new parser with
-.Xr dc_parser_new 3
-and set the parsed data with
-.Xr dc_parser_set_data 3 .
+.Xr dc_parser_new 3 .
.It
Get attributes of the parsed dive with
.Xr dc_parser_get_field 3 .
diff --git a/examples/dctool_download.c b/examples/dctool_download.c
index 04aedcf8..29742e0c 100644
--- a/examples/dctool_download.c
+++ b/examples/dctool_download.c
@@ -80,20 +80,12 @@ dive_cb (const unsigned char *data, unsigned int size, const unsigned char *fing
// Create the parser.
message ("Creating the parser.\n");
- rc = dc_parser_new (&parser, divedata->device);
+ rc = dc_parser_new (&parser, divedata->device, data, size);
if (rc != DC_STATUS_SUCCESS) {
ERROR ("Error creating the parser.");
goto cleanup;
}
- // Register the data.
- message ("Registering the data.\n");
- rc = dc_parser_set_data (parser, data, size);
- if (rc != DC_STATUS_SUCCESS) {
- ERROR ("Error registering the data.");
- goto cleanup;
- }
-
// Parse the dive data.
message ("Parsing the dive data.\n");
rc = dctool_output_write (divedata->output, parser, data, size, fingerprint, fsize);
diff --git a/examples/dctool_parse.c b/examples/dctool_parse.c
index b898b5c8..4ecf30e3 100644
--- a/examples/dctool_parse.c
+++ b/examples/dctool_parse.c
@@ -54,17 +54,17 @@ parse (dc_buffer_t *buffer, dc_context_t *context, dc_descriptor_t *descriptor,
// Create the parser.
message ("Creating the parser.\n");
- rc = dc_parser_new2 (&parser, context, descriptor, devtime, systime);
+ rc = dc_parser_new2 (&parser, context, descriptor, data, size);
if (rc != DC_STATUS_SUCCESS) {
ERROR ("Error creating the parser.");
goto cleanup;
}
- // Register the data.
- message ("Registering the data.\n");
- rc = dc_parser_set_data (parser, data, size);
- if (rc != DC_STATUS_SUCCESS) {
- ERROR ("Error registering the data.");
+ // Set the clock.
+ message ("Setting the clock.\n");
+ rc = dc_parser_set_clock (parser, devtime, systime);
+ if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
+ ERROR ("Error setting the clock.");
goto cleanup;
}
diff --git a/examples/output_xml.c b/examples/output_xml.c
index 8e9380a2..1bb673bf 100644
--- a/examples/output_xml.c
+++ b/examples/output_xml.c
@@ -90,7 +90,7 @@ convert_volume (double value, dctool_units_t units)
}
static void
-sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
+sample_cb (dc_sample_type_t type, const dc_sample_value_t *value, void *userdata)
{
static const char *events[] = {
"none", "deco", "rbt", "ascent", "ceiling", "workload", "transmitter",
@@ -104,64 +104,80 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
sample_data_t *sampledata = (sample_data_t *) userdata;
+ unsigned int seconds = 0, milliseconds = 0;
+
switch (type) {
case DC_SAMPLE_TIME:
+ seconds = value->time / 1000;
+ milliseconds = value->time % 1000;
if (sampledata->nsamples++)
fprintf (sampledata->ostream, "\n");
fprintf (sampledata->ostream, "\n");
- fprintf (sampledata->ostream, " \n", value.time / 60, value.time % 60);
+ if (milliseconds) {
+ fprintf (sampledata->ostream, " \n", seconds / 60, seconds % 60, milliseconds);
+ } else {
+ fprintf (sampledata->ostream, " \n", seconds / 60, seconds % 60);
+ }
break;
case DC_SAMPLE_DEPTH:
fprintf (sampledata->ostream, " %.2f\n",
- convert_depth(value.depth, sampledata->units));
+ convert_depth(value->depth, sampledata->units));
break;
case DC_SAMPLE_PRESSURE:
fprintf (sampledata->ostream, " %.2f\n",
- value.pressure.tank,
- convert_pressure(value.pressure.value, sampledata->units));
+ value->pressure.tank,
+ convert_pressure(value->pressure.value, sampledata->units));
break;
case DC_SAMPLE_TEMPERATURE:
fprintf (sampledata->ostream, " %.2f\n",
- convert_temperature(value.temperature, sampledata->units));
+ convert_temperature(value->temperature, sampledata->units));
break;
case DC_SAMPLE_EVENT:
- if (value.event.type != SAMPLE_EVENT_GASCHANGE && value.event.type != SAMPLE_EVENT_GASCHANGE2) {
+ if (value->event.type != SAMPLE_EVENT_GASCHANGE && value->event.type != SAMPLE_EVENT_GASCHANGE2) {
fprintf (sampledata->ostream, " %s\n",
- value.event.type, value.event.time, value.event.flags, value.event.value, events[value.event.type]);
+ value->event.type, value->event.time, value->event.flags, value->event.value, events[value->event.type]);
}
break;
case DC_SAMPLE_RBT:
- fprintf (sampledata->ostream, " %u\n", value.rbt);
+ fprintf (sampledata->ostream, " %u\n", value->rbt);
break;
case DC_SAMPLE_HEARTBEAT:
- fprintf (sampledata->ostream, " %u\n", value.heartbeat);
+ fprintf (sampledata->ostream, " %u\n", value->heartbeat);
break;
case DC_SAMPLE_BEARING:
- fprintf (sampledata->ostream, " %u\n", value.bearing);
+ fprintf (sampledata->ostream, " %u\n", value->bearing);
break;
case DC_SAMPLE_VENDOR:
- fprintf (sampledata->ostream, " ", value.vendor.type, value.vendor.size);
- for (unsigned int i = 0; i < value.vendor.size; ++i)
- fprintf (sampledata->ostream, "%02X", ((const unsigned char *) value.vendor.data)[i]);
+ fprintf (sampledata->ostream, " ", value->vendor.type, value->vendor.size);
+ for (unsigned int i = 0; i < value->vendor.size; ++i)
+ fprintf (sampledata->ostream, "%02X", ((const unsigned char *) value->vendor.data)[i]);
fprintf (sampledata->ostream, "\n");
break;
case DC_SAMPLE_SETPOINT:
- fprintf (sampledata->ostream, " %.2f\n", value.setpoint);
+ fprintf (sampledata->ostream, " %.2f\n", value->setpoint);
break;
case DC_SAMPLE_PPO2:
- fprintf (sampledata->ostream, " %.2f\n", value.ppo2);
+ if (value->ppo2.sensor != DC_SENSOR_NONE) {
+ fprintf (sampledata->ostream, " %.2f\n", value->ppo2.sensor, value->ppo2.value);
+ } else {
+ fprintf (sampledata->ostream, " %.2f\n", value->ppo2.value);
+ }
break;
case DC_SAMPLE_CNS:
- fprintf (sampledata->ostream, " %.1f\n", value.cns * 100.0);
+ fprintf (sampledata->ostream, " %.1f\n", value->cns * 100.0);
break;
case DC_SAMPLE_DECO:
fprintf (sampledata->ostream, " %s\n",
- value.deco.time,
- convert_depth(value.deco.depth, sampledata->units),
- decostop[value.deco.type]);
+ value->deco.time,
+ convert_depth(value->deco.depth, sampledata->units),
+ decostop[value->deco.type]);
+ if (value->deco.tts) {
+ fprintf (sampledata->ostream, " %u\n",
+ value->deco.tts);
+ }
break;
case DC_SAMPLE_GASMIX:
- fprintf (sampledata->ostream, " %u\n", value.gasmix);
+ fprintf (sampledata->ostream, " %u\n", value->gasmix);
break;
default:
break;
@@ -322,11 +338,19 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
"\n"
" %.1f\n"
" %.1f\n"
- " %.1f\n"
- "\n",
+ " %.1f\n",
gasmix.helium * 100.0,
gasmix.oxygen * 100.0,
gasmix.nitrogen * 100.0);
+ if (gasmix.usage) {
+ const char *usage[] = {"none", "oxygen", "diluent", "sidemount"};
+ fprintf (output->ostream,
+ " %s\n",
+ usage[gasmix.usage]);
+ }
+ fprintf (output->ostream,
+ "\n");
+
}
// Parse the tanks.
@@ -354,6 +378,12 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
" %u\n",
tank.gasmix);
}
+ if (tank.usage) {
+ const char *usage[] = {"none", "oxygen", "diluent", "sidemount"};
+ fprintf (output->ostream,
+ " %s\n",
+ usage[tank.usage]);
+ }
if (tank.type != DC_TANKVOLUME_NONE) {
fprintf (output->ostream,
" %s\n"
@@ -420,8 +450,14 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
}
if (status != DC_STATUS_UNSUPPORTED) {
- fprintf (output->ostream, "%.1f\n",
- salinity.type, salinity.density);
+ const char *names[] = {"fresh", "salt"};
+ if (salinity.density) {
+ fprintf (output->ostream, "%s\n",
+ salinity.density, names[salinity.type]);
+ } else {
+ fprintf (output->ostream, "%s\n",
+ names[salinity.type]);
+ }
}
// Parse the atmospheric pressure.
diff --git a/include/libdivecomputer/atomics_cobalt.h b/include/libdivecomputer/atomics_cobalt.h
index 5afb1c14..c2dfd66f 100644
--- a/include/libdivecomputer/atomics_cobalt.h
+++ b/include/libdivecomputer/atomics_cobalt.h
@@ -36,9 +36,6 @@ atomics_cobalt_device_version (dc_device_t *device, unsigned char data[], unsign
dc_status_t
atomics_cobalt_device_set_simulation (dc_device_t *device, unsigned int simulation);
-dc_status_t
-atomics_cobalt_parser_set_calibration (dc_parser_t *parser, double atmospheric, double hydrostatic);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/libdivecomputer/descriptor.h b/include/libdivecomputer/descriptor.h
index a2b4495e..bdd8c73c 100644
--- a/include/libdivecomputer/descriptor.h
+++ b/include/libdivecomputer/descriptor.h
@@ -29,29 +29,96 @@
extern "C" {
#endif /* __cplusplus */
+/**
+ * Opaque object representing a supported dive computer.
+ */
typedef struct dc_descriptor_t dc_descriptor_t;
+/**
+ * Create an iterator to enumerate the supported dive computers.
+ *
+ * @param[out] iterator A location to store the iterator.
+ * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code
+ * on failure.
+ */
dc_status_t
dc_descriptor_iterator (dc_iterator_t **iterator);
+/**
+ * Free the device descriptor.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ */
void
dc_descriptor_free (dc_descriptor_t *descriptor);
+/**
+ * Get the vendor name of the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns The vendor name of the dive computer on success, or NULL on failure.
+ */
const char *
dc_descriptor_get_vendor (dc_descriptor_t *descriptor);
+/**
+ * Get the product name of the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns The product name of the dive computer on success, or NULL on
+ * failure.
+ */
const char *
dc_descriptor_get_product (dc_descriptor_t *descriptor);
+/**
+ * Get the family type of the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns The family type of the dive computer on success, or DC_FAMILY_NULL
+ * on failure.
+ */
dc_family_t
dc_descriptor_get_type (dc_descriptor_t *descriptor);
+/**
+ * Get the model number of the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns The model number of the dive computer on success, or zero on
+ * failure.
+ */
unsigned int
dc_descriptor_get_model (dc_descriptor_t *descriptor);
+/**
+ * Get all transports supported by the dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @returns A bitmask with all the transports supported by the dive computer on
+ * success, or DC_TRANSPORT_NONE on failure.
+ */
unsigned int
dc_descriptor_get_transports (dc_descriptor_t *descriptor);
+/**
+ * Check if a low-level I/O device matches a supported dive computer.
+ *
+ * @param[in] descriptor A valid device descriptor.
+ * @param[in] transport The transport type of the I/O device.
+ * @param[in] userdata A pointer to a transport specific data structure:
+ * - DC_TRANSPORT_SERIAL: Name of the device node (string)
+ * - DC_TRANSPORT_USB: USB VID/PID (#dc_usb_desc_t)
+ * - DC_TRANSPORT_USBHID: USB VID/PID (#dc_usbhid_desc_t)
+ * - DC_TRANSPORT_IRDA: IrDA device name (string)
+ * - DC_TRANSPORT_BLUETOOTH: Bluetooth device name (string)
+ * - DC_TRANSPORT_BLE: Bluetooth device name (string)
+ * @returns Non-zero if the device matches a supported dive computer, or zero if
+ * there is no match.
+ */
+int
+dc_descriptor_filter (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/libdivecomputer/parser.h b/include/libdivecomputer/parser.h
index 37c9f813..71797ba2 100644
--- a/include/libdivecomputer/parser.h
+++ b/include/libdivecomputer/parser.h
@@ -173,12 +173,21 @@ typedef struct dc_salinity_t {
double density;
} dc_salinity_t;
+typedef enum dc_usage_t {
+ DC_USAGE_NONE,
+ DC_USAGE_OXYGEN,
+ DC_USAGE_DILUENT,
+ DC_USAGE_SIDEMOUNT,
+} dc_usage_t;
+
typedef struct dc_gasmix_t {
double helium;
double oxygen;
double nitrogen;
+ dc_usage_t usage;
} dc_gasmix_t;
+#define DC_SENSOR_NONE 0xFFFFFFFF
#define DC_GASMIX_UNKNOWN 0xFFFFFFFF
typedef unsigned int dc_tankinfo_t;
@@ -222,6 +231,7 @@ typedef struct dc_tank_t {
double workpressure; /* Work pressure (bar) */
double beginpressure; /* Begin pressure (bar) */
double endpressure; /* End pressure (bar) */
+ dc_usage_t usage;
} dc_tank_t;
typedef enum dc_decomodel_type_t {
@@ -267,7 +277,7 @@ typedef struct dc_field_string_t {
} dc_field_string_t;
typedef union dc_sample_value_t {
- unsigned int time;
+ unsigned int time; /* Milliseconds */
double depth;
struct {
unsigned int tank;
@@ -290,25 +300,29 @@ typedef union dc_sample_value_t {
const void *data;
} vendor;
double setpoint;
- double ppo2;
+ struct {
+ unsigned int sensor;
+ double value;
+ } ppo2;
double cns;
struct {
unsigned int type;
unsigned int time;
double depth;
+ unsigned int tts;
} deco;
unsigned int gasmix; /* Gas mix index */
} dc_sample_value_t;
typedef struct dc_parser_t dc_parser_t;
-typedef void (*dc_sample_callback_t) (dc_sample_type_t type, dc_sample_value_t value, void *userdata);
+typedef void (*dc_sample_callback_t) (dc_sample_type_t type, const dc_sample_value_t *value, void *userdata);
dc_status_t
-dc_parser_new (dc_parser_t **parser, dc_device_t *device);
+dc_parser_new (dc_parser_t **parser, dc_device_t *device, const unsigned char data[], size_t size);
dc_status_t
-dc_parser_new2 (dc_parser_t **parser, dc_context_t *context, dc_descriptor_t *descriptor, unsigned int devtime, dc_ticks_t systime);
+dc_parser_new2 (dc_parser_t **parser, dc_context_t *context, dc_descriptor_t *descriptor, const unsigned char data[], size_t size);
dc_family_t
dc_parser_get_type (dc_parser_t *parser);
@@ -322,9 +336,6 @@ dc_parser_set_atmospheric (dc_parser_t *parser, double atmospheric);
dc_status_t
dc_parser_set_density (dc_parser_t *parser, double density);
-dc_status_t
-dc_parser_set_data (dc_parser_t *parser, const unsigned char *data, unsigned int size);
-
dc_status_t
dc_parser_get_datetime (dc_parser_t *parser, dc_datetime_t *datetime);
diff --git a/include/libdivecomputer/reefnet_sensus.h b/include/libdivecomputer/reefnet_sensus.h
index 583d9af6..b0fe2716 100644
--- a/include/libdivecomputer/reefnet_sensus.h
+++ b/include/libdivecomputer/reefnet_sensus.h
@@ -35,9 +35,6 @@ extern "C" {
dc_status_t
reefnet_sensus_device_get_handshake (dc_device_t *device, unsigned char data[], unsigned int size);
-dc_status_t
-reefnet_sensus_parser_set_calibration (dc_parser_t *parser, double atmospheric, double hydrostatic);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/libdivecomputer/reefnet_sensuspro.h b/include/libdivecomputer/reefnet_sensuspro.h
index a92966f0..b879a502 100644
--- a/include/libdivecomputer/reefnet_sensuspro.h
+++ b/include/libdivecomputer/reefnet_sensuspro.h
@@ -38,9 +38,6 @@ reefnet_sensuspro_device_get_handshake (dc_device_t *device, unsigned char data[
dc_status_t
reefnet_sensuspro_device_write_interval (dc_device_t *device, unsigned char interval);
-dc_status_t
-reefnet_sensuspro_parser_set_calibration (dc_parser_t *parser, double atmospheric, double hydrostatic);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/libdivecomputer/reefnet_sensusultra.h b/include/libdivecomputer/reefnet_sensusultra.h
index c5a89444..fc1b4f7c 100644
--- a/include/libdivecomputer/reefnet_sensusultra.h
+++ b/include/libdivecomputer/reefnet_sensusultra.h
@@ -56,9 +56,6 @@ reefnet_sensusultra_device_write_parameter (dc_device_t *device, reefnet_sensusu
dc_status_t
reefnet_sensusultra_device_sense (dc_device_t *device, unsigned char data[], unsigned int size);
-dc_status_t
-reefnet_sensusultra_parser_set_calibration (dc_parser_t *parser, double atmospheric, double hydrostatic);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/libdivecomputer/usb.h b/include/libdivecomputer/usb.h
index 6d138137..82e58818 100644
--- a/include/libdivecomputer/usb.h
+++ b/include/libdivecomputer/usb.h
@@ -86,6 +86,14 @@ typedef enum dc_usb_recipient_t {
DC_USB_RECIPIENT_OTHER = 0x03,
} dc_usb_recipient_t;
+/**
+ * USB device descriptor.
+ */
+typedef struct dc_usb_desc_t {
+ unsigned short vid;
+ unsigned short pid;
+} dc_usb_desc_t;
+
/**
* Opaque object representing a USB device.
*/
diff --git a/include/libdivecomputer/usbhid.h b/include/libdivecomputer/usbhid.h
index f1c542a0..245adf0e 100644
--- a/include/libdivecomputer/usbhid.h
+++ b/include/libdivecomputer/usbhid.h
@@ -32,6 +32,14 @@
extern "C" {
#endif /* __cplusplus */
+/**
+ * USB HID device descriptor.
+ */
+typedef struct dc_usbhid_desc_t {
+ unsigned short vid;
+ unsigned short pid;
+} dc_usbhid_desc_t;
+
/**
* Opaque object representing a USB HID device.
*/
diff --git a/src/Makefile.am b/src/Makefile.am
index fec3d319..21399599 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,7 +16,7 @@ endif
libdivecomputer_la_SOURCES = \
version.c \
- descriptor-private.h descriptor.c \
+ descriptor.c \
iostream-private.h iostream.c \
iterator-private.h iterator.c \
common-private.h common.c \
diff --git a/src/array.c b/src/array.c
index 29f5faf3..f47c3eb0 100644
--- a/src/array.c
+++ b/src/array.c
@@ -404,3 +404,14 @@ signextend (unsigned int value, unsigned int nbits)
else
return value & mask;
}
+
+unsigned int
+popcount (unsigned int value)
+{
+ unsigned int count = 0;
+ while (value) {
+ value &= value - 1;
+ count++;
+ }
+ return count;
+}
diff --git a/src/array.h b/src/array.h
index a6ef21e9..fab1475e 100644
--- a/src/array.h
+++ b/src/array.h
@@ -126,6 +126,9 @@ dec2bcd (unsigned char value);
unsigned int
signextend (unsigned int value, unsigned int nbits);
+unsigned int
+popcount (unsigned int value);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/src/atomics_cobalt.c b/src/atomics_cobalt.c
index 1c2e3a57..8c386965 100644
--- a/src/atomics_cobalt.c
+++ b/src/atomics_cobalt.c
@@ -41,6 +41,8 @@
#define FP_OFFSET 20
+#define SZ_HEADER 228
+
#define SZ_MEMORY1 (29 * 64 * 1024) // Cobalt 1
#define SZ_MEMORY2 (41 * 64 * 1024) // Cobalt 2
#define SZ_VERSION 14
@@ -347,6 +349,12 @@ atomics_cobalt_device_foreach (dc_device_t *abstract, dc_dive_callback_t callbac
return DC_STATUS_SUCCESS;
}
+ if (size < SZ_HEADER) {
+ ERROR (abstract->context, "Dive header is too small (%u).", size);
+ dc_buffer_free (buffer);
+ return DC_STATUS_DATAFORMAT;
+ }
+
if (memcmp (data + FP_OFFSET, device->fingerprint, sizeof (device->fingerprint)) == 0) {
dc_buffer_free (buffer);
return DC_STATUS_SUCCESS;
diff --git a/src/atomics_cobalt.h b/src/atomics_cobalt.h
index 09f02267..8c706415 100644
--- a/src/atomics_cobalt.h
+++ b/src/atomics_cobalt.h
@@ -36,7 +36,7 @@ dc_status_t
atomics_cobalt_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-atomics_cobalt_parser_create (dc_parser_t **parser, dc_context_t *context);
+atomics_cobalt_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/atomics_cobalt_parser.c b/src/atomics_cobalt_parser.c
index 7a95e6fa..1121234a 100644
--- a/src/atomics_cobalt_parser.c
+++ b/src/atomics_cobalt_parser.c
@@ -49,7 +49,6 @@ struct atomics_cobalt_parser_t {
double hydrostatic;
};
-static dc_status_t atomics_cobalt_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t atomics_cobalt_parser_set_density (dc_parser_t *abstract, double density);
static dc_status_t atomics_cobalt_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
@@ -58,7 +57,6 @@ static dc_status_t atomics_cobalt_parser_samples_foreach (dc_parser_t *abstract,
static const dc_parser_vtable_t atomics_cobalt_parser_vtable = {
sizeof(atomics_cobalt_parser_t),
DC_FAMILY_ATOMICS_COBALT,
- atomics_cobalt_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
atomics_cobalt_parser_set_density, /* set_density */
@@ -70,7 +68,7 @@ static const dc_parser_vtable_t atomics_cobalt_parser_vtable = {
dc_status_t
-atomics_cobalt_parser_create (dc_parser_t **out, dc_context_t *context)
+atomics_cobalt_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
atomics_cobalt_parser_t *parser = NULL;
@@ -78,7 +76,7 @@ atomics_cobalt_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (atomics_cobalt_parser_t *) dc_parser_allocate (context, &atomics_cobalt_parser_vtable);
+ parser = (atomics_cobalt_parser_t *) dc_parser_allocate (context, &atomics_cobalt_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -93,27 +91,6 @@ atomics_cobalt_parser_create (dc_parser_t **out, dc_context_t *context)
}
-static dc_status_t
-atomics_cobalt_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
-dc_status_t
-atomics_cobalt_parser_set_calibration (dc_parser_t *abstract, double atmospheric, double hydrostatic)
-{
- atomics_cobalt_parser_t *parser = (atomics_cobalt_parser_t*) abstract;
-
- if (!ISINSTANCE (abstract))
- return DC_STATUS_INVALIDARGS;
-
- parser->hydrostatic = hydrostatic;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
atomics_cobalt_parser_set_density (dc_parser_t *abstract, double density)
{
@@ -182,6 +159,7 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
*((unsigned int *) value) = p[0x2a];
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = p[SZ_HEADER + SZ_GASMIX * flags + 5] / 100.0;
gasmix->oxygen = p[SZ_HEADER + SZ_GASMIX * flags + 4] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -213,6 +191,7 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
tank->gasmix = flags;
tank->beginpressure = array_uint16_le(p + 6) * PSI / BAR;
tank->endpressure = array_uint16_le(p + 14) * PSI / BAR;
+ tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_DIVEMODE:
switch(p[0x24]) {
@@ -310,19 +289,19 @@ atomics_cobalt_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
// Time (seconds).
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/1000 bar).
unsigned int depth = array_uint16_le (data + offset + 0);
sample.depth = (signed int)(depth - atmospheric) * (BAR / 1000.0) / parser->hydrostatic;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Pressure (1 psi).
unsigned int pressure = array_uint16_le (data + offset + 2);
sample.pressure.tank = tank;
sample.pressure.value = pressure * PSI / BAR;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
// Current gas mix
unsigned int gasmix = data[offset + 4];
@@ -338,14 +317,14 @@ atomics_cobalt_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
return DC_STATUS_DATAFORMAT;
}
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
// Temperature (1 °F).
unsigned int temperature = data[offset + 8];
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// violation status
sample.event.type = 0;
@@ -355,15 +334,15 @@ atomics_cobalt_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
unsigned int violation = data[offset + 11];
if (violation & 0x01) {
sample.event.type = SAMPLE_EVENT_ASCENT;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
if (violation & 0x04) {
sample.event.type = SAMPLE_EVENT_CEILING;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
if (violation & 0x08) {
sample.event.type = SAMPLE_EVENT_PO2;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
// NDL & deco
@@ -378,7 +357,8 @@ atomics_cobalt_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
sample.deco.type = DC_DECO_NDL;
sample.deco.time = ndl;
sample.deco.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
offset += SZ_SEGMENT;
}
diff --git a/src/bluetooth.c b/src/bluetooth.c
index aa5f05a8..309953cc 100644
--- a/src/bluetooth.c
+++ b/src/bluetooth.c
@@ -51,7 +51,6 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
-#include "descriptor-private.h"
#include "platform.h"
#ifdef _WIN32
@@ -455,7 +454,7 @@ dc_bluetooth_iterator_next (dc_iterator_t *abstract, void *out)
INFO (abstract->context, "Discover: address=" DC_ADDRESS_FORMAT ", name=%s",
address, name ? name : "");
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_BLUETOOTH, name, NULL)) {
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_BLUETOOTH, name)) {
continue;
}
diff --git a/src/citizen_aqualand.c b/src/citizen_aqualand.c
index 63760ac7..66455f4b 100644
--- a/src/citizen_aqualand.c
+++ b/src/citizen_aqualand.c
@@ -31,6 +31,8 @@
#define ISINSTANCE(device) dc_device_isinstance((device), &citizen_aqualand_device_vtable)
+#define SZ_HEADER 32
+
typedef struct citizen_aqualand_device_t {
dc_device_t base;
dc_iostream_t *iostream;
@@ -200,6 +202,12 @@ citizen_aqualand_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb
unsigned char *data = dc_buffer_get_data (buffer);
unsigned int size = dc_buffer_get_size (buffer);
+ if (size < SZ_HEADER) {
+ ERROR (abstract->context, "Dive header is too small (%u).", size);
+ dc_buffer_free (buffer);
+ return DC_STATUS_DATAFORMAT;
+ }
+
if (callback && memcmp (data + 0x05, device->fingerprint, sizeof (device->fingerprint)) != 0) {
callback (data, size, data + 0x05, sizeof (device->fingerprint), userdata);
}
diff --git a/src/citizen_aqualand.h b/src/citizen_aqualand.h
index ac47cb6a..bc233119 100644
--- a/src/citizen_aqualand.h
+++ b/src/citizen_aqualand.h
@@ -35,7 +35,7 @@ dc_status_t
citizen_aqualand_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-citizen_aqualand_parser_create (dc_parser_t **parser, dc_context_t *context);
+citizen_aqualand_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/citizen_aqualand_parser.c b/src/citizen_aqualand_parser.c
index 5b955559..ff1ea9ed 100644
--- a/src/citizen_aqualand_parser.c
+++ b/src/citizen_aqualand_parser.c
@@ -36,7 +36,6 @@ typedef struct citizen_aqualand_parser_t {
dc_parser_t base;
} citizen_aqualand_parser_t;
-static dc_status_t citizen_aqualand_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t citizen_aqualand_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t citizen_aqualand_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t citizen_aqualand_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -44,7 +43,6 @@ static dc_status_t citizen_aqualand_parser_samples_foreach (dc_parser_t *abstrac
static const dc_parser_vtable_t citizen_aqualand_parser_vtable = {
sizeof(citizen_aqualand_parser_t),
DC_FAMILY_CITIZEN_AQUALAND,
- citizen_aqualand_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -56,7 +54,7 @@ static const dc_parser_vtable_t citizen_aqualand_parser_vtable = {
dc_status_t
-citizen_aqualand_parser_create (dc_parser_t **out, dc_context_t *context)
+citizen_aqualand_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
citizen_aqualand_parser_t *parser = NULL;
@@ -64,7 +62,7 @@ citizen_aqualand_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (citizen_aqualand_parser_t *) dc_parser_allocate (context, &citizen_aqualand_parser_vtable);
+ parser = (citizen_aqualand_parser_t *) dc_parser_allocate (context, &citizen_aqualand_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -76,13 +74,6 @@ citizen_aqualand_parser_create (dc_parser_t **out, dc_context_t *context)
}
-static dc_status_t
-citizen_aqualand_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
citizen_aqualand_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -241,15 +232,15 @@ citizen_aqualand_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
// Time
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth
if (metric)
sample.depth = depth / 10.0;
else
sample.depth = depth * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature
if (time % 300 == 0) {
@@ -260,7 +251,7 @@ citizen_aqualand_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
sample.temperature = temperature / 10.0;
else
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
}
}
diff --git a/src/cochran_commander.h b/src/cochran_commander.h
index 84a521e3..1a36676f 100644
--- a/src/cochran_commander.h
+++ b/src/cochran_commander.h
@@ -35,7 +35,7 @@ dc_status_t
cochran_commander_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-cochran_commander_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+cochran_commander_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/cochran_commander_parser.c b/src/cochran_commander_parser.c
index a4515ea8..aeaf25c8 100644
--- a/src/cochran_commander_parser.c
+++ b/src/cochran_commander_parser.c
@@ -99,7 +99,6 @@ typedef struct cochran_commander_parser_t {
unsigned int nevents;
} cochran_commander_parser_t ;
-static dc_status_t cochran_commander_parser_set_data (dc_parser_t *parser, const unsigned char *data, unsigned int size);
static dc_status_t cochran_commander_parser_get_datetime (dc_parser_t *parser, dc_datetime_t *datetime);
static dc_status_t cochran_commander_parser_get_field (dc_parser_t *parser, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t cochran_commander_parser_samples_foreach (dc_parser_t *parser, dc_sample_callback_t callback, void *userdata);
@@ -107,7 +106,6 @@ static dc_status_t cochran_commander_parser_samples_foreach (dc_parser_t *parser
static const dc_parser_vtable_t cochran_commander_parser_vtable = {
sizeof(cochran_commander_parser_t),
DC_FAMILY_COCHRAN_COMMANDER,
- cochran_commander_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -315,7 +313,7 @@ cochran_commander_handle_event (cochran_commander_parser_t *parser, unsigned cha
sample.event.time = 0;
sample.event.value = 0;
sample.event.flags = event->flag;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
}
@@ -352,7 +350,7 @@ cochran_commander_backparse(cochran_commander_parser_t *parser, const unsigned c
dc_status_t
-cochran_commander_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+cochran_commander_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
cochran_commander_parser_t *parser = NULL;
dc_status_t status = DC_STATUS_SUCCESS;
@@ -361,7 +359,7 @@ cochran_commander_parser_create (dc_parser_t **out, dc_context_t *context, unsig
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (cochran_commander_parser_t *) dc_parser_allocate (context, &cochran_commander_parser_vtable);
+ parser = (cochran_commander_parser_t *) dc_parser_allocate (context, &cochran_commander_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -407,13 +405,6 @@ cochran_commander_parser_create (dc_parser_t **out, dc_context_t *context, unsig
}
-static dc_status_t
-cochran_commander_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
cochran_commander_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -514,6 +505,7 @@ cochran_commander_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
// Gas percentages are decimal and encoded as
// highbyte = integer portion
// lowbyte = decimal portion, divide by 256 to get decimal value
+ gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = array_uint16_le (data + layout->oxygen + 2 * flags) / 256.0 / 100;
if (layout->helium == UNSUPPORTED) {
gasmix->helium = 0;
@@ -578,26 +570,26 @@ cochran_commander_parser_samples_foreach_tm (dc_parser_t *abstract, dc_sample_ca
unsigned int temp = samples[0]; // Half degrees F
unsigned int depth = samples[1]; // Half feet
- last_sample_time = sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ last_sample_time = sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
sample.depth = (depth / 2.0) * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
sample.temperature = (temp / 2.0 - 32.0) / 1.8;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
sample.gasmix = 0;
- if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback(DC_SAMPLE_GASMIX, &sample, userdata);
while (offset < size) {
const unsigned char *s = samples + offset;
- sample.time = time;
+ sample.time = time * 1000;
if (last_sample_time != sample.time) {
// We haven't issued this time yet.
last_sample_time = sample.time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
}
if (*s & 0x80) {
@@ -615,7 +607,8 @@ cochran_commander_parser_samples_foreach_tm (dc_parser_t *abstract, dc_sample_ca
sample.deco.type = DC_DECO_DECOSTOP;
sample.deco.time = 60; // We don't know the duration
sample.deco.depth = deco_ceiling * FEET;
- if (callback) callback(DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback(DC_SAMPLE_DECO, &sample, userdata);
break;
case 0xAD: // Increment ceiling (shallower)
deco_ceiling -= 10; // feet
@@ -623,7 +616,8 @@ cochran_commander_parser_samples_foreach_tm (dc_parser_t *abstract, dc_sample_ca
sample.deco.type = DC_DECO_DECOSTOP;
sample.deco.depth = deco_ceiling * FEET;
sample.deco.time = 60; // We don't know the duration
- if (callback) callback(DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback(DC_SAMPLE_DECO, &sample, userdata);
break;
default:
cochran_commander_handle_event(parser, s[0], callback, userdata);
@@ -636,7 +630,7 @@ cochran_commander_parser_samples_foreach_tm (dc_parser_t *abstract, dc_sample_ca
else
temp += (*s & 0x0f);
sample.temperature = (temp / 2.0 - 32.0) / 1.8;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
offset++;
@@ -650,7 +644,7 @@ cochran_commander_parser_samples_foreach_tm (dc_parser_t *abstract, dc_sample_ca
depth += s[0] & 0x3f;
sample.depth = (depth / 2.0) * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
offset++;
time += sample_interval;
@@ -714,27 +708,27 @@ cochran_commander_parser_samples_foreach_emc (dc_parser_t *abstract, dc_sample_c
start_depth = array_uint16_le (data + layout->start_depth) / 256.0;
}
- last_sample_time = sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ last_sample_time = sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
sample.depth = start_depth * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
sample.temperature = (data[layout->start_temp] - 32.0) / 1.8;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
sample.gasmix = 0;
- if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback(DC_SAMPLE_GASMIX, &sample, userdata);
unsigned int last_gasmix = sample.gasmix;
while (offset < size) {
const unsigned char *s = samples + offset;
- sample.time = time;
+ sample.time = time * 1000;
if (last_sample_time != sample.time) {
// We haven't issued this time yet.
last_sample_time = sample.time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
}
// If corrupt_dive end before offset
@@ -774,7 +768,8 @@ cochran_commander_parser_samples_foreach_emc (dc_parser_t *abstract, dc_sample_c
sample.deco.type = DC_DECO_DECOSTOP;
sample.deco.time = (array_uint16_le(s + 3) + 1) * 60;
sample.deco.depth = deco_ceiling * FEET;
- if (callback) callback(DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback(DC_SAMPLE_DECO, &sample, userdata);
break;
case 0xAD: // Increment ceiling (shallower)
deco_ceiling -= 10; // feet
@@ -782,7 +777,8 @@ cochran_commander_parser_samples_foreach_emc (dc_parser_t *abstract, dc_sample_c
sample.deco.type = DC_DECO_DECOSTOP;
sample.deco.depth = deco_ceiling * FEET;
sample.deco.time = (array_uint16_le(s + 3) + 1) * 60;
- if (callback) callback(DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback(DC_SAMPLE_DECO, &sample, userdata);
break;
case 0xC0: // Switched to FO2 21% mode (surface)
// Event seen upon surfacing
@@ -791,14 +787,14 @@ cochran_commander_parser_samples_foreach_emc (dc_parser_t *abstract, dc_sample_c
case 0xEF: // Switched to gas blend 2
if (last_gasmix != 1) {
sample.gasmix = 1;
- if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback(DC_SAMPLE_GASMIX, &sample, userdata);
last_gasmix = sample.gasmix;
}
break;
case 0xF3: // Switched to gas blend 1
if (last_gasmix != 0) {
sample.gasmix = 0;
- if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback(DC_SAMPLE_GASMIX, &sample, userdata);
last_gasmix = sample.gasmix;
}
break;
@@ -818,7 +814,7 @@ cochran_commander_parser_samples_foreach_emc (dc_parser_t *abstract, dc_sample_c
depth += (s[0] & 0x3f);
sample.depth = (start_depth + depth / 4.0) * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Ascent rate is logged in the 0th sample, temp in the 1st, repeat.
if (time % 2 == 0) {
@@ -834,7 +830,7 @@ cochran_commander_parser_samples_foreach_emc (dc_parser_t *abstract, dc_sample_c
double temperature = s[1] / 2.0 + 20.0;
sample.temperature = (temperature - 32.0) / 1.8;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
// Cochran EMC models store NDL and deco stop time
@@ -855,7 +851,8 @@ cochran_commander_parser_samples_foreach_emc (dc_parser_t *abstract, dc_sample_c
sample.deco.type = DC_DECO_NDL;
sample.deco.time = deco_time * 60;
sample.deco.depth = 0;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
}
break;
case 23:
@@ -865,7 +862,8 @@ cochran_commander_parser_samples_foreach_emc (dc_parser_t *abstract, dc_sample_c
sample.deco.type = DC_DECO_DECOSTOP;
sample.deco.depth = deco_ceiling * FEET;
sample.deco.time = deco_time * 60;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
}
break;
}
diff --git a/src/cressi_edy.c b/src/cressi_edy.c
index 86ed76e3..d61b84e1 100644
--- a/src/cressi_edy.c
+++ b/src/cressi_edy.c
@@ -38,6 +38,8 @@
#define SZ_PACKET 0x80
#define SZ_PAGE (SZ_PACKET / 4)
+#define SZ_HEADER 32
+
#define IQ700 0x05
#define EDY 0x08
@@ -522,6 +524,13 @@ cressi_edy_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v
return rc;
}
+ if (length < SZ_HEADER) {
+ ERROR (abstract->context, "Dive header is too small (%u).", length);
+ dc_rbstream_free (rbstream);
+ free (buffer);
+ return DC_STATUS_DATAFORMAT;
+ }
+
unsigned char *p = buffer + offset;
if (memcmp (p, device->fingerprint, sizeof (device->fingerprint)) == 0)
diff --git a/src/cressi_edy.h b/src/cressi_edy.h
index 7aa5a34f..238e5df2 100644
--- a/src/cressi_edy.h
+++ b/src/cressi_edy.h
@@ -35,7 +35,7 @@ dc_status_t
cressi_edy_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-cressi_edy_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+cressi_edy_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/cressi_edy_parser.c b/src/cressi_edy_parser.c
index 3817fc75..951c032b 100644
--- a/src/cressi_edy_parser.c
+++ b/src/cressi_edy_parser.c
@@ -31,6 +31,8 @@
#define IQ700 0x05
#define EDY 0x08
+#define SZ_HEADER 32
+
typedef struct cressi_edy_parser_t cressi_edy_parser_t;
struct cressi_edy_parser_t {
@@ -38,7 +40,6 @@ struct cressi_edy_parser_t {
unsigned int model;
};
-static dc_status_t cressi_edy_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t cressi_edy_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t cressi_edy_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t cressi_edy_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -46,7 +47,6 @@ static dc_status_t cressi_edy_parser_samples_foreach (dc_parser_t *abstract, dc_
static const dc_parser_vtable_t cressi_edy_parser_vtable = {
sizeof(cressi_edy_parser_t),
DC_FAMILY_CRESSI_EDY,
- cressi_edy_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -73,7 +73,7 @@ cressi_edy_parser_count_gasmixes (const unsigned char *data)
}
dc_status_t
-cressi_edy_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+cressi_edy_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
cressi_edy_parser_t *parser = NULL;
@@ -81,7 +81,7 @@ cressi_edy_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (cressi_edy_parser_t *) dc_parser_allocate (context, &cressi_edy_parser_vtable);
+ parser = (cressi_edy_parser_t *) dc_parser_allocate (context, &cressi_edy_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -96,17 +96,10 @@ cressi_edy_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int
}
-static dc_status_t
-cressi_edy_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
cressi_edy_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
- if (abstract->size < 32)
+ if (abstract->size < SZ_HEADER)
return DC_STATUS_DATAFORMAT;
const unsigned char *p = abstract->data;
@@ -130,7 +123,7 @@ cressi_edy_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
{
cressi_edy_parser_t *parser = (cressi_edy_parser_t *) abstract;
- if (abstract->size < 32)
+ if (abstract->size < SZ_HEADER)
return DC_STATUS_DATAFORMAT;
const unsigned char *p = abstract->data;
@@ -152,6 +145,7 @@ cressi_edy_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
*((unsigned int *) value) = cressi_edy_parser_count_gasmixes(p);
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = bcd2dec (p[0x17 - flags]) / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -188,7 +182,7 @@ cressi_edy_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
unsigned int ngasmixes = cressi_edy_parser_count_gasmixes(data);
unsigned int gasmix = 0xFFFFFFFF;
- unsigned int offset = 32;
+ unsigned int offset = SZ_HEADER;
while (offset + 2 <= size) {
dc_sample_value_t sample = {0};
@@ -201,13 +195,13 @@ cressi_edy_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
// Time (seconds).
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
unsigned int depth = bcd2dec (data[offset + 0] & 0x0F) * 100 + bcd2dec (data[offset + 1]);
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Current gasmix
if (ngasmixes) {
@@ -220,7 +214,7 @@ cressi_edy_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
}
if (idx != gasmix) {
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix = idx;
}
}
diff --git a/src/cressi_goa.h b/src/cressi_goa.h
index 0a925129..63283a07 100644
--- a/src/cressi_goa.h
+++ b/src/cressi_goa.h
@@ -35,7 +35,7 @@ dc_status_t
cressi_goa_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-cressi_goa_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+cressi_goa_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/cressi_goa_parser.c b/src/cressi_goa_parser.c
index f5d4a4c8..28986622 100644
--- a/src/cressi_goa_parser.c
+++ b/src/cressi_goa_parser.c
@@ -62,7 +62,6 @@ typedef struct cressi_goa_layout_t {
unsigned int temperature;
} cressi_goa_layout_t;
-static dc_status_t cressi_goa_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t cressi_goa_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t cressi_goa_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -70,7 +69,6 @@ static dc_status_t cressi_goa_parser_samples_foreach (dc_parser_t *abstract, dc_
static const dc_parser_vtable_t cressi_goa_parser_vtable = {
sizeof(cressi_goa_parser_t),
DC_FAMILY_CRESSI_GOA,
- cressi_goa_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -128,7 +126,7 @@ static const cressi_goa_layout_t layouts[] = {
};
dc_status_t
-cressi_goa_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+cressi_goa_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
cressi_goa_parser_t *parser = NULL;
@@ -136,7 +134,7 @@ cressi_goa_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (cressi_goa_parser_t *) dc_parser_allocate (context, &cressi_goa_parser_vtable);
+ parser = (cressi_goa_parser_t *) dc_parser_allocate (context, &cressi_goa_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -149,12 +147,6 @@ cressi_goa_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int
return DC_STATUS_SUCCESS;
}
-static dc_status_t
-cressi_goa_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
static dc_status_t
cressi_goa_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -250,6 +242,7 @@ cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
*((unsigned int *) value) = ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = data[layout->gasmix + 2 * flags + 1] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -329,25 +322,25 @@ cressi_goa_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
if (complete) {
// Time (seconds).
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ 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);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
have_temperature = 0;
}
// Depth (1/10 m).
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Gas change
if (divemode == SCUBA || divemode == NITROX) {
if (gasmix != gasmix_previous) {
sample.gasmix = gasmix;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
}
diff --git a/src/cressi_leonardo.h b/src/cressi_leonardo.h
index 982bb012..2efc4d82 100644
--- a/src/cressi_leonardo.h
+++ b/src/cressi_leonardo.h
@@ -35,7 +35,7 @@ dc_status_t
cressi_leonardo_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-cressi_leonardo_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+cressi_leonardo_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/cressi_leonardo_parser.c b/src/cressi_leonardo_parser.c
index 7ef6f98e..2f83ab99 100644
--- a/src/cressi_leonardo_parser.c
+++ b/src/cressi_leonardo_parser.c
@@ -39,7 +39,6 @@ struct cressi_leonardo_parser_t {
unsigned int model;
};
-static dc_status_t cressi_leonardo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t cressi_leonardo_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t cressi_leonardo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -47,7 +46,6 @@ static dc_status_t cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract
static const dc_parser_vtable_t cressi_leonardo_parser_vtable = {
sizeof(cressi_leonardo_parser_t),
DC_FAMILY_CRESSI_LEONARDO,
- cressi_leonardo_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -59,7 +57,7 @@ static const dc_parser_vtable_t cressi_leonardo_parser_vtable = {
dc_status_t
-cressi_leonardo_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+cressi_leonardo_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
cressi_leonardo_parser_t *parser = NULL;
@@ -67,7 +65,7 @@ cressi_leonardo_parser_create (dc_parser_t **out, dc_context_t *context, unsigne
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (cressi_leonardo_parser_t *) dc_parser_allocate (context, &cressi_leonardo_parser_vtable);
+ parser = (cressi_leonardo_parser_t *) dc_parser_allocate (context, &cressi_leonardo_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -81,13 +79,6 @@ cressi_leonardo_parser_create (dc_parser_t **out, dc_context_t *context, unsigne
}
-static dc_status_t
-cressi_leonardo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
cressi_leonardo_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -146,6 +137,7 @@ cressi_leonardo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u
}
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = data[0x19] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -196,12 +188,12 @@ cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
// Time (seconds).
time += surftime;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
sample.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
offset += 4;
} else {
@@ -211,17 +203,17 @@ cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
// Time (seconds).
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Gas change.
if (gasmix != gasmix_previous) {
sample.gasmix = gasmix;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
@@ -235,8 +227,7 @@ cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
else
sample.event.flags = 0;
sample.event.value = ascent;
-
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
offset += 2;
diff --git a/src/deepblu_cosmiq.h b/src/deepblu_cosmiq.h
index 35878122..0d0c29a7 100644
--- a/src/deepblu_cosmiq.h
+++ b/src/deepblu_cosmiq.h
@@ -36,7 +36,7 @@ dc_status_t
deepblu_cosmiq_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-deepblu_cosmiq_parser_create (dc_parser_t **parser, dc_context_t *context);
+deepblu_cosmiq_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/deepblu_cosmiq_parser.c b/src/deepblu_cosmiq_parser.c
index 508bc5d8..95b5ae78 100644
--- a/src/deepblu_cosmiq_parser.c
+++ b/src/deepblu_cosmiq_parser.c
@@ -41,7 +41,6 @@ typedef struct deepblu_cosmiq_parser_t {
double hydrostatic;
} deepblu_cosmiq_parser_t;
-static dc_status_t deepblu_cosmiq_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t deepblu_cosmiq_parser_set_density (dc_parser_t *abstract, double density);
static dc_status_t deepblu_cosmiq_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t deepblu_cosmiq_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
@@ -50,7 +49,6 @@ static dc_status_t deepblu_cosmiq_parser_samples_foreach (dc_parser_t *abstract,
static const dc_parser_vtable_t deepblu_cosmiq_parser_vtable = {
sizeof(deepblu_cosmiq_parser_t),
DC_FAMILY_DEEPBLU_COSMIQ,
- deepblu_cosmiq_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
deepblu_cosmiq_parser_set_density, /* set_density */
@@ -61,7 +59,7 @@ static const dc_parser_vtable_t deepblu_cosmiq_parser_vtable = {
};
dc_status_t
-deepblu_cosmiq_parser_create (dc_parser_t **out, dc_context_t *context)
+deepblu_cosmiq_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
deepblu_cosmiq_parser_t *parser = NULL;
@@ -69,7 +67,7 @@ deepblu_cosmiq_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (deepblu_cosmiq_parser_t *) dc_parser_allocate (context, &deepblu_cosmiq_parser_vtable);
+ parser = (deepblu_cosmiq_parser_t *) dc_parser_allocate (context, &deepblu_cosmiq_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -83,12 +81,6 @@ deepblu_cosmiq_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_SUCCESS;
}
-static dc_status_t
-deepblu_cosmiq_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
static dc_status_t
deepblu_cosmiq_parser_set_density (dc_parser_t *abstract, double density)
{
@@ -151,6 +143,7 @@ deepblu_cosmiq_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
*((unsigned int *) value) = mode == SCUBA;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = data[3] / 100.0;
gasmix->helium = 0.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -204,14 +197,14 @@ deepblu_cosmiq_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
offset += SZ_SAMPLE;
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
sample.depth = (signed int) (depth - atmospheric) * (BAR / 1000.0) / parser->hydrostatic;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
sample.temperature = temperature / 10.0;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
return DC_STATUS_SUCCESS;
diff --git a/src/deepsix_excursion.h b/src/deepsix_excursion.h
index 42ecffc8..839511f9 100644
--- a/src/deepsix_excursion.h
+++ b/src/deepsix_excursion.h
@@ -35,7 +35,7 @@ dc_status_t
deepsix_excursion_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-deepsix_excursion_parser_create (dc_parser_t **parser, dc_context_t *context);
+deepsix_excursion_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/deepsix_excursion_parser.c b/src/deepsix_excursion_parser.c
index 2fc8c2c1..52d06af9 100644
--- a/src/deepsix_excursion_parser.c
+++ b/src/deepsix_excursion_parser.c
@@ -112,7 +112,6 @@ typedef struct deepsix_excursion_parser_t {
deepsix_excursion_gasmix_t gasmix[MAX_GASMIXES];
} deepsix_excursion_parser_t;
-static dc_status_t deepsix_excursion_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t deepsix_excursion_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t deepsix_excursion_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t deepsix_excursion_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -122,7 +121,6 @@ static dc_status_t deepsix_excursion_parser_samples_foreach_v1 (dc_parser_t *abs
static const dc_parser_vtable_t deepsix_parser_vtable = {
sizeof(deepsix_excursion_parser_t),
DC_FAMILY_DEEPSIX_EXCURSION,
- deepsix_excursion_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -185,7 +183,7 @@ deepsix_excursion_find_gasmix(deepsix_excursion_parser_t *parser, unsigned int o
}
dc_status_t
-deepsix_excursion_parser_create (dc_parser_t **out, dc_context_t *context)
+deepsix_excursion_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
deepsix_excursion_parser_t *parser = NULL;
@@ -193,7 +191,7 @@ deepsix_excursion_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (deepsix_excursion_parser_t *) dc_parser_allocate (context, &deepsix_parser_vtable);
+ parser = (deepsix_excursion_parser_t *) dc_parser_allocate (context, &deepsix_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -213,23 +211,6 @@ deepsix_excursion_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_SUCCESS;
}
-static dc_status_t
-deepsix_excursion_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- deepsix_excursion_parser_t *parser = (deepsix_excursion_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->ngasmixes = 0;
- for (unsigned int i = 0; i < MAX_GASMIXES; ++i) {
- parser->gasmix[i].id = 0;
- parser->gasmix[i].oxygen = 0;
- parser->gasmix[i].helium = 0;
- }
-
- return DC_STATUS_SUCCESS;
-}
-
static dc_status_t
deepsix_excursion_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -322,6 +303,7 @@ deepsix_excursion_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -423,11 +405,11 @@ deepsix_excursion_parser_samples_foreach_v0 (dc_parser_t *abstract, dc_sample_ca
if (type == TEMPERATURE) {
time += interval;
- sample.time = time;
- if (callback) callback(DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback(DC_SAMPLE_TIME, &sample, userdata);
sample.depth = pressure_to_depth(depth, atmospheric, DENSITY);
- if (callback) callback(DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback(DC_SAMPLE_DEPTH, &sample, userdata);
}
if (type == ALARM) {
@@ -440,11 +422,11 @@ deepsix_excursion_parser_samples_foreach_v0 (dc_parser_t *abstract, dc_sample_ca
length = 8;
} else if (temperature >= 10) {
sample.temperature = temperature / 10.0;
- if (callback) callback(DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback(DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
} else {
sample.temperature = temperature / 10.0;
- if (callback) callback(DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback(DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
} else if (type == DECO) {
unsigned int deco = array_uint16_le(data + offset + 4);
@@ -454,7 +436,7 @@ deepsix_excursion_parser_samples_foreach_v0 (dc_parser_t *abstract, dc_sample_ca
} else if (type == CNS) {
unsigned int cns = array_uint16_le(data + offset + 4);
sample.cns = cns / 100.0;
- if (callback) callback(DC_SAMPLE_CNS, sample, userdata);
+ if (callback) callback(DC_SAMPLE_CNS, &sample, userdata);
}
offset += length;
@@ -591,12 +573,12 @@ deepsix_excursion_parser_samples_foreach_v1 (dc_parser_t *abstract, dc_sample_ca
// Time (seconds).
time += samplerate;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
unsigned int depth = array_uint16_le (data + offset);
sample.depth = pressure_to_depth(depth, atmospheric, density);
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
offset += 2;
// event info
@@ -664,7 +646,7 @@ deepsix_excursion_parser_samples_foreach_v1 (dc_parser_t *abstract, dc_sample_ca
break;
}
if (sample.event.type != SAMPLE_EVENT_NONE) {
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
}
break;
@@ -686,7 +668,7 @@ deepsix_excursion_parser_samples_foreach_v1 (dc_parser_t *abstract, dc_sample_ca
}
sample.gasmix = mix_idx;
- if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback(DC_SAMPLE_GASMIX, &sample, userdata);
break;
case EVENT_SAMPLES_MISSED:
count = array_uint16_le(data + offset + event_offset);
@@ -727,12 +709,12 @@ deepsix_excursion_parser_samples_foreach_v1 (dc_parser_t *abstract, dc_sample_ca
case SAMPLE_TEMPERATURE:
value = array_uint16_le(data + offset);
sample.temperature = value / 10.0;
- if (callback) callback(DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback(DC_SAMPLE_TEMPERATURE, &sample, userdata);
break;
case SAMPLE_CNS:
value = array_uint16_le(data + offset);
sample.cns = value / 10000.0;
- if (callback) callback (DC_SAMPLE_CNS, sample, userdata);
+ if (callback) callback (DC_SAMPLE_CNS, &sample, userdata);
break;
case SAMPLE_DECO_NDL:
deco_flags = data[offset];
@@ -752,7 +734,7 @@ deepsix_excursion_parser_samples_foreach_v1 (dc_parser_t *abstract, dc_sample_ca
sample.deco.depth = 0;
sample.deco.time = deco_ndl_tts;
}
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
break;
default:
break;
diff --git a/src/descriptor-private.h b/src/descriptor-private.h
deleted file mode 100644
index 3346654b..00000000
--- a/src/descriptor-private.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libdivecomputer
- *
- * Copyright (C) 2017 Jef Driesen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#ifndef DC_DESCRIPTOR_PRIVATE_H
-#define DC_DESCRIPTOR_PRIVATE_H
-
-#include
-
-// Oh joy. Windows is some truly horrendously broken crap
-#undef interface
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-typedef struct dc_usb_desc_t {
- unsigned short vid;
- unsigned short pid;
-} dc_usb_desc_t;
-
-typedef struct dc_usb_params_t {
- unsigned int interface;
- unsigned char endpoint_in;
- unsigned char endpoint_out;
-} dc_usb_params_t;
-
-int
-dc_descriptor_filter (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* DC_DESCRIPTOR_PRIVATE_H */
diff --git a/src/descriptor.c b/src/descriptor.c
index c4e719f5..7a824dcb 100644
--- a/src/descriptor.c
+++ b/src/descriptor.c
@@ -23,7 +23,10 @@
#include
#include
-#include "descriptor-private.h"
+#include
+#include
+#include
+
#include "iterator-private.h"
#include "platform.h"
@@ -36,39 +39,29 @@
values, \
C_ARRAY_SIZE(values) - isnullterminated, \
C_ARRAY_ITEMSIZE(values), \
- match, \
- NULL, NULL, 0)
-
-#define DC_FILTER_INTERNAL_WITH_PARAMS(key, values, isnullterminated, match, params_dst, params_src) \
- dc_filter_internal( \
- key, \
- values, \
- C_ARRAY_SIZE(values) - isnullterminated, \
- C_ARRAY_ITEMSIZE(values), \
- match, \
- params_dst, params_src, sizeof *(params_src))
+ match)
typedef int (*dc_match_t)(const void *, const void *);
-typedef int (*dc_filter_t) (dc_transport_t transport, const void *userdata, void *params);
-
-static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_suunto (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_shearwater (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_hw (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_mares (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_divesystem (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_oceanic (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_mclean (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_atomic (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_deepsix (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_deepblu (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_oceans (dc_transport_t transport, const void *userdata, void *params);
-static int dc_filter_divesoft (dc_transport_t transport, const void *userdata, void *params);
+typedef int (*dc_filter_t) (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+
+static int dc_filter_uwatec (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_suunto (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_shearwater (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_hw (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_tecdiving (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_mares (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_divesystem (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_oceanic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_mclean (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_atomic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_deepsix (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_deepblu (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_oceans (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
+static int dc_filter_divesoft (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
// Not merged upstream yet
-static int dc_filter_garmin (dc_transport_t transport, const void *userdata, void *params);
+static int dc_filter_garmin (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata);
static dc_status_t dc_descriptor_iterator_next (dc_iterator_t *iterator, void *item);
@@ -180,7 +173,10 @@ static const dc_descriptor_t g_descriptors[] = {
{"Scubapro", "G2 TEK", DC_FAMILY_UWATEC_SMART, 0x31, DC_TRANSPORT_USBHID | DC_TRANSPORT_BLE, dc_filter_uwatec},
{"Scubapro", "G2", DC_FAMILY_UWATEC_SMART, 0x32, DC_TRANSPORT_USBHID | DC_TRANSPORT_BLE, dc_filter_uwatec},
{"Scubapro", "G2 Console", DC_FAMILY_UWATEC_SMART, 0x32, DC_TRANSPORT_USBHID | DC_TRANSPORT_BLE, dc_filter_uwatec},
+ {"Scubapro", "G3", DC_FAMILY_UWATEC_SMART, 0x34, DC_TRANSPORT_USBHID | DC_TRANSPORT_BLE, dc_filter_uwatec},
{"Scubapro", "G2 HUD", DC_FAMILY_UWATEC_SMART, 0x42, DC_TRANSPORT_USBHID | DC_TRANSPORT_BLE, dc_filter_uwatec},
+ {"Scubapro", "Luna 2.0 AI", DC_FAMILY_UWATEC_SMART, 0x50, DC_TRANSPORT_BLE, dc_filter_uwatec},
+ {"Scubapro", "Luna 2.0", DC_FAMILY_UWATEC_SMART, 0x51, DC_TRANSPORT_BLE, dc_filter_uwatec},
/* Reefnet */
{"Reefnet", "Sensus", DC_FAMILY_REEFNET_SENSUS, 1, DC_TRANSPORT_SERIAL, NULL},
{"Reefnet", "Sensus Pro", DC_FAMILY_REEFNET_SENSUSPRO, 2, DC_TRANSPORT_SERIAL, NULL},
@@ -364,6 +360,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Shearwater", "Peregrine", DC_FAMILY_SHEARWATER_PETREL, 9, DC_TRANSPORT_BLE, dc_filter_shearwater},
{"Shearwater", "Petrel 3", DC_FAMILY_SHEARWATER_PETREL, 10, DC_TRANSPORT_BLE, dc_filter_shearwater},
{"Shearwater", "Perdix 2", DC_FAMILY_SHEARWATER_PETREL, 11, DC_TRANSPORT_BLE, dc_filter_shearwater},
+ {"Shearwater", "Tern", DC_FAMILY_SHEARWATER_PETREL, 12, DC_TRANSPORT_BLE, dc_filter_shearwater},
/* Dive Rite NiTek Q */
{"Dive Rite", "NiTek Q", DC_FAMILY_DIVERITE_NITEKQ, 0, DC_TRANSPORT_SERIAL, NULL},
/* Citizen Hyper Aqualand */
@@ -417,6 +414,20 @@ static const dc_descriptor_t g_descriptors[] = {
{"Ratio", "iX3M 2021 Pro Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x73, DC_TRANSPORT_SERIAL, NULL},
{"Ratio", "iX3M 2021 Pro Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x74, DC_TRANSPORT_SERIAL, NULL},
{"Ratio", "iX3M 2021 Pro Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x75, DC_TRANSPORT_SERIAL, NULL},
+ {"Ratio", "iDive 2 Free", DC_FAMILY_DIVESYSTEM_IDIVE, 0x80, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iDive 2 Fancy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x81, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iDive 2 Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x82, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iDive 2 Pro", DC_FAMILY_DIVESYSTEM_IDIVE, 0x83, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iDive 2 Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x84, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iDive 2 Tech", DC_FAMILY_DIVESYSTEM_IDIVE, 0x85, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iDive 2 Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x86, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iX3M 2 GPS Gauge", DC_FAMILY_DIVESYSTEM_IDIVE, 0x90, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iX3M 2 GPS Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x91, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iX3M 2 GPS Pro", DC_FAMILY_DIVESYSTEM_IDIVE, 0x92, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iX3M 2 GPS Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x93, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iX3M 2 GPS Tech", DC_FAMILY_DIVESYSTEM_IDIVE, 0x94, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "iX3M 2 GPS Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x95, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
+ {"Ratio", "ATOM", DC_FAMILY_DIVESYSTEM_IDIVE, 0x96, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
{"Ratio", "iX3M 2 Gauge", DC_FAMILY_DIVESYSTEM_IDIVE, 0x100, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
{"Ratio", "iX3M 2 Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x101, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
{"Ratio", "iX3M 2 Pro", DC_FAMILY_DIVESYSTEM_IDIVE, 0x102, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
@@ -446,7 +457,6 @@ static const dc_descriptor_t g_descriptors[] = {
{"Deep Six", "Excursion", DC_FAMILY_DEEPSIX_EXCURSION, 0, DC_TRANSPORT_BLE, dc_filter_deepsix},
{"Crest", "CR-4", DC_FAMILY_DEEPSIX_EXCURSION, 0, DC_TRANSPORT_BLE, dc_filter_deepsix},
{"Genesis", "Centauri", DC_FAMILY_DEEPSIX_EXCURSION, 0, DC_TRANSPORT_BLE, dc_filter_deepsix},
- {"Tusa", "TC1", DC_FAMILY_DEEPSIX_EXCURSION, 0, DC_TRANSPORT_BLE, dc_filter_deepsix},
{"Scorpena", "Alpha", DC_FAMILY_DEEPSIX_EXCURSION, 0, DC_TRANSPORT_BLE, dc_filter_deepsix},
/* Seac Screen */
{"Seac", "Screen", DC_FAMILY_SEAC_SCREEN, 0, DC_TRANSPORT_SERIAL, NULL},
@@ -504,6 +514,15 @@ dc_match_usb (const void *key, const void *value)
return k->vid == v->vid && k->pid == v->pid;
}
+static int
+dc_match_usbhid (const void *key, const void *value)
+{
+ const dc_usbhid_desc_t *k = (const dc_usbhid_desc_t *) key;
+ const dc_usbhid_desc_t *v = (const dc_usbhid_desc_t *) value;
+
+ return k->vid == v->vid && k->pid == v->pid;
+}
+
static int
dc_match_number_with_prefix (const void *key, const void *value)
{
@@ -544,16 +563,13 @@ dc_match_oceanic (const void *key, const void *value)
}
static int
-dc_filter_internal (const void *key, const void *values, size_t count, size_t size, dc_match_t match, void *params_dst, const void *params_src, size_t params_size)
+dc_filter_internal (const void *key, const void *values, size_t count, size_t size, dc_match_t match)
{
if (key == NULL)
return 1;
for (size_t i = 0; i < count; ++i) {
if (match (key, (const unsigned char *) values + i * size)) {
- if (params_src && params_dst) {
- memcpy (params_dst, params_src, params_size);
- }
return 1;
}
}
@@ -568,7 +584,8 @@ static const char * const rfcomm[] = {
NULL
};
-static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_uwatec (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const irda[] = {
"Aladin Smart Com",
@@ -579,7 +596,7 @@ static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, voi
"UWATEC Galileo",
"UWATEC Galileo Sol",
};
- static const dc_usb_desc_t usbhid[] = {
+ static const dc_usbhid_desc_t usbhid[] = {
{0x2e6c, 0x3201}, // G2, G2 TEK
{0x2e6c, 0x3211}, // G2 Console
{0x2e6c, 0x4201}, // G2 HUD
@@ -592,12 +609,15 @@ static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, voi
"A1",
"A2",
"G2 TEK",
+ "Galileo 3",
+ "Luna 2.0 AI",
+ "Luna 2.0",
};
if (transport == DC_TRANSPORT_IRDA) {
return DC_FILTER_INTERNAL (userdata, irda, 0, dc_match_name);
} else if (transport == DC_TRANSPORT_USBHID) {
- return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usb);
+ return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usbhid);
} else if (transport == DC_TRANSPORT_BLE) {
return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_name);
}
@@ -605,9 +625,10 @@ static int dc_filter_uwatec (dc_transport_t transport, const void *userdata, voi
return 1;
}
-static int dc_filter_suunto (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_suunto (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
- static const dc_usb_desc_t usbhid[] = {
+ static const dc_usbhid_desc_t usbhid[] = {
{0x1493, 0x0030}, // Eon Steel
{0x1493, 0x0033}, // Eon Core
{0x1493, 0x0035}, // D5
@@ -621,7 +642,7 @@ static int dc_filter_suunto (dc_transport_t transport, const void *userdata, voi
};
if (transport == DC_TRANSPORT_USBHID) {
- return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usb);
+ return DC_FILTER_INTERNAL (userdata, usbhid, 0, dc_match_usbhid);
} else if (transport == DC_TRANSPORT_BLE) {
return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_prefix);
}
@@ -629,7 +650,8 @@ static int dc_filter_suunto (dc_transport_t transport, const void *userdata, voi
return 1;
}
-static int dc_filter_hw (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_hw (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"OSTC",
@@ -645,7 +667,8 @@ static int dc_filter_hw (dc_transport_t transport, const void *userdata, void *p
return 1;
}
-static int dc_filter_shearwater (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_shearwater (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"Predator",
@@ -657,6 +680,7 @@ static int dc_filter_shearwater (dc_transport_t transport, const void *userdata,
"Perdix 2",
"Teric",
"Peregrine",
+ "Tern"
};
if (transport == DC_TRANSPORT_BLUETOOTH || transport == DC_TRANSPORT_BLE) {
@@ -668,7 +692,8 @@ static int dc_filter_shearwater (dc_transport_t transport, const void *userdata,
return 1;
}
-static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_tecdiving (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"DiveComputer",
@@ -683,7 +708,8 @@ static int dc_filter_tecdiving (dc_transport_t transport, const void *userdata,
return 1;
}
-static int dc_filter_mares (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_mares (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"Mares bluelink pro",
@@ -697,11 +723,13 @@ static int dc_filter_mares (dc_transport_t transport, const void *userdata, void
return 1;
}
-static int dc_filter_divesystem (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_divesystem (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"DS",
"IX5M",
+ "RATIO-",
};
if (transport == DC_TRANSPORT_BLUETOOTH || transport == DC_TRANSPORT_BLE) {
@@ -711,7 +739,8 @@ static int dc_filter_divesystem (dc_transport_t transport, const void *userdata,
return 1;
}
-static int dc_filter_oceanic (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_oceanic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const unsigned int model[] = {
0x4552, // Oceanic Pro Plus X
@@ -738,7 +767,8 @@ static int dc_filter_oceanic (dc_transport_t transport, const void *userdata, vo
return 1;
}
-static int dc_filter_mclean(dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_mclean(dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"McLean Extreme",
@@ -753,30 +783,27 @@ static int dc_filter_mclean(dc_transport_t transport, const void *userdata, void
return 1;
}
-static int dc_filter_atomic (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_atomic (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const dc_usb_desc_t usb[] = {
{0x0471, 0x0888}, // Atomic Aquatics Cobalt
};
- static const dc_usb_params_t usb_params = {
- 0, 0x82, 0x02
- };
-
if (transport == DC_TRANSPORT_USB) {
- return DC_FILTER_INTERNAL_WITH_PARAMS (userdata, usb, 0, dc_match_usb, params, &usb_params);
+ return DC_FILTER_INTERNAL (userdata, usb, 0, dc_match_usb);
}
return 1;
}
-static int dc_filter_deepsix (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_deepsix (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"EXCURSION",
"Crest-CR4",
"CENTAURI",
- "TC1",
"ALPHA",
};
@@ -787,7 +814,8 @@ static int dc_filter_deepsix (dc_transport_t transport, const void *userdata, vo
return 1;
}
-static int dc_filter_deepblu (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_deepblu (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"COSMIQ",
@@ -800,7 +828,8 @@ static int dc_filter_deepblu (dc_transport_t transport, const void *userdata, vo
return 1;
}
-static int dc_filter_oceans (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_oceans (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"S1",
@@ -813,7 +842,8 @@ static int dc_filter_oceans (dc_transport_t transport, const void *userdata, voi
return 1;
}
-static int dc_filter_divesoft (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_divesoft (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const char * const bluetooth[] = {
"Freedom",
@@ -828,7 +858,8 @@ static int dc_filter_divesoft (dc_transport_t transport, const void *userdata, v
}
// Not merged upstream yet
-static int dc_filter_garmin (dc_transport_t transport, const void *userdata, void *params)
+static int
+dc_filter_garmin (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
static const dc_usb_desc_t usbhid[] = {
{0x091e, 0x2b2b}, // Garmin Descent Mk1
@@ -933,10 +964,10 @@ dc_descriptor_get_transports (dc_descriptor_t *descriptor)
}
int
-dc_descriptor_filter (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata, void *params)
+dc_descriptor_filter (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata)
{
if (descriptor == NULL || descriptor->filter == NULL || userdata == NULL)
return 1;
- return descriptor->filter (transport, userdata, params);
+ return descriptor->filter (descriptor, transport, userdata);
}
diff --git a/src/diverite_nitekq.h b/src/diverite_nitekq.h
index e016cabb..9bbf7280 100644
--- a/src/diverite_nitekq.h
+++ b/src/diverite_nitekq.h
@@ -35,7 +35,7 @@ dc_status_t
diverite_nitekq_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-diverite_nitekq_parser_create (dc_parser_t **parser, dc_context_t *context);
+diverite_nitekq_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/diverite_nitekq_parser.c b/src/diverite_nitekq_parser.c
index 56237696..d9f6dccd 100644
--- a/src/diverite_nitekq_parser.c
+++ b/src/diverite_nitekq_parser.c
@@ -49,7 +49,6 @@ struct diverite_nitekq_parser_t {
double maxdepth;
};
-static dc_status_t diverite_nitekq_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t diverite_nitekq_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t diverite_nitekq_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t diverite_nitekq_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -57,7 +56,6 @@ static dc_status_t diverite_nitekq_parser_samples_foreach (dc_parser_t *abstract
static const dc_parser_vtable_t diverite_nitekq_parser_vtable = {
sizeof(diverite_nitekq_parser_t),
DC_FAMILY_DIVERITE_NITEKQ,
- diverite_nitekq_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -69,7 +67,7 @@ static const dc_parser_vtable_t diverite_nitekq_parser_vtable = {
dc_status_t
-diverite_nitekq_parser_create (dc_parser_t **out, dc_context_t *context)
+diverite_nitekq_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
diverite_nitekq_parser_t *parser = NULL;
@@ -77,7 +75,7 @@ diverite_nitekq_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (diverite_nitekq_parser_t *) dc_parser_allocate (context, &diverite_nitekq_parser_vtable);
+ parser = (diverite_nitekq_parser_t *) dc_parser_allocate (context, &diverite_nitekq_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -101,13 +99,6 @@ diverite_nitekq_parser_create (dc_parser_t **out, dc_context_t *context)
}
-static dc_status_t
-diverite_nitekq_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
diverite_nitekq_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -161,6 +152,7 @@ diverite_nitekq_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->he[flags] / 100.0;
gasmix->oxygen = parser->o2[flags] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -264,13 +256,13 @@ diverite_nitekq_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
// Time (seconds).
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Gas change
if (gasmix != gasmix_previous) {
sample.gasmix = gasmix;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
@@ -282,7 +274,7 @@ diverite_nitekq_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
sample.depth = depth / 10.0;
else
sample.depth = depth * FEET / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
offset += 2;
if (type == 3) {
@@ -293,8 +285,9 @@ diverite_nitekq_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
if (offset + 1 > size)
return DC_STATUS_DATAFORMAT;
unsigned int ppo2 = data[offset];
- sample.ppo2 = ppo2 / 100.0;
- if (callback) callback (DC_SAMPLE_PPO2, sample, userdata);
+ sample.ppo2.sensor = DC_SENSOR_NONE;
+ sample.ppo2.value = ppo2 / 100.0;
+ if (callback) callback (DC_SAMPLE_PPO2, &sample, userdata);
offset++;
}
} else {
diff --git a/src/divesoft_freedom.h b/src/divesoft_freedom.h
index db04edb6..bca87b7f 100644
--- a/src/divesoft_freedom.h
+++ b/src/divesoft_freedom.h
@@ -35,7 +35,7 @@ dc_status_t
divesoft_freedom_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-divesoft_freedom_parser_create (dc_parser_t **parser, dc_context_t *context);
+divesoft_freedom_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/divesoft_freedom_parser.c b/src/divesoft_freedom_parser.c
index b595e63b..96475113 100644
--- a/src/divesoft_freedom_parser.c
+++ b/src/divesoft_freedom_parser.c
@@ -254,7 +254,6 @@ typedef struct divesoft_freedom_parser_t {
unsigned int calibrated;
} divesoft_freedom_parser_t;
-static dc_status_t divesoft_freedom_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t divesoft_freedom_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t divesoft_freedom_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -262,7 +261,6 @@ static dc_status_t divesoft_freedom_parser_samples_foreach (dc_parser_t *abstrac
static const dc_parser_vtable_t divesoft_freedom_parser_vtable = {
sizeof(divesoft_freedom_parser_t),
DC_FAMILY_DIVESOFT_FREEDOM,
- divesoft_freedom_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -643,7 +641,7 @@ divesoft_freedom_cache (divesoft_freedom_parser_t *parser)
}
dc_status_t
-divesoft_freedom_parser_create (dc_parser_t **out, dc_context_t *context)
+divesoft_freedom_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
divesoft_freedom_parser_t *parser = NULL;
@@ -651,7 +649,7 @@ divesoft_freedom_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (divesoft_freedom_parser_t *) dc_parser_allocate (context, &divesoft_freedom_parser_vtable);
+ parser = (divesoft_freedom_parser_t *) dc_parser_allocate (context, &divesoft_freedom_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -698,50 +696,6 @@ divesoft_freedom_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_SUCCESS;
}
-static dc_status_t
-divesoft_freedom_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- divesoft_freedom_parser_t *parser = (divesoft_freedom_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->version = 0;
- parser->headersize = 0;
- parser->divetime = 0;
- parser->divemode = 0;
- parser->temperature_min = 0;
- parser->maxdepth = 0;
- parser->atmospheric = 0;
- parser->avgdepth = 0;
- parser->ngasmixes = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->gasmix[i].oxygen = 0;
- parser->gasmix[i].helium = 0;
- parser->gasmix[i].type = 0;
- parser->gasmix[i].id = 0;
- }
- parser->diluent = UNDEFINED;
- parser->ntanks = 0;
- for (unsigned int i = 0; i < NTANKS; ++i) {
- parser->tank[i].volume = 0;
- parser->tank[i].workpressure = 0;
- parser->tank[i].beginpressure = 0;
- parser->tank[i].endpressure = 0;
- parser->tank[i].transmitter = 0;
- parser->tank[i].active = 0;
- }
- parser->vpm = 0;
- parser->gf_lo = 0;
- parser->gf_hi = 0;
- parser->seawater = 0;
- for (unsigned int i = 0; i < NSENSORS; ++i) {
- parser->calibration[i] = 0;
- }
- parser->calibrated = 0;
-
- return DC_STATUS_SUCCESS;
-}
-
static dc_status_t
divesoft_freedom_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -838,6 +792,13 @@ divesoft_freedom_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ if (parser->gasmix[flags].type == OXYGEN) {
+ gasmix->usage = DC_USAGE_OXYGEN;
+ } else if (parser->gasmix[flags].type == DILUENT) {
+ gasmix->usage = DC_USAGE_DILUENT;
+ } else {
+ gasmix->usage = DC_USAGE_NONE;
+ }
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -859,6 +820,7 @@ divesoft_freedom_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
tank->beginpressure = parser->tank[flags].beginpressure * 2.0;
tank->endpressure = parser->tank[flags].endpressure * 2.0;
tank->gasmix = flags;
+ tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_DECOMODEL:
if (parser->vpm) {
@@ -924,15 +886,15 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
continue;
}
time = timestamp;
- sample.time = time;
- if (callback) callback(DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback(DC_SAMPLE_TIME, &sample, userdata);
}
// Initial diluent.
if (!initial) {
if (parser->diluent != UNDEFINED) {
sample.gasmix = parser->diluent;
- if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback(DC_SAMPLE_GASMIX, &sample, userdata);
}
initial = 1;
}
@@ -943,18 +905,19 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
unsigned int ppo2 = array_uint16_le (data + offset + 6);
sample.depth = depth / 100.0;
- if (callback) callback(DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback(DC_SAMPLE_DEPTH, &sample, userdata);
if (ppo2) {
- sample.ppo2 = ppo2 * 10.0 / BAR;
- if (callback) callback(DC_SAMPLE_PPO2, sample, userdata);
+ sample.ppo2.sensor = DC_SENSOR_NONE;
+ sample.ppo2.value = ppo2 * 10.0 / BAR;
+ if (callback) callback(DC_SAMPLE_PPO2, &sample, userdata);
}
if (id == POINT_2) {
unsigned int orientation = array_uint32_le (data + offset + 8);
unsigned int heading = orientation & 0x1FF;
sample.bearing = heading;
- if (callback) callback (DC_SAMPLE_BEARING, sample, userdata);
+ if (callback) callback (DC_SAMPLE_BEARING, &sample, userdata);
} else if (id == POINT_1 || id == POINT_1_OLD) {
unsigned int misc = array_uint32_le (data + offset + 8);
unsigned int ceiling = array_uint16_le (data + offset + 12);
@@ -965,7 +928,7 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
// Temperature
sample.temperature = (signed int) signextend (temp, 10) / 10.0;
- if (callback) callback(DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback(DC_SAMPLE_TEMPERATURE, &sample, userdata);
// Deco / NDL
if (ceiling) {
@@ -977,12 +940,13 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
sample.deco.time = ndl * 60;
sample.deco.depth = 0.0;
}
- if (callback) callback(DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = tts * 60;
+ if (callback) callback(DC_SAMPLE_DECO, &sample, userdata);
// Setpoint
if (setpoint) {
sample.setpoint = setpoint / 100.0;
- if (callback) callback(DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback(DC_SAMPLE_SETPOINT, &sample, userdata);
}
}
} else if ((type >= LREC_MANIPULATION && type <= LREC_ACTIVITY) || type == LREC_INFO) {
@@ -994,7 +958,7 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = 0;
- if (callback) callback(DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback(DC_SAMPLE_EVENT, &sample, userdata);
} else if (event == EVENT_MIX_CHANGED || event == EVENT_DILUENT || event == EVENT_CHANGE_MODE) {
unsigned int o2 = data[offset + 6];
unsigned int he = data[offset + 7];
@@ -1014,13 +978,13 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
return DC_STATUS_DATAFORMAT;
}
sample.gasmix = idx;
- if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback(DC_SAMPLE_GASMIX, &sample, userdata);
} else if (event == EVENT_CNS) {
sample.cns = array_uint16_le (data + offset + 6) / 100.0;
- if (callback) callback(DC_SAMPLE_CNS, sample, userdata);
+ if (callback) callback(DC_SAMPLE_CNS, &sample, userdata);
} else if (event == EVENT_SETPOINT_MANUAL || event == EVENT_SETPOINT_AUTO) {
sample.setpoint = data[6] / 100.0;
- if (callback) callback(DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback(DC_SAMPLE_SETPOINT, &sample, userdata);
}
} else if (type == LREC_MEASURE) {
// Measurement record.
@@ -1038,25 +1002,27 @@ divesoft_freedom_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
sample.pressure.tank = idx;
sample.pressure.value = pressure * 2.0;
- if (callback) callback(DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback(DC_SAMPLE_PRESSURE, &sample, userdata);
}
} else if (id == MEASURE_ID_OXYGEN) {
for (unsigned int i = 0; i < NSENSORS; ++i) {
unsigned int ppo2 = array_uint16_le (data + offset + 4 + i * 2);
if (ppo2 == 0 || ppo2 == 0xFFFF)
continue;
- sample.ppo2 = ppo2 * 10.0 / BAR;
- if (callback) callback(DC_SAMPLE_PPO2, sample, userdata);
+ sample.ppo2.sensor = i;
+ sample.ppo2.value = ppo2 * 10.0 / BAR;
+ if (callback) callback(DC_SAMPLE_PPO2, &sample, userdata);
}
} else if (id == MEASURE_ID_OXYGEN_MV) {
for (unsigned int i = 0; i < NSENSORS; ++i) {
unsigned int value = array_uint16_le (data + offset + 4 + i * 2);
unsigned int state = data[offset + 12 + i];
- if (!parser->calibrated || state == SENSTAT_UNCALIBRATED ||
- state == SENSTAT_NOT_EXIST)
+ if (!parser->calibrated || parser->calibration[i] == 0 ||
+ state == SENSTAT_UNCALIBRATED || state == SENSTAT_NOT_EXIST)
continue;
- sample.ppo2 = value / 100.0 * parser->calibration[i] / BAR;
- if (callback) callback(DC_SAMPLE_PPO2, sample, userdata);
+ sample.ppo2.sensor = i;
+ sample.ppo2.value = value / 100.0 * parser->calibration[i] / BAR;
+ if (callback) callback(DC_SAMPLE_PPO2, &sample, userdata);
}
}
} else if (type == LREC_STATE) {
diff --git a/src/divesystem_idive.h b/src/divesystem_idive.h
index 1da80a00..91e1ea95 100644
--- a/src/divesystem_idive.h
+++ b/src/divesystem_idive.h
@@ -36,7 +36,7 @@ dc_status_t
divesystem_idive_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream, unsigned int model);
dc_status_t
-divesystem_idive_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+divesystem_idive_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/divesystem_idive_parser.c b/src/divesystem_idive_parser.c
index 3270c55c..c13a8047 100644
--- a/src/divesystem_idive_parser.c
+++ b/src/divesystem_idive_parser.c
@@ -58,6 +58,9 @@
#define IX3M2_ZHL16C 2
#define IX3M2_VPM 3
+#define REC_SAMPLE 0
+#define REC_INFO 1
+
typedef struct divesystem_idive_parser_t divesystem_idive_parser_t;
typedef struct divesystem_idive_gasmix_t {
@@ -89,7 +92,6 @@ struct divesystem_idive_parser_t {
unsigned int gf_high;
};
-static dc_status_t divesystem_idive_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t divesystem_idive_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t divesystem_idive_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -97,7 +99,6 @@ static dc_status_t divesystem_idive_parser_samples_foreach (dc_parser_t *abstrac
static const dc_parser_vtable_t divesystem_idive_parser_vtable = {
sizeof(divesystem_idive_parser_t),
DC_FAMILY_DIVESYSTEM_IDIVE,
- divesystem_idive_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -109,7 +110,7 @@ static const dc_parser_vtable_t divesystem_idive_parser_vtable = {
dc_status_t
-divesystem_idive_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+divesystem_idive_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
divesystem_idive_parser_t *parser = NULL;
@@ -117,7 +118,7 @@ divesystem_idive_parser_create (dc_parser_t **out, dc_context_t *context, unsign
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (divesystem_idive_parser_t *) dc_parser_allocate (context, &divesystem_idive_parser_vtable);
+ parser = (divesystem_idive_parser_t *) dc_parser_allocate (context, &divesystem_idive_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -156,35 +157,6 @@ divesystem_idive_parser_create (dc_parser_t **out, dc_context_t *context, unsign
}
-static dc_status_t
-divesystem_idive_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- divesystem_idive_parser_t *parser = (divesystem_idive_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->divemode = INVALID;
- parser->divetime = 0;
- parser->maxdepth = 0;
- parser->ngasmixes = 0;
- parser->ntanks = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->gasmix[i].oxygen = 0;
- parser->gasmix[i].helium = 0;
- }
- for (unsigned int i = 0; i < NTANKS; ++i) {
- parser->tank[i].id = 0;
- parser->tank[i].beginpressure = 0;
- parser->tank[i].endpressure = 0;
- }
- parser->algorithm = INVALID;
- parser->gf_low = INVALID;
- parser->gf_high = INVALID;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
divesystem_idive_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -317,6 +289,7 @@ divesystem_idive_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -331,6 +304,7 @@ divesystem_idive_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
tank->beginpressure = parser->tank[flags].beginpressure;
tank->endpressure = parser->tank[flags].endpressure;
tank->gasmix = DC_GASMIX_UNKNOWN;
+ tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_ATMOSPHERIC:
if (ISIX3M(parser->model)) {
@@ -439,6 +413,7 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
unsigned int algorithm_previous = INVALID;
unsigned int gf_low = INVALID;
unsigned int gf_high = INVALID;
+ unsigned int have_bearing = 0;
unsigned int firmware = 0;
unsigned int apos4 = 0;
@@ -467,27 +442,37 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
while (offset + samplesize <= size) {
dc_sample_value_t sample = {0};
+ // Get the record type.
+ unsigned int type = ISIX3M(parser->model) ?
+ array_uint16_le (data + offset + 52) :
+ REC_SAMPLE;
+ if (type != REC_SAMPLE) {
+ // Skip non-sample records.
+ offset += samplesize;
+ continue;
+ }
+
// Time (seconds).
unsigned int timestamp = array_uint32_le (data + offset + 2);
- if (timestamp <= time) {
- ERROR (abstract->context, "Timestamp moved backwards.");
+ if (timestamp <= time && time != 0) {
+ ERROR (abstract->context, "Timestamp moved backwards (%u %u).", timestamp, time);
return DC_STATUS_DATAFORMAT;
}
time = timestamp;
- sample.time = timestamp;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = timestamp * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
unsigned int depth = array_uint16_le (data + offset + 6);
if (maxdepth < depth)
maxdepth = depth;
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (Celsius).
signed int temperature = (signed short) array_uint16_le (data + offset + 8);
sample.temperature = temperature / 10.0;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// Dive mode
unsigned int mode = data[offset + 18];
@@ -521,7 +506,7 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
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);
+ if (callback) callback (DC_SAMPLE_SETPOINT, &sample, userdata);
}
// Gaschange.
@@ -548,7 +533,7 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
}
sample.gasmix = i;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
o2_previous = o2;
he_previous = he;
}
@@ -566,18 +551,20 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
if (decostop) {
sample.deco.type = DC_DECO_DECOSTOP;
sample.deco.depth = decostop / 10.0;
- sample.deco.time = apos4 ? decotime : tts;
+ sample.deco.time = decotime;
+ sample.deco.tts = tts;
} else {
sample.deco.type = DC_DECO_NDL;
sample.deco.depth = 0.0;
sample.deco.time = tts;
+ sample.deco.tts = 0;
}
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
// CNS
unsigned int cns = array_uint16_le (data + offset + 29);
sample.cns = cns / 100.0;
- if (callback) callback (DC_SAMPLE_CNS, sample, userdata);
+ if (callback) callback (DC_SAMPLE_CNS, &sample, userdata);
// Tank Pressure
if (samplesize == SZ_SAMPLE_IX3M_APOS4) {
@@ -598,7 +585,7 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = 0;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
} else {
// Get the index of the tank.
if (id != tank_previous) {
@@ -628,10 +615,20 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
if (tank_idx < ntanks) {
sample.pressure.tank = tank_idx;
sample.pressure.value = pressure;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
tank[tank_idx].endpressure = pressure;
}
}
+
+ // Compass bearing
+ unsigned int bearing = array_uint16_le (data + offset + 50);
+ if (bearing != 0) {
+ have_bearing = 1; // Stop ignoring zero values.
+ }
+ if (have_bearing && bearing != 0xFFFF) {
+ sample.bearing = bearing;
+ if (callback) callback (DC_SAMPLE_BEARING, &sample, userdata);
+ }
}
offset += samplesize;
diff --git a/src/field-cache.h b/src/field-cache.h
index 1a869ad0..09c06e0c 100644
--- a/src/field-cache.h
+++ b/src/field-cache.h
@@ -26,6 +26,7 @@ typedef struct dc_field_cache {
// dc_tank_t TANK[MAXGASES]
// but that's for later
dc_tankinfo_t tankinfo[MAXGASES];
+ dc_usage_t tankusage[MAXGASES];
double tanksize[MAXGASES];
double tankworkingpressure[MAXGASES];
diff --git a/src/garmin.c b/src/garmin.c
index c156097b..f51e19ae 100644
--- a/src/garmin.c
+++ b/src/garmin.c
@@ -448,7 +448,6 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
{
dc_status_t status = DC_STATUS_SUCCESS;
garmin_device_t *device = (garmin_device_t *) abstract;
- dc_parser_t *parser;
char pathname[PATH_MAX];
char pathname_input[PATH_MAX];
size_t pathlen;
@@ -539,16 +538,12 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
free(files.array);
return DC_STATUS_NOMEMORY;
}
- if ((rc = garmin_parser_create(&parser, abstract->context) != DC_STATUS_SUCCESS)) {
- ERROR (abstract->context, "Failed to create parser for dive verification.");
- free(files.array);
- return rc;
- }
dc_event_devinfo_t devinfo;
dc_event_devinfo_t *devinfo_p = &devinfo;
for (int i = 0; i < files.nr; i++) {
const char *name = files.array[i].name;
+ dc_parser_t *parser;
const unsigned char *data;
unsigned int size;
short is_dive = 0;
@@ -574,7 +569,14 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
data = dc_buffer_get_data(file);
size = dc_buffer_get_size(file);
- is_dive = !device->model || garmin_parser_is_dive(parser, data, size, devinfo_p);
+ status = garmin_parser_create(&parser, abstract->context, data, size);
+ if (status != DC_STATUS_SUCCESS) {
+ ERROR (abstract->context, "Failed to create parser for dive verification.");
+ free(files.array);
+ return rc;
+ }
+
+ is_dive = !device->model || garmin_parser_is_dive(parser, devinfo_p);
if (devinfo_p) {
// first time we came through here, let's emit the
// devinfo and vendor events
@@ -583,6 +585,7 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
}
if (!is_dive) {
DEBUG(abstract->context, "decided %s isn't a dive.", name);
+ dc_parser_destroy(parser);
continue;
}
@@ -591,10 +594,10 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
progress.current++;
device_event_emit(abstract, DC_EVENT_PROGRESS, &progress);
+ dc_parser_destroy(parser);
}
free(files.array);
- dc_parser_destroy(parser);
dc_buffer_free(file);
return status;
}
diff --git a/src/garmin.h b/src/garmin.h
index ade3d6c0..88bb6523 100644
--- a/src/garmin.h
+++ b/src/garmin.h
@@ -35,12 +35,12 @@ dc_status_t
garmin_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream, unsigned int model);
dc_status_t
-garmin_parser_create (dc_parser_t **parser, dc_context_t *context);
+garmin_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
// we need to be able to call into the parser to check if the
// files that we find are actual dives
int
-garmin_parser_is_dive (dc_parser_t *abstract, const unsigned char *data, unsigned int size, dc_event_devinfo_t *devinfo_p);
+garmin_parser_is_dive (dc_parser_t *abstract, dc_event_devinfo_t *devinfo_p);
// The dive names are of the form "2018-08-20-10-23-30.fit"
// With the terminating zero, that's 24 bytes.
diff --git a/src/garmin_parser.c b/src/garmin_parser.c
index 466c6d21..c344ebd9 100644
--- a/src/garmin_parser.c
+++ b/src/garmin_parser.c
@@ -232,12 +232,12 @@ static void garmin_event(struct garmin_parser_t *garmin,
if (!sample.event.name)
return;
- garmin->callback(DC_SAMPLE_EVENT, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_EVENT, &sample, garmin->userdata);
return;
case 57:
sample.gasmix = data;
- garmin->callback(DC_SAMPLE_GASMIX, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_GASMIX, &sample, garmin->userdata);
dc_tankinfo_t *tankinfo = &garmin->cache.tankinfo[data];
if (!garmin->dive.current_tankinfo || (*tankinfo & DC_TANKINFO_CC_DILUENT) != (*garmin->dive.current_tankinfo & DC_TANKINFO_CC_DILUENT)) {
@@ -250,7 +250,7 @@ static void garmin_event(struct garmin_parser_t *garmin,
}
sample2.event.flags = 2 << SAMPLE_FLAGS_SEVERITY_SHIFT;
- garmin->callback(DC_SAMPLE_EVENT, sample2, garmin->userdata);
+ garmin->callback(DC_SAMPLE_EVENT, &sample2, garmin->userdata);
garmin->dive.current_tankinfo = tankinfo;
}
@@ -324,7 +324,7 @@ static void flush_pending_record(struct garmin_parser_t *garmin)
sample.deco.type = DC_DECO_DECOSTOP;
sample.deco.time = record->stop_time;
sample.deco.depth = record->ceiling;
- garmin->callback(DC_SAMPLE_DECO, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_DECO, &sample, garmin->userdata);
}
if (pending & RECORD_EVENT) {
@@ -337,19 +337,19 @@ static void flush_pending_record(struct garmin_parser_t *garmin)
sample.pressure.tank = find_tank_index(garmin, record->sensor);
sample.pressure.value = record->pressure / 100.0;
- garmin->callback(DC_SAMPLE_PRESSURE, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_PRESSURE, &sample, garmin->userdata);
}
if (pending & RECORD_SETPOINT_CHANGE) {
dc_sample_value_t sample = {0};
sample.setpoint = record->setpoint_actual_cbar / 100.0;
- garmin->callback(DC_SAMPLE_SETPOINT, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_SETPOINT, &sample, garmin->userdata);
}
}
-static dc_status_t garmin_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
+static dc_status_t garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsigned int size);
static dc_status_t garmin_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t garmin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t garmin_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -357,7 +357,6 @@ static dc_status_t garmin_parser_samples_foreach (dc_parser_t *abstract, dc_samp
static const dc_parser_vtable_t garmin_parser_vtable = {
sizeof(garmin_parser_t),
DC_FAMILY_GARMIN,
- garmin_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -368,7 +367,7 @@ static const dc_parser_vtable_t garmin_parser_vtable = {
};
dc_status_t
-garmin_parser_create (dc_parser_t **out, dc_context_t *context)
+garmin_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
garmin_parser_t *parser = NULL;
@@ -376,12 +375,14 @@ garmin_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (garmin_parser_t *) dc_parser_allocate (context, &garmin_parser_vtable);
+ parser = (garmin_parser_t *) dc_parser_allocate (context, &garmin_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
}
+ garmin_parser_set_data(parser, data, size);
+
*out = (dc_parser_t *) parser;
return DC_STATUS_SUCCESS;
@@ -509,7 +510,7 @@ DECLARE_FIELD(ANY, timestamp, UINT32)
// Now we're ready to actually update the sample times
garmin->record_data.time = data+1;
sample.time = data;
- garmin->callback(DC_SAMPLE_TIME, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_TIME, &sample, garmin->userdata);
}
}
DECLARE_FIELD(ANY, message_index, UINT16) { garmin->record_data.index = data; }
@@ -556,7 +557,7 @@ DECLARE_FIELD(RECORD, heart_rate, UINT8) // bpm
if (garmin->callback) {
dc_sample_value_t sample = {0};
sample.heartbeat = data;
- garmin->callback(DC_SAMPLE_HEARTBEAT, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_HEARTBEAT, &sample, garmin->userdata);
}
}
DECLARE_FIELD(RECORD, cadence, UINT8) { } // cadence
@@ -568,7 +569,7 @@ DECLARE_FIELD(RECORD, temperature, SINT8) // degrees C
if (garmin->callback) {
dc_sample_value_t sample = {0};
sample.temperature = data;
- garmin->callback(DC_SAMPLE_TEMPERATURE, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_TEMPERATURE, &sample, garmin->userdata);
}
}
DECLARE_FIELD(RECORD, abs_pressure, UINT32) {} // Pascal
@@ -577,7 +578,7 @@ DECLARE_FIELD(RECORD, depth, UINT32) // mm
if (garmin->callback) {
dc_sample_value_t sample = {0};
sample.depth = data / 1000.0;
- garmin->callback(DC_SAMPLE_DEPTH, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_DEPTH, &sample, garmin->userdata);
}
}
DECLARE_FIELD(RECORD, next_stop_depth, UINT32) // mm
@@ -595,7 +596,7 @@ DECLARE_FIELD(RECORD, tts, UINT32)
if (garmin->callback) {
dc_sample_value_t sample = {0};
sample.time = data;
- garmin->callback(DC_SAMPLE_TTS, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_TTS, &sample, garmin->userdata);
}
}
DECLARE_FIELD(RECORD, ndl, UINT32) // s
@@ -604,7 +605,7 @@ DECLARE_FIELD(RECORD, ndl, UINT32) // s
dc_sample_value_t sample = {0};
sample.deco.type = DC_DECO_NDL;
sample.deco.time = data;
- garmin->callback(DC_SAMPLE_DECO, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_DECO, &sample, garmin->userdata);
}
}
DECLARE_FIELD(RECORD, cns_load, UINT8)
@@ -612,7 +613,7 @@ DECLARE_FIELD(RECORD, cns_load, UINT8)
if (garmin->callback) {
dc_sample_value_t sample = {0};
sample.cns = data / 100.0;
- garmin->callback(DC_SAMPLE_CNS, sample, garmin->userdata);
+ garmin->callback(DC_SAMPLE_CNS, &sample, garmin->userdata);
}
}
DECLARE_FIELD(RECORD, n2_load, UINT16) { } // percent
@@ -1586,10 +1587,8 @@ static void add_gps_string(garmin_parser_t *garmin, const char *desc, struct pos
}
int
-garmin_parser_is_dive (dc_parser_t *abstract, const unsigned char *data, unsigned int size, dc_event_devinfo_t *devinfo_p)
+garmin_parser_is_dive (dc_parser_t *abstract, dc_event_devinfo_t *devinfo_p)
{
- // set up the parser and extract data
- dc_parser_set_data(abstract, data, size);
garmin_parser_t *garmin = (garmin_parser_t *) abstract;
if (devinfo_p) {
@@ -1621,10 +1620,8 @@ static void add_sensor_string(garmin_parser_t *garmin, const char *desc, const s
}
static dc_status_t
-garmin_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
+garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsigned int size)
{
- garmin_parser_t *garmin = (garmin_parser_t *) abstract;
-
/* Walk the data once without a callback to set up the core fields */
garmin->callback = NULL;
garmin->userdata = NULL;
diff --git a/src/hw_ostc.h b/src/hw_ostc.h
index 5635e6d3..922fa02c 100644
--- a/src/hw_ostc.h
+++ b/src/hw_ostc.h
@@ -36,7 +36,7 @@ dc_status_t
hw_ostc_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-hw_ostc_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int serial);
+hw_ostc_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int serial);
#ifdef __cplusplus
}
diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c
index 023c978c..f0cb7b19 100644
--- a/src/hw_ostc3.c
+++ b/src/hw_ostc3.c
@@ -240,7 +240,7 @@ hw_ostc3_write (hw_ostc3_device_t *device, dc_event_progress_t *progress, const
size_t nbytes = 0;
while (nbytes < size) {
// Set the maximum packet size.
- size_t length = 64;
+ size_t length = (device->hardware == OSTC4) ? 64 : 1024;
// Limit the packet size to the total size.
if (nbytes + length > size)
diff --git a/src/hw_ostc3.h b/src/hw_ostc3.h
index 1e7720a3..f2d7bbf1 100644
--- a/src/hw_ostc3.h
+++ b/src/hw_ostc3.h
@@ -36,7 +36,7 @@ dc_status_t
hw_ostc3_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int serial, unsigned int model);
+hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial);
#ifdef __cplusplus
}
diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c
index 92017421..6f09107f 100644
--- a/src/hw_ostc_parser.c
+++ b/src/hw_ostc_parser.c
@@ -43,10 +43,6 @@
#define UNDEFINED 0xFFFFFFFF
-#define ALL 0
-#define FIXED 1
-#define MANUAL 2
-
#define HEADER 1
#define PROFILE 2
@@ -117,10 +113,12 @@ typedef struct hw_ostc_layout_t {
} hw_ostc_layout_t;
typedef struct hw_ostc_gasmix_t {
+ unsigned int id;
unsigned int oxygen;
unsigned int helium;
unsigned int type;
unsigned int enabled;
+ unsigned int active;
unsigned int diluent;
} hw_ostc_gasmix_t;
@@ -136,6 +134,7 @@ typedef struct hw_ostc_parser_t {
const hw_ostc_layout_t *layout;
unsigned int ngasmixes;
unsigned int nfixed;
+ unsigned int ndisabled;
unsigned int initial;
unsigned int initial_setpoint;
unsigned int initial_cns;
@@ -143,15 +142,15 @@ typedef struct hw_ostc_parser_t {
unsigned int current_divemode_ccr;
} hw_ostc_parser_t;
-static dc_status_t hw_ostc_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
+static dc_status_t hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t callback, void *userdata);
+
static const dc_parser_vtable_t hw_ostc_parser_vtable = {
sizeof(hw_ostc_parser_t),
DC_FAMILY_HW_OSTC,
- hw_ostc_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -216,15 +215,10 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc3 = {
};
static unsigned int
-hw_ostc_find_gasmix (hw_ostc_parser_t *parser, unsigned int o2, unsigned int he, unsigned int dil, unsigned int type)
+hw_ostc_find_gasmix_manual (hw_ostc_parser_t *parser, unsigned int o2, unsigned int he, unsigned int dil)
{
- unsigned int offset = 0;
+ unsigned int offset = parser->nfixed - parser->ndisabled;
unsigned int count = parser->ngasmixes;
- if (type == FIXED) {
- count = parser->nfixed;
- } else if (type == MANUAL) {
- offset = parser->nfixed;
- }
unsigned int i = offset;
while (i < count) {
@@ -236,6 +230,22 @@ hw_ostc_find_gasmix (hw_ostc_parser_t *parser, unsigned int o2, unsigned int he,
return i;
}
+static unsigned int
+hw_ostc_find_gasmix_fixed (hw_ostc_parser_t *parser, unsigned int id)
+{
+ unsigned int offset = 0;
+ unsigned int count = parser->nfixed - parser->ndisabled;
+
+ unsigned int i = offset;
+ while (i < count) {
+ if (id == parser->gasmix[i].id)
+ break;
+ i++;
+ }
+
+ return i;
+}
+
static unsigned int
hw_ostc_is_ccr (unsigned int divemode, unsigned int version)
{
@@ -317,19 +327,23 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
initial = data[31];
}
for (unsigned int i = 0; i < ngasmixes; ++i) {
+ gasmix[i].id = i + 1;
gasmix[i].oxygen = data[25 + 2 * i];
gasmix[i].helium = 0;
gasmix[i].type = 0;
gasmix[i].enabled = 1;
+ gasmix[i].active = 0;
gasmix[i].diluent = 0;
}
} else if (version == 0x23 || version == 0x24) {
ngasmixes = 5;
for (unsigned int i = 0; i < ngasmixes; ++i) {
+ gasmix[i].id = i + 1;
gasmix[i].oxygen = data[28 + 4 * i + 0];
gasmix[i].helium = data[28 + 4 * i + 1];
gasmix[i].type = data[28 + 4 * i + 3];
gasmix[i].enabled = gasmix[i].type != 0;
+ gasmix[i].active = 0;
gasmix[i].diluent = ccr;
// Find the first gas marked as the initial gas.
if (initial == UNDEFINED && data[28 + 4 * i + 3] == 1) {
@@ -348,6 +362,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
initial = data[31];
}
for (unsigned int i = 0; i < ngasmixes; ++i) {
+ gasmix[i].id = i + 1;
gasmix[i].oxygen = data[19 + 2 * i + 0];
gasmix[i].helium = data[19 + 2 * i + 1];
gasmix[i].type = 0;
@@ -356,6 +371,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
} else {
gasmix[i].enabled = 1;
}
+ gasmix[i].active = 0;
gasmix[i].diluent = ccr;
}
}
@@ -364,7 +380,6 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
ERROR(abstract->context, "Invalid initial gas mix.");
return DC_STATUS_DATAFORMAT;
}
- initial--; /* Convert to a zero based index. */
} else {
WARNING(abstract->context, "No initial gas mix available.");
}
@@ -375,6 +390,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
parser->layout = layout;
parser->ngasmixes = ngasmixes;
parser->nfixed = ngasmixes;
+ parser->ndisabled = 0;
parser->initial = initial;
parser->initial_setpoint = initial_setpoint;
parser->initial_cns = initial_cns;
@@ -387,7 +403,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
}
static dc_status_t
-hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, unsigned int serial, unsigned int hwos, unsigned int model)
+hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int hwos, unsigned int model, unsigned int serial)
{
hw_ostc_parser_t *parser = NULL;
@@ -395,7 +411,7 @@ hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, unsign
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (hw_ostc_parser_t *) dc_parser_allocate (context, &hw_ostc_parser_vtable);
+ parser = (hw_ostc_parser_t *) dc_parser_allocate (context, &hw_ostc_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -410,14 +426,17 @@ hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, unsign
parser->layout = NULL;
parser->ngasmixes = 0;
parser->nfixed = 0;
+ parser->ndisabled = 0;
parser->initial = 0;
parser->initial_setpoint = 0;
parser->initial_cns = 0;
for (unsigned int i = 0; i < NGASMIXES; ++i) {
+ parser->gasmix[i].id = 0;
parser->gasmix[i].oxygen = 0;
parser->gasmix[i].helium = 0;
parser->gasmix[i].type = 0;
parser->gasmix[i].enabled = 0;
+ parser->gasmix[i].active = 0;
parser->gasmix[i].diluent = 0;
}
parser->serial = serial;
@@ -429,44 +448,17 @@ hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, unsign
dc_status_t
-hw_ostc_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int serial)
+hw_ostc_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int serial)
{
- return hw_ostc_parser_create_internal (out, context, serial, 0, 0);
+ return hw_ostc_parser_create_internal (out, context, data, size, 0, 0, serial);
}
dc_status_t
-hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int serial, unsigned int model)
-{
- return hw_ostc_parser_create_internal (out, context, serial, 1, model);
-}
-
-static dc_status_t
-hw_ostc_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
+hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial)
{
- hw_ostc_parser_t *parser = (hw_ostc_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->version = 0;
- parser->header = 0;
- parser->layout = NULL;
- parser->ngasmixes = 0;
- parser->nfixed = 0;
- parser->initial = 0;
- parser->initial_setpoint = 0;
- parser->initial_cns = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->gasmix[i].oxygen = 0;
- parser->gasmix[i].helium = 0;
- parser->gasmix[i].type = 0;
- parser->gasmix[i].enabled = 0;
- parser->gasmix[i].diluent = 0;
- }
-
- return DC_STATUS_SUCCESS;
+ return hw_ostc_parser_create_internal (out, context, data, size, 1, model, serial);
}
-
static dc_status_t
hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -542,7 +534,7 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
// Cache the profile data.
if (parser->cached < PROFILE) {
- rc = hw_ostc_parser_samples_foreach (abstract, NULL, NULL);
+ rc = hw_ostc_parser_internal_foreach (parser, NULL, NULL);
if (rc != DC_STATUS_SUCCESS)
return rc;
}
@@ -582,6 +574,8 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
return DC_STATUS_UNSUPPORTED;
}
+ gasmix->usage = parser->gasmix[flags].diluent ?
+ DC_USAGE_DILUENT : DC_USAGE_NONE;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -839,7 +833,7 @@ static void hw_ostc_notify_bailout(hw_ostc_parser_t *parser, const unsigned char
}
if (callback) {
- callback(DC_SAMPLE_EVENT, sample, userdata);
+ callback(DC_SAMPLE_EVENT, &sample, userdata);
}
parser->current_divemode_ccr = parser->gasmix[index].diluent;
@@ -847,17 +841,12 @@ static void hw_ostc_notify_bailout(hw_ostc_parser_t *parser, const unsigned char
}
static dc_status_t
-hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
+hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t callback, void *userdata)
{
- hw_ostc_parser_t *parser = (hw_ostc_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 = hw_ostc_parser_cache (parser);
- if (rc != DC_STATUS_SUCCESS)
- return rc;
-
unsigned int version = parser->version;
unsigned int header = parser->header;
const hw_ostc_layout_t *layout = parser->layout;
@@ -964,7 +953,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
unsigned int time = 0;
unsigned int nsamples = 0;
- unsigned int tank = parser->initial != UNDEFINED ? parser->initial : 0;
+ unsigned int tank = parser->initial != UNDEFINED ? parser->initial - 1 : 0;
unsigned int offset = header;
if (version == 0x23 || version == 0x24)
@@ -976,31 +965,33 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
// Time (seconds).
time += samplerate;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Initial gas mix.
if (time == samplerate && parser->initial != UNDEFINED) {
- sample.gasmix = parser->initial;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ unsigned int idx = hw_ostc_find_gasmix_fixed (parser, parser->initial);
+ parser->gasmix[idx].active = 1;
+ sample.gasmix = idx;
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
}
// Initial setpoint (mbar).
if (time == samplerate && parser->initial_setpoint != UNDEFINED) {
sample.setpoint = parser->initial_setpoint / 100.0;
- if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_SETPOINT, &sample, userdata);
}
// Initial CNS (%).
if (time == samplerate && parser->initial_cns != UNDEFINED) {
sample.cns = parser->initial_cns / 100.0;
- if (callback) callback (DC_SAMPLE_CNS, sample, userdata);
+ if (callback) callback (DC_SAMPLE_CNS, &sample, userdata);
}
// Depth (1/100 m).
unsigned int depth = array_uint16_le (data + offset);
sample.depth = depth / 100.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
offset += 2;
// Extended sample info.
@@ -1059,7 +1050,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
break;
}
if (sample.event.type && callback)
- callback (DC_SAMPLE_EVENT, sample, userdata);
+ callback (DC_SAMPLE_EVENT, &sample, userdata);
// Manual Gas Set & Change
if (events & 0x10) {
@@ -1076,25 +1067,25 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
diluent = ccr;
}
unsigned int he = data[offset + 1];
- unsigned int idx = hw_ostc_find_gasmix (parser, o2, he, diluent, MANUAL);
+ unsigned int idx = hw_ostc_find_gasmix_manual (parser, o2, he, ccr);
if (idx >= parser->ngasmixes) {
if (idx >= NGASMIXES) {
ERROR (abstract->context, "Maximum number of gas mixes reached.");
return DC_STATUS_NOMEMORY;
}
+ parser->gasmix[idx].id = 0;
parser->gasmix[idx].oxygen = o2;
parser->gasmix[idx].helium = he;
parser->gasmix[idx].type = 0;
parser->gasmix[idx].enabled = 1;
+ parser->gasmix[idx].active = 1;
parser->gasmix[idx].diluent = diluent;
parser->ngasmixes = idx + 1;
}
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
-
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
hw_ostc_notify_bailout(parser, data, idx, callback, userdata);
-
offset += 2;
length -= 2;
}
@@ -1105,22 +1096,21 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
ERROR (abstract->context, "Buffer overflow detected!");
return DC_STATUS_DATAFORMAT;
}
- unsigned int idx = data[offset];
- if (idx > parser->nfixed && idx <= parser->nfixed + OSTC4_CC_DILUENT_GAS_OFFSET) {
- // OSTC4 reports gas changes to another diluent with an offset
- idx -= OSTC4_CC_DILUENT_GAS_OFFSET;
+ unsigned int id = data[offset];
+ if (parser->model == OSTC4 && ccr && id > parser->nfixed) {
+ // Fix the OSTC4 diluent index.
+ id -= parser->nfixed;
}
- if (idx < 1 || idx > parser->nfixed) {
- ERROR(abstract->context, "Invalid gas mix (%u).", idx);
+ if (id < 1 || id > parser->nfixed) {
+ ERROR(abstract->context, "Invalid gas mix (%u).", id);
return DC_STATUS_DATAFORMAT;
}
- idx--; /* Convert to a zero based index. */
+ unsigned int idx = hw_ostc_find_gasmix_fixed (parser, id);
+ parser->gasmix[idx].active = 1;
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
- tank = idx;
-
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
+ tank = id - 1;
hw_ostc_notify_bailout(parser, data, idx, callback, userdata);
-
offset++;
length--;
}
@@ -1133,7 +1123,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
return DC_STATUS_DATAFORMAT;
}
sample.setpoint = data[offset] / 100.0;
- if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_SETPOINT, &sample, userdata);
offset++;
length--;
}
@@ -1147,25 +1137,25 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
unsigned int o2 = data[offset];
unsigned int he = data[offset + 1];
- unsigned int idx = hw_ostc_find_gasmix (parser, o2, he, 0, MANUAL);
+ unsigned int idx = hw_ostc_find_gasmix_manual (parser, o2, he, 0);
if (idx >= parser->ngasmixes) {
if (idx >= NGASMIXES) {
ERROR (abstract->context, "Maximum number of gas mixes reached.");
return DC_STATUS_NOMEMORY;
}
+ parser->gasmix[idx].id = 0;
parser->gasmix[idx].oxygen = o2;
parser->gasmix[idx].helium = he;
parser->gasmix[idx].type = 0;
parser->gasmix[idx].enabled = 1;
+ parser->gasmix[idx].active = 1;
parser->gasmix[idx].diluent = 0;
parser->ngasmixes = idx + 1;
}
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
-
- hw_ostc_notify_bailout(parser, data, idx, callback, userdata);
-
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
+ hw_ostc_notify_bailout(parser, data, idx, callback, userdata);
offset += 2;
length -= 2;
}
@@ -1197,7 +1187,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
case TEMPERATURE:
value = array_uint16_le (data + offset);
sample.temperature = value / 10.0;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
break;
case DECO:
// Due to a firmware bug, the deco/ndl info is incorrect for
@@ -1212,7 +1202,8 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
sample.deco.depth = 0.0;
}
sample.deco.time = data[offset + 1] * 60;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
break;
case PPO2:
for (unsigned int j = 0; j < 3; ++j) {
@@ -1226,8 +1217,9 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
}
if (count) {
for (unsigned int j = 0; j < 3; ++j) {
- sample.ppo2 = ppo2[j] / 100.0;
- if (callback) callback (DC_SAMPLE_PPO2, sample, userdata);
+ sample.ppo2.sensor = i;
+ sample.ppo2.value = ppo2[j] / 100.0;
+ if (callback) callback (DC_SAMPLE_PPO2, &sample, userdata);
}
}
break;
@@ -1236,7 +1228,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
sample.cns = array_uint16_le (data + offset) / 100.0;
else
sample.cns = data[offset] / 100.0;
- if (callback) callback (DC_SAMPLE_CNS, sample, userdata);
+ if (callback) callback (DC_SAMPLE_CNS, &sample, userdata);
break;
case TANK:
value = array_uint16_le (data + offset);
@@ -1249,7 +1241,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
(firmware >= OSTC3FW(10,40) && firmware <= OSTC3FW(10,50))) {
sample.pressure.value /= 10.0;
}
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
break;
default: // Not yet used.
@@ -1269,7 +1261,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
return DC_STATUS_DATAFORMAT;
}
sample.setpoint = data[offset] / 100.0;
- if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_SETPOINT, &sample, userdata);
offset++;
length--;
}
@@ -1283,25 +1275,25 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
unsigned int o2 = data[offset];
unsigned int he = data[offset + 1];
- unsigned int idx = hw_ostc_find_gasmix (parser, o2, he, 0, MANUAL);
+ unsigned int idx = hw_ostc_find_gasmix_manual (parser, o2, he, 0);
if (idx >= parser->ngasmixes) {
if (idx >= NGASMIXES) {
ERROR (abstract->context, "Maximum number of gas mixes reached.");
return DC_STATUS_NOMEMORY;
}
+ parser->gasmix[idx].id = 0;
parser->gasmix[idx].oxygen = o2;
parser->gasmix[idx].helium = he;
parser->gasmix[idx].type = 0;
parser->gasmix[idx].enabled = 1;
+ parser->gasmix[idx].active = 1;
parser->gasmix[idx].diluent = 0;
parser->ngasmixes = idx + 1;
}
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
-
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
hw_ostc_notify_bailout(parser, data, idx, callback, userdata);
-
offset += 2;
length -= 2;
}
@@ -1319,7 +1311,50 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
return DC_STATUS_DATAFORMAT;
}
+ // Remove the disabled gas mixes from the fixed gas mixes.
+ unsigned int ndisabled = 0, nenabled = 0;
+ unsigned int count = parser->nfixed - parser->ndisabled;
+ for (unsigned int i = 0; i < count; ++i) {
+ if (parser->gasmix[i].enabled || parser->gasmix[i].active) {
+ // Move the fixed gas mix.
+ parser->gasmix[nenabled] = parser->gasmix[i];
+ nenabled++;
+ } else {
+ ndisabled++;
+ }
+ }
+
+ // Move all the manual gas mixes.
+ memmove (parser->gasmix + nenabled, parser->gasmix + count,
+ (parser->ngasmixes - count) * sizeof (hw_ostc_gasmix_t));
+ memset (parser->gasmix + parser->ngasmixes - ndisabled, 0,
+ ndisabled * sizeof (hw_ostc_gasmix_t));
+
+ // Adjust the counts.
+ parser->ngasmixes -= ndisabled;
+ parser->ndisabled += ndisabled;
+
parser->cached = PROFILE;
return DC_STATUS_SUCCESS;
}
+
+static dc_status_t
+hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
+{
+ hw_ostc_parser_t *parser = (hw_ostc_parser_t *) abstract;
+
+ // Cache the header data.
+ dc_status_t rc = hw_ostc_parser_cache (parser);
+ if (rc != DC_STATUS_SUCCESS)
+ return rc;
+
+ // Cache the profile data.
+ if (parser->cached < PROFILE) {
+ rc = hw_ostc_parser_internal_foreach (parser, NULL, NULL);
+ if (rc != DC_STATUS_SUCCESS)
+ return rc;
+ }
+
+ return hw_ostc_parser_internal_foreach (parser, callback, userdata);
+}
diff --git a/src/irda.c b/src/irda.c
index a5bb8e45..dd5397b4 100644
--- a/src/irda.c
+++ b/src/irda.c
@@ -47,7 +47,6 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
-#include "descriptor-private.h"
#include "array.h"
#include "platform.h"
@@ -226,7 +225,7 @@ dc_irda_iterator_new (dc_iterator_t **out, dc_context_t *context, dc_descriptor_
INFO (context, "Discover: address=%08x, name=%s, charset=%02x, hints=%04x",
address, name, charset, hints);
- if (!dc_descriptor_filter (descriptor, DC_TRANSPORT_IRDA, name, NULL)) {
+ if (!dc_descriptor_filter (descriptor, DC_TRANSPORT_IRDA, name)) {
continue;
}
diff --git a/src/libdivecomputer.symbols b/src/libdivecomputer.symbols
index 85d99ec8..b346ef01 100644
--- a/src/libdivecomputer.symbols
+++ b/src/libdivecomputer.symbols
@@ -34,6 +34,7 @@ dc_descriptor_get_product
dc_descriptor_get_type
dc_descriptor_get_model
dc_descriptor_get_transports
+dc_descriptor_filter
dc_iostream_get_transport
dc_iostream_set_timeout
@@ -93,17 +94,11 @@ dc_parser_set_clock
dc_parser_set_atmospheric
dc_parser_set_density
dc_parser_get_type
-dc_parser_set_data
dc_parser_get_datetime
dc_parser_get_field
dc_parser_samples_foreach
dc_parser_destroy
-reefnet_sensus_parser_set_calibration
-reefnet_sensuspro_parser_set_calibration
-reefnet_sensusultra_parser_set_calibration
-atomics_cobalt_parser_set_calibration
-
dc_device_open
dc_device_close
dc_device_dump
diff --git a/src/liquivision_lynx.h b/src/liquivision_lynx.h
index 52e72944..dd278b45 100644
--- a/src/liquivision_lynx.h
+++ b/src/liquivision_lynx.h
@@ -35,7 +35,7 @@ dc_status_t
liquivision_lynx_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-liquivision_lynx_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+liquivision_lynx_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/liquivision_lynx_parser.c b/src/liquivision_lynx_parser.c
index 764d20e3..c336b6a0 100644
--- a/src/liquivision_lynx_parser.c
+++ b/src/liquivision_lynx_parser.c
@@ -117,7 +117,6 @@ struct liquivision_lynx_parser_t {
liquivision_lynx_tank_t tank[NTANKS];
};
-static dc_status_t liquivision_lynx_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t liquivision_lynx_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t liquivision_lynx_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t liquivision_lynx_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -125,7 +124,6 @@ static dc_status_t liquivision_lynx_parser_samples_foreach (dc_parser_t *abstrac
static const dc_parser_vtable_t liquivision_lynx_parser_vtable = {
sizeof(liquivision_lynx_parser_t),
DC_FAMILY_LIQUIVISION_LYNX,
- liquivision_lynx_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -137,7 +135,7 @@ static const dc_parser_vtable_t liquivision_lynx_parser_vtable = {
dc_status_t
-liquivision_lynx_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+liquivision_lynx_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
liquivision_lynx_parser_t *parser = NULL;
@@ -145,7 +143,7 @@ liquivision_lynx_parser_create (dc_parser_t **out, dc_context_t *context, unsign
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (liquivision_lynx_parser_t *) dc_parser_allocate (context, &liquivision_lynx_parser_vtable);
+ parser = (liquivision_lynx_parser_t *) dc_parser_allocate (context, &liquivision_lynx_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -173,29 +171,6 @@ liquivision_lynx_parser_create (dc_parser_t **out, dc_context_t *context, unsign
}
-static dc_status_t
-liquivision_lynx_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- liquivision_lynx_parser_t *parser = (liquivision_lynx_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->ngasmixes = 0;
- parser->ntanks = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->gasmix[i].oxygen = 0;
- parser->gasmix[i].helium = 0;
- }
- for (unsigned int i = 0; i < NTANKS; ++i) {
- parser->tank[i].id = 0;
- parser->tank[i].beginpressure = 0;
- parser->tank[i].endpressure = 0;
- }
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
liquivision_lynx_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -315,6 +290,7 @@ liquivision_lynx_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -329,6 +305,7 @@ liquivision_lynx_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
tank->beginpressure = parser->tank[flags].beginpressure / 100.0;
tank->endpressure = parser->tank[flags].endpressure / 100.0;
tank->gasmix = DC_GASMIX_UNKNOWN;
+ tank->usage = DC_USAGE_NONE;
break;
default:
return DC_STATUS_UNSUPPORTED;
@@ -545,29 +522,29 @@ liquivision_lynx_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
// Time (seconds).
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/100 m).
sample.depth = value / 100.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (1/10 °C).
int temperature = (signed short) array_uint16_le (data + offset);
sample.temperature = temperature / 10.0;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// Gas mix
if (have_gasmix) {
sample.gasmix = gasmix_idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
have_gasmix = 0;
}
// Setpoint (1/10 bar).
if (have_setpoint) {
sample.setpoint = setpoint / 10.0;
- if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_SETPOINT, &sample, userdata);
have_setpoint = 0;
}
@@ -577,7 +554,7 @@ liquivision_lynx_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
if (have_pressure & (1 << i)) {
sample.pressure.tank = i;
sample.pressure.value = pressure[i] / 100.0;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
}
have_pressure = 0;
@@ -593,7 +570,8 @@ liquivision_lynx_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
sample.deco.depth = 0.0;
}
sample.deco.time = 0;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
have_deco = 0;
}
diff --git a/src/mares_darwin.h b/src/mares_darwin.h
index a902014f..35efbcb2 100644
--- a/src/mares_darwin.h
+++ b/src/mares_darwin.h
@@ -35,7 +35,7 @@ dc_status_t
mares_darwin_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream, unsigned int model);
dc_status_t
-mares_darwin_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+mares_darwin_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/mares_darwin_parser.c b/src/mares_darwin_parser.c
index 88e831c8..bebd89cd 100644
--- a/src/mares_darwin_parser.c
+++ b/src/mares_darwin_parser.c
@@ -47,7 +47,6 @@ struct mares_darwin_parser_t {
unsigned int samplesize;
};
-static dc_status_t mares_darwin_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t mares_darwin_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t mares_darwin_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -55,7 +54,6 @@ static dc_status_t mares_darwin_parser_samples_foreach (dc_parser_t *abstract, d
static const dc_parser_vtable_t mares_darwin_parser_vtable = {
sizeof(mares_darwin_parser_t),
DC_FAMILY_MARES_DARWIN,
- mares_darwin_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -67,7 +65,7 @@ static const dc_parser_vtable_t mares_darwin_parser_vtable = {
dc_status_t
-mares_darwin_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+mares_darwin_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
mares_darwin_parser_t *parser = NULL;
@@ -75,7 +73,7 @@ mares_darwin_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (mares_darwin_parser_t *) dc_parser_allocate (context, &mares_darwin_parser_vtable);
+ parser = (mares_darwin_parser_t *) dc_parser_allocate (context, &mares_darwin_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -97,13 +95,6 @@ mares_darwin_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
}
-static dc_status_t
-mares_darwin_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
mares_darwin_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -159,6 +150,7 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
}
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
if (mode == NITROX) {
gasmix->oxygen = p[0x0E] / 100.0;
@@ -185,6 +177,7 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
tank->gasmix = 0;
tank->beginpressure = array_uint16_be (p + 0x17);
tank->endpressure = array_uint16_be (p + 0x19);
+ tank->usage = DC_USAGE_NONE;
} else {
return DC_STATUS_UNSUPPORTED;
}
@@ -242,17 +235,17 @@ mares_darwin_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
// Surface Time (seconds).
time += 20;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Gas change.
if (gasmix != gasmix_previous) {
sample.gasmix = gasmix;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
@@ -262,7 +255,7 @@ mares_darwin_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = ascent;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
// Deco violation
@@ -271,7 +264,7 @@ mares_darwin_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = 0;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
// Deco stop
@@ -282,7 +275,8 @@ mares_darwin_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
}
sample.deco.time = 0;
sample.deco.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
if (parser->samplesize == 3) {
unsigned int type = (time / 20 + 2) % 3;
@@ -291,7 +285,7 @@ mares_darwin_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
pressure -= abstract->data[offset + 2];
sample.pressure.tank = 0;
sample.pressure.value = pressure;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
}
diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c
index eb4f337a..b86ff0d4 100644
--- a/src/mares_iconhd.c
+++ b/src/mares_iconhd.c
@@ -21,7 +21,6 @@
#include // memcpy, memcmp
#include // malloc, free
-#include // assert
#include "mares_iconhd.h"
#include "context-private.h"
@@ -94,7 +93,6 @@ typedef struct mares_iconhd_device_t {
unsigned char version[140];
unsigned int model;
unsigned int packetsize;
- unsigned int splitcommand;
} mares_iconhd_device_t;
static dc_status_t mares_iconhd_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
@@ -179,27 +177,35 @@ mares_iconhd_get_model (mares_iconhd_device_t *device)
static dc_status_t
mares_iconhd_packet (mares_iconhd_device_t *device,
- const unsigned char command[], unsigned int csize,
+ unsigned char cmd,
+ const unsigned char data[], unsigned int size,
unsigned char answer[], unsigned int asize)
{
dc_status_t status = DC_STATUS_SUCCESS;
dc_device_t *abstract = (dc_device_t *) device;
- unsigned int split_csize;
-
- assert (csize >= 2);
if (device_is_cancelled (abstract))
return DC_STATUS_CANCELLED;
- split_csize = device->splitcommand ? 2 : csize;
-
// Send the command header to the dive computer.
- status = dc_iostream_write (device->iostream, command, split_csize, NULL);
+ const unsigned char command[2] = {
+ cmd, cmd ^ XOR,
+ };
+ status = dc_iostream_write (device->iostream, command, sizeof(command), NULL);
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to send the command.");
return status;
}
+ // Send the command payload to the dive computer.
+ if (size) {
+ status = dc_iostream_write (device->iostream, data, size, NULL);
+ if (status != DC_STATUS_SUCCESS) {
+ ERROR (abstract->context, "Failed to send the command.");
+ return status;
+ }
+ }
+
// Receive the header byte.
unsigned char header[1] = {0};
status = dc_iostream_read (device->iostream, header, sizeof (header), NULL);
@@ -214,15 +220,6 @@ mares_iconhd_packet (mares_iconhd_device_t *device,
return DC_STATUS_PROTOCOL;
}
- // Send any remaining command payload to the dive computer.
- if (csize > split_csize) {
- status = dc_iostream_write (device->iostream, command + split_csize, csize - split_csize, NULL);
- if (status != DC_STATUS_SUCCESS) {
- ERROR (abstract->context, "Failed to send the command.");
- return status;
- }
- }
-
// Read the packet.
status = dc_iostream_read (device->iostream, answer, asize, NULL);
if (status != DC_STATUS_SUCCESS) {
@@ -248,11 +245,11 @@ mares_iconhd_packet (mares_iconhd_device_t *device,
}
static dc_status_t
-mares_iconhd_transfer (mares_iconhd_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize)
+mares_iconhd_transfer (mares_iconhd_device_t *device, unsigned char cmd, const unsigned char data[], unsigned int size, unsigned char answer[], unsigned int asize)
{
unsigned int nretries = 0;
dc_status_t rc = DC_STATUS_SUCCESS;
- while ((rc = mares_iconhd_packet (device, command, csize, answer, asize)) != DC_STATUS_SUCCESS) {
+ while ((rc = mares_iconhd_packet (device, cmd, data, size, answer, asize)) != DC_STATUS_SUCCESS) {
// Automatically discard a corrupted packet,
// and request a new one.
if (rc != DC_STATUS_PROTOCOL && rc != DC_STATUS_TIMEOUT)
@@ -287,23 +284,21 @@ mares_iconhd_read_object(mares_iconhd_device_t *device, dc_event_progress_t *pro
// Transfer the init packet.
unsigned char rsp_init[16];
- unsigned char cmd_init[18] = {
- CMD_OBJ_INIT,
- CMD_OBJ_INIT ^ XOR,
+ unsigned char cmd_init[16] = {
0x40,
(index >> 0) & 0xFF,
(index >> 8) & 0xFF,
subindex & 0xFF
};
memset (cmd_init + 6, 0x00, sizeof(cmd_init) - 6);
- status = mares_iconhd_transfer (device, cmd_init, sizeof (cmd_init), rsp_init, sizeof (rsp_init));
+ status = mares_iconhd_transfer (device, CMD_OBJ_INIT, cmd_init, sizeof (cmd_init), rsp_init, sizeof (rsp_init));
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to transfer the init packet.");
return status;
}
// Verify the packet header.
- if (memcmp (cmd_init + 3, rsp_init + 1, 3) != 0) {
+ if (memcmp (cmd_init + 1, rsp_init + 1, 3) != 0) {
ERROR (abstract->context, "Unexpected packet header.");
return DC_STATUS_PROTOCOL;
}
@@ -351,8 +346,7 @@ mares_iconhd_read_object(mares_iconhd_device_t *device, dc_event_progress_t *pro
// Transfer the segment packet.
unsigned char rsp_segment[1 + 504];
- unsigned char cmd_segment[] = {cmd, cmd ^ XOR};
- status = mares_iconhd_transfer (device, cmd_segment, sizeof (cmd_segment), rsp_segment, len + 1);
+ status = mares_iconhd_transfer (device, cmd, NULL, 0, rsp_segment, len + 1);
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to transfer the segment packet.");
return status;
@@ -419,15 +413,6 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_
device->iostream = iostream;
}
- /*
- * At least the Mares Matrix needs the command to be split into
- * base and argument, with a wait for the ACK byte in between.
- *
- * See commit 59bfb0f3189b ("Add support for the Mares Matrix")
- * for details.
- */
- device->splitcommand = 1;
-
// Set the serial communication protocol (115200 8E1).
status = dc_iostream_configure (device->iostream, 115200, 8, DC_PARITY_EVEN, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE);
if (status != DC_STATUS_SUCCESS) {
@@ -460,8 +445,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_
dc_iostream_purge (device->iostream, DC_DIRECTION_ALL);
// Send the version command.
- unsigned char command[] = {CMD_VERSION, CMD_VERSION ^ XOR};
- status = mares_iconhd_transfer (device, command, sizeof (command),
+ status = mares_iconhd_transfer (device, CMD_VERSION, NULL, 0,
device->version, sizeof (device->version));
if (status != DC_STATUS_SUCCESS) {
goto error_free_iostream;
@@ -473,9 +457,8 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_
// Read the size of the flash memory.
unsigned int memsize = 0;
if (device->model == QUAD) {
- unsigned char cmd_flash[] = {CMD_FLASHSIZE, CMD_FLASHSIZE ^ XOR};
unsigned char rsp_flash[4] = {0};
- status = mares_iconhd_transfer (device, cmd_flash, sizeof (cmd_flash), rsp_flash, sizeof (rsp_flash));
+ status = mares_iconhd_transfer (device, CMD_FLASHSIZE, NULL, 0, rsp_flash, sizeof (rsp_flash));
if (status != DC_STATUS_SUCCESS) {
WARNING (context, "Failed to read the flash memory size.");
} else {
@@ -538,14 +521,6 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_
*/
if (device->packetsize > 128)
device->packetsize = 128;
- /*
- * With BLE, don't wait for ACK before sending the arguments
- * to a command.
- *
- * There is some timing issue that makes that take too long
- * and causes the command to be aborted.
- */
- device->splitcommand = 0;
}
*out = (dc_device_t *) device;
@@ -608,7 +583,7 @@ mares_iconhd_device_read (dc_device_t *abstract, unsigned int address, unsigned
len = device->packetsize;
// Read the packet.
- unsigned char command[] = {CMD_READ, CMD_READ ^ XOR,
+ unsigned char command[] = {
(address ) & 0xFF,
(address >> 8) & 0xFF,
(address >> 16) & 0xFF,
@@ -617,7 +592,7 @@ mares_iconhd_device_read (dc_device_t *abstract, unsigned int address, unsigned
(len >> 8) & 0xFF,
(len >> 16) & 0xFF,
(len >> 24) & 0xFF};
- rc = mares_iconhd_transfer (device, command, sizeof (command), data, len);
+ rc = mares_iconhd_transfer (device, CMD_READ, command, sizeof (command), data, len);
if (rc != DC_STATUS_SUCCESS)
return rc;
diff --git a/src/mares_iconhd.h b/src/mares_iconhd.h
index 1354f775..c055012d 100644
--- a/src/mares_iconhd.h
+++ b/src/mares_iconhd.h
@@ -35,7 +35,7 @@ dc_status_t
mares_iconhd_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-mares_iconhd_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model, unsigned int serial);
+mares_iconhd_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial);
#ifdef __cplusplus
}
diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c
index 50cf6f74..08dbea52 100644
--- a/src/mares_iconhd_parser.c
+++ b/src/mares_iconhd_parser.c
@@ -267,7 +267,6 @@ static const mares_iconhd_layout_t horizon = {
0x54 + 8, /* tanks */
};
-static dc_status_t mares_iconhd_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t mares_iconhd_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -275,7 +274,6 @@ static dc_status_t mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, d
static const dc_parser_vtable_t mares_iconhd_parser_vtable = {
sizeof(mares_iconhd_parser_t),
DC_FAMILY_MARES_ICONHD,
- mares_iconhd_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -404,12 +402,12 @@ mares_iconhd_cache (mares_iconhd_parser_t *parser)
unsigned int samplerate = 0;
if (parser->model == SMARTAPNEA) {
unsigned int idx = (settings & 0x0600) >> 9;
- interval = 1;
samplerate = 1 << idx;
+ interval = 1000 / samplerate;
} else {
const unsigned int intervals[] = {1, 5, 10, 20};
unsigned int idx = (settings & 0x0C00) >> 10;
- interval = intervals[idx];
+ interval = intervals[idx] * 1000;
samplerate = 1;
}
@@ -628,7 +626,7 @@ mares_genius_cache (mares_iconhd_parser_t *parser)
parser->headersize = headersize;
parser->settings = settings;
parser->surftime = surftime * 60;
- parser->interval = 5;
+ parser->interval = 5000;
parser->samplerate = 1;
parser->ntanks = ntanks;
parser->ngasmixes = ngasmixes;
@@ -659,7 +657,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser)
}
dc_status_t
-mares_iconhd_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int serial)
+mares_iconhd_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial)
{
mares_iconhd_parser_t *parser = NULL;
@@ -667,7 +665,7 @@ mares_iconhd_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (mares_iconhd_parser_t *) dc_parser_allocate (context, &mares_iconhd_parser_vtable);
+ parser = (mares_iconhd_parser_t *) dc_parser_allocate (context, &mares_iconhd_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -705,41 +703,6 @@ mares_iconhd_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
return DC_STATUS_SUCCESS;
}
-
-static dc_status_t
-mares_iconhd_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- mares_iconhd_parser_t *parser = (mares_iconhd_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->logformat = 0;
- parser->mode = (parser->model == GENIUS || parser->model == HORIZON) ? GENIUS_AIR : ICONHD_AIR;
- parser->nsamples = 0;
- parser->samplesize = 0;
- parser->headersize = 0;
- parser->settings = 0;
- parser->surftime = 0;
- parser->interval = 0;
- parser->samplerate = 0;
- parser->ntanks = 0;
- parser->ngasmixes = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->gasmix[i].oxygen = 0;
- parser->gasmix[i].helium = 0;
- }
- for (unsigned int i = 0; i < NTANKS; ++i) {
- parser->tank[i].volume = 0;
- parser->tank[i].workpressure = 0;
- parser->tank[i].beginpressure = 0;
- parser->tank[i].endpressure = 0;
- }
- parser->layout = NULL;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
mares_iconhd_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -827,7 +790,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
if (parser->layout->divetime != UNSUPPORTED) {
*((unsigned int *) value) = array_uint16_le (p + parser->layout->divetime);
} else {
- *((unsigned int *) value) = parser->nsamples * parser->interval - parser->surftime;
+ *((unsigned int *) value) = parser->nsamples * parser->interval / 1000 - parser->surftime;
}
break;
case DC_FIELD_MAXDEPTH:
@@ -837,6 +800,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -864,6 +828,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
} else {
tank->gasmix = DC_GASMIX_UNKNOWN;
}
+ tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_ATMOSPHERIC:
*((double *) value) = array_uint16_le (p + parser->layout->atmospheric) / (1000.0 * parser->layout->atmospheric_divisor);
@@ -981,14 +946,6 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
const unsigned char *data = abstract->data;
- if (parser->samplerate > 1) {
- // The Smart Apnea supports multiple samples per second
- // (e.g. 2, 4 or 8). Since our smallest unit of time is one
- // second, we can't represent this, and the extra samples
- // will get dropped.
- WARNING(abstract->context, "Multiple samples per second are not supported!");
- }
-
// Previous gas mix - initialize with impossible value
unsigned int gasmix_previous = 0xFFFFFFFF;
@@ -1039,29 +996,30 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
unsigned int surftime = array_uint16_le (data + offset + 4);
// Surface Time (seconds).
- time += surftime;
+ time += surftime * 1000;
sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Surface Depth (0 m).
sample.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
offset += parser->samplesize;
nsamples++;
- for (unsigned int i = 0; i < divetime; ++i) {
+ unsigned int count = divetime * parser->samplerate;
+ for (unsigned int i = 0; i < count; ++i) {
// Time (seconds).
time += parser->interval;
sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
unsigned int depth = array_uint16_le (data + offset);
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
- offset += 2 * parser->samplerate;
+ offset += 2;
}
} else if (parser->model != GENIUS && parser->model != HORIZON && parser->mode == ICONHD_FREEDIVE) {
unsigned int maxdepth = array_uint16_le (data + offset + 0);
@@ -1069,22 +1027,22 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
unsigned int surftime = array_uint16_le (data + offset + 4);
// Surface Time (seconds).
- time += surftime;
+ time += surftime * 1000;
sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Surface Depth (0 m).
sample.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Dive Time (seconds).
- time += divetime;
+ time += divetime * 1000;
sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Maximum Depth (1/10 m).
sample.depth = maxdepth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
offset += parser->samplesize;
nsamples++;
@@ -1142,15 +1100,15 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
// Time (seconds).
time += parser->interval;
sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (1/10 °C).
sample.temperature = temperature / 10.0;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// Current gas mix
if (parser->ngasmixes > 0) {
@@ -1160,7 +1118,7 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
}
if (gasmix != gasmix_previous) {
sample.gasmix = gasmix;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
}
@@ -1171,7 +1129,7 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = bookmark;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
if (parser->model == GENIUS || parser->model == HORIZON) {
@@ -1184,7 +1142,8 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
sample.deco.depth = 0.0;
}
sample.deco.time = decotime * 60;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = tts;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
// Alarms
for (unsigned int v = alarms, i = 0; v; v >>= 1, ++i) {
@@ -1210,7 +1169,7 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = 0;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
}
}
@@ -1231,7 +1190,7 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
if (gasmix < parser->ntanks) {
sample.pressure.tank = gasmix;
sample.pressure.value = pressure / 100.0;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
} else if (pressure != 0) {
WARNING (abstract->context, "Invalid tank with non-zero pressure.");
}
diff --git a/src/mares_nemo.h b/src/mares_nemo.h
index c7a162bd..1847d0f3 100644
--- a/src/mares_nemo.h
+++ b/src/mares_nemo.h
@@ -35,7 +35,7 @@ dc_status_t
mares_nemo_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-mares_nemo_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+mares_nemo_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/mares_nemo_parser.c b/src/mares_nemo_parser.c
index 2f26605c..cb3e3bfe 100644
--- a/src/mares_nemo_parser.c
+++ b/src/mares_nemo_parser.c
@@ -59,7 +59,6 @@ struct mares_nemo_parser_t {
unsigned int extra;
};
-static dc_status_t mares_nemo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t mares_nemo_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t mares_nemo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t mares_nemo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -67,7 +66,6 @@ static dc_status_t mares_nemo_parser_samples_foreach (dc_parser_t *abstract, dc_
static const dc_parser_vtable_t mares_nemo_parser_vtable = {
sizeof(mares_nemo_parser_t),
DC_FAMILY_MARES_NEMO,
- mares_nemo_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -79,15 +77,16 @@ static const dc_parser_vtable_t mares_nemo_parser_vtable = {
dc_status_t
-mares_nemo_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+mares_nemo_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
+ dc_status_t status = DC_STATUS_SUCCESS;
mares_nemo_parser_t *parser = NULL;
if (out == NULL)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (mares_nemo_parser_t *) dc_parser_allocate (context, &mares_nemo_parser_vtable);
+ parser = (mares_nemo_parser_t *) dc_parser_allocate (context, &mares_nemo_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -98,70 +97,42 @@ mares_nemo_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int
if (model == NEMOWIDE || model == NEMOAIR || model == PUCK || model == PUCKAIR)
freedive = GAUGE;
- // Set the default values.
- parser->model = model;
- parser->freedive = freedive;
- parser->mode = AIR;
- parser->length = 0;
- parser->sample_count = 0;
- parser->sample_size = 0;
- parser->header = 0;
- parser->extra = 0;
-
- *out = (dc_parser_t*) parser;
-
- return DC_STATUS_SUCCESS;
-}
-
-
-static dc_status_t
-mares_nemo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- mares_nemo_parser_t *parser = (mares_nemo_parser_t *) abstract;
-
- // Clear the previous state.
- parser->base.data = NULL;
- parser->base.size = 0;
- parser->mode = AIR;
- parser->length = 0;
- parser->sample_count = 0;
- parser->sample_size = 0;
- parser->header = 0;
- parser->extra = 0;
-
- if (size == 0)
- return DC_STATUS_SUCCESS;
-
- if (size < 2 + 3)
- return DC_STATUS_DATAFORMAT;
+ if (size < 2 + 3) {
+ status = DC_STATUS_DATAFORMAT;
+ goto error_free;
+ }
unsigned int length = array_uint16_le (data);
- if (length > size)
- return DC_STATUS_DATAFORMAT;
+ if (length > size) {
+ status = DC_STATUS_DATAFORMAT;
+ goto error_free;
+ }
unsigned int extra = 0;
const unsigned char marker[3] = {0xAA, 0xBB, 0xCC};
if (memcmp (data + length - 3, marker, sizeof (marker)) == 0) {
- if (parser->model == PUCKAIR)
+ if (model == PUCKAIR)
extra = 7;
else
extra = 12;
}
- if (length < 2 + extra + 3)
- return DC_STATUS_DATAFORMAT;
+ if (length < 2 + extra + 3) {
+ status = DC_STATUS_DATAFORMAT;
+ goto error_free;
+ }
unsigned int mode = data[length - extra - 1];
unsigned int header_size = 53;
unsigned int sample_size = 2;
if (extra) {
- if (parser->model == PUCKAIR)
+ if (model == PUCKAIR)
sample_size = 3;
else
sample_size = 5;
}
- if (mode == parser->freedive) {
+ if (mode == freedive) {
header_size = 28;
sample_size = 6;
}
@@ -169,12 +140,14 @@ mares_nemo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, un
unsigned int nsamples = array_uint16_le (data + length - extra - 3);
unsigned int nbytes = 2 + nsamples * sample_size + header_size + extra;
- if (length != nbytes)
- return DC_STATUS_DATAFORMAT;
+ if (length != nbytes) {
+ status = DC_STATUS_DATAFORMAT;
+ goto error_free;
+ }
- // Store the new state.
- parser->base.data = data;
- parser->base.size = size;
+ // Set the default values.
+ parser->model = model;
+ parser->freedive = freedive;
parser->mode = mode;
parser->length = length;
parser->sample_count = nsamples;
@@ -182,7 +155,13 @@ mares_nemo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, un
parser->header = header_size;
parser->extra = extra;
+ *out = (dc_parser_t*) parser;
+
return DC_STATUS_SUCCESS;
+
+error_free:
+ dc_parser_deallocate ((dc_parser_t *) parser);
+ return status;
}
@@ -251,6 +230,7 @@ mares_nemo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
}
gasmix->helium = 0.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
+ gasmix->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TANK_COUNT:
if (parser->extra)
@@ -290,6 +270,7 @@ mares_nemo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
} else {
tank->gasmix = DC_GASMIX_UNKNOWN;
}
+ tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
*((double *) value) = (signed char) p[53 - 11];
@@ -382,17 +363,17 @@ mares_nemo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
// Time (seconds).
time += 20;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Gas change.
if (gasmix != gasmix_previous) {
sample.gasmix = gasmix;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
@@ -402,7 +383,7 @@ mares_nemo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = ascent;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
// Deco violation
@@ -411,7 +392,7 @@ mares_nemo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = 0;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
// Deco stop
@@ -422,20 +403,21 @@ mares_nemo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
}
sample.deco.time = 0;
sample.deco.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
// Pressure (1 bar).
if (parser->sample_size == 3) {
sample.pressure.tank = 0;
sample.pressure.value = data[idx + 2];
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
} else if (parser->sample_size == 5) {
unsigned int type = (time / 20) % 3;
if (type == 0) {
pressure -= data[idx + 2] * 100;
sample.pressure.tank = 0;
sample.pressure.value = pressure / 100.0;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
}
}
@@ -459,12 +441,12 @@ mares_nemo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
// Surface Time (seconds).
time += surftime;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Surface Depth (0 m).
sample.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
if (profiles) {
// Get the freedive sample interval for this model.
@@ -500,12 +482,12 @@ mares_nemo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
time += interval;
if (time > maxtime)
time = maxtime; // Adjust the last sample.
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
}
// Verify that the number of samples in the profile data
@@ -519,12 +501,12 @@ mares_nemo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
} else {
// Dive Time (seconds).
time += divetime;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Maximum Depth (1/10 m).
sample.depth = maxdepth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
}
}
}
diff --git a/src/mclean_extreme.h b/src/mclean_extreme.h
index c388bd47..fd7c6bcd 100644
--- a/src/mclean_extreme.h
+++ b/src/mclean_extreme.h
@@ -35,7 +35,7 @@ dc_status_t
mclean_extreme_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-mclean_extreme_parser_create (dc_parser_t **parser, dc_context_t *context);
+mclean_extreme_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/mclean_extreme_parser.c b/src/mclean_extreme_parser.c
index 694bf603..b9de4950 100644
--- a/src/mclean_extreme_parser.c
+++ b/src/mclean_extreme_parser.c
@@ -58,7 +58,6 @@ struct mclean_extreme_parser_t {
unsigned int gasmix[NGASMIXES];
};
-static dc_status_t mclean_extreme_parser_set_data(dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t mclean_extreme_parser_get_datetime(dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t mclean_extreme_parser_get_field(dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t mclean_extreme_parser_samples_foreach(dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -66,7 +65,6 @@ static dc_status_t mclean_extreme_parser_samples_foreach(dc_parser_t *abstract,
static const dc_parser_vtable_t mclean_extreme_parser_vtable = {
sizeof(mclean_extreme_parser_t),
DC_FAMILY_MCLEAN_EXTREME,
- mclean_extreme_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -77,7 +75,7 @@ static const dc_parser_vtable_t mclean_extreme_parser_vtable = {
};
dc_status_t
-mclean_extreme_parser_create(dc_parser_t **out, dc_context_t *context)
+mclean_extreme_parser_create(dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
mclean_extreme_parser_t *parser = NULL;
@@ -86,7 +84,7 @@ mclean_extreme_parser_create(dc_parser_t **out, dc_context_t *context)
}
// Allocate memory.
- parser = (mclean_extreme_parser_t *)dc_parser_allocate(context, &mclean_extreme_parser_vtable);
+ parser = (mclean_extreme_parser_t *)dc_parser_allocate(context, &mclean_extreme_parser_vtable, data, size);
if (parser == NULL) {
ERROR(context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -104,21 +102,6 @@ mclean_extreme_parser_create(dc_parser_t **out, dc_context_t *context)
return DC_STATUS_SUCCESS;
}
-static dc_status_t
-mclean_extreme_parser_set_data(dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- mclean_extreme_parser_t *parser = (mclean_extreme_parser_t *)abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->ngasmixes = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->gasmix[i] = INVALID;
- }
-
- return DC_STATUS_SUCCESS;
-}
-
static dc_status_t
mclean_extreme_parser_get_datetime(dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -221,6 +204,7 @@ mclean_extreme_parser_get_field(dc_parser_t *abstract, dc_field_type_t type, uns
*((unsigned int *)value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.01 * abstract->data[0x0001 + 1 + 2 * parser->gasmix[flags]];
gasmix->oxygen = 0.01 * abstract->data[0x0001 + 0 + 2 * parser->gasmix[flags]];
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -269,14 +253,14 @@ mclean_extreme_parser_samples_foreach(dc_parser_t *abstract, dc_sample_callback_
const unsigned int setpoint = abstract->data[0x0013 + sp_index];
time += interval;
- sample.time = time;
- if (callback) callback(DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback(DC_SAMPLE_TIME, &sample, userdata);
sample.depth = 0.1 * depth;
- if (callback) callback(DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback(DC_SAMPLE_DEPTH, &sample, userdata);
sample.temperature = temperature;
- if (callback) callback(DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback(DC_SAMPLE_TEMPERATURE, &sample, userdata);
if (gasmix_id != gasmix_previous) {
// Find the gasmix in the list.
@@ -298,13 +282,13 @@ mclean_extreme_parser_samples_foreach(dc_parser_t *abstract, dc_sample_callback_
}
sample.gasmix = idx;
- if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback(DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix_id;
}
if (ccr) {
sample.setpoint = 0.01 * setpoint;
- if (callback) callback(DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback(DC_SAMPLE_SETPOINT, &sample, userdata);
}
offset += SZ_SAMPLE;
diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c
index a032f9cf..d9f3a6d6 100644
--- a/src/oceanic_atom2.c
+++ b/src/oceanic_atom2.c
@@ -339,7 +339,7 @@ static const oceanic_common_layout_t oceanic_reactpro_layout = {
0x0600, /* rb_logbook_end */
8, /* rb_logbook_entry_size */
0x0600, /* rb_profile_begin */
- 0xFFF0, /* rb_profile_end */
+ 0xFE00, /* rb_profile_end */
1, /* pt_mode_global */
1, /* pt_mode_logbook */
0, /* pt_mode_serial */
diff --git a/src/oceanic_atom2.h b/src/oceanic_atom2.h
index 657c7196..201ac320 100644
--- a/src/oceanic_atom2.h
+++ b/src/oceanic_atom2.h
@@ -37,7 +37,7 @@ dc_status_t
oceanic_atom2_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream, unsigned int model);
dc_status_t
-oceanic_atom2_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model, unsigned int serial);
+oceanic_atom2_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial);
#ifdef __cplusplus
}
diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c
index edb652d0..fe50796d 100644
--- a/src/oceanic_atom2_parser.c
+++ b/src/oceanic_atom2_parser.c
@@ -62,7 +62,6 @@ struct oceanic_atom2_parser_t {
double maxdepth;
};
-static dc_status_t oceanic_atom2_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -70,7 +69,6 @@ static dc_status_t oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract,
static const dc_parser_vtable_t oceanic_atom2_parser_vtable = {
sizeof(oceanic_atom2_parser_t),
DC_FAMILY_OCEANIC_ATOM2,
- oceanic_atom2_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -82,7 +80,7 @@ static const dc_parser_vtable_t oceanic_atom2_parser_vtable = {
dc_status_t
-oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int serial)
+oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial)
{
oceanic_atom2_parser_t *parser = NULL;
@@ -90,7 +88,7 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (oceanic_atom2_parser_t *) dc_parser_allocate (context, &oceanic_atom2_parser_vtable);
+ parser = (oceanic_atom2_parser_t *) dc_parser_allocate (context, &oceanic_atom2_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -157,28 +155,6 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
}
-static dc_status_t
-oceanic_atom2_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- oceanic_atom2_parser_t *parser = (oceanic_atom2_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->header = 0;
- parser->footer = 0;
- parser->mode = NORMAL;
- parser->ngasmixes = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->oxygen[i] = 0;
- parser->helium[i] = 0;
- }
- parser->divetime = 0;
- parser->maxdepth = 0.0;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -524,6 +500,7 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->oxygen = parser->oxygen[flags] / 100.0;
gasmix->helium = parser->helium[flags] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -605,7 +582,7 @@ oceanic_atom2_parser_vendor (oceanic_atom2_parser_t *parser, const unsigned char
sample.vendor.type = SAMPLE_VENDOR_OCEANIC_ATOM2;
sample.vendor.size = length;
sample.vendor.data = data + offset;
- if (callback) callback (DC_SAMPLE_VENDOR, sample, userdata);
+ if (callback) callback (DC_SAMPLE_VENDOR, &sample, userdata);
offset += length;
}
@@ -627,8 +604,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
unsigned int extratime = 0;
unsigned int time = 0;
- unsigned int interval = 1;
- unsigned int samplerate = 1;
+ unsigned int interval = 1000;
if (parser->mode != FREEDIVE) {
unsigned int offset = 0x17;
if (parser->model == A300CS || parser->model == VTX ||
@@ -636,21 +612,13 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
parser->model == PROPLUSX || parser->model == I770R ||
parser->model == SAGE || parser->model == BEACON)
offset = 0x1f;
- const unsigned int intervals[] = {2, 15, 30, 60};
+ const unsigned int intervals[] = {2000, 15000, 30000, 60000};
unsigned int idx = data[offset] & 0x03;
interval = intervals[idx];
} else if (parser->model == F11A || parser->model == F11B) {
- const unsigned int intervals[] = {1, 1, 1, 2};
- const unsigned int samplerates[] = {4, 2, 1, 1};
+ const unsigned int intervals[] = {250, 500, 1000, 2000};
unsigned int idx = data[0x29] & 0x03;
interval = intervals[idx];
- samplerate = samplerates[idx];
- if (samplerate > 1) {
- // Some models supports multiple samples per second.
- // Since our smallest unit of time is one second, we can't
- // represent this, and the extra samples will get dropped.
- WARNING(abstract->context, "Multiple samples per second are not supported!");
- }
}
unsigned int samplesize = PAGESIZE / 2;
@@ -771,14 +739,14 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
// The surface time is not always a nice multiple of the samplerate.
// The number of inserted surface samples is therefore rounded down
// to keep the timestamps aligned at multiples of the samplerate.
- unsigned int surftime = 60 * bcd2dec (data[offset + 1]) + bcd2dec (data[offset + 2]);
+ unsigned int surftime = (60 * bcd2dec (data[offset + 1]) + bcd2dec (data[offset + 2])) * 1000;
unsigned int nsamples = surftime / interval;
for (unsigned int i = 0; i < nsamples; ++i) {
// Time
time += interval;
sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Vendor specific data
if (i == 0) {
@@ -790,25 +758,18 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
// Depth
sample.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
complete = 1;
}
extratime += surftime;
} else {
- // Skip the extra samples.
- if ((count % samplerate) != 0) {
- offset += samplesize;
- count++;
- continue;
- }
-
// Time.
if (parser->model == I450T || parser->model == I470TC) {
unsigned int minute = bcd2dec(data[offset + 0]);
unsigned int hour = bcd2dec(data[offset + 1] & 0x0F);
unsigned int second = bcd2dec(data[offset + 2]);
- unsigned int timestamp = (hour * 3600) + (minute * 60 ) + second + extratime;
+ unsigned int timestamp = ((hour * 3600) + (minute * 60 ) + second) * 1000 + extratime;
if (timestamp < time) {
ERROR (abstract->context, "Timestamp moved backwards.");
return DC_STATUS_DATAFORMAT;
@@ -822,7 +783,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
time += interval;
}
sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Vendor specific data
oceanic_atom2_parser_vendor (parser,
@@ -884,7 +845,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
temperature += (data[offset + 7] & 0x0C) >> 2;
}
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
// Tank Pressure (psi)
@@ -912,7 +873,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
pressure -= data[offset + 1];
sample.pressure.tank = tank;
sample.pressure.value = pressure * PSI / BAR;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
// Depth (1/16 ft)
@@ -935,7 +896,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
else
depth = (data[offset + 2] + (data[offset + 3] << 8)) & 0x0FFF;
sample.depth = depth / 16.0 * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Gas mix
unsigned int have_gasmix = 0;
@@ -950,7 +911,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
return DC_STATUS_DATAFORMAT;
}
sample.gasmix = gasmix - 1;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
@@ -999,7 +960,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
sample.deco.depth = 0.0;
}
sample.deco.time = decotime * 60;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
}
unsigned int have_rbt = 0;
@@ -1022,7 +984,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
}
if (have_rbt) {
sample.rbt = rbt;
- if (callback) callback (DC_SAMPLE_RBT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_RBT, &sample, userdata);
}
// Bookmarks
@@ -1037,7 +999,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = 0;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
count++;
diff --git a/src/oceanic_veo250.h b/src/oceanic_veo250.h
index fc79375a..5d24f74b 100644
--- a/src/oceanic_veo250.h
+++ b/src/oceanic_veo250.h
@@ -37,7 +37,7 @@ dc_status_t
oceanic_veo250_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-oceanic_veo250_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+oceanic_veo250_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/oceanic_veo250_parser.c b/src/oceanic_veo250_parser.c
index 90d33830..096e47c8 100644
--- a/src/oceanic_veo250_parser.c
+++ b/src/oceanic_veo250_parser.c
@@ -42,7 +42,6 @@ struct oceanic_veo250_parser_t {
double maxdepth;
};
-static dc_status_t oceanic_veo250_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t oceanic_veo250_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t oceanic_veo250_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -50,7 +49,6 @@ static dc_status_t oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract,
static const dc_parser_vtable_t oceanic_veo250_parser_vtable = {
sizeof(oceanic_veo250_parser_t),
DC_FAMILY_OCEANIC_VEO250,
- oceanic_veo250_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -62,7 +60,7 @@ static const dc_parser_vtable_t oceanic_veo250_parser_vtable = {
dc_status_t
-oceanic_veo250_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+oceanic_veo250_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
oceanic_veo250_parser_t *parser = NULL;
@@ -70,7 +68,7 @@ oceanic_veo250_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (oceanic_veo250_parser_t *) dc_parser_allocate (context, &oceanic_veo250_parser_vtable);
+ parser = (oceanic_veo250_parser_t *) dc_parser_allocate (context, &oceanic_veo250_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -88,20 +86,6 @@ oceanic_veo250_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
}
-static dc_status_t
-oceanic_veo250_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- oceanic_veo250_parser_t *parser = (oceanic_veo250_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->divetime = 0;
- parser->maxdepth = 0.0;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
oceanic_veo250_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -170,6 +154,7 @@ oceanic_veo250_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
if (data[footer + 6])
gasmix->oxygen = data[footer + 6] / 100.0;
@@ -230,19 +215,19 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
// Time.
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Vendor specific data
sample.vendor.type = SAMPLE_VENDOR_OCEANIC_VEO250;
sample.vendor.size = PAGESIZE / 2;
sample.vendor.data = data + offset;
- if (callback) callback (DC_SAMPLE_VENDOR, sample, userdata);
+ if (callback) callback (DC_SAMPLE_VENDOR, &sample, userdata);
// Depth (ft)
unsigned int depth = data[offset + 2];
sample.depth = depth * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (°F)
unsigned int temperature;
@@ -253,7 +238,7 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
temperature = data[offset + 7];
}
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// NDL / Deco
unsigned int have_deco = 0;
@@ -277,7 +262,8 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
sample.deco.depth = 0.0;
}
sample.deco.time = decotime * 60;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
}
offset += PAGESIZE / 2;
diff --git a/src/oceanic_vtpro.h b/src/oceanic_vtpro.h
index 6a3c2cd6..3928adf5 100644
--- a/src/oceanic_vtpro.h
+++ b/src/oceanic_vtpro.h
@@ -37,7 +37,7 @@ dc_status_t
oceanic_vtpro_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream, unsigned int model);
dc_status_t
-oceanic_vtpro_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+oceanic_vtpro_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/oceanic_vtpro_parser.c b/src/oceanic_vtpro_parser.c
index 9650c496..ec380b32 100644
--- a/src/oceanic_vtpro_parser.c
+++ b/src/oceanic_vtpro_parser.c
@@ -42,7 +42,6 @@ struct oceanic_vtpro_parser_t {
double maxdepth;
};
-static dc_status_t oceanic_vtpro_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t oceanic_vtpro_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t oceanic_vtpro_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t oceanic_vtpro_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -50,7 +49,6 @@ static dc_status_t oceanic_vtpro_parser_samples_foreach (dc_parser_t *abstract,
static const dc_parser_vtable_t oceanic_vtpro_parser_vtable = {
sizeof(oceanic_vtpro_parser_t),
DC_FAMILY_OCEANIC_VTPRO,
- oceanic_vtpro_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -62,7 +60,7 @@ static const dc_parser_vtable_t oceanic_vtpro_parser_vtable = {
dc_status_t
-oceanic_vtpro_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+oceanic_vtpro_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
oceanic_vtpro_parser_t *parser = NULL;
@@ -70,7 +68,7 @@ oceanic_vtpro_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (oceanic_vtpro_parser_t *) dc_parser_allocate (context, &oceanic_vtpro_parser_vtable);
+ parser = (oceanic_vtpro_parser_t *) dc_parser_allocate (context, &oceanic_vtpro_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -88,20 +86,6 @@ oceanic_vtpro_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
}
-static dc_status_t
-oceanic_vtpro_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- oceanic_vtpro_parser_t *parser = (oceanic_vtpro_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->divetime = 0;
- parser->maxdepth = 0.0;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
oceanic_vtpro_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -200,6 +184,7 @@ oceanic_vtpro_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
if (oxygen)
gasmix->oxygen = oxygen / 100.0;
@@ -220,6 +205,7 @@ oceanic_vtpro_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
tank->gasmix = flags;
tank->beginpressure = beginpressure * 2 * PSI / BAR;
tank->endpressure = endpressure * 2 * PSI / BAR;
+ tank->usage = DC_USAGE_NONE;
break;
default:
return DC_STATUS_UNSUPPORTED;
@@ -331,14 +317,14 @@ oceanic_vtpro_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
time = timestamp * 60 + (i + 1) * interval;
else
time = timestamp * 60 + (i + 1) * 60.0 / count + 0.5;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Vendor specific data
sample.vendor.type = SAMPLE_VENDOR_OCEANIC_VTPRO;
sample.vendor.size = PAGESIZE / 2;
sample.vendor.data = data + offset;
- if (callback) callback (DC_SAMPLE_VENDOR, sample, userdata);
+ if (callback) callback (DC_SAMPLE_VENDOR, &sample, userdata);
// Depth (ft)
unsigned int depth = 0;
@@ -348,7 +334,7 @@ oceanic_vtpro_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
depth = data[offset + 3];
}
sample.depth = depth * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (°F)
unsigned int temperature = 0;
@@ -358,7 +344,7 @@ oceanic_vtpro_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
temperature = data[offset + 6];
}
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// NDL / Deco
if (parser->model != AERIS500AI) {
@@ -372,7 +358,8 @@ oceanic_vtpro_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
sample.deco.depth = 0.0;
}
sample.deco.time = decotime * 60;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
}
offset += PAGESIZE / 2;
diff --git a/src/oceans_s1.h b/src/oceans_s1.h
index 825d3093..e5e43f8d 100644
--- a/src/oceans_s1.h
+++ b/src/oceans_s1.h
@@ -36,7 +36,7 @@ dc_status_t
oceans_s1_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-oceans_s1_parser_create (dc_parser_t **parser, dc_context_t *context);
+oceans_s1_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/oceans_s1_parser.c b/src/oceans_s1_parser.c
index 8b4cfbd8..cce50312 100644
--- a/src/oceans_s1_parser.c
+++ b/src/oceans_s1_parser.c
@@ -58,7 +58,6 @@ struct oceans_s1_parser_t {
unsigned int divetime;
};
-static dc_status_t oceans_s1_parser_set_data(dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t oceans_s1_parser_get_datetime(dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t oceans_s1_parser_get_field(dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t oceans_s1_parser_samples_foreach(dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -66,7 +65,6 @@ static dc_status_t oceans_s1_parser_samples_foreach(dc_parser_t *abstract, dc_sa
static const dc_parser_vtable_t oceans_s1_parser_vtable = {
sizeof(oceans_s1_parser_t),
DC_FAMILY_OCEANS_S1,
- oceans_s1_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -77,7 +75,7 @@ static const dc_parser_vtable_t oceans_s1_parser_vtable = {
};
dc_status_t
-oceans_s1_parser_create (dc_parser_t **out, dc_context_t *context)
+oceans_s1_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
oceans_s1_parser_t *parser = NULL;
@@ -85,7 +83,7 @@ oceans_s1_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (oceans_s1_parser_t *) dc_parser_allocate (context, &oceans_s1_parser_vtable);
+ parser = (oceans_s1_parser_t *) dc_parser_allocate (context, &oceans_s1_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -105,23 +103,6 @@ oceans_s1_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_SUCCESS;
}
-static dc_status_t
-oceans_s1_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- oceans_s1_parser_t *parser = (oceans_s1_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->timestamp = 0;
- parser->number = 0;
- parser->divemode = 0;
- parser->oxygen = 0;
- parser->maxdepth = 0;
- parser->divetime = 0;
-
- return DC_STATUS_SUCCESS;
-}
-
static dc_status_t
oceans_s1_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -166,6 +147,7 @@ oceans_s1_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
*((unsigned int *) value) = parser->divemode == SCUBA;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = parser->oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -249,19 +231,19 @@ oceans_s1_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
unsigned int nsamples = seconds / interval;
for (unsigned int i = 0; i < nsamples; ++i) {
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
sample.depth = 0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
}
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
sample.depth = depth / 100.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
} else if (strncmp(line, "enddive", 7) == 0) {
if (sscanf(line, "enddive %u,%u", &maxdepth, &divetime) != 2) {
ERROR (parser->base.context, "Failed to parse the line '%s'.", line);
@@ -280,14 +262,14 @@ oceans_s1_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
}
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
sample.depth = depth / 100.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
sample.temperature = temperature;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
if (events & EVENT_DECO_STOP) {
sample.deco.type = DC_DECO_DECOSTOP;
@@ -298,7 +280,8 @@ oceans_s1_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
}
sample.deco.depth = 0.0;
sample.deco.time = 0;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
}
}
diff --git a/src/parser-private.h b/src/parser-private.h
index af1a76e8..73e2e592 100644
--- a/src/parser-private.h
+++ b/src/parser-private.h
@@ -41,7 +41,7 @@ typedef struct dc_parser_vtable_t dc_parser_vtable_t;
struct dc_parser_t {
const dc_parser_vtable_t *vtable;
dc_context_t *context;
- const unsigned char *data;
+ unsigned char *data;
unsigned int size;
};
@@ -50,8 +50,6 @@ struct dc_parser_vtable_t {
dc_family_t type;
- dc_status_t (*set_data) (dc_parser_t *parser, const unsigned char *data, unsigned int size);
-
dc_status_t (*set_clock) (dc_parser_t *parser, unsigned int devtime, dc_ticks_t systime);
dc_status_t (*set_atmospheric) (dc_parser_t *parser, double atmospheric);
@@ -68,7 +66,7 @@ struct dc_parser_vtable_t {
};
dc_parser_t *
-dc_parser_allocate (dc_context_t *context, const dc_parser_vtable_t *vtable);
+dc_parser_allocate (dc_context_t *context, const dc_parser_vtable_t *vtable, const unsigned char data[], size_t size);
void
dc_parser_deallocate (dc_parser_t *parser);
@@ -84,7 +82,7 @@ typedef struct sample_statistics_t {
#define SAMPLE_STATISTICS_INITIALIZER {0, 0.0}
void
-sample_statistics_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata);
+sample_statistics_cb (dc_sample_type_t type, const dc_sample_value_t *value, void *userdata);
#ifdef __cplusplus
}
diff --git a/src/parser.c b/src/parser.c
index b2530704..840c9198 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -20,6 +20,7 @@
*/
#include
+#include
#include
#include "suunto_d9.h"
@@ -75,7 +76,7 @@
#define REACTPROWHITE 0x4354
static dc_status_t
-dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, dc_family_t family, unsigned int model, unsigned int serial, unsigned int devtime, dc_ticks_t systime)
+dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, dc_family_t family, unsigned int model, unsigned int serial)
{
dc_status_t rc = DC_STATUS_SUCCESS;
dc_parser_t *parser = NULL;
@@ -85,133 +86,133 @@ dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, dc_family_t fa
switch (family) {
case DC_FAMILY_SUUNTO_SOLUTION:
- rc = suunto_solution_parser_create (&parser, context);
+ rc = suunto_solution_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_SUUNTO_EON:
- rc = suunto_eon_parser_create (&parser, context, 0);
+ rc = suunto_eon_parser_create (&parser, context, data, size, 0);
break;
case DC_FAMILY_SUUNTO_VYPER:
if (model == 0x01)
- rc = suunto_eon_parser_create (&parser, context, 1);
+ rc = suunto_eon_parser_create (&parser, context, data, size, 1);
else
- rc = suunto_vyper_parser_create (&parser, context, serial);
+ rc = suunto_vyper_parser_create (&parser, context, data, size, serial);
break;
case DC_FAMILY_SUUNTO_VYPER2:
case DC_FAMILY_SUUNTO_D9:
- rc = suunto_d9_parser_create (&parser, context, model, serial);
+ rc = suunto_d9_parser_create (&parser, context, data, size, model, serial);
break;
case DC_FAMILY_SUUNTO_EONSTEEL:
- rc = suunto_eonsteel_parser_create(&parser, context, model);
+ rc = suunto_eonsteel_parser_create(&parser, context, data, size, model);
break;
case DC_FAMILY_UWATEC_ALADIN:
case DC_FAMILY_UWATEC_MEMOMOUSE:
- rc = uwatec_memomouse_parser_create (&parser, context, devtime, systime);
+ rc = uwatec_memomouse_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_UWATEC_SMART:
- rc = uwatec_smart_parser_create (&parser, context, model);
+ rc = uwatec_smart_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_REEFNET_SENSUS:
- rc = reefnet_sensus_parser_create (&parser, context, devtime, systime);
+ rc = reefnet_sensus_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_REEFNET_SENSUSPRO:
- rc = reefnet_sensuspro_parser_create (&parser, context, devtime, systime);
+ rc = reefnet_sensuspro_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_REEFNET_SENSUSULTRA:
- rc = reefnet_sensusultra_parser_create (&parser, context, devtime, systime);
+ rc = reefnet_sensusultra_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_OCEANIC_VTPRO:
- rc = oceanic_vtpro_parser_create (&parser, context, model);
+ rc = oceanic_vtpro_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_OCEANIC_VEO250:
- rc = oceanic_veo250_parser_create (&parser, context, model);
+ rc = oceanic_veo250_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_OCEANIC_ATOM2:
if (model == REACTPROWHITE)
- rc = oceanic_veo250_parser_create (&parser, context, model);
+ rc = oceanic_veo250_parser_create (&parser, context, data, size, model);
else
- rc = oceanic_atom2_parser_create (&parser, context, model, serial);
+ rc = oceanic_atom2_parser_create (&parser, context, data, size, model, serial);
break;
case DC_FAMILY_MARES_NEMO:
case DC_FAMILY_MARES_PUCK:
- rc = mares_nemo_parser_create (&parser, context, model);
+ rc = mares_nemo_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_MARES_DARWIN:
- rc = mares_darwin_parser_create (&parser, context, model);
+ rc = mares_darwin_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_MARES_ICONHD:
- rc = mares_iconhd_parser_create (&parser, context, model, serial);
+ rc = mares_iconhd_parser_create (&parser, context, data, size, model, serial);
break;
case DC_FAMILY_HW_OSTC:
- rc = hw_ostc_parser_create (&parser, context, serial);
+ rc = hw_ostc_parser_create (&parser, context, data, size, serial);
break;
case DC_FAMILY_HW_FROG:
case DC_FAMILY_HW_OSTC3:
- rc = hw_ostc3_parser_create (&parser, context, serial, model);
+ rc = hw_ostc3_parser_create (&parser, context, data, size, model, serial);
break;
case DC_FAMILY_CRESSI_EDY:
case DC_FAMILY_ZEAGLE_N2ITION3:
- rc = cressi_edy_parser_create (&parser, context, model);
+ rc = cressi_edy_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_CRESSI_LEONARDO:
- rc = cressi_leonardo_parser_create (&parser, context, model);
+ rc = cressi_leonardo_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_CRESSI_GOA:
- rc = cressi_goa_parser_create (&parser, context, model);
+ rc = cressi_goa_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_ATOMICS_COBALT:
- rc = atomics_cobalt_parser_create (&parser, context);
+ rc = atomics_cobalt_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_SHEARWATER_PREDATOR:
- rc = shearwater_predator_parser_create (&parser, context, model, serial);
+ rc = shearwater_predator_parser_create (&parser, context, data, size, model, serial);
break;
case DC_FAMILY_SHEARWATER_PETREL:
- rc = shearwater_petrel_parser_create (&parser, context, model, serial);
+ rc = shearwater_petrel_parser_create (&parser, context, data, size, model, serial);
break;
case DC_FAMILY_DIVERITE_NITEKQ:
- rc = diverite_nitekq_parser_create (&parser, context);
+ rc = diverite_nitekq_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_CITIZEN_AQUALAND:
- rc = citizen_aqualand_parser_create (&parser, context);
+ rc = citizen_aqualand_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_DIVESYSTEM_IDIVE:
- rc = divesystem_idive_parser_create (&parser, context, model);
+ rc = divesystem_idive_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_COCHRAN_COMMANDER:
- rc = cochran_commander_parser_create (&parser, context, model);
+ rc = cochran_commander_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_TECDIVING_DIVECOMPUTEREU:
- rc = tecdiving_divecomputereu_parser_create (&parser, context);
+ rc = tecdiving_divecomputereu_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_MCLEAN_EXTREME:
- rc = mclean_extreme_parser_create (&parser, context);
+ rc = mclean_extreme_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_LIQUIVISION_LYNX:
- rc = liquivision_lynx_parser_create (&parser, context, model);
+ rc = liquivision_lynx_parser_create (&parser, context, data, size, model);
break;
case DC_FAMILY_SPORASUB_SP2:
- rc = sporasub_sp2_parser_create (&parser, context);
+ rc = sporasub_sp2_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_DEEPSIX_EXCURSION:
- rc = deepsix_excursion_parser_create (&parser, context);
+ rc = deepsix_excursion_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_SEAC_SCREEN:
- rc = seac_screen_parser_create (&parser, context);
+ rc = seac_screen_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_DEEPBLU_COSMIQ:
- rc = deepblu_cosmiq_parser_create (&parser, context);
+ rc = deepblu_cosmiq_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_OCEANS_S1:
- rc = oceans_s1_parser_create (&parser, context);
+ rc = oceans_s1_parser_create (&parser, context, data, size);
break;
case DC_FAMILY_DIVESOFT_FREEDOM:
- rc = divesoft_freedom_parser_create (&parser, context);
+ rc = divesoft_freedom_parser_create (&parser, context, data, size);
break;
default:
return DC_STATUS_INVALIDARGS;
// Not merged upstream yet
case DC_FAMILY_GARMIN:
- rc = garmin_parser_create (&parser, context);
+ rc = garmin_parser_create (&parser, context, data, size);
break;
}
@@ -221,30 +222,42 @@ dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, dc_family_t fa
}
dc_status_t
-dc_parser_new (dc_parser_t **out, dc_device_t *device)
+dc_parser_new (dc_parser_t **out, dc_device_t *device, const unsigned char data[], size_t size)
{
+ dc_status_t status = DC_STATUS_SUCCESS;
+ dc_parser_t *parser = NULL;
+
if (device == NULL)
return DC_STATUS_INVALIDARGS;
- return dc_parser_new_internal (out, device->context,
- dc_device_get_type (device),
- device->devinfo.model,
- device->devinfo.serial,
- device->clock.devtime, device->clock.systime);
+ status = dc_parser_new_internal (&parser, device->context, data, size,
+ dc_device_get_type (device), device->devinfo.model, 0);
+ if (status != DC_STATUS_SUCCESS)
+ goto error_exit;
+
+ status = dc_parser_set_clock (parser, device->clock.devtime, device->clock.systime);
+ if (status != DC_STATUS_SUCCESS && status != DC_STATUS_UNSUPPORTED)
+ goto error_free;
+
+ *out = parser;
+
+ return DC_STATUS_SUCCESS;
+
+error_free:
+ dc_parser_deallocate (parser);
+error_exit:
+ return status;
}
dc_status_t
-dc_parser_new2 (dc_parser_t **out, dc_context_t *context, dc_descriptor_t *descriptor, unsigned int devtime, dc_ticks_t systime)
+dc_parser_new2 (dc_parser_t **out, dc_context_t *context, dc_descriptor_t *descriptor, const unsigned char data[], size_t size)
{
- return dc_parser_new_internal (out, context,
- dc_descriptor_get_type (descriptor),
- dc_descriptor_get_model (descriptor),
- 0,
- devtime, systime);
+ return dc_parser_new_internal (out, context, data, size,
+ dc_descriptor_get_type (descriptor), dc_descriptor_get_model (descriptor), 0);
}
dc_parser_t *
-dc_parser_allocate (dc_context_t *context, const dc_parser_vtable_t *vtable)
+dc_parser_allocate (dc_context_t *context, const dc_parser_vtable_t *vtable, const unsigned char data[], size_t size)
{
dc_parser_t *parser = NULL;
@@ -261,15 +274,34 @@ dc_parser_allocate (dc_context_t *context, const dc_parser_vtable_t *vtable)
// Initialize the base class.
parser->vtable = vtable;
parser->context = context;
- parser->data = NULL;
- parser->size = 0;
+ if (size) {
+ // Allocate memory for the data.
+ parser->data = malloc (size);
+ if (parser->data == NULL) {
+ ERROR (context, "Failed to allocate memory.");
+ free (parser);
+ return NULL;
+ }
+
+ // Copy the data.
+ memcpy (parser->data, data, size);
+ parser->size = size;
+ } else {
+ parser->data = NULL;
+ parser->size = 0;
+
+ }
return parser;
}
void
dc_parser_deallocate (dc_parser_t *parser)
{
+ if (parser == NULL)
+ return;
+
+ free (parser->data);
free (parser);
}
@@ -332,22 +364,6 @@ dc_parser_set_density (dc_parser_t *parser, double density)
}
-dc_status_t
-dc_parser_set_data (dc_parser_t *parser, const unsigned char *data, unsigned int size)
-{
- if (parser == NULL)
- return DC_STATUS_UNSUPPORTED;
-
- if (parser->vtable->set_data == NULL)
- return DC_STATUS_UNSUPPORTED;
-
- parser->data = data;
- parser->size = size;
-
- return parser->vtable->set_data (parser, data, size);
-}
-
-
dc_status_t
dc_parser_get_datetime (dc_parser_t *parser, dc_datetime_t *datetime)
{
@@ -405,17 +421,17 @@ dc_parser_destroy (dc_parser_t *parser)
void
-sample_statistics_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
+sample_statistics_cb (dc_sample_type_t type, const dc_sample_value_t *value, void *userdata)
{
sample_statistics_t *statistics = (sample_statistics_t *) userdata;
switch (type) {
case DC_SAMPLE_TIME:
- statistics->divetime = value.time;
+ statistics->divetime = value->time / 1000;
break;
case DC_SAMPLE_DEPTH:
- if (statistics->maxdepth < value.depth)
- statistics->maxdepth = value.depth;
+ if (statistics->maxdepth < value->depth)
+ statistics->maxdepth = value->depth;
break;
default:
break;
diff --git a/src/reefnet_sensus.h b/src/reefnet_sensus.h
index a021b86e..38157dcc 100644
--- a/src/reefnet_sensus.h
+++ b/src/reefnet_sensus.h
@@ -36,7 +36,7 @@ dc_status_t
reefnet_sensus_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-reefnet_sensus_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int devtime, dc_ticks_t systime);
+reefnet_sensus_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/reefnet_sensus_parser.c b/src/reefnet_sensus_parser.c
index 00c3b477..29e7f464 100644
--- a/src/reefnet_sensus_parser.c
+++ b/src/reefnet_sensus_parser.c
@@ -48,7 +48,6 @@ struct reefnet_sensus_parser_t {
unsigned int maxdepth;
};
-static dc_status_t reefnet_sensus_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t reefnet_sensus_parser_set_clock (dc_parser_t *abstract, unsigned int devtime, dc_ticks_t systime);
static dc_status_t reefnet_sensus_parser_set_atmospheric (dc_parser_t *abstract, double atmospheric);
static dc_status_t reefnet_sensus_parser_set_density (dc_parser_t *abstract, double density);
@@ -59,7 +58,6 @@ static dc_status_t reefnet_sensus_parser_samples_foreach (dc_parser_t *abstract,
static const dc_parser_vtable_t reefnet_sensus_parser_vtable = {
sizeof(reefnet_sensus_parser_t),
DC_FAMILY_REEFNET_SENSUS,
- reefnet_sensus_parser_set_data, /* set_data */
reefnet_sensus_parser_set_clock, /* set_clock */
reefnet_sensus_parser_set_atmospheric, /* set_atmospheric */
reefnet_sensus_parser_set_density, /* set_density */
@@ -71,7 +69,7 @@ static const dc_parser_vtable_t reefnet_sensus_parser_vtable = {
dc_status_t
-reefnet_sensus_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int devtime, dc_ticks_t systime)
+reefnet_sensus_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
reefnet_sensus_parser_t *parser = NULL;
@@ -79,7 +77,7 @@ reefnet_sensus_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (reefnet_sensus_parser_t *) dc_parser_allocate (context, &reefnet_sensus_parser_vtable);
+ parser = (reefnet_sensus_parser_t *) dc_parser_allocate (context, &reefnet_sensus_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -88,8 +86,8 @@ reefnet_sensus_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
// Set the default values.
parser->atmospheric = DEF_ATMOSPHERIC;
parser->hydrostatic = DEF_DENSITY_SALT * GRAVITY;
- parser->devtime = devtime;
- parser->systime = systime;
+ parser->devtime = 0;
+ parser->systime = 0;
parser->cached = 0;
parser->divetime = 0;
parser->maxdepth = 0;
@@ -100,35 +98,6 @@ reefnet_sensus_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
}
-static dc_status_t
-reefnet_sensus_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- reefnet_sensus_parser_t *parser = (reefnet_sensus_parser_t*) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->divetime = 0;
- parser->maxdepth = 0;
-
- return DC_STATUS_SUCCESS;
-}
-
-
-dc_status_t
-reefnet_sensus_parser_set_calibration (dc_parser_t *abstract, double atmospheric, double hydrostatic)
-{
- reefnet_sensus_parser_t *parser = (reefnet_sensus_parser_t*) abstract;
-
- if (!ISINSTANCE (abstract))
- return DC_STATUS_INVALIDARGS;
-
- parser->atmospheric = atmospheric;
- parser->hydrostatic = hydrostatic;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
reefnet_sensus_parser_set_clock (dc_parser_t *abstract, unsigned int devtime, dc_ticks_t systime)
{
@@ -279,13 +248,13 @@ reefnet_sensus_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
// Time (seconds)
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (adjusted feet of seawater).
unsigned int depth = data[offset++];
sample.depth = ((depth + 33.0 - (double) SAMPLE_DEPTH_ADJUST) * FSW - parser->atmospheric) / parser->hydrostatic;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (degrees Fahrenheit)
if ((nsamples % 6) == 0) {
@@ -293,7 +262,7 @@ reefnet_sensus_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
return DC_STATUS_DATAFORMAT;
unsigned int temperature = data[offset++];
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
// Current sample is complete.
diff --git a/src/reefnet_sensuspro.h b/src/reefnet_sensuspro.h
index 99325155..f187f935 100644
--- a/src/reefnet_sensuspro.h
+++ b/src/reefnet_sensuspro.h
@@ -36,7 +36,7 @@ dc_status_t
reefnet_sensuspro_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-reefnet_sensuspro_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int devtime, dc_ticks_t systime);
+reefnet_sensuspro_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/reefnet_sensuspro_parser.c b/src/reefnet_sensuspro_parser.c
index ad371d79..5d6fd5eb 100644
--- a/src/reefnet_sensuspro_parser.c
+++ b/src/reefnet_sensuspro_parser.c
@@ -47,7 +47,6 @@ struct reefnet_sensuspro_parser_t {
unsigned int maxdepth;
};
-static dc_status_t reefnet_sensuspro_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t reefnet_sensuspro_parser_set_clock (dc_parser_t *abstract, unsigned int devtime, dc_ticks_t systime);
static dc_status_t reefnet_sensuspro_parser_set_atmospheric (dc_parser_t *abstract, double atmospheric);
static dc_status_t reefnet_sensuspro_parser_set_density (dc_parser_t *abstract, double density);
@@ -58,7 +57,6 @@ static dc_status_t reefnet_sensuspro_parser_samples_foreach (dc_parser_t *abstra
static const dc_parser_vtable_t reefnet_sensuspro_parser_vtable = {
sizeof(reefnet_sensuspro_parser_t),
DC_FAMILY_REEFNET_SENSUSPRO,
- reefnet_sensuspro_parser_set_data, /* set_data */
reefnet_sensuspro_parser_set_clock, /* set_clock */
reefnet_sensuspro_parser_set_atmospheric, /* set_atmospheric */
reefnet_sensuspro_parser_set_density, /* set_density */
@@ -70,7 +68,7 @@ static const dc_parser_vtable_t reefnet_sensuspro_parser_vtable = {
dc_status_t
-reefnet_sensuspro_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int devtime, dc_ticks_t systime)
+reefnet_sensuspro_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
reefnet_sensuspro_parser_t *parser = NULL;
@@ -78,7 +76,7 @@ reefnet_sensuspro_parser_create (dc_parser_t **out, dc_context_t *context, unsig
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (reefnet_sensuspro_parser_t *) dc_parser_allocate (context, &reefnet_sensuspro_parser_vtable);
+ parser = (reefnet_sensuspro_parser_t *) dc_parser_allocate (context, &reefnet_sensuspro_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -87,8 +85,8 @@ reefnet_sensuspro_parser_create (dc_parser_t **out, dc_context_t *context, unsig
// Set the default values.
parser->atmospheric = DEF_ATMOSPHERIC;
parser->hydrostatic = DEF_DENSITY_SALT * GRAVITY;
- parser->devtime = devtime;
- parser->systime = systime;
+ parser->devtime = 0;
+ parser->systime = 0;
parser->cached = 0;
parser->divetime = 0;
parser->maxdepth = 0;
@@ -99,35 +97,6 @@ reefnet_sensuspro_parser_create (dc_parser_t **out, dc_context_t *context, unsig
}
-static dc_status_t
-reefnet_sensuspro_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- reefnet_sensuspro_parser_t *parser = (reefnet_sensuspro_parser_t*) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->divetime = 0;
- parser->maxdepth = 0;
-
- return DC_STATUS_SUCCESS;
-}
-
-
-dc_status_t
-reefnet_sensuspro_parser_set_calibration (dc_parser_t *abstract, double atmospheric, double hydrostatic)
-{
- reefnet_sensuspro_parser_t *parser = (reefnet_sensuspro_parser_t*) abstract;
-
- if (!ISINSTANCE (abstract))
- return DC_STATUS_INVALIDARGS;
-
- parser->atmospheric = atmospheric;
- parser->hydrostatic = hydrostatic;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
reefnet_sensuspro_parser_set_clock (dc_parser_t *abstract, unsigned int devtime, dc_ticks_t systime)
{
@@ -278,16 +247,16 @@ reefnet_sensuspro_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callb
// Time (seconds)
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Temperature (°F)
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// Depth (absolute pressure in fsw)
sample.depth = (depth * FSW - parser->atmospheric) / parser->hydrostatic;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
offset += 2;
}
diff --git a/src/reefnet_sensusultra.h b/src/reefnet_sensusultra.h
index af73c8a6..1cefc9c9 100644
--- a/src/reefnet_sensusultra.h
+++ b/src/reefnet_sensusultra.h
@@ -36,7 +36,7 @@ dc_status_t
reefnet_sensusultra_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-reefnet_sensusultra_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int devtime, dc_ticks_t systime);
+reefnet_sensusultra_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/reefnet_sensusultra_parser.c b/src/reefnet_sensusultra_parser.c
index bc52f1f6..670a0c3c 100644
--- a/src/reefnet_sensusultra_parser.c
+++ b/src/reefnet_sensusultra_parser.c
@@ -47,7 +47,6 @@ struct reefnet_sensusultra_parser_t {
unsigned int maxdepth;
};
-static dc_status_t reefnet_sensusultra_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t reefnet_sensusultra_parser_set_clock (dc_parser_t *abstract, unsigned int devtime, dc_ticks_t systime);
static dc_status_t reefnet_sensusultra_parser_set_atmospheric (dc_parser_t *abstract, double atmospheric);
static dc_status_t reefnet_sensusultra_parser_set_density (dc_parser_t *abstract, double density);
@@ -58,7 +57,6 @@ static dc_status_t reefnet_sensusultra_parser_samples_foreach (dc_parser_t *abst
static const dc_parser_vtable_t reefnet_sensusultra_parser_vtable = {
sizeof(reefnet_sensusultra_parser_t),
DC_FAMILY_REEFNET_SENSUSULTRA,
- reefnet_sensusultra_parser_set_data, /* set_data */
reefnet_sensusultra_parser_set_clock, /* set_clock */
reefnet_sensusultra_parser_set_atmospheric, /* set_atmospheric */
reefnet_sensusultra_parser_set_density, /* set_density */
@@ -70,7 +68,7 @@ static const dc_parser_vtable_t reefnet_sensusultra_parser_vtable = {
dc_status_t
-reefnet_sensusultra_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int devtime, dc_ticks_t systime)
+reefnet_sensusultra_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
reefnet_sensusultra_parser_t *parser = NULL;
@@ -78,7 +76,7 @@ reefnet_sensusultra_parser_create (dc_parser_t **out, dc_context_t *context, uns
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (reefnet_sensusultra_parser_t *) dc_parser_allocate (context, &reefnet_sensusultra_parser_vtable);
+ parser = (reefnet_sensusultra_parser_t *) dc_parser_allocate (context, &reefnet_sensusultra_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -87,8 +85,8 @@ reefnet_sensusultra_parser_create (dc_parser_t **out, dc_context_t *context, uns
// Set the default values.
parser->atmospheric = DEF_ATMOSPHERIC;
parser->hydrostatic = DEF_DENSITY_SALT * GRAVITY;
- parser->devtime = devtime;
- parser->systime = systime;
+ parser->devtime = 0;
+ parser->systime = 0;
parser->cached = 0;
parser->divetime = 0;
parser->maxdepth = 0;
@@ -99,35 +97,6 @@ reefnet_sensusultra_parser_create (dc_parser_t **out, dc_context_t *context, uns
}
-static dc_status_t
-reefnet_sensusultra_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- reefnet_sensusultra_parser_t *parser = (reefnet_sensusultra_parser_t*) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->divetime = 0;
- parser->maxdepth = 0;
-
- return DC_STATUS_SUCCESS;
-}
-
-
-dc_status_t
-reefnet_sensusultra_parser_set_calibration (dc_parser_t *abstract, double atmospheric, double hydrostatic)
-{
- reefnet_sensusultra_parser_t *parser = (reefnet_sensusultra_parser_t*) abstract;
-
- if (!ISINSTANCE (abstract))
- return DC_STATUS_INVALIDARGS;
-
- parser->atmospheric = atmospheric;
- parser->hydrostatic = hydrostatic;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
reefnet_sensusultra_parser_set_clock (dc_parser_t *abstract, unsigned int devtime, dc_ticks_t systime)
{
@@ -275,18 +244,18 @@ reefnet_sensusultra_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
// Time (seconds)
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Temperature (0.01 °K)
unsigned int temperature = array_uint16_le (data + offset);
sample.temperature = temperature / 100.0 - 273.15;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// Depth (absolute pressure in millibar)
unsigned int depth = array_uint16_le (data + offset + 2);
sample.depth = (depth * BAR / 1000.0 - parser->atmospheric) / parser->hydrostatic;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
offset += 4;
}
diff --git a/src/seac_screen.h b/src/seac_screen.h
index 64c15b65..4ff05eae 100644
--- a/src/seac_screen.h
+++ b/src/seac_screen.h
@@ -35,7 +35,7 @@ dc_status_t
seac_screen_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-seac_screen_parser_create (dc_parser_t **parser, dc_context_t *context);
+seac_screen_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/seac_screen_parser.c b/src/seac_screen_parser.c
index c4a855c3..07553d6c 100644
--- a/src/seac_screen_parser.c
+++ b/src/seac_screen_parser.c
@@ -48,7 +48,6 @@ struct seac_screen_parser_t {
unsigned int gf_high;
};
-static dc_status_t seac_screen_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t seac_screen_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t seac_screen_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t seac_screen_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -56,7 +55,6 @@ static dc_status_t seac_screen_parser_samples_foreach (dc_parser_t *abstract, dc
static const dc_parser_vtable_t seac_screen_parser_vtable = {
sizeof(seac_screen_parser_t),
DC_FAMILY_SEAC_SCREEN,
- seac_screen_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -67,7 +65,7 @@ static const dc_parser_vtable_t seac_screen_parser_vtable = {
};
dc_status_t
-seac_screen_parser_create (dc_parser_t **out, dc_context_t *context)
+seac_screen_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
seac_screen_parser_t *parser = NULL;
@@ -75,7 +73,7 @@ seac_screen_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (seac_screen_parser_t *) dc_parser_allocate (context, &seac_screen_parser_vtable);
+ parser = (seac_screen_parser_t *) dc_parser_allocate (context, &seac_screen_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -95,23 +93,6 @@ seac_screen_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_SUCCESS;
}
-static dc_status_t
-seac_screen_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- seac_screen_parser_t *parser = (seac_screen_parser_t *)abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->ngasmixes = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->oxygen[i] = 0;
- }
- parser->gf_low = 0;
- parser->gf_high = 0;
-
- return DC_STATUS_SUCCESS;
-}
-
static dc_status_t
seac_screen_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -239,6 +220,7 @@ seac_screen_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsig
*((unsigned int *)value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = parser->oxygen[flags] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -331,16 +313,16 @@ seac_screen_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
return DC_STATUS_DATAFORMAT;
}
time = timestamp;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/100 m).
sample.depth = depth / 100.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (1/100 °C).
sample.temperature = temperature / 100.0;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// Gas mix
if (o2 != o2_previous) {
@@ -363,7 +345,7 @@ seac_screen_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
}
sample.gasmix = idx;
- if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback(DC_SAMPLE_GASMIX, &sample, userdata);
o2_previous = o2;
}
@@ -377,11 +359,12 @@ seac_screen_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
sample.deco.time = ndl_tts;
sample.deco.depth = 0;
}
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
// CNS
sample.cns = cns / 100.0;
- if (callback) callback (DC_SAMPLE_CNS, sample, userdata);
+ if (callback) callback (DC_SAMPLE_CNS, &sample, userdata);
// Deco model
if (gf_low == 0 && gf_high == 0) {
diff --git a/src/serial_posix.c b/src/serial_posix.c
index a189e150..792a1c9f 100644
--- a/src/serial_posix.c
+++ b/src/serial_posix.c
@@ -57,7 +57,6 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
-#include "descriptor-private.h"
#include "platform.h"
#include "timer.h"
@@ -230,7 +229,7 @@ dc_serial_iterator_next (dc_iterator_t *abstract, void *out)
return DC_STATUS_NOMEMORY;
}
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_SERIAL, filename, NULL)) {
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_SERIAL, filename)) {
continue;
}
diff --git a/src/serial_win32.c b/src/serial_win32.c
index aeeeb830..e506cbd4 100644
--- a/src/serial_win32.c
+++ b/src/serial_win32.c
@@ -31,7 +31,6 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
-#include "descriptor-private.h"
#include "platform.h"
static dc_status_t dc_serial_iterator_next (dc_iterator_t *iterator, void *item);
@@ -228,7 +227,7 @@ dc_serial_iterator_next (dc_iterator_t *abstract, void *out)
// Null terminate the string.
data[data_len] = 0;
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_SERIAL, data, NULL)) {
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_SERIAL, data)) {
continue;
}
diff --git a/src/shearwater_common.c b/src/shearwater_common.c
index bea08898..43da4551 100644
--- a/src/shearwater_common.c
+++ b/src/shearwater_common.c
@@ -36,10 +36,13 @@
#define ESC_END 0xDC
#define ESC_ESC 0xDD
-// SIDs for CAN WDBI (Write Data By Identifier) as defined by ISO 14229-1
-// (the RDBI command is implemented in shearwater_common_identifier)
-#define CAN_WDBI_REQUEST_SID 0x2E
-#define CAN_WDBI_RESPONSE_SID 0x6E
+#define RDBI_REQUEST 0x22
+#define RDBI_RESPONSE 0x62
+
+#define WDBI_REQUEST 0x2E
+#define WDBI_RESPONSE 0x6E
+
+#define NAK 0x7F
dc_status_t
shearwater_common_setup (shearwater_common_device_t *device, dc_context_t *context, dc_iostream_t *iostream)
@@ -90,7 +93,7 @@ shearwater_common_decompress_lre (unsigned char *data, unsigned int size, dc_buf
// The 9th bit indicates whether the remaining 8 bits represent
// a run of zero bytes or not. If the bit is set, the value is
- // not a run and doesn’t need expansion. If the bit is not set,
+ // not a run and doesn't need expansion. If the bit is not set,
// the value contains the number of zero bytes in the run. A
// zero-length run indicates the end of the compressed stream.
if (value & 0x100) {
@@ -517,195 +520,230 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
dc_status_t
-shearwater_common_identifier (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id)
+shearwater_common_rdbi (shearwater_common_device_t *device, unsigned int id, unsigned char data[], unsigned int size)
{
+ dc_status_t status = DC_STATUS_SUCCESS;
dc_device_t *abstract = (dc_device_t *) device;
- dc_status_t rc = DC_STATUS_SUCCESS;
-
- // Erase the buffer.
- if (!dc_buffer_clear (buffer)) {
- ERROR (abstract->context, "Insufficient buffer space available.");
- return DC_STATUS_NOMEMORY;
- }
// Transfer the request.
unsigned int n = 0;
- unsigned char request[] = {0x22,
+ unsigned char request[] = {
+ RDBI_REQUEST,
(id >> 8) & 0xFF,
(id ) & 0xFF};
unsigned char response[SZ_PACKET];
- rc = shearwater_common_transfer (device, request, sizeof (request), response, sizeof (response), &n);
- if (rc != DC_STATUS_SUCCESS) {
- return rc;
+ status = shearwater_common_transfer (device, request, sizeof (request), response, sizeof (response), &n);
+ if (status != DC_STATUS_SUCCESS) {
+ return status;
}
// Verify the response.
- if (n < 3 || response[0] != 0x62 || response[1] != request[1] || response[2] != request[2]) {
+ if (n < 3 || response[0] != RDBI_RESPONSE || response[1] != request[1] || response[2] != request[2]) {
+ if (n == 3 && response[0] == NAK && response[1] == RDBI_REQUEST) {
+ ERROR (abstract->context, "Received NAK packet with error code 0x%02x.", response[2]);
+ return DC_STATUS_UNSUPPORTED;
+ }
ERROR (abstract->context, "Unexpected response packet.");
return DC_STATUS_PROTOCOL;
}
- // Append the packet to the output buffer.
- if (!dc_buffer_append (buffer, response + 3, n - 3)) {
- ERROR (abstract->context, "Insufficient buffer space available.");
- return DC_STATUS_NOMEMORY;
+ unsigned int length = n - 3;
+
+ if (length != size) {
+ ERROR (abstract->context, "Unexpected packet size (%u bytes).", length);
+ return DC_STATUS_PROTOCOL;
}
- return rc;
-}
+ if (length) {
+ memcpy (data, response + 3, length);
+ }
+ return status;
+}
-dc_status_t shearwater_common_can_wdbi (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id)
+dc_status_t
+shearwater_common_wdbi (shearwater_common_device_t *device, unsigned int id, const unsigned char data[], unsigned int size)
{
- dc_device_t *abstract = (dc_device_t *)device;
+ dc_status_t status = DC_STATUS_SUCCESS;
+ dc_device_t *abstract = (dc_device_t *) device;
- unsigned n = 0;
- char request_header[] = {
- CAN_WDBI_REQUEST_SID,
- (id >> 8) & 0xFF,
- id & 0xFF
- };
- if (!dc_buffer_prepend(buffer, request_header, sizeof(request_header))) {
- ERROR(abstract->context, "Insufficient buffer space available.");
- return DC_STATUS_NOMEMORY;
+ if (size + 3 > SZ_PACKET) {
+ return DC_STATUS_INVALIDARGS;
}
- char response[SZ_PACKET];
- dc_status_t rc = shearwater_common_transfer(device, dc_buffer_get_data(buffer), dc_buffer_get_size(buffer), response, sizeof(response), &n);
- if (rc != DC_STATUS_SUCCESS) {
- return rc;
+ // Transfer the request.
+ unsigned int n = 0;
+ unsigned char request[SZ_PACKET] = {
+ WDBI_REQUEST,
+ (id >> 8) & 0xFF,
+ (id ) & 0xFF};
+ if (size) {
+ memcpy (request + 3, data, size);
+ }
+ unsigned char response[SZ_PACKET];
+ status = shearwater_common_transfer (device, request, size + 3, response, sizeof (response), &n);
+ if (status != DC_STATUS_SUCCESS) {
+ return status;
}
// Verify the response.
- if (n < 3 || response[0] != CAN_WDBI_RESPONSE_SID || response[1] != request_header[1] || response[2] != request_header[2]) {
- ERROR(abstract->context, "Unexpected response packet.");
-
+ if (n < 3 || response[0] != WDBI_RESPONSE || response[1] != request[1] || response[2] != request[2]) {
+ if (n == 3 && response[0] == NAK && response[1] == WDBI_REQUEST) {
+ ERROR (abstract->context, "Received NAK packet with error code 0x%02x.", response[2]);
+ return DC_STATUS_UNSUPPORTED;
+ }
+ ERROR (abstract->context, "Unexpected response packet.");
return DC_STATUS_PROTOCOL;
}
- return rc;
+ return status;
}
-
-dc_status_t shearwater_common_device_timesync(dc_device_t *abstract, const dc_datetime_t *datetime)
+dc_status_t
+shearwater_common_timesync_local (shearwater_common_device_t *device, const dc_datetime_t *datetime)
{
- shearwater_common_device_t *device = (shearwater_common_device_t *)abstract;
+ dc_status_t status = DC_STATUS_SUCCESS;
+ dc_device_t *abstract = (dc_device_t *) device;
- dc_datetime_t local_time;
- memcpy(&local_time, datetime, sizeof(local_time));
+ // Convert to local time.
+ dc_datetime_t local = *datetime;
+ local.timezone = DC_TIMEZONE_NONE;
- // We need to supply a unix timestamp in _local_ time
- local_time.timezone = DC_TIMEZONE_NONE;
+ dc_ticks_t ticks = dc_datetime_mktime (&local);
+ if (ticks == -1) {
+ ERROR (abstract->context, "Invalid date/time value specified.");
+ return DC_STATUS_INVALIDARGS;
+ }
- dc_ticks_t unix_timestamp = dc_datetime_mktime(&local_time);
- if (unix_timestamp == -1) {
- ERROR(abstract->context, "Invalid date/time value specified.");
+ const unsigned char timestamp[] = {
+ (ticks >> 24) & 0xFF,
+ (ticks >> 16) & 0xFF,
+ (ticks >> 8) & 0xFF,
+ (ticks ) & 0xFF,
+ };
- return DC_STATUS_INVALIDARGS;
+ status = shearwater_common_wdbi (device, ID_TIME_LOCAL, timestamp, sizeof(timestamp));
+ if (status != DC_STATUS_SUCCESS) {
+ ERROR (abstract->context, "Failed to write the dive computer local time.");
+ return status;
}
- dc_buffer_t *buffer = dc_buffer_new(WDBI_TIME_PACKET_SIZE);
- if (buffer == NULL) {
- ERROR(abstract->context, "Insufficient buffer space available.");
- dc_buffer_free(buffer);
+ return status;
+}
- return DC_STATUS_NOMEMORY;
+dc_status_t
+shearwater_common_timesync_utc (shearwater_common_device_t *device, const dc_datetime_t *datetime)
+{
+ dc_status_t status = DC_STATUS_SUCCESS;
+ dc_device_t *abstract = (dc_device_t *) device;
+
+ // Convert to UTC time.
+ dc_ticks_t ticks = dc_datetime_mktime (datetime);
+ if (ticks == -1) {
+ ERROR (abstract->context, "Invalid date/time value specified.");
+ return DC_STATUS_INVALIDARGS;
}
- char shearwater_timestamp[] = {
- (unix_timestamp >> 24) & 0xFF,
- (unix_timestamp >> 16) & 0xFF,
- (unix_timestamp >> 8) & 0xFF,
- unix_timestamp & 0xFF,
+ const unsigned char timestamp[] = {
+ (ticks >> 24) & 0xFF,
+ (ticks >> 16) & 0xFF,
+ (ticks >> 8) & 0xFF,
+ (ticks ) & 0xFF,
};
- dc_buffer_append(buffer, shearwater_timestamp, 4);
- dc_status_t rc = shearwater_common_can_wdbi(device, buffer, ID_LOCAL_TIME);
- if (rc != DC_STATUS_SUCCESS) {
- ERROR(abstract->context, "Failed to write the dive computer time.");
+ status = shearwater_common_wdbi (device, ID_TIME_UTC, timestamp, sizeof(timestamp));
+ if (status != DC_STATUS_SUCCESS) {
+ ERROR (abstract->context, "Failed to write the dive computer UTC time.");
+ return status;
}
- dc_buffer_free(buffer);
-
- return rc;
-}
+ int timezone = datetime->timezone / 60;
+ const unsigned char offset[] = {
+ (timezone >> 24) & 0xFF,
+ (timezone >> 16) & 0xFF,
+ (timezone >> 8) & 0xFF,
+ (timezone ) & 0xFF,
+ };
-dc_status_t shearwater_common_read_model(shearwater_common_device_t *device, unsigned int *model)
-{
- dc_buffer_t *buffer = dc_buffer_new(SZ_PACKET);
- if (buffer == NULL) {
- ERROR(device->base.context, "Insufficient buffer space available.");
- return DC_STATUS_NOMEMORY;
+ status = shearwater_common_wdbi (device, ID_TIME_OFFSET, offset, sizeof (offset));
+ if (status != DC_STATUS_SUCCESS) {
+ ERROR (abstract->context, "Failed to write the dive computer timezone offset.");
+ return status;
}
- // Read the hardware type.
- dc_status_t rc = shearwater_common_identifier(device, buffer, ID_HARDWARE);
- if (rc != DC_STATUS_SUCCESS) {
- ERROR(device->base.context, "Failed to read the hardware type.");
- dc_buffer_free(buffer);
+ // We don't have a way to determine the daylight savings time setting,
+ // but the required offset is already factored into the timezone offset.
+ const unsigned char dst[] = {0, 0, 0, 0};
- return rc;
+ status = shearwater_common_wdbi (device, ID_TIME_DST, dst, sizeof (dst));
+ if (status != DC_STATUS_SUCCESS) {
+ ERROR (abstract->context, "Failed to write the dive computer DST setting.");
+ return status;
}
- // Convert and map to the model number.
- unsigned int hardware = array_uint_be(dc_buffer_get_data(buffer), dc_buffer_get_size(buffer));
+ return status;
+}
+
+unsigned int
+shearwater_common_get_model (shearwater_common_device_t *device, unsigned int hardware)
+{
+ unsigned int model = 0;
+
switch (hardware) {
case 0x0101:
case 0x0202:
- *model = PREDATOR;
- break;
- case 0x0606:
- case 0x0A0A: // Nerd 1
- *model = NERD;
- break;
- case 0x7E2D:
- case 0x0E0D: // Nerd 2
- *model = NERD2;
+ model = PREDATOR;
break;
case 0x0404:
-case 0x0909: // Petrel 1
- *model = PETREL;
+ case 0x0909:
+ model = PETREL;
break;
case 0x0505:
case 0x0808:
case 0x0838:
case 0x08A5:
+ case 0x0B0B:
case 0x7828:
case 0x7B2C:
- case 0x8838: // Petrel 2
- case 0x0B0B: // current docs (June 2023) imply this is a Petrel 2
- *model = PETREL;
+ case 0x8838:
+ model = PETREL2;
break;
- case 0xB407: // Petrel 3
- *model = PETREL3;
+ case 0xB407:
+ model = PETREL3;
break;
- case 0x0707: // Perdix
- *model = PERDIX;
+ case 0x0606:
+ case 0x0A0A:
+ model = NERD;
break;
-case 0x0C0C: // current docs (June 2023) imply this is not a valid hardware ID
- case 0x0C0D: // current docs (June 2023) show this as Perdix AI
- case 0x0D0D: // current docs (June 2023) imply this is not a valid hardware ID
- case 0x7C2D: // Perdix AI
+ case 0x0E0D:
+ case 0x7E2D:
+ model = NERD2;
+ break;
+ case 0x0707:
+ model = PERDIX;
+ break;
+ case 0x0C0D:
+ case 0x7C2D:
case 0x8D6C:
- *model = PERDIXAI;
+ model = PERDIXAI;
break;
- case 0xC407: // Perdix 2
- *model = PERDIX2;
+ case 0xC407:
+ model = PERDIX2;
break;
case 0x0F0F:
case 0x1F0A:
case 0x1F0F:
- *model = TERIC;
+ model = TERIC;
break;
-case 0x1512:
- *model = PEREGRINE;
+ case 0x1512:
+ model = PEREGRINE;
+ break;
+ case 0xC0E0:
+ model = TERN;
break;
default:
- // return a model of 0 which is unknown
- WARNING(device->base.context, "Unknown hardware type %04x. Assuming Petrel.", hardware);
+ WARNING (device->base.context, "Unknown hardware type 0x%04x.", hardware);
}
- dc_buffer_free(buffer);
-
- return rc;
+ return model;
}
diff --git a/src/shearwater_common.h b/src/shearwater_common.h
index 397d9508..377c8df0 100644
--- a/src/shearwater_common.h
+++ b/src/shearwater_common.h
@@ -41,6 +41,11 @@ extern "C" {
#define WDBI_TIME_PACKET_SIZE 7
+#define ID_TIME_LOCAL 0x9030
+#define ID_TIME_UTC 0x9031
+#define ID_TIME_OFFSET 0x9032
+#define ID_TIME_DST 0x9033
+
#define PREDATOR 2
#define PETREL 3
#define PETREL2 PETREL
@@ -52,6 +57,7 @@ extern "C" {
#define PEREGRINE 9
#define PETREL3 10
#define PERDIX2 11
+#define TERN 12
#define NSTEPS 10000
#define STEP(i,n) ((NSTEPS * (i) + (n) / 2) / (n))
@@ -71,7 +77,19 @@ dc_status_t
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression, dc_event_progress_t *progress);
dc_status_t
-shearwater_common_identifier (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id);
+shearwater_common_rdbi (shearwater_common_device_t *device, unsigned int id, unsigned char data[], unsigned int size);
+
+dc_status_t
+shearwater_common_wdbi (shearwater_common_device_t *device, unsigned int id, const unsigned char data[], unsigned int size);
+
+dc_status_t
+shearwater_common_timesync_local (shearwater_common_device_t *device, const dc_datetime_t *datetime);
+
+dc_status_t
+shearwater_common_timesync_utc (shearwater_common_device_t *device, const dc_datetime_t *datetime);
+
+unsigned int
+shearwater_common_get_model (shearwater_common_device_t *device, unsigned int hardware);
dc_status_t shearwater_common_can_wdbi (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id);
diff --git a/src/shearwater_petrel.c b/src/shearwater_petrel.c
index 3b0a0b31..7ec18ff8 100644
--- a/src/shearwater_petrel.c
+++ b/src/shearwater_petrel.c
@@ -44,81 +44,9 @@ typedef struct shearwater_petrel_device_t {
unsigned char fingerprint[4];
} shearwater_petrel_device_t;
-
-static dc_status_t shearwater_petrel_device_timesync(dc_device_t *abstract, const dc_datetime_t *datetime)
-{
- shearwater_common_device_t *device = (shearwater_common_device_t *)abstract;
-
- unsigned int model = 0;
- shearwater_common_read_model(device, &model);
- if (model == TERIC) {
- dc_ticks_t unix_timestamp = dc_datetime_mktime(datetime);
- if (unix_timestamp == -1) {
- ERROR(abstract->context, "Invalid date/time value specified.");
-
- return DC_STATUS_INVALIDARGS;
- }
-
- dc_buffer_t *buffer = dc_buffer_new(WDBI_TIME_PACKET_SIZE);
- if (buffer == NULL) {
- ERROR(abstract->context, "Insufficient buffer space available.");
- dc_buffer_free(buffer);
-
- return DC_STATUS_NOMEMORY;
- }
-
- char shearwater_timestamp[] = {
- (unix_timestamp >> 24) & 0xFF,
- (unix_timestamp >> 16) & 0xFF,
- (unix_timestamp >> 8) & 0xFF,
- unix_timestamp & 0xFF,
- };
- dc_buffer_append(buffer, shearwater_timestamp, 4);
-
- dc_status_t rc = shearwater_common_can_wdbi(device, buffer, ID_UTC_TIME);
- if (rc != DC_STATUS_SUCCESS) {
- ERROR(abstract->context, "Failed to write the dive computer UTC time.");
- }
-
- dc_buffer_clear(buffer);
-
- int local_time_offset_minutes = datetime->timezone / 60;
- char shearwater_local_time_offset[] = {
- (local_time_offset_minutes >> 24) & 0xFF,
- (local_time_offset_minutes >> 16) & 0xFF,
- (local_time_offset_minutes >> 8) & 0xFF,
- local_time_offset_minutes & 0xFF,
- };
- dc_buffer_append(buffer, shearwater_local_time_offset, 4);
-
- rc = shearwater_common_can_wdbi(device, buffer, ID_LOCAL_TIME_OFFSET);
- if (rc != DC_STATUS_SUCCESS) {
- ERROR(abstract->context, "Failed to write the dive computer local time offset.");
- }
-
- dc_buffer_clear(buffer);
-
- // We don't have a way to determine the daylight savings time setting,
- // but the required offset is already factored into ID_LOCAL_TIME_OFFSET
- char shearwater_local_time_dst[] = { 0, 0, 0, 0 };
- dc_buffer_append(buffer, shearwater_local_time_dst, 4);
-
- rc = shearwater_common_can_wdbi(device, buffer, ID_LOCAL_TIME_DST);
- if (rc != DC_STATUS_SUCCESS) {
- ERROR(abstract->context, "Failed to write the dive computer DST setting.");
- }
-
- dc_buffer_free(buffer);
-
- return rc;
- }
-
- return shearwater_common_device_timesync(abstract, datetime);
-}
-
-
static dc_status_t shearwater_petrel_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
static dc_status_t shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
+static dc_status_t shearwater_petrel_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime);
static dc_status_t shearwater_petrel_device_close (dc_device_t *abstract);
static const dc_device_vtable_t shearwater_petrel_device_vtable = {
@@ -225,55 +153,48 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
shearwater_petrel_device_t *device = (shearwater_petrel_device_t *) abstract;
dc_status_t rc = DC_STATUS_SUCCESS;
- // Allocate memory buffers for the manifests.
- dc_buffer_t *buffer = dc_buffer_new (MANIFEST_SIZE);
- dc_buffer_t *manifests = dc_buffer_new (MANIFEST_SIZE);
- if (buffer == NULL || manifests == NULL) {
- ERROR (abstract->context, "Insufficient buffer space available.");
- dc_buffer_free (buffer);
- dc_buffer_free (manifests);
- return DC_STATUS_NOMEMORY;
- }
-
// Enable progress notifications.
unsigned int current = 0, maximum = 0;
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
// Read the serial number.
- rc = shearwater_common_identifier (&device->base, buffer, ID_SERIAL);
+ unsigned char rsp_serial[8] = {0};
+ rc = shearwater_common_rdbi (&device->base, ID_SERIAL, rsp_serial, sizeof(rsp_serial));
if (rc != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the serial number.");
- dc_buffer_free (buffer);
- dc_buffer_free (manifests);
return rc;
}
// Convert to a number.
unsigned char serial[4] = {0};
- if (array_convert_hex2bin (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer),
- serial, sizeof (serial)) != 0 ) {
+ if (array_convert_hex2bin (rsp_serial, sizeof(rsp_serial), serial, sizeof (serial)) != 0 ) {
ERROR (abstract->context, "Failed to convert the serial number.");
- dc_buffer_free (buffer);
- dc_buffer_free (manifests);
return DC_STATUS_DATAFORMAT;
-
}
// Read the firmware version.
- rc = shearwater_common_identifier (&device->base, buffer, ID_FIRMWARE);
+ unsigned char rsp_firmware[11] = {0};
+ rc = shearwater_common_rdbi (&device->base, ID_FIRMWARE, rsp_firmware, sizeof(rsp_firmware));
if (rc != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the firmware version.");
- dc_buffer_free (buffer);
- dc_buffer_free (manifests);
return rc;
}
// Convert to a number.
- unsigned int firmware = str2num (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer), 1);
+ unsigned int firmware = str2num (rsp_firmware, sizeof(rsp_firmware), 1);
+
+ // Read the hardware type.
+ unsigned char rsp_hardware[2] = {0};
+ rc = shearwater_common_rdbi (&device->base, ID_HARDWARE, rsp_hardware, sizeof(rsp_hardware));
+ if (rc != DC_STATUS_SUCCESS) {
+ ERROR (abstract->context, "Failed to read the hardware type.");
+ return rc;
+ }
- unsigned int model = 0;
- shearwater_common_read_model((shearwater_common_device_t *)device, &model);
+ // Convert and map to the model number.
+ unsigned int hardware = array_uint16_be (rsp_hardware);
+ unsigned int model = shearwater_common_get_model (&device->base, hardware);
// Emit a device info event.
dc_event_devinfo_t devinfo;
@@ -283,22 +204,14 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
// Read the logbook type
- rc = shearwater_common_identifier (&device->base, buffer, ID_LOGUPLOAD);
+ unsigned char rsp_logupload[9] = {0};
+ rc = shearwater_common_rdbi (&device->base, ID_LOGUPLOAD, rsp_logupload, sizeof(rsp_logupload));
if (rc != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the logbook type.");
- dc_buffer_free (buffer);
- dc_buffer_free (manifests);
return rc;
}
- if (dc_buffer_get_size (buffer) != 9) {
- ERROR (abstract->context, "Unexpected packet size (" DC_PRINTF_SIZE " bytes).", dc_buffer_get_size(buffer));
- dc_buffer_free (buffer);
- dc_buffer_free (manifests);
- return DC_STATUS_DATAFORMAT;
- }
-
- unsigned int base_addr = array_uint32_be (dc_buffer_get_data (buffer) + 1);
+ unsigned int base_addr = array_uint32_be (rsp_logupload + 1);
switch (base_addr) {
case 0xDD000000: // Predator - we shouldn't get here, we could give up or we can try 0xC0000000
case 0xC0000000: // Predator-Like Format (what we used to call the Petrel format)
@@ -311,9 +224,17 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
break;
default: // unknown format
ERROR (abstract->context, "Unknown logbook format %08x", base_addr);
+ return DC_STATUS_DATAFORMAT;
+ }
+
+ // Allocate memory buffers for the manifests.
+ dc_buffer_t *buffer = dc_buffer_new (MANIFEST_SIZE);
+ dc_buffer_t *manifests = dc_buffer_new (MANIFEST_SIZE);
+ if (buffer == NULL || manifests == NULL) {
+ ERROR (abstract->context, "Insufficient buffer space available.");
dc_buffer_free (buffer);
dc_buffer_free (manifests);
- return DC_STATUS_DATAFORMAT;
+ return DC_STATUS_NOMEMORY;
}
// Read the manifest pages
@@ -430,3 +351,28 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
return rc;
}
+
+static dc_status_t
+shearwater_petrel_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime)
+{
+ dc_status_t status = DC_STATUS_SUCCESS;
+ shearwater_common_device_t *device = (shearwater_common_device_t *) abstract;
+
+ // Read the hardware type.
+ unsigned char rsp_hardware[2] = {0};
+ status = shearwater_common_rdbi (device, ID_HARDWARE, rsp_hardware, sizeof(rsp_hardware));
+ if (status != DC_STATUS_SUCCESS) {
+ ERROR (abstract->context, "Failed to read the hardware type.");
+ return status;
+ }
+
+ // Convert and map to the model number.
+ unsigned int hardware = array_uint16_be (rsp_hardware);
+ unsigned int model = shearwater_common_get_model (device, hardware);
+
+ if (model == TERIC) {
+ return shearwater_common_timesync_utc (device, datetime);
+ } else {
+ return shearwater_common_timesync_local (device, datetime);
+ }
+}
diff --git a/src/shearwater_petrel.h b/src/shearwater_petrel.h
index 0d8593cb..ea52ee96 100644
--- a/src/shearwater_petrel.h
+++ b/src/shearwater_petrel.h
@@ -35,7 +35,7 @@ dc_status_t
shearwater_petrel_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-shearwater_petrel_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model, unsigned int serial);
+shearwater_petrel_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial);
#ifdef __cplusplus
}
diff --git a/src/shearwater_predator.c b/src/shearwater_predator.c
index cb713a9e..fffd511f 100644
--- a/src/shearwater_predator.c
+++ b/src/shearwater_predator.c
@@ -44,6 +44,7 @@ typedef struct shearwater_predator_device_t {
static dc_status_t shearwater_predator_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
static dc_status_t shearwater_predator_device_dump (dc_device_t *abstract, dc_buffer_t *buffer);
static dc_status_t shearwater_predator_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
+static dc_status_t shearwater_predator_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime);
static const dc_device_vtable_t shearwater_predator_device_vtable = {
sizeof(shearwater_predator_device_t),
@@ -53,7 +54,7 @@ static const dc_device_vtable_t shearwater_predator_device_vtable = {
NULL, /* write */
shearwater_predator_device_dump, /* dump */
shearwater_predator_device_foreach, /* foreach */
- shearwater_common_device_timesync,
+ shearwater_predator_device_timesync,
NULL /* close */
};
@@ -357,3 +358,9 @@ shearwater_predator_extract_dives (dc_device_t *abstract, const unsigned char da
return shearwater_predator_extract_predator (abstract, data, size, callback, userdata);
}
}
+
+static dc_status_t
+shearwater_predator_device_timesync (dc_device_t *abstract, const dc_datetime_t *datetime)
+{
+ return shearwater_common_timesync_local ((shearwater_common_device_t *) abstract, datetime);
+}
diff --git a/src/shearwater_predator.h b/src/shearwater_predator.h
index 2682e0a5..419c4b84 100644
--- a/src/shearwater_predator.h
+++ b/src/shearwater_predator.h
@@ -35,7 +35,7 @@ dc_status_t
shearwater_predator_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-shearwater_predator_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model, unsigned int serial);
+shearwater_predator_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial);
#ifdef __cplusplus
}
diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c
index 419dd354..44c0c5b1 100644
--- a/src/shearwater_predator_parser.c
+++ b/src/shearwater_predator_parser.c
@@ -109,6 +109,8 @@ typedef struct shearwater_predator_gasmix_t {
unsigned int oxygen;
unsigned int helium;
unsigned int diluent;
+ unsigned int enabled;
+ unsigned int active;
} shearwater_predator_gasmix_t;
typedef struct shearwater_predator_tank_t {
@@ -120,6 +122,7 @@ typedef struct shearwater_predator_tank_t {
unsigned int pressure_reserve;
unsigned int serial;
char name[2];
+ dc_usage_t usage;
unsigned int battery;
} shearwater_predator_tank_t;
@@ -143,8 +146,10 @@ struct shearwater_predator_parser_t {
shearwater_predator_tank_t tank[NTANKS];
unsigned int tankidx[NTANKS];
unsigned int aimode;
+ unsigned int hpccr;
unsigned int calibrated;
double calibration[3];
+ unsigned int divemode;
unsigned int serial;
unsigned int units;
unsigned int atmospheric;
@@ -154,7 +159,6 @@ struct shearwater_predator_parser_t {
struct dc_field_cache cache;
};
-static dc_status_t shearwater_predator_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t shearwater_predator_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -164,7 +168,6 @@ static dc_status_t shearwater_predator_parser_cache (shearwater_predator_parser_
static const dc_parser_vtable_t shearwater_predator_parser_vtable = {
sizeof(shearwater_predator_parser_t),
DC_FAMILY_SHEARWATER_PREDATOR,
- shearwater_predator_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -177,7 +180,6 @@ static const dc_parser_vtable_t shearwater_predator_parser_vtable = {
static const dc_parser_vtable_t shearwater_petrel_parser_vtable = {
sizeof(shearwater_predator_parser_t),
DC_FAMILY_SHEARWATER_PETREL,
- shearwater_predator_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -188,6 +190,12 @@ static const dc_parser_vtable_t shearwater_petrel_parser_vtable = {
};
+static unsigned int
+shearwater_predator_is_ccr (unsigned int divemode)
+{
+ return divemode == M_CC || divemode == M_CC2 || divemode == M_SC;
+}
+
static unsigned int
shearwater_predator_find_gasmix (shearwater_predator_parser_t *parser, unsigned int o2, unsigned int he, unsigned int dil)
{
@@ -203,7 +211,7 @@ shearwater_predator_find_gasmix (shearwater_predator_parser_t *parser, unsigned
static dc_status_t
-shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int serial, unsigned int petrel)
+shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int petrel, unsigned int serial)
{
shearwater_predator_parser_t *parser = NULL;
const dc_parser_vtable_t *vtable = NULL;
@@ -221,7 +229,7 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig
}
// Allocate memory.
- parser = (shearwater_predator_parser_t *) dc_parser_allocate (context, vtable);
+ parser = (shearwater_predator_parser_t *) dc_parser_allocate (context, vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -249,6 +257,8 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig
parser->gasmix[i].oxygen = 0;
parser->gasmix[i].helium = 0;
parser->gasmix[i].diluent = 0;
+ parser->gasmix[i].enabled = 0;
+ parser->gasmix[i].active = 0;
}
parser->ntanks = 0;
for (unsigned int i = 0; i < NTANKS; ++i) {
@@ -260,10 +270,12 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig
parser->tank[i].pressure_reserve = 0;
parser->tank[i].serial = 0;
memset (parser->tank[i].name, 0, sizeof (parser->tank[i].name));
+ parser->tank[i].usage = DC_USAGE_NONE;
parser->tank[i].battery = 0;
parser->tankidx[i] = i;
}
parser->aimode = AI_OFF;
+ parser->hpccr = 0;
parser->calibrated = 0;
for (unsigned int i = 0; i < 3; ++i) {
parser->calibration[i] = 0.0;
@@ -281,65 +293,16 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig
dc_status_t
-shearwater_predator_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int serial)
+shearwater_predator_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial)
{
- return shearwater_common_parser_create (out, context, model, serial, 0);
+ return shearwater_common_parser_create (out, context, data, size, model, 0, serial);
}
dc_status_t
-shearwater_petrel_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int serial)
+shearwater_petrel_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial)
{
- return shearwater_common_parser_create (out, context, model, serial, 1);
-}
-
-
-static dc_status_t
-shearwater_predator_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- shearwater_predator_parser_t *parser = (shearwater_predator_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->pnf = 0;
- parser->logversion = 0;
- parser->headersize = 0;
- parser->footersize = 0;
- for (unsigned int i = 0; i < NRECORDS; ++i) {
- parser->opening[i] = UNDEFINED;
- parser->closing[i] = UNDEFINED;
- }
- parser->final = UNDEFINED;
- parser->ngasmixes = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->gasmix[i].oxygen = 0;
- parser->gasmix[i].helium = 0;
- parser->gasmix[i].diluent = 0;
- }
- parser->ntanks = 0;
- for (unsigned int i = 0; i < NTANKS; ++i) {
- parser->tank[i].enabled = 0;
- parser->tank[i].active = 0;
- parser->tank[i].beginpressure = 0;
- parser->tank[i].endpressure = 0;
- parser->tank[i].pressure_max = 0;
- parser->tank[i].pressure_reserve = 0;
- parser->tank[i].serial = 0;
- memset (parser->tank[i].name, 0, sizeof (parser->tank[i].name));
- parser->tankidx[i] = i;
- }
- parser->aimode = AI_OFF;
- parser->calibrated = 0;
- for (unsigned int i = 0; i < 3; ++i) {
- parser->calibration[i] = 0.0;
- }
- parser->units = METRIC;
- parser->density = DEF_DENSITY_SALT;
- parser->atmospheric = DEF_ATMOSPHERIC / (BAR / 1000);
-
- DC_ASSIGN_FIELD(parser->cache, DIVEMODE, DC_DIVEMODE_OC);
-
- return DC_STATUS_SUCCESS;
+ return shearwater_common_parser_create (out, context, data, size, model, 1, serial);
}
@@ -522,11 +485,13 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
shearwater_predator_tank_t tank[NTANKS] = {0};
unsigned int o2_previous = UNDEFINED, he_previous = UNDEFINED, dil_previous = UNDEFINED;
unsigned int aimode = AI_OFF;
+ unsigned int hpccr = 0;
if (!pnf) {
for (unsigned int i = 0; i < NFIXED; ++i) {
gasmix[i].oxygen = data[20 + i];
gasmix[i].helium = data[30 + i];
gasmix[i].diluent = i >= 5;
+ gasmix[i].enabled = 1;
}
}
@@ -575,6 +540,8 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
ngasmixes = idx + 1;
}
+ gasmix[idx].active = 1;
+
o2_previous = o2;
he_previous = he;
dil_previous = ccr;
@@ -636,8 +603,8 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
tank[id].enabled = 1;
tank[id].beginpressure = pressure;
tank[id].endpressure = pressure;
- tank[id].name[0] = i == 0 ? 'D': 'O';
- tank[id].name[1] = 0;
+ tank[id].usage = i == 0 ? DC_USAGE_DILUENT : DC_USAGE_OXYGEN;
+ hpccr = 1;
}
tank[id].endpressure = pressure;
}
@@ -681,9 +648,24 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
if (aimode == AI_HPCCR) {
for (unsigned int i = 0; i < 2; ++i) {
tank[4 + i].enabled = 1;
- tank[4 + i].name[0] = i == 0 ? 'D': 'O';
- tank[4 + i].name[1] = 0;
+ tank[4 + i].usage = i == 0 ? DC_USAGE_DILUENT : DC_USAGE_OXYGEN;
}
+ hpccr = 1;
+ }
+ }
+ }
+
+ // Gas mix on/off state.
+ unsigned int state = array_uint16_be (data + offset + 17);
+ for (unsigned int i = 0; i < NFIXED; ++i) {
+ gasmix[i].enabled = (state & (1 << i)) != 0;
+ }
+
+ unsigned int gtrmode = data[offset + 29];
+ if (popcount(gtrmode) >= 2) {
+ for (unsigned int i = 0; i < 4; ++i) {
+ if (gtrmode & (1 << i)) {
+ tank[i].usage = DC_USAGE_SIDEMOUNT;
}
}
}
@@ -809,6 +791,10 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
for (unsigned int i = 0; i < ngasmixes; ++i) {
if (gasmix[i].oxygen == 0 && gasmix[i].helium == 0)
continue;
+ if (!gasmix[i].enabled && !gasmix[i].active)
+ continue;
+ if (gasmix[i].diluent && !shearwater_predator_is_ccr (divemode))
+ continue;
parser->gasmix[parser->ngasmixes] = gasmix[i];
parser->ngasmixes++;
}
@@ -824,6 +810,8 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
}
}
parser->aimode = aimode;
+ parser->hpccr = hpccr;
+ parser->divemode = divemode;
parser->units = data[parser->opening[0] + 8];
parser->atmospheric = array_uint16_be (data + parser->opening[1] + (parser->pnf ? 16 : 47));
parser->density = array_uint16_be (data + parser->opening[3] + (parser->pnf ? 3 : 83));
@@ -907,6 +895,7 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = parser->gasmix[flags].diluent ? DC_USAGE_DILUENT : DC_USAGE_NONE;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -921,6 +910,21 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
tank->beginpressure = parser->tank[flags].beginpressure * 2 * PSI / BAR;
tank->endpressure = parser->tank[flags].endpressure * 2 * PSI / BAR;
tank->gasmix = DC_GASMIX_UNKNOWN;
+ if (shearwater_predator_is_ccr (parser->divemode) && !parser->hpccr) {
+ switch (parser->tank[flags].name[0]) {
+ case 'O':
+ tank->usage = DC_USAGE_OXYGEN;
+ break;
+ case 'D':
+ tank->usage = DC_USAGE_DILUENT;
+ break;
+ default:
+ tank->usage = DC_USAGE_NONE;
+ break;
+ }
+ } else {
+ tank->usage = parser->tank[flags].usage;
+ }
break;
case DC_FIELD_SALINITY:
if (parser->density == 1000)
@@ -984,14 +988,9 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
// Sample interval.
unsigned int time = 0;
- unsigned int interval = 10;
+ unsigned int interval = 10000;
if (parser->pnf && parser->logversion >= 9 && parser->opening[5] != UNDEFINED) {
interval = array_uint16_be (data + parser->opening[5] + 23);
- if (interval % 1000 != 0) {
- ERROR (abstract->context, "Unsupported sample interval (%u ms).", interval);
- return DC_STATUS_DATAFORMAT;
- }
- interval /= 1000;
}
unsigned int pnf = parser->pnf;
@@ -1017,7 +1016,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
// Time (seconds).
time += interval;
sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m or ft).
unsigned int depth = array_uint16_be (data + pnf + offset);
@@ -1025,7 +1024,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
sample.depth = depth * FEET / 10.0;
else
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (°C or °F).
int temperature = (signed char) data[offset + pnf + 13];
@@ -1040,7 +1039,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
else
sample.temperature = temperature;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// Status flags.
unsigned int status = data[offset + pnf + 11];
@@ -1049,19 +1048,21 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
if (ccr) {
// PPO2
if ((status & PPO2_EXTERNAL) == 0) {
- if (!parser->calibrated) {
- sample.ppo2 = data[offset + pnf + 6] / 100.0;
- if (callback) callback (DC_SAMPLE_PPO2, sample, userdata);
- } else {
- sample.ppo2 = data[offset + pnf + 12] * parser->calibration[0];
- if (callback && (parser->calibrated & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata);
+ sample.ppo2.sensor = DC_SENSOR_NONE;
+ sample.ppo2.value = data[offset + pnf + 6] / 100.0;
+ if (callback) callback (DC_SAMPLE_PPO2, &sample, userdata);
- sample.ppo2 = data[offset + pnf + 14] * parser->calibration[1];
- if (callback && (parser->calibrated & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata);
+ sample.ppo2.sensor = 0;
+ sample.ppo2.value = data[offset + pnf + 12] * parser->calibration[0];
+ if (callback && (parser->calibrated & 0x01)) callback (DC_SAMPLE_PPO2, &sample, userdata);
- sample.ppo2 = data[offset + pnf + 15] * parser->calibration[2];
- if (callback && (parser->calibrated & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata);
- }
+ sample.ppo2.sensor = 1;
+ sample.ppo2.value = data[offset + pnf + 14] * parser->calibration[1];
+ if (callback && (parser->calibrated & 0x02)) callback (DC_SAMPLE_PPO2, &sample, userdata);
+
+ sample.ppo2.sensor = 2;
+ sample.ppo2.value = data[offset + pnf + 15] * parser->calibration[2];
+ if (callback && (parser->calibrated & 0x04)) callback (DC_SAMPLE_PPO2, &sample, userdata);
}
// Setpoint
@@ -1075,13 +1076,13 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
sample.setpoint = data[17] / 100.0;
}
}
- if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_SETPOINT, &sample, userdata);
}
// CNS
if (parser->petrel) {
sample.cns = data[offset + pnf + 22] / 100.0;
- if (callback) callback (DC_SAMPLE_CNS, sample, userdata);
+ if (callback) callback (DC_SAMPLE_CNS, &sample, userdata);
}
// Gaschange.
@@ -1096,7 +1097,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
}
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
o2_previous = o2;
he_previous = he;
dil_previous = ccr;
@@ -1115,7 +1116,8 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
sample.deco.depth = 0.0;
}
sample.deco.time = data[offset + pnf + 9] * 60;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = array_uint16_be (data + offset + pnf + 4) * 60;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
// for logversion 7 and newer (introduced for Perdix AI)
// detect tank pressure
@@ -1137,7 +1139,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
pressure &= 0x0FFF;
sample.pressure.tank = parser->tankidx[id];
sample.pressure.value = pressure * 2 * PSI / BAR;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
}
@@ -1150,7 +1152,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
// 0xFB Tank size or max pressure haven’t been set up
if (data[offset + pnf + 21] < 0xF0) {
sample.rbt = data[offset + pnf + 21];
- if (callback) callback (DC_SAMPLE_RBT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_RBT, &sample, userdata);
}
}
} else if (type == LOG_RECORD_DIVE_SAMPLE_EXT) {
@@ -1163,7 +1165,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
pressure &= 0x0FFF;
sample.pressure.tank = parser->tankidx[id];
sample.pressure.value = pressure * 2 * PSI / BAR;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
}
}
@@ -1175,7 +1177,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
if (pressure) {
sample.pressure.tank = parser->tankidx[id];
sample.pressure.value = pressure * 2 * PSI / BAR;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
}
}
@@ -1194,17 +1196,17 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
// Time (seconds).
time += interval;
sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (absolute pressure in millibar)
unsigned int depth = array_uint16_be (data + idx + 1);
sample.depth = (signed int)(depth - parser->atmospheric) * (BAR / 1000.0) / (parser->density * GRAVITY);
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (1/10 °C).
int temperature = (signed short) array_uint16_be (data + idx + 3);
sample.temperature = temperature / 10.0;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
} else if (type == LOG_RECORD_INFO_EVENT) {
unsigned int event = data[offset + 1];
@@ -1216,7 +1218,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
// Compass heading
if (w1 != 0xFFFFFFFF) {
sample.bearing = w1;
- if (callback) callback (DC_SAMPLE_BEARING, sample, userdata);
+ if (callback) callback (DC_SAMPLE_BEARING, &sample, userdata);
}
// Tag
@@ -1224,7 +1226,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = w2;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
}
diff --git a/src/sporasub_sp2.h b/src/sporasub_sp2.h
index de2ca42a..6b21c458 100644
--- a/src/sporasub_sp2.h
+++ b/src/sporasub_sp2.h
@@ -35,7 +35,7 @@ dc_status_t
sporasub_sp2_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-sporasub_sp2_parser_create (dc_parser_t **parser, dc_context_t *context);
+sporasub_sp2_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/sporasub_sp2_parser.c b/src/sporasub_sp2_parser.c
index 5ac44b8a..37f02115 100644
--- a/src/sporasub_sp2_parser.c
+++ b/src/sporasub_sp2_parser.c
@@ -37,7 +37,6 @@ struct sporasub_sp2_parser_t {
dc_parser_t base;
};
-static dc_status_t sporasub_sp2_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t sporasub_sp2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t sporasub_sp2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t sporasub_sp2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -45,7 +44,6 @@ static dc_status_t sporasub_sp2_parser_samples_foreach (dc_parser_t *abstract, d
static const dc_parser_vtable_t sporasub_sp2_parser_vtable = {
sizeof(sporasub_sp2_parser_t),
DC_FAMILY_SPORASUB_SP2,
- sporasub_sp2_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -57,7 +55,7 @@ static const dc_parser_vtable_t sporasub_sp2_parser_vtable = {
dc_status_t
-sporasub_sp2_parser_create (dc_parser_t **out, dc_context_t *context)
+sporasub_sp2_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
sporasub_sp2_parser_t *parser = NULL;
@@ -65,7 +63,7 @@ sporasub_sp2_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (sporasub_sp2_parser_t *) dc_parser_allocate (context, &sporasub_sp2_parser_vtable);
+ parser = (sporasub_sp2_parser_t *) dc_parser_allocate (context, &sporasub_sp2_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -77,13 +75,6 @@ sporasub_sp2_parser_create (dc_parser_t **out, dc_context_t *context)
}
-static dc_status_t
-sporasub_sp2_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
sporasub_sp2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -184,21 +175,21 @@ sporasub_sp2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
// Time (seconds)
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/100 m)
sample.depth = depth / 100.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (1/10 °C)
sample.temperature = temperature / 10.0 - 20.0;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// Heartrate
if (heartrate) {
sample.heartbeat = heartrate;
- if (callback) callback (DC_SAMPLE_HEARTBEAT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_HEARTBEAT, &sample, userdata);
}
offset += SZ_SAMPLE;
diff --git a/src/suunto_d9.h b/src/suunto_d9.h
index a522fb87..a7bf60d0 100644
--- a/src/suunto_d9.h
+++ b/src/suunto_d9.h
@@ -36,7 +36,7 @@ dc_status_t
suunto_d9_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream, unsigned int model);
dc_status_t
-suunto_d9_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model, unsigned int serial);
+suunto_d9_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial);
#ifdef __cplusplus
}
diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c
index 9eafeb15..55d45ef9 100644
--- a/src/suunto_d9_parser.c
+++ b/src/suunto_d9_parser.c
@@ -94,7 +94,6 @@ typedef struct sample_info_t {
unsigned int divisor;
} sample_info_t;
-static dc_status_t suunto_d9_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -102,7 +101,6 @@ static dc_status_t suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_s
static const dc_parser_vtable_t suunto_d9_parser_vtable = {
sizeof(suunto_d9_parser_t),
DC_FAMILY_SUUNTO_D9,
- suunto_d9_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -253,7 +251,7 @@ suunto_d9_parser_cache (suunto_d9_parser_t *parser)
}
dc_status_t
-suunto_d9_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int serial)
+suunto_d9_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model, unsigned int serial)
{
suunto_d9_parser_t *parser = NULL;
@@ -261,7 +259,7 @@ suunto_d9_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (suunto_d9_parser_t *) dc_parser_allocate (context, &suunto_d9_parser_vtable);
+ parser = (suunto_d9_parser_t *) dc_parser_allocate (context, &suunto_d9_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -288,28 +286,6 @@ suunto_d9_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int
}
-static dc_status_t
-suunto_d9_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- suunto_d9_parser_t *parser = (suunto_d9_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->id = 0;
- parser->mode = AIR;
- parser->ngasmixes = 0;
- parser->nccr = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->oxygen[i] = 0;
- parser->helium[i] = 0;
- }
- parser->gasmix = 0;
- parser->config = 0;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -395,6 +371,7 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->helium[flags] / 100.0;
gasmix->oxygen = parser->oxygen[flags] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -539,8 +516,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
dc_sample_value_t sample = {0};
// Time (seconds).
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Sample data.
for (unsigned int i = 0; i < nparams; ++i) {
@@ -555,19 +532,19 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
case 0x64: // Depth
value = array_uint16_le (data + offset);
sample.depth = value / (double) info[i].divisor;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
break;
case 0x68: // Pressure
value = array_uint16_le (data + offset);
if (value != 0xFFFF) {
sample.pressure.tank = 0;
sample.pressure.value = value / (double) info[i].divisor;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
break;
case 0x74: // Temperature
sample.temperature = (signed char) data[offset] / (double) info[i].divisor;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
break;
default: // Unknown sample type
ERROR (abstract->context, "Unknown sample type 0x%02x.", info[i].type);
@@ -585,7 +562,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
return DC_STATUS_DATAFORMAT;
}
sample.gasmix = parser->gasmix;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
}
// Events
@@ -625,7 +602,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
seconds = data[offset + 1];
sample.event.type = SAMPLE_EVENT_SURFACE;
sample.event.time = seconds;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
offset += 2;
break;
case 0x03: // Event
@@ -731,7 +708,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
sample.event.flags = SAMPLE_FLAGS_BEGIN;
sample.event.time = seconds;
if (sample.event.type != SAMPLE_EVENT_NONE) {
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
offset += 2;
break;
@@ -751,7 +728,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
sample.event.value = heading / 2;
}
sample.event.time = seconds;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
offset += 4;
break;
case 0x05: // Gas Change
@@ -767,7 +744,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
return DC_STATUS_DATAFORMAT;
}
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
offset += 2;
break;
case 0x06: // Gas Change
@@ -801,10 +778,10 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
return DC_STATUS_DATAFORMAT;
}
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
if (type & 0x80) {
sample.setpoint = ppo2 / 10.0;
- if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_SETPOINT, &sample, userdata);
}
offset += length;
break;
@@ -829,7 +806,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
}
sample.deco.time = 0;
sample.deco.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
time += interval_sample;
nsamples++;
diff --git a/src/suunto_eon.h b/src/suunto_eon.h
index 5e99a695..9c605ebb 100644
--- a/src/suunto_eon.h
+++ b/src/suunto_eon.h
@@ -36,7 +36,7 @@ dc_status_t
suunto_eon_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-suunto_eon_parser_create (dc_parser_t **parser, dc_context_t *context, int spyder);
+suunto_eon_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, int spyder);
#ifdef __cplusplus
}
diff --git a/src/suunto_eon_parser.c b/src/suunto_eon_parser.c
index 8e80aca4..94370a33 100644
--- a/src/suunto_eon_parser.c
+++ b/src/suunto_eon_parser.c
@@ -43,7 +43,6 @@ struct suunto_eon_parser_t {
unsigned int nitrox;
};
-static dc_status_t suunto_eon_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t suunto_eon_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t suunto_eon_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t suunto_eon_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -51,7 +50,6 @@ static dc_status_t suunto_eon_parser_samples_foreach (dc_parser_t *abstract, dc_
static const dc_parser_vtable_t suunto_eon_parser_vtable = {
sizeof(suunto_eon_parser_t),
DC_FAMILY_SUUNTO_EON,
- suunto_eon_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -112,7 +110,7 @@ suunto_eon_parser_cache (suunto_eon_parser_t *parser)
}
dc_status_t
-suunto_eon_parser_create (dc_parser_t **out, dc_context_t *context, int spyder)
+suunto_eon_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, int spyder)
{
suunto_eon_parser_t *parser = NULL;
@@ -120,7 +118,7 @@ suunto_eon_parser_create (dc_parser_t **out, dc_context_t *context, int spyder)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (suunto_eon_parser_t *) dc_parser_allocate (context, &suunto_eon_parser_vtable);
+ parser = (suunto_eon_parser_t *) dc_parser_allocate (context, &suunto_eon_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -140,22 +138,6 @@ suunto_eon_parser_create (dc_parser_t **out, dc_context_t *context, int spyder)
}
-static dc_status_t
-suunto_eon_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- suunto_eon_parser_t *parser = (suunto_eon_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->divetime = 0;
- parser->maxdepth = 0;
- parser->marker = 0;
- parser->nitrox = 0;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
suunto_eon_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -225,6 +207,7 @@ suunto_eon_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -242,6 +225,7 @@ suunto_eon_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
tank->gasmix = 0;
tank->beginpressure = beginpressure;
tank->endpressure = endpressure;
+ tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
if (parser->spyder)
@@ -273,15 +257,15 @@ suunto_eon_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
// Time
sample.time = 0;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (0 ft)
sample.depth = 0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Initial gas mix.
sample.gasmix = 0;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
unsigned int depth = 0;
unsigned int time = 0;
@@ -294,8 +278,8 @@ suunto_eon_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
if (complete) {
// Time (seconds).
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
complete = 0;
}
@@ -305,7 +289,7 @@ suunto_eon_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
// Depth (ft).
sample.depth = depth * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
complete = 1;
} else {
@@ -333,7 +317,7 @@ suunto_eon_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
}
if (sample.event.type != SAMPLE_EVENT_NONE) {
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
}
}
@@ -341,13 +325,13 @@ suunto_eon_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c
// Time
if (complete) {
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
}
// Depth (0 ft)
sample.depth = 0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
return DC_STATUS_SUCCESS;
}
diff --git a/src/suunto_eonsteel.h b/src/suunto_eonsteel.h
index 28001070..cb18296e 100644
--- a/src/suunto_eonsteel.h
+++ b/src/suunto_eonsteel.h
@@ -35,7 +35,7 @@ dc_status_t
suunto_eonsteel_device_open(dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream, unsigned int model);
dc_status_t
-suunto_eonsteel_parser_create(dc_parser_t **parser, dc_context_t *context, unsigned int model);
+suunto_eonsteel_parser_create(dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/suunto_eonsteel_parser.c b/src/suunto_eonsteel_parser.c
index 29472219..0147f515 100644
--- a/src/suunto_eonsteel_parser.c
+++ b/src/suunto_eonsteel_parser.c
@@ -445,8 +445,8 @@ static void sample_time(struct sample_data *info, unsigned short time_delta)
dc_sample_value_t sample = {0};
info->time += time_delta;
- sample.time = info->time / 1000;
- if (info->callback) info->callback(DC_SAMPLE_TIME, sample, info->userdata);
+ sample.time = info->time;
+ if (info->callback) info->callback(DC_SAMPLE_TIME, &sample, info->userdata);
}
static void sample_depth(struct sample_data *info, unsigned short depth)
@@ -457,7 +457,7 @@ static void sample_depth(struct sample_data *info, unsigned short depth)
return;
sample.depth = depth / 100.0;
- if (info->callback) info->callback(DC_SAMPLE_DEPTH, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_DEPTH, &sample, info->userdata);
}
static void sample_temp(struct sample_data *info, short temp)
@@ -468,7 +468,7 @@ static void sample_temp(struct sample_data *info, short temp)
return;
sample.temperature = temp / 10.0;
- if (info->callback) info->callback(DC_SAMPLE_TEMPERATURE, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_TEMPERATURE, &sample, info->userdata);
}
static void sample_ndl(struct sample_data *info, short ndl)
@@ -480,7 +480,8 @@ static void sample_ndl(struct sample_data *info, short ndl)
sample.deco.type = DC_DECO_NDL;
sample.deco.time = ndl;
- if (info->callback) info->callback(DC_SAMPLE_DECO, sample, info->userdata);
+ sample.deco.tts = 0;
+ if (info->callback) info->callback(DC_SAMPLE_DECO, &sample, info->userdata);
}
static void sample_tts(struct sample_data *info, unsigned short tts)
@@ -488,7 +489,7 @@ static void sample_tts(struct sample_data *info, unsigned short tts)
if (tts != 0xffff) {
dc_sample_value_t sample = {0};
sample.time = tts;
- if (info->callback) info->callback(DC_SAMPLE_TTS, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_TTS, &sample, info->userdata);
}
}
@@ -504,7 +505,8 @@ static void sample_ceiling(struct sample_data *info, unsigned short ceiling)
sample.deco.type = DC_DECO_DECOSTOP;
sample.deco.time = ceiling ? 60 : 0;
sample.deco.depth = ceiling / 100.0;
- if (info->callback) info->callback(DC_SAMPLE_DECO, sample, info->userdata);
+ sample.deco.tts = 0; // Fixme? DC_SAMPLE_TTS?
+ if (info->callback) info->callback(DC_SAMPLE_DECO, &sample, info->userdata);
}
}
@@ -517,7 +519,7 @@ static void sample_heading(struct sample_data *info, unsigned short heading)
sample.event.type = SAMPLE_EVENT_HEADING;
sample.event.value = heading;
- if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_EVENT, &sample, info->userdata);
}
static void sample_abspressure(struct sample_data *info, unsigned short pressure)
@@ -532,7 +534,7 @@ static void sample_gastime(struct sample_data *info, short gastime)
return;
sample.rbt = gastime / 60;
- if (info->callback) info->callback (DC_SAMPLE_RBT, sample, info->userdata);
+ if (info->callback) info->callback (DC_SAMPLE_RBT, &sample, info->userdata);
}
/*
@@ -560,7 +562,7 @@ static void sample_pressure(struct sample_data *info, unsigned short pressure)
sample.pressure.tank = info->gasnr-1;
sample.pressure.value = pressure / 100.0;
- if (info->callback) info->callback(DC_SAMPLE_PRESSURE, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_PRESSURE, &sample, info->userdata);
}
static void sample_bookmark_event(struct sample_data *info, unsigned short idx)
@@ -570,7 +572,7 @@ static void sample_bookmark_event(struct sample_data *info, unsigned short idx)
sample.event.type = SAMPLE_EVENT_BOOKMARK;
sample.event.value = idx;
- if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_EVENT, &sample, info->userdata);
}
static void sample_gas_switch_event(struct sample_data *info, unsigned short idx)
@@ -582,7 +584,7 @@ static void sample_gas_switch_event(struct sample_data *info, unsigned short idx
return;
sample.gasmix = idx - 1;
- if (info->callback) info->callback(DC_SAMPLE_GASMIX, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_GASMIX, &sample, info->userdata);
}
static const char *mixname(suunto_eonsteel_parser_t *eon, int idx)
@@ -622,7 +624,7 @@ static void sample_insert_gas_event(struct sample_data *info, unsigned short idx
sample.event.name = strdup(event);
sample.event.flags = SAMPLE_FLAGS_SEVERITY_INFO;
- info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
+ info->callback(DC_SAMPLE_EVENT, &sample, info->userdata);
}
static void sample_remove_gas_event(struct sample_data *info, unsigned short idx)
@@ -639,7 +641,7 @@ static void sample_remove_gas_event(struct sample_data *info, unsigned short idx
sample.event.name = strdup(event);
sample.event.flags = SAMPLE_FLAGS_SEVERITY_INFO;
- info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
+ info->callback(DC_SAMPLE_EVENT, &sample, info->userdata);
}
/*
@@ -730,7 +732,7 @@ static void sample_event_state_value(const struct type_desc *desc, struct sample
sample.event.flags = value ? SAMPLE_FLAGS_BEGIN : SAMPLE_FLAGS_END;
sample.event.flags |= 1 << SAMPLE_FLAGS_SEVERITY_SHIFT;
- if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_EVENT, &sample, info->userdata);
}
static void sample_event_notify_type(const struct type_desc *desc, struct sample_data *info, unsigned char type)
@@ -753,7 +755,7 @@ static void sample_event_notify_value(const struct type_desc *desc, struct sampl
sample.event.flags = value ? SAMPLE_FLAGS_BEGIN : SAMPLE_FLAGS_END;
sample.event.flags |= 2 << SAMPLE_FLAGS_SEVERITY_SHIFT;
- if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_EVENT, &sample, info->userdata);
}
@@ -777,7 +779,7 @@ static void sample_event_warning_value(const struct type_desc *desc, struct samp
sample.event.flags = value ? SAMPLE_FLAGS_BEGIN : SAMPLE_FLAGS_END;
sample.event.flags |= 3 << SAMPLE_FLAGS_SEVERITY_SHIFT;
- if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_EVENT, &sample, info->userdata);
}
static void sample_event_alarm_type(const struct type_desc *desc, struct sample_data *info, unsigned char type)
@@ -801,7 +803,7 @@ static void sample_event_alarm_value(const struct type_desc *desc, struct sample
sample.event.flags = value ? SAMPLE_FLAGS_BEGIN : SAMPLE_FLAGS_END;
sample.event.flags |= 4 << SAMPLE_FLAGS_SEVERITY_SHIFT;
- if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_EVENT, &sample, info->userdata);
}
// enum:0=Low,1=High,2=Custom
@@ -827,7 +829,7 @@ static void sample_setpoint_type(const struct type_desc *desc, struct sample_dat
return;
}
- if (info->callback) info->callback(DC_SAMPLE_SETPOINT, sample, info->userdata);
+ if (info->callback) info->callback(DC_SAMPLE_SETPOINT, &sample, info->userdata);
free(type);
}
@@ -1048,6 +1050,7 @@ suunto_eonsteel_parser_get_field(dc_parser_t *parser, dc_field_type_t type, unsi
if (fabs(tank->volume - rint(tank->volume)) > 0.001)
tank->type += DC_TANKINFO_IMPERIAL - DC_TANKINFO_METRIC;
}
+ tank->usage = eon->cache.tankusage[flags];
}
return dc_field_get(&eon->cache, type, flags, value);
@@ -1106,6 +1109,7 @@ static dc_status_t add_gas_type(suunto_eonsteel_parser_t *eon, const struct type
{
int idx = eon->cache.GASMIX_COUNT;
dc_tankinfo_t tankinfo = DC_TANKINFO_METRIC;
+ dc_usage_t usage = DC_USAGE_NONE;
char *name;
if (idx >= MAXGASES)
@@ -1116,15 +1120,17 @@ static dc_status_t add_gas_type(suunto_eonsteel_parser_t *eon, const struct type
if (!name)
DEBUG(eon->base.context, "Unable to look up gas type %u in %s", type, desc->format);
else if (!strcasecmp(name, "Diluent"))
- tankinfo |= DC_TANKINFO_CC_DILUENT;
+ usage = DC_USAGE_DILUENT;
else if (!strcasecmp(name, "Oxygen"))
- tankinfo |= DC_TANKINFO_CC_O2;
+ usage = DC_USAGE_OXYGEN;
else if (!strcasecmp(name, "None"))
tankinfo = DC_TANKVOLUME_NONE;
else if (strcasecmp(name, "Primary"))
DEBUG(eon->base.context, "Unknown gas type %u (%s)", type, name);
eon->cache.tankinfo[idx] = tankinfo;
+ eon->cache.tankusage[idx] = usage;
+ eon->cache.GASMIX[idx].usage = usage;
eon->cache.initialized |= 1 << DC_FIELD_GASMIX_COUNT;
eon->cache.initialized |= 1 << DC_FIELD_TANK_COUNT;
@@ -1488,18 +1494,6 @@ static void show_all_descriptors(suunto_eonsteel_parser_t *eon)
show_descriptor(eon, i, eon->type_desc+i);
}
-static dc_status_t
-suunto_eonsteel_parser_set_data(dc_parser_t *parser, const unsigned char *data, unsigned int size)
-{
- suunto_eonsteel_parser_t *eon = (suunto_eonsteel_parser_t *) parser;
-
- desc_free(eon->type_desc, MAXTYPE);
- memset(eon->type_desc, 0, sizeof(eon->type_desc));
- initialize_field_caches(eon);
- show_all_descriptors(eon);
- return DC_STATUS_SUCCESS;
-}
-
static dc_status_t
suunto_eonsteel_parser_destroy(dc_parser_t *parser)
{
@@ -1513,7 +1507,6 @@ suunto_eonsteel_parser_destroy(dc_parser_t *parser)
static const dc_parser_vtable_t suunto_eonsteel_parser_vtable = {
sizeof(suunto_eonsteel_parser_t),
DC_FAMILY_SUUNTO_EONSTEEL,
- suunto_eonsteel_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -1524,14 +1517,14 @@ static const dc_parser_vtable_t suunto_eonsteel_parser_vtable = {
};
dc_status_t
-suunto_eonsteel_parser_create(dc_parser_t **out, dc_context_t *context, unsigned int model)
+suunto_eonsteel_parser_create(dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
suunto_eonsteel_parser_t *parser = NULL;
if (out == NULL)
return DC_STATUS_INVALIDARGS;
- parser = (suunto_eonsteel_parser_t *) dc_parser_allocate (context, &suunto_eonsteel_parser_vtable);
+ parser = (suunto_eonsteel_parser_t *) dc_parser_allocate (context, &suunto_eonsteel_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -1540,6 +1533,9 @@ suunto_eonsteel_parser_create(dc_parser_t **out, dc_context_t *context, unsigned
memset(&parser->type_desc, 0, sizeof(parser->type_desc));
memset(&parser->cache, 0, sizeof(parser->cache));
+ initialize_field_caches(parser);
+ show_all_descriptors(parser);
+
*out = (dc_parser_t *) parser;
return DC_STATUS_SUCCESS;
diff --git a/src/suunto_solution.h b/src/suunto_solution.h
index 9d9e632d..0556ad71 100644
--- a/src/suunto_solution.h
+++ b/src/suunto_solution.h
@@ -35,7 +35,7 @@ dc_status_t
suunto_solution_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-suunto_solution_parser_create (dc_parser_t **parser, dc_context_t *context);
+suunto_solution_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/suunto_solution_parser.c b/src/suunto_solution_parser.c
index 59648d53..69c6977b 100644
--- a/src/suunto_solution_parser.c
+++ b/src/suunto_solution_parser.c
@@ -39,14 +39,12 @@ struct suunto_solution_parser_t {
unsigned int maxdepth;
};
-static dc_status_t suunto_solution_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t suunto_solution_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t suunto_solution_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
static const dc_parser_vtable_t suunto_solution_parser_vtable = {
sizeof(suunto_solution_parser_t),
DC_FAMILY_SUUNTO_SOLUTION,
- suunto_solution_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -58,7 +56,7 @@ static const dc_parser_vtable_t suunto_solution_parser_vtable = {
dc_status_t
-suunto_solution_parser_create (dc_parser_t **out, dc_context_t *context)
+suunto_solution_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
suunto_solution_parser_t *parser = NULL;
@@ -66,7 +64,7 @@ suunto_solution_parser_create (dc_parser_t **out, dc_context_t *context)
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (suunto_solution_parser_t *) dc_parser_allocate (context, &suunto_solution_parser_vtable);
+ parser = (suunto_solution_parser_t *) dc_parser_allocate (context, &suunto_solution_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -83,20 +81,6 @@ suunto_solution_parser_create (dc_parser_t **out, dc_context_t *context)
}
-static dc_status_t
-suunto_solution_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- suunto_solution_parser_t *parser = (suunto_solution_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->divetime = 0;
- parser->maxdepth = 0;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
suunto_solution_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value)
{
@@ -151,6 +135,7 @@ suunto_solution_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
gasmix->oxygen = 0.21;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -183,8 +168,8 @@ suunto_solution_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
if (value < 0x7e || value > 0x82) {
// Time (minutes).
time += 3 * 60;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (ft).
depth += (signed char) value;
@@ -197,12 +182,12 @@ suunto_solution_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
depth += (signed char) data[offset++];
}
sample.depth = depth * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Gas change.
if (gasmix != gasmix_previous) {
sample.gasmix = gasmix;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
} else {
@@ -227,7 +212,7 @@ suunto_solution_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
}
if (sample.event.type != SAMPLE_EVENT_NONE) {
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
}
}
diff --git a/src/suunto_vyper.h b/src/suunto_vyper.h
index e6f88124..3babccf9 100644
--- a/src/suunto_vyper.h
+++ b/src/suunto_vyper.h
@@ -35,7 +35,7 @@ dc_status_t
suunto_vyper_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-suunto_vyper_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int serial);
+suunto_vyper_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int serial);
#ifdef __cplusplus
}
diff --git a/src/suunto_vyper_parser.c b/src/suunto_vyper_parser.c
index 20a52df1..3d4317a9 100644
--- a/src/suunto_vyper_parser.c
+++ b/src/suunto_vyper_parser.c
@@ -47,7 +47,6 @@ struct suunto_vyper_parser_t {
unsigned int oxygen[NGASMIXES];
};
-static dc_status_t suunto_vyper_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t suunto_vyper_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -55,7 +54,6 @@ static dc_status_t suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, d
static const dc_parser_vtable_t suunto_vyper_parser_vtable = {
sizeof(suunto_vyper_parser_t),
DC_FAMILY_SUUNTO_VYPER,
- suunto_vyper_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -165,7 +163,7 @@ suunto_vyper_parser_cache (suunto_vyper_parser_t *parser)
dc_status_t
-suunto_vyper_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int serial)
+suunto_vyper_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int serial)
{
suunto_vyper_parser_t *parser = NULL;
@@ -173,7 +171,7 @@ suunto_vyper_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (suunto_vyper_parser_t *) dc_parser_allocate (context, &suunto_vyper_parser_vtable);
+ parser = (suunto_vyper_parser_t *) dc_parser_allocate (context, &suunto_vyper_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -196,25 +194,6 @@ suunto_vyper_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
}
-static dc_status_t
-suunto_vyper_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- suunto_vyper_parser_t *parser = (suunto_vyper_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->divetime = 0;
- parser->maxdepth = 0;
- parser->marker = 0;
- parser->ngasmixes = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->oxygen[i] = 0;
- }
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
suunto_vyper_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -274,6 +253,7 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gas->usage = DC_USAGE_NONE;
gas->helium = 0.0;
gas->oxygen = parser->oxygen[flags] / 100.0;
gas->nitrogen = 1.0 - gas->oxygen - gas->helium;
@@ -294,6 +274,7 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
tank->gasmix = 0;
tank->beginpressure = beginpressure;
tank->endpressure = endpressure;
+ tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_SURFACE:
*((double *) value) = (signed char) data[8];
@@ -348,16 +329,16 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
// Time
sample.time = 0;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (0 ft)
sample.depth = 0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Initial gas mix
if (!gauge) {
sample.gasmix = 0;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
}
unsigned int depth = 0;
@@ -371,8 +352,8 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
if (complete) {
// Time (seconds).
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
complete = 0;
}
@@ -382,7 +363,7 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
// Depth (ft).
sample.depth = depth * FEET;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
complete = 1;
} else {
@@ -426,7 +407,7 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
}
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
sample.event.type = SAMPLE_EVENT_NONE;
break;
default: // Unknown
@@ -435,7 +416,7 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
}
if (sample.event.type != SAMPLE_EVENT_NONE) {
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
}
}
@@ -443,13 +424,13 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
// Time
if (complete) {
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
}
// Depth (0 ft)
sample.depth = 0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
return DC_STATUS_SUCCESS;
}
diff --git a/src/tecdiving_divecomputereu.h b/src/tecdiving_divecomputereu.h
index 714ae43c..8eafb4e8 100644
--- a/src/tecdiving_divecomputereu.h
+++ b/src/tecdiving_divecomputereu.h
@@ -35,7 +35,7 @@ dc_status_t
tecdiving_divecomputereu_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-tecdiving_divecomputereu_parser_create (dc_parser_t **parser, dc_context_t *context);
+tecdiving_divecomputereu_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/tecdiving_divecomputereu_parser.c b/src/tecdiving_divecomputereu_parser.c
index d060996d..4f3f5142 100644
--- a/src/tecdiving_divecomputereu_parser.c
+++ b/src/tecdiving_divecomputereu_parser.c
@@ -36,7 +36,6 @@ struct tecdiving_divecomputereu_parser_t {
dc_parser_t base;
};
-static dc_status_t tecdiving_divecomputereu_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t tecdiving_divecomputereu_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t tecdiving_divecomputereu_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t tecdiving_divecomputereu_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
@@ -44,7 +43,6 @@ static dc_status_t tecdiving_divecomputereu_parser_samples_foreach (dc_parser_t
static const dc_parser_vtable_t tecdiving_divecomputereu_parser_vtable = {
sizeof(tecdiving_divecomputereu_parser_t),
DC_FAMILY_TECDIVING_DIVECOMPUTEREU,
- tecdiving_divecomputereu_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -56,7 +54,7 @@ static const dc_parser_vtable_t tecdiving_divecomputereu_parser_vtable = {
dc_status_t
-tecdiving_divecomputereu_parser_create (dc_parser_t **out, dc_context_t *context)
+tecdiving_divecomputereu_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
tecdiving_divecomputereu_parser_t *parser = NULL;
@@ -64,7 +62,7 @@ tecdiving_divecomputereu_parser_create (dc_parser_t **out, dc_context_t *context
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (tecdiving_divecomputereu_parser_t *) dc_parser_allocate (context, &tecdiving_divecomputereu_parser_vtable);
+ parser = (tecdiving_divecomputereu_parser_t *) dc_parser_allocate (context, &tecdiving_divecomputereu_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -76,13 +74,6 @@ tecdiving_divecomputereu_parser_create (dc_parser_t **out, dc_context_t *context
}
-static dc_status_t
-tecdiving_divecomputereu_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
tecdiving_divecomputereu_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -159,28 +150,29 @@ tecdiving_divecomputereu_parser_samples_foreach (dc_parser_t *abstract, dc_sampl
// Time (seconds).
time += interval;
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (1/10 m).
unsigned int depth = array_uint16_be (data + offset + 2);
sample.depth = depth / 10.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Temperature (Celsius).
signed int temperature = (signed char) data[offset];
sample.temperature = temperature;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
// ppO2
unsigned int ppo2 = data[offset + 1];
- sample.ppo2 = ppo2 / 10.0;
- if (callback) callback (DC_SAMPLE_PPO2, sample, userdata);
+ sample.ppo2.sensor = DC_SENSOR_NONE;
+ sample.ppo2.value = ppo2 / 10.0;
+ if (callback) callback (DC_SAMPLE_PPO2, &sample, userdata);
// Setpoint
unsigned int setpoint = data[offset + 4];
sample.setpoint = setpoint / 10.0;
- if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_SETPOINT, &sample, userdata);
offset += 8;
}
diff --git a/src/usb.c b/src/usb.c
index 758c604b..d7074cb9 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -39,12 +39,23 @@
#include "common-private.h"
#include "context-private.h"
#include "iostream-private.h"
-#include "descriptor-private.h"
#include "iterator-private.h"
#include "platform.h"
+#include "array.h"
#define ISINSTANCE(device) dc_iostream_isinstance((device), &dc_usb_vtable)
+typedef struct dc_usb_params_t {
+ unsigned int interface;
+ unsigned char endpoint_in;
+ unsigned char endpoint_out;
+} dc_usb_params_t;
+
+typedef struct dc_usb_config_t {
+ dc_usb_desc_t desc;
+ dc_usb_params_t params;
+} dc_usb_config_t;
+
typedef struct dc_usb_session_t {
size_t refcount;
#ifdef HAVE_LIBUSB
@@ -120,6 +131,26 @@ static const dc_iostream_vtable_t dc_usb_vtable = {
dc_usb_close, /* close */
};
+static const dc_usb_config_t g_usb_config[] = {
+ // Atomic Aquatics Cobalt
+ {{0x0471, 0x0888}, {0, 0x82, 0x02}},
+};
+
+static const dc_usb_params_t *
+dc_usb_params_find (const dc_usb_desc_t *desc)
+{
+ if (desc == NULL)
+ return NULL;
+
+ for (size_t i = 0; i < C_ARRAY_SIZE(g_usb_config); ++i) {
+ if (g_usb_config[i].desc.vid == desc->vid &&
+ g_usb_config[i].desc.pid == desc->pid)
+ return &g_usb_config[i].params;
+ }
+
+ return NULL;
+}
+
static dc_status_t
syserror(int errcode)
{
@@ -305,11 +336,13 @@ dc_usb_iterator_next (dc_iterator_t *abstract, void *out)
}
dc_usb_desc_t usb = {dev.idVendor, dev.idProduct};
- dc_usb_params_t params = {0, 0, 0};
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USB, &usb, ¶ms)) {
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USB, &usb)) {
continue;
}
+ // Check for known USB parameters.
+ const dc_usb_params_t *params = dc_usb_params_find (&usb);
+
// Get the active configuration descriptor.
struct libusb_config_descriptor *config = NULL;
rc = libusb_get_active_config_descriptor (current, &config);
@@ -325,7 +358,8 @@ dc_usb_iterator_next (dc_iterator_t *abstract, void *out)
const struct libusb_interface *iface = &config->interface[i];
for (int j = 0; j < iface->num_altsetting; j++) {
const struct libusb_interface_descriptor *desc = &iface->altsetting[j];
- if (interface == NULL && desc->bInterfaceNumber == params.interface) {
+ if (interface == NULL &&
+ (params == NULL || params->interface == desc->bInterfaceNumber)) {
interface = desc;
}
}
@@ -349,12 +383,12 @@ dc_usb_iterator_next (dc_iterator_t *abstract, void *out)
}
if (ep_in == NULL && direction == LIBUSB_ENDPOINT_IN &&
- (params.endpoint_in == 0 || params.endpoint_in == desc->bEndpointAddress)) {
+ (params == NULL || params->endpoint_in == desc->bEndpointAddress)) {
ep_in = desc;
}
if (ep_out == NULL && direction == LIBUSB_ENDPOINT_OUT &&
- (params.endpoint_out == 0 || params.endpoint_out == desc->bEndpointAddress)) {
+ (params == NULL || params->endpoint_out == desc->bEndpointAddress)) {
ep_out = desc;
}
}
diff --git a/src/usb_storage.c b/src/usb_storage.c
index 8bad4922..ab33a03b 100644
--- a/src/usb_storage.c
+++ b/src/usb_storage.c
@@ -35,7 +35,6 @@
#include "context-private.h"
#include "iostream-private.h"
#include "iterator-private.h"
-#include "descriptor-private.h"
#include "timer.h"
// Fake "device" that just contains the directory name that
diff --git a/src/usbhid.c b/src/usbhid.c
index acd20ef7..b7818e04 100644
--- a/src/usbhid.c
+++ b/src/usbhid.c
@@ -57,7 +57,6 @@
#include "common-private.h"
#include "context-private.h"
#include "iostream-private.h"
-#include "descriptor-private.h"
#include "iterator-private.h"
#include "platform.h"
@@ -438,8 +437,8 @@ dc_usbhid_iterator_next (dc_iterator_t *abstract, void *out)
return syserror (rc);
}
- dc_usb_desc_t usb = {dev.idVendor, dev.idProduct};
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb, NULL)) {
+ dc_usbhid_desc_t usb = {dev.idVendor, dev.idProduct};
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb)) {
continue;
}
@@ -522,8 +521,8 @@ dc_usbhid_iterator_next (dc_iterator_t *abstract, void *out)
struct hid_device_info *current = iterator->current;
iterator->current = current->next;
- dc_usb_desc_t usb = {current->vendor_id, current->product_id};
- if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb, NULL)) {
+ dc_usbhid_desc_t usb = {current->vendor_id, current->product_id};
+ if (!dc_descriptor_filter (iterator->descriptor, DC_TRANSPORT_USBHID, &usb)) {
continue;
}
diff --git a/src/uwatec_memomouse.h b/src/uwatec_memomouse.h
index 49ecf9e7..e038cf98 100644
--- a/src/uwatec_memomouse.h
+++ b/src/uwatec_memomouse.h
@@ -35,7 +35,7 @@ dc_status_t
uwatec_memomouse_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-uwatec_memomouse_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int devtime, dc_ticks_t systime);
+uwatec_memomouse_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size);
#ifdef __cplusplus
}
diff --git a/src/uwatec_memomouse_parser.c b/src/uwatec_memomouse_parser.c
index 3c818fa6..0849a3c6 100644
--- a/src/uwatec_memomouse_parser.c
+++ b/src/uwatec_memomouse_parser.c
@@ -38,7 +38,6 @@ struct uwatec_memomouse_parser_t {
dc_ticks_t systime;
};
-static dc_status_t uwatec_memomouse_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t uwatec_memomouse_parser_set_clock (dc_parser_t *abstract, unsigned int devtime, dc_ticks_t systime);
static dc_status_t uwatec_memomouse_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
static dc_status_t uwatec_memomouse_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
@@ -47,7 +46,6 @@ static dc_status_t uwatec_memomouse_parser_samples_foreach (dc_parser_t *abstrac
static const dc_parser_vtable_t uwatec_memomouse_parser_vtable = {
sizeof(uwatec_memomouse_parser_t),
DC_FAMILY_UWATEC_MEMOMOUSE,
- uwatec_memomouse_parser_set_data, /* set_data */
uwatec_memomouse_parser_set_clock, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -59,7 +57,7 @@ static const dc_parser_vtable_t uwatec_memomouse_parser_vtable = {
dc_status_t
-uwatec_memomouse_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int devtime, dc_ticks_t systime)
+uwatec_memomouse_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size)
{
uwatec_memomouse_parser_t *parser = NULL;
@@ -67,15 +65,15 @@ uwatec_memomouse_parser_create (dc_parser_t **out, dc_context_t *context, unsign
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (uwatec_memomouse_parser_t *) dc_parser_allocate (context, &uwatec_memomouse_parser_vtable);
+ parser = (uwatec_memomouse_parser_t *) dc_parser_allocate (context, &uwatec_memomouse_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
}
// Set the default values.
- parser->devtime = devtime;
- parser->systime = systime;
+ parser->devtime = 0;
+ parser->systime = 0;
*out = (dc_parser_t*) parser;
@@ -83,13 +81,6 @@ uwatec_memomouse_parser_create (dc_parser_t **out, dc_context_t *context, unsign
}
-static dc_status_t
-uwatec_memomouse_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
uwatec_memomouse_parser_set_clock (dc_parser_t *abstract, unsigned int devtime, dc_ticks_t systime)
{
@@ -166,6 +157,7 @@ uwatec_memomouse_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
*((unsigned int *) value) = 1;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = 0.0;
if (size >= header + 18) {
if (is_oxygen)
@@ -197,6 +189,7 @@ uwatec_memomouse_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
}
tank->endpressure = 0.0;
tank->gasmix = 0;
+ tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
*((double *) value) = (signed char) data[15] / 4.0;
@@ -250,17 +243,17 @@ uwatec_memomouse_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
offset += 2;
// Time (seconds)
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
// Depth (meters)
sample.depth = depth * 10.0 / 64.0;
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
// Gas change.
if (gasmix != gasmix_previous) {
sample.gasmix = gasmix;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
@@ -272,7 +265,8 @@ uwatec_memomouse_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
}
sample.deco.time = 0;
sample.deco.depth = 0.0;
- if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
+ sample.deco.tts = 0;
+ if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
// Warnings
for (unsigned int i = 0; i < 6; ++i) {
@@ -301,7 +295,7 @@ uwatec_memomouse_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
break;
}
if (sample.event.type != SAMPLE_EVENT_NONE) {
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
}
}
@@ -325,7 +319,7 @@ uwatec_memomouse_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
offset++;
}
- if (callback) callback (DC_SAMPLE_VENDOR, sample, userdata);
+ if (callback) callback (DC_SAMPLE_VENDOR, &sample, userdata);
}
time += 20;
diff --git a/src/uwatec_smart.c b/src/uwatec_smart.c
index 63915c88..e0d34c1b 100644
--- a/src/uwatec_smart.c
+++ b/src/uwatec_smart.c
@@ -287,8 +287,6 @@ uwatec_smart_usbhid_send (uwatec_smart_device_t *device, unsigned char cmd, cons
return DC_STATUS_INVALIDARGS;
}
- HEXDUMP (abstract->context, DC_LOGLEVEL_DEBUG, "cmd", data, size);
-
buf[0] = 0;
buf[1] = size + 1;
buf[2] = cmd;
@@ -297,6 +295,8 @@ uwatec_smart_usbhid_send (uwatec_smart_device_t *device, unsigned char cmd, cons
}
memset(buf + 3 + size, 0, sizeof(buf) - (size + 3));
+ HEXDUMP (abstract->context, DC_LOGLEVEL_DEBUG, "cmd", buf + 2, size + 1);
+
if (dc_iostream_get_transport(device->iostream) == DC_TRANSPORT_BLE) {
rc = dc_iostream_write(device->iostream, buf + 1, size + 2, NULL);
} else {
diff --git a/src/uwatec_smart.h b/src/uwatec_smart.h
index 49013c51..646cc977 100644
--- a/src/uwatec_smart.h
+++ b/src/uwatec_smart.h
@@ -35,7 +35,7 @@ dc_status_t
uwatec_smart_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
-uwatec_smart_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
+uwatec_smart_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model);
#ifdef __cplusplus
}
diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c
index bd849a80..8e455a7f 100644
--- a/src/uwatec_smart_parser.c
+++ b/src/uwatec_smart_parser.c
@@ -51,7 +51,10 @@
#define ALADINA2 0x28
#define G2TEK 0x31
#define G2 0x32
+#define G3 0x34
#define G2HUD 0x42
+#define LUNA2AI 0x50
+#define LUNA2 0x51
#define UNSUPPORTED 0xFFFFFFFF
@@ -157,7 +160,6 @@ struct uwatec_smart_parser_t {
dc_divemode_t divemode;
};
-static dc_status_t uwatec_smart_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
static dc_status_t uwatec_smart_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime);
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);
@@ -167,7 +169,6 @@ static dc_status_t uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_
static const dc_parser_vtable_t uwatec_smart_parser_vtable = {
sizeof(uwatec_smart_parser_t),
DC_FAMILY_UWATEC_SMART,
- uwatec_smart_parser_set_data, /* set_data */
NULL, /* set_clock */
NULL, /* set_atmospheric */
NULL, /* set_density */
@@ -534,7 +535,8 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser)
parser->model == G2 || parser->model == ALADINSPORTMATRIX ||
parser->model == ALADINSQUARE || parser->model == G2HUD ||
parser->model == ALADINA1 || parser->model == ALADINA2 ||
- parser->model == G2TEK) {
+ parser->model == G2TEK || parser->model == G3 ||
+ parser->model == LUNA2AI || parser->model == LUNA2) {
unsigned int offset = header->tankpressure + 2 * i;
endpressure = array_uint16_le(data + offset);
beginpressure = array_uint16_le(data + offset + 2 * header->ngases);
@@ -573,7 +575,7 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser)
dc_status_t
-uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
+uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size, unsigned int model)
{
dc_status_t status = DC_STATUS_SUCCESS;
uwatec_smart_parser_t *parser = NULL;
@@ -582,7 +584,7 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
return DC_STATUS_INVALIDARGS;
// Allocate memory.
- parser = (uwatec_smart_parser_t *) dc_parser_allocate (context, &uwatec_smart_parser_vtable);
+ parser = (uwatec_smart_parser_t *) dc_parser_allocate (context, &uwatec_smart_parser_vtable, data, size);
if (parser == NULL) {
ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY;
@@ -625,9 +627,12 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
case G2:
case G2HUD:
case G2TEK:
+ case G3:
case ALADINSPORTMATRIX:
case ALADINA1:
case ALADINA2:
+ case LUNA2AI:
+ case LUNA2:
parser->headersize = 84;
parser->header = &uwatec_smart_trimix_header;
parser->samples = uwatec_smart_galileo_samples;
@@ -707,31 +712,6 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
}
-static dc_status_t
-uwatec_smart_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
-{
- uwatec_smart_parser_t *parser = (uwatec_smart_parser_t *) abstract;
-
- // Reset the cache.
- parser->cached = 0;
- parser->ngasmixes = 0;
- parser->ntanks = 0;
- for (unsigned int i = 0; i < NGASMIXES; ++i) {
- parser->gasmix[i].id = 0;
- parser->gasmix[i].oxygen = 0;
- parser->gasmix[i].helium = 0;
- parser->tank[i].id = 0;
- parser->tank[i].beginpressure = 0;
- parser->tank[i].endpressure = 0;
- parser->tank[i].gasmix = 0;
- }
- parser->watertype = DC_WATER_FRESH;
- parser->divemode = DC_DIVEMODE_OC;
-
- return DC_STATUS_SUCCESS;
-}
-
-
static dc_status_t
uwatec_smart_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
@@ -807,6 +787,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
+ gasmix->usage = DC_USAGE_NONE;
gasmix->helium = parser->gasmix[flags].helium / 100.0;
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
@@ -821,6 +802,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
tank->beginpressure = parser->tank[flags].beginpressure / 128.0;
tank->endpressure = parser->tank[flags].endpressure / 128.0;
tank->gasmix = parser->tank[flags].gasmix;
+ tank->usage = DC_USAGE_NONE;
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
*((double *) value) = (signed short) array_uint16_le (data + table->temp_minimum) / 10.0;
@@ -953,7 +935,8 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback
parser->model == G2 || parser->model == ALADINSPORTMATRIX ||
parser->model == ALADINSQUARE || parser->model == G2HUD ||
parser->model == ALADINA1 || parser->model == ALADINA2 ||
- parser->model == G2TEK) {
+ parser->model == G2TEK || parser->model == G3 ||
+ parser->model == LUNA2AI || parser->model == LUNA2) {
// Uwatec Galileo
id = uwatec_galileo_identify (data[offset]);
} else {
@@ -1162,8 +1145,8 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback
}
while (complete) {
- sample.time = time;
- if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
+ sample.time = time * 1000;
+ if (callback) callback (DC_SAMPLE_TIME, &sample, userdata);
if (parser->ngasmixes && gasmix != gasmix_previous) {
idx = uwatec_smart_find_gasmix (parser, gasmix);
@@ -1172,13 +1155,13 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback
return DC_STATUS_DATAFORMAT;
}
sample.gasmix = idx;
- if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
+ if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
gasmix_previous = gasmix;
}
if (have_temperature) {
sample.temperature = temperature / 2.5;
- if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_TEMPERATURE, &sample, userdata);
}
if (bookmark) {
@@ -1186,12 +1169,12 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = 0;
- if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_EVENT, &sample, userdata);
}
if (have_rbt || have_pressure) {
sample.rbt = rbt;
- if (callback) callback (DC_SAMPLE_RBT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_RBT, &sample, userdata);
}
if (have_pressure) {
@@ -1199,24 +1182,24 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback
if (idx < parser->ntanks) {
sample.pressure.tank = idx;
sample.pressure.value = pressure / 4.0;
- if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
+ if (callback) callback (DC_SAMPLE_PRESSURE, &sample, userdata);
}
}
if (have_heartrate) {
sample.heartbeat = heartrate;
- if (callback) callback (DC_SAMPLE_HEARTBEAT, sample, userdata);
+ if (callback) callback (DC_SAMPLE_HEARTBEAT, &sample, userdata);
}
if (have_bearing) {
sample.bearing = bearing;
- if (callback) callback (DC_SAMPLE_BEARING, sample, userdata);
+ if (callback) callback (DC_SAMPLE_BEARING, &sample, userdata);
have_bearing = 0;
}
if (have_depth) {
sample.depth = (signed int)(depth - depth_calibration) * (2.0 * BAR / 1000.0) / (density * 10.0);
- if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
+ if (callback) callback (DC_SAMPLE_DEPTH, &sample, userdata);
}
time += interval;