2017-04-27 18:18:03 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2014-11-07 16:30:44 +00:00
|
|
|
#include <string.h>
|
2023-12-03 21:59:21 +00:00
|
|
|
#include <stdlib.h>
|
2014-11-07 16:30:44 +00:00
|
|
|
|
2018-05-22 07:07:42 +00:00
|
|
|
#include "ssrf.h"
|
2019-03-04 22:20:29 +00:00
|
|
|
#include "divesite.h"
|
2020-05-01 11:43:52 +00:00
|
|
|
#include "dive.h"
|
core: introduce divelog structure
The parser API was very annoying, as a number of tables
to-be-filled were passed in as pointers. The goal of this
commit is to collect all these tables in a single struct.
This should make it (more or less) clear what is actually
written into the divelog files.
Moreover, it should now be rather easy to search for
instances, where the global logfile is accessed (and it
turns out that there are many!).
The divelog struct does not contain the tables as substructs,
but only collects pointers. The idea is that the "divelog.h"
file can be included without all the other files describing
the numerous tables.
To make it easier to use from C++ parts of the code, the
struct implements a constructor and a destructor. Sadly,
we can't use smart pointers, since the pointers are accessed
from C code. Therfore the constructor and destructor are
quite complex.
The whole commit is large, but was mostly an automatic
conversion.
One oddity of note: the divelog structure also contains
the "autogroup" flag, since that is saved in the divelog.
This actually fixes a bug: Before, when importing dives
from a different log, the autogroup flag was overwritten.
This was probably not intended and does not happen anymore.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-11-08 20:31:08 +00:00
|
|
|
#include "divelog.h"
|
2014-11-07 16:30:44 +00:00
|
|
|
#include "file.h"
|
2020-10-25 12:28:55 +00:00
|
|
|
#include "sample.h"
|
2015-06-01 06:12:30 +00:00
|
|
|
#include "strndup.h"
|
2014-11-07 16:30:44 +00:00
|
|
|
|
|
|
|
// Convert bytes into an INT
|
|
|
|
#define array_uint16_le(p) ((unsigned int) (p)[0] \
|
|
|
|
+ ((p)[1]<<8) )
|
|
|
|
#define array_uint32_le(p) ((unsigned int) (p)[0] \
|
|
|
|
+ ((p)[1]<<8) + ((p)[2]<<16) \
|
|
|
|
+ ((p)[3]<<24))
|
|
|
|
|
2014-11-09 18:03:07 +00:00
|
|
|
struct lv_event {
|
2022-08-20 15:20:18 +00:00
|
|
|
uint32_t time;
|
2014-11-09 18:03:07 +00:00
|
|
|
struct pressure {
|
|
|
|
int sensor;
|
|
|
|
int mbar;
|
|
|
|
} pressure;
|
|
|
|
};
|
|
|
|
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
// Liquivision supports the following sensor configurations:
|
|
|
|
// Primary sensor only
|
|
|
|
// Primary + Buddy sensor
|
|
|
|
// Primary + Up to 4 additional sensors
|
|
|
|
// Primary + Up to 9 addiitonal sensors
|
|
|
|
struct lv_sensor_ids {
|
|
|
|
uint16_t primary;
|
|
|
|
uint16_t buddy;
|
|
|
|
uint16_t group[9];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct lv_sensor_ids sensor_ids;
|
2015-03-08 19:40:31 +00:00
|
|
|
|
2024-03-01 12:09:20 +00:00
|
|
|
static int handle_event_ver2(int, const unsigned char *, unsigned int, struct lv_event *)
|
2014-11-09 18:03:07 +00:00
|
|
|
{
|
|
|
|
// Skip 4 bytes
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int handle_event_ver3(int code, const unsigned char *ps, unsigned int ps_ptr, struct lv_event *event)
|
|
|
|
{
|
|
|
|
int skip = 4;
|
2015-03-08 19:40:31 +00:00
|
|
|
uint16_t current_sensor;
|
2014-11-09 18:03:07 +00:00
|
|
|
|
|
|
|
switch (code) {
|
|
|
|
case 0x0002: // Unknown
|
|
|
|
case 0x0004: // Unknown
|
|
|
|
skip = 4;
|
|
|
|
break;
|
|
|
|
case 0x0005: // Unknown
|
|
|
|
skip = 6;
|
|
|
|
break;
|
|
|
|
case 0x0007: // Gas
|
|
|
|
// 4 byte time
|
|
|
|
// 1 byte O2, 1 bye He
|
|
|
|
skip = 6;
|
|
|
|
break;
|
|
|
|
case 0x0008:
|
|
|
|
// 4 byte time
|
2017-03-06 12:36:42 +00:00
|
|
|
// 2 byte gas setpoint 2
|
2014-11-09 18:03:07 +00:00
|
|
|
skip = 6;
|
|
|
|
break;
|
|
|
|
case 0x000f:
|
|
|
|
// Tank pressure
|
|
|
|
event->time = array_uint32_le(ps + ps_ptr);
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
current_sensor = array_uint16_le(ps + ps_ptr + 4);
|
2015-03-08 19:40:31 +00:00
|
|
|
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
event->pressure.sensor = -1;
|
|
|
|
event->pressure.mbar = array_uint16_le(ps + ps_ptr + 6) * 10; // cb->mb
|
2015-03-08 19:40:31 +00:00
|
|
|
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
if (current_sensor == sensor_ids.primary) {
|
2015-03-08 19:40:31 +00:00
|
|
|
event->pressure.sensor = 0;
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
} else if (current_sensor == sensor_ids.buddy) {
|
2015-03-08 19:40:31 +00:00
|
|
|
event->pressure.sensor = 1;
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
} else {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 9; ++i) {
|
|
|
|
if (current_sensor == sensor_ids.group[i]) {
|
|
|
|
event->pressure.sensor = i + 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-03-08 19:40:31 +00:00
|
|
|
}
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
|
2014-11-09 18:03:07 +00:00
|
|
|
// 1 byte PSR
|
|
|
|
// 1 byte ST
|
|
|
|
skip = 10;
|
|
|
|
break;
|
2024-03-01 12:09:20 +00:00
|
|
|
case 0x0010: {
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
// 4 byte time
|
|
|
|
// 2 byte primary transmitter S/N
|
|
|
|
// 2 byte buddy transmitter S/N
|
|
|
|
// 2 byte group transmitter S/N (9x)
|
|
|
|
|
|
|
|
// I don't think it's possible to change sensor IDs once a dive has started but disallow it here just in case
|
|
|
|
if (sensor_ids.primary == 0) {
|
|
|
|
sensor_ids.primary = array_uint16_le(ps + ps_ptr + 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sensor_ids.buddy == 0) {
|
|
|
|
sensor_ids.buddy = array_uint16_le(ps + ps_ptr + 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
int i;
|
|
|
|
const unsigned char *group_ptr = ps + ps_ptr + 8;
|
|
|
|
for (i = 0; i < 9; ++i, group_ptr += 2) {
|
|
|
|
if (sensor_ids.group[i] == 0) {
|
|
|
|
sensor_ids.group[i] = array_uint16_le(group_ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-09 18:03:07 +00:00
|
|
|
skip = 26;
|
|
|
|
break;
|
2024-03-01 12:09:20 +00:00
|
|
|
}
|
2014-11-09 18:03:07 +00:00
|
|
|
case 0x0015: // Unknown
|
|
|
|
skip = 2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
skip = 4;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return skip;
|
|
|
|
}
|
|
|
|
|
2019-02-28 21:45:17 +00:00
|
|
|
static void parse_dives(int log_version, const unsigned char *buf, unsigned int buf_size, struct dive_table *table, struct dive_site_table *sites)
|
2014-11-08 05:08:54 +00:00
|
|
|
{
|
2014-11-07 16:30:44 +00:00
|
|
|
unsigned int ptr = 0;
|
|
|
|
unsigned char model;
|
|
|
|
|
|
|
|
struct dive *dive;
|
|
|
|
struct divecomputer *dc;
|
|
|
|
struct sample *sample;
|
|
|
|
|
|
|
|
while (ptr < buf_size) {
|
2015-03-08 19:40:31 +00:00
|
|
|
int i;
|
2014-11-07 16:30:44 +00:00
|
|
|
dive = alloc_dive();
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
memset(&sensor_ids, 0, sizeof(sensor_ids));
|
2014-11-07 16:30:44 +00:00
|
|
|
dc = &dive->dc;
|
|
|
|
|
2015-03-08 19:40:31 +00:00
|
|
|
/* Just the main cylinder until we can handle the buddy cylinder porperly */
|
2019-08-04 16:44:57 +00:00
|
|
|
for (i = 0; i < 1; i++) {
|
2020-01-07 03:00:20 +00:00
|
|
|
cylinder_t cyl = empty_cylinder;
|
2019-08-04 16:44:57 +00:00
|
|
|
fill_default_cylinder(dive, &cyl);
|
2020-04-28 12:50:40 +00:00
|
|
|
add_cylinder(&dive->cylinders, i, cyl);
|
2019-08-04 16:44:57 +00:00
|
|
|
}
|
2015-03-08 19:40:31 +00:00
|
|
|
|
2014-11-07 16:30:44 +00:00
|
|
|
// Model 0=Xen, 1,2=Xeo, 4=Lynx, other=Liquivision
|
|
|
|
model = *(buf + ptr);
|
|
|
|
switch (model) {
|
|
|
|
case 0:
|
2016-02-03 05:21:13 +00:00
|
|
|
dc->model = strdup("Xen");
|
2014-11-07 16:30:44 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
2016-02-03 05:21:13 +00:00
|
|
|
dc->model = strdup("Xeo");
|
2014-11-07 16:30:44 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2016-02-03 05:21:13 +00:00
|
|
|
dc->model = strdup("Lynx");
|
2014-11-07 16:30:44 +00:00
|
|
|
break;
|
|
|
|
default:
|
2016-02-03 05:21:13 +00:00
|
|
|
dc->model = strdup("Liquivision");
|
2014-11-07 16:30:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
ptr++;
|
|
|
|
|
|
|
|
// Dive location, assemble Location and Place
|
|
|
|
unsigned int len, place_len;
|
2015-02-13 02:55:56 +00:00
|
|
|
char *location;
|
2014-11-07 16:30:44 +00:00
|
|
|
len = array_uint32_le(buf + ptr);
|
|
|
|
ptr += 4;
|
|
|
|
place_len = array_uint32_le(buf + ptr + len);
|
|
|
|
|
|
|
|
if (len && place_len) {
|
2024-03-01 12:09:20 +00:00
|
|
|
location = (char *)malloc(len + place_len + 4);
|
2015-02-13 02:55:56 +00:00
|
|
|
memset(location, 0, len + place_len + 4);
|
|
|
|
memcpy(location, buf + ptr, len);
|
|
|
|
memcpy(location + len, ", ", 2);
|
|
|
|
memcpy(location + len + 2, buf + ptr + len + 4, place_len);
|
2014-11-07 16:30:44 +00:00
|
|
|
} else if (len) {
|
2015-07-06 20:59:14 +00:00
|
|
|
location = strndup((char *)buf + ptr, len);
|
2014-11-07 16:30:44 +00:00
|
|
|
} else if (place_len) {
|
2015-07-06 20:59:14 +00:00
|
|
|
location = strndup((char *)buf + ptr + len + 4, place_len);
|
2014-11-07 16:30:44 +00:00
|
|
|
}
|
2015-03-08 19:40:30 +00:00
|
|
|
|
|
|
|
/* Store the location only if we have one */
|
2019-03-03 17:39:12 +00:00
|
|
|
if (len || place_len) {
|
2019-03-05 21:58:47 +00:00
|
|
|
add_dive_to_dive_site(dive, find_or_create_dive_site_with_name(location, sites));
|
2019-03-03 17:39:12 +00:00
|
|
|
free(location);
|
|
|
|
}
|
2014-11-07 16:30:44 +00:00
|
|
|
|
|
|
|
ptr += len + 4 + place_len;
|
|
|
|
|
|
|
|
// Dive comment
|
|
|
|
len = array_uint32_le(buf + ptr);
|
|
|
|
ptr += 4;
|
|
|
|
|
|
|
|
// Blank notes are better than the default text
|
2015-07-06 20:59:14 +00:00
|
|
|
if (len && strncmp((char *)buf + ptr, "Comment ...", 11)) {
|
|
|
|
dive->notes = strndup((char *)buf + ptr, len);
|
2014-11-07 16:30:44 +00:00
|
|
|
}
|
|
|
|
ptr += len;
|
|
|
|
|
|
|
|
dive->id = array_uint32_le(buf + ptr);
|
|
|
|
ptr += 4;
|
|
|
|
|
|
|
|
dive->number = array_uint16_le(buf + ptr) + 1;
|
|
|
|
ptr += 2;
|
|
|
|
|
|
|
|
dive->duration.seconds = array_uint32_le(buf + ptr); // seconds
|
|
|
|
ptr += 4;
|
|
|
|
|
|
|
|
dive->maxdepth.mm = array_uint16_le(buf + ptr) * 10; // cm->mm
|
|
|
|
ptr += 2;
|
|
|
|
|
|
|
|
dive->meandepth.mm = array_uint16_le(buf + ptr) * 10; // cm->mm
|
|
|
|
ptr += 2;
|
|
|
|
|
|
|
|
dive->when = array_uint32_le(buf + ptr);
|
|
|
|
ptr += 4;
|
|
|
|
|
|
|
|
//unsigned int end_time = array_uint32_le(buf + ptr);
|
|
|
|
ptr += 4;
|
|
|
|
|
|
|
|
//unsigned int sit = array_uint32_le(buf + ptr);
|
|
|
|
ptr += 4;
|
|
|
|
//if (sit == 0xffffffff) {
|
|
|
|
//}
|
|
|
|
|
|
|
|
dive->surface_pressure.mbar = array_uint16_le(buf + ptr); // ???
|
|
|
|
ptr += 2;
|
|
|
|
|
|
|
|
//unsigned int rep_dive = array_uint16_le(buf + ptr);
|
|
|
|
ptr += 2;
|
|
|
|
|
|
|
|
dive->mintemp.mkelvin = C_to_mkelvin((float)array_uint16_le(buf + ptr)/10);// C->mK
|
|
|
|
ptr += 2;
|
|
|
|
|
|
|
|
dive->maxtemp.mkelvin = C_to_mkelvin((float)array_uint16_le(buf + ptr)/10);// C->mK
|
|
|
|
ptr += 2;
|
|
|
|
|
|
|
|
dive->salinity = *(buf + ptr); // ???
|
|
|
|
ptr += 1;
|
|
|
|
|
|
|
|
unsigned int sample_count = array_uint32_le(buf + ptr);
|
|
|
|
ptr += 4;
|
|
|
|
|
|
|
|
// Sample interval
|
|
|
|
unsigned char sample_interval;
|
|
|
|
sample_interval = 1;
|
|
|
|
|
|
|
|
unsigned char intervals[6] = {1,2,5,10,30,60};
|
|
|
|
if (*(buf + ptr) < 6)
|
|
|
|
sample_interval = intervals[*(buf + ptr)];
|
|
|
|
ptr += 1;
|
|
|
|
|
2024-03-01 12:09:20 +00:00
|
|
|
[[maybe_unused]] float start_cns = 0;
|
|
|
|
[[maybe_unused]] unsigned char dive_mode = 0;
|
|
|
|
[[maybe_unused]] unsigned char algorithm = 0;
|
2014-11-07 16:30:44 +00:00
|
|
|
if (array_uint32_le(buf + ptr) != sample_count) {
|
|
|
|
// Xeo, with CNS and OTU
|
|
|
|
start_cns = *(float *) (buf + ptr);
|
|
|
|
ptr += 4;
|
2017-03-09 16:07:30 +00:00
|
|
|
dive->cns = lrintf(*(float *) (buf + ptr)); // end cns
|
2014-11-07 16:30:44 +00:00
|
|
|
ptr += 4;
|
2017-03-09 16:07:30 +00:00
|
|
|
dive->otu = lrintf(*(float *) (buf + ptr));
|
2014-11-07 16:30:44 +00:00
|
|
|
ptr += 4;
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
dive_mode = *(buf + ptr++); // 0=Deco, 1=Gauge, 2=None, 35=Rec
|
2014-11-07 16:30:44 +00:00
|
|
|
algorithm = *(buf + ptr++); // 0=ZH-L16C+GF
|
|
|
|
sample_count = array_uint32_le(buf + ptr);
|
|
|
|
}
|
2017-10-07 11:45:42 +00:00
|
|
|
|
|
|
|
if (sample_count == 0) {
|
|
|
|
fprintf(stderr, "DEBUG: sample count 0 - terminating parser\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ptr + sample_count * 4 + 4 > buf_size) {
|
|
|
|
fprintf(stderr, "DEBUG: BOF - terminating parser\n");
|
|
|
|
break;
|
|
|
|
}
|
2014-11-08 05:08:54 +00:00
|
|
|
// we aren't using the start_cns, dive_mode, and algorithm, yet
|
|
|
|
|
2014-11-07 16:30:44 +00:00
|
|
|
ptr += 4;
|
|
|
|
|
|
|
|
// Parse dive samples
|
|
|
|
const unsigned char *ds = buf + ptr;
|
|
|
|
const unsigned char *ts = buf + ptr + sample_count * 2 + 4;
|
|
|
|
const unsigned char *ps = buf + ptr + sample_count * 4 + 4;
|
|
|
|
unsigned int ps_count = array_uint32_le(ps);
|
|
|
|
ps += 4;
|
|
|
|
|
|
|
|
// Bump ptr
|
|
|
|
ptr += sample_count * 4 + 4;
|
|
|
|
|
|
|
|
// Handle events
|
|
|
|
unsigned int ps_ptr;
|
|
|
|
ps_ptr = 0;
|
|
|
|
|
2014-11-09 18:03:07 +00:00
|
|
|
unsigned int event_code, d = 0, e;
|
|
|
|
struct lv_event event;
|
2018-01-09 07:43:59 +00:00
|
|
|
memset(&event, 0, sizeof(event));
|
2014-11-07 16:30:44 +00:00
|
|
|
|
|
|
|
// Loop through events
|
|
|
|
for (e = 0; e < ps_count; e++) {
|
|
|
|
// Get event
|
2014-11-09 18:03:07 +00:00
|
|
|
event_code = array_uint16_le(ps + ps_ptr);
|
2014-11-07 16:30:44 +00:00
|
|
|
ps_ptr += 2;
|
|
|
|
|
2014-11-09 18:03:07 +00:00
|
|
|
if (log_version == 3) {
|
|
|
|
ps_ptr += handle_event_ver3(event_code, ps, ps_ptr, &event);
|
2017-07-29 04:33:41 +00:00
|
|
|
if (event_code != 0xf)
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
continue; // ignore all but pressure sensor event
|
2014-11-09 18:03:07 +00:00
|
|
|
} else { // version 2
|
|
|
|
ps_ptr += handle_event_ver2(event_code, ps, ps_ptr, &event);
|
|
|
|
continue; // ignore all events
|
2014-11-07 16:30:44 +00:00
|
|
|
}
|
2022-08-20 15:20:18 +00:00
|
|
|
uint32_t sample_time, last_time;
|
2014-11-07 16:30:44 +00:00
|
|
|
int depth_mm, last_depth, temp_mk, last_temp;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
sample = prepare_sample(dc);
|
|
|
|
|
|
|
|
// Get sample times
|
|
|
|
sample_time = d * sample_interval;
|
|
|
|
depth_mm = array_uint16_le(ds + d * 2) * 10; // cm->mm
|
2014-11-07 17:51:01 +00:00
|
|
|
temp_mk = C_to_mkelvin((float)array_uint16_le(ts + d * 2) / 10); // dC->mK
|
2014-11-07 16:30:44 +00:00
|
|
|
last_time = (d ? (d - 1) * sample_interval : 0);
|
|
|
|
|
|
|
|
if (d == sample_count) {
|
|
|
|
// We still have events to record
|
2014-11-09 18:03:07 +00:00
|
|
|
sample->time.seconds = event.time;
|
2014-11-07 17:51:01 +00:00
|
|
|
sample->depth.mm = array_uint16_le(ds + (d - 1) * 2) * 10; // cm->mm
|
|
|
|
sample->temperature.mkelvin = C_to_mkelvin((float) array_uint16_le(ts + (d - 1) * 2) / 10); // dC->mK
|
2022-03-06 10:34:12 +00:00
|
|
|
add_sample_pressure(sample, event.pressure.sensor, event.pressure.mbar);
|
2014-11-07 16:30:44 +00:00
|
|
|
finish_sample(dc);
|
|
|
|
|
|
|
|
break;
|
2014-11-09 18:03:07 +00:00
|
|
|
} else if (event.time > sample_time) {
|
2014-11-07 16:30:44 +00:00
|
|
|
// Record sample and loop
|
|
|
|
sample->time.seconds = sample_time;
|
|
|
|
sample->depth.mm = depth_mm;
|
|
|
|
sample->temperature.mkelvin = temp_mk;
|
|
|
|
finish_sample(dc);
|
|
|
|
d++;
|
|
|
|
|
|
|
|
continue;
|
2014-11-09 18:03:07 +00:00
|
|
|
} else if (event.time == sample_time) {
|
2014-11-07 16:30:44 +00:00
|
|
|
sample->time.seconds = sample_time;
|
|
|
|
sample->depth.mm = depth_mm;
|
|
|
|
sample->temperature.mkelvin = temp_mk;
|
2022-03-06 10:34:12 +00:00
|
|
|
add_sample_pressure(sample, event.pressure.sensor, event.pressure.mbar);
|
2014-11-07 16:30:44 +00:00
|
|
|
finish_sample(dc);
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
d++;
|
2014-11-07 16:30:44 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
} else { // Event is prior to sample
|
2014-11-09 18:03:07 +00:00
|
|
|
sample->time.seconds = event.time;
|
2022-03-06 10:34:12 +00:00
|
|
|
add_sample_pressure(sample, event.pressure.sensor, event.pressure.mbar);
|
2014-11-07 16:30:44 +00:00
|
|
|
if (last_time == sample_time) {
|
|
|
|
sample->depth.mm = depth_mm;
|
|
|
|
sample->temperature.mkelvin = temp_mk;
|
|
|
|
} else {
|
|
|
|
// Extrapolate
|
|
|
|
last_depth = array_uint16_le(ds + (d - 1) * 2) * 10; // cm->mm
|
2014-11-07 17:51:01 +00:00
|
|
|
last_temp = C_to_mkelvin((float) array_uint16_le(ts + (d - 1) * 2) / 10); // dC->mK
|
2014-11-07 16:30:44 +00:00
|
|
|
sample->depth.mm = last_depth + (depth_mm - last_depth)
|
2022-08-20 15:20:18 +00:00
|
|
|
* ((int)event.time - (int)last_time) / sample_interval;
|
2014-11-07 16:30:44 +00:00
|
|
|
sample->temperature.mkelvin = last_temp + (temp_mk - last_temp)
|
2022-08-20 15:20:18 +00:00
|
|
|
* ((int)event.time - (int)last_time) / sample_interval;
|
2014-11-07 16:30:44 +00:00
|
|
|
}
|
|
|
|
finish_sample(dc);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} // while (true);
|
|
|
|
} // for each event sample
|
|
|
|
|
|
|
|
// record trailing depth samples
|
|
|
|
for ( ;d < sample_count; d++) {
|
|
|
|
sample = prepare_sample(dc);
|
|
|
|
sample->time.seconds = d * sample_interval;
|
|
|
|
|
|
|
|
sample->depth.mm = array_uint16_le(ds + d * 2) * 10; // cm->mm
|
|
|
|
sample->temperature.mkelvin =
|
|
|
|
C_to_mkelvin((float)array_uint16_le(ts + d * 2) / 10);
|
|
|
|
finish_sample(dc);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (log_version == 3 && model == 4) {
|
|
|
|
// Advance to begin of next dive
|
|
|
|
switch (array_uint16_le(ps + ps_ptr)) {
|
|
|
|
case 0x0000:
|
|
|
|
ps_ptr += 5;
|
|
|
|
break;
|
|
|
|
case 0x0100:
|
|
|
|
ps_ptr += 7;
|
|
|
|
break;
|
|
|
|
case 0x0200:
|
|
|
|
ps_ptr += 9;
|
|
|
|
break;
|
|
|
|
case 0x0300:
|
|
|
|
ps_ptr += 11;
|
|
|
|
break;
|
|
|
|
case 0x0b0b:
|
|
|
|
ps_ptr += 27;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
Fix buffer overrun and primary sensor id issues in Liquivision import
This changeset fixes 5 issues specific to importing from Liquivision dive logs:
Issue #1: Buffer overrun causes segmentation fault.
At the end of a dive record, untranslatable data is skipped and the file is
scanned for the start of the next dive. This scan was implemented without
regard to buffer size and so the scan ran over the buffer boundary when trying
to scan for the next record after importing the last record in the file.
Issue #2: Incorrect identification of the primary sensor.
The primary tank pressure transmitter was being identified by using the sensor
ID reported in the first pressure event record encountered. When diving with
multiple transmitters (buddy, student, or group transmitters), this is often
not the case and results in the buddy or other group transmitter's pressure
data being imported instead of the primary's.
Through empirical observation of several multi-sensor logs, I identified a
previously unhandled event code (0x10) as marking a sensor identification
event record. Parsing this record allows the primary and other sensors
to be definitively identified regardless of which one sends the first pressure
event.
Issue #3: Sensor values added to the sample collection regardless of sensor ID.
When processing events, the code previously dropped through to create a sample
for every pressure event record, regardless of which sensor ID that event is
associated with. Pressure events for sensors other than the primary are now
ignored and omitted from the sample collection.
Issue #4: Duplicate samples when pressure event time syncs with sample time.
The sample index (d) was not incremented in this specific case resulting in
a duplicate sample (for the same sample time) being created when processing
the next pressure event record.
Issue #5: Unsigned time difference results in erroneous interpolated samples.
When interpolating/extrapolating depth and temperature values for a between-
samples pressure event, a signed time value is subtracted from an unsigned time
value, resulting in an unsigned term. This term is used as a scaling factor
and should be signed to allow for a negative value. Currently, negative values
are instead treated as large unsigned values which result in erroneous scaled
depth and temperature values.
Signed-off-by: Robert Bodily <robert@bodily.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-06-11 22:11:49 +00:00
|
|
|
while (((ptr + ps_ptr + 4) < buf_size) && (*(ps + ps_ptr) != 0x04))
|
2014-11-07 16:30:44 +00:00
|
|
|
ps_ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// End dive
|
2018-09-28 11:59:01 +00:00
|
|
|
record_dive_to_table(dive, table);
|
2017-12-26 22:22:52 +00:00
|
|
|
dive = NULL;
|
2014-11-07 16:30:44 +00:00
|
|
|
|
|
|
|
// Advance ptr for next dive
|
|
|
|
ptr += ps_ptr + 4;
|
|
|
|
} // while
|
|
|
|
|
2014-11-09 18:03:07 +00:00
|
|
|
//DEBUG save_dives("/tmp/test.xml");
|
2017-12-26 22:22:52 +00:00
|
|
|
|
|
|
|
// if we bailed out of the loop, the dive hasn't been recorded and dive hasn't been set to NULL
|
2022-08-20 15:24:45 +00:00
|
|
|
free_dive(dive);
|
2014-11-07 16:30:44 +00:00
|
|
|
}
|
|
|
|
|
2024-03-01 12:09:20 +00:00
|
|
|
int try_to_open_liquivision(const char *, std::string &mem, struct divelog *log)
|
2014-11-07 16:30:44 +00:00
|
|
|
{
|
2024-03-01 12:09:20 +00:00
|
|
|
const unsigned char *buf = (unsigned char *)mem.data();
|
|
|
|
unsigned int buf_size = (unsigned int)mem.size();
|
2014-11-07 16:30:44 +00:00
|
|
|
unsigned int ptr;
|
|
|
|
int log_version;
|
|
|
|
|
2015-08-19 17:12:16 +00:00
|
|
|
// Get name length
|
2014-11-07 16:30:44 +00:00
|
|
|
unsigned int len = array_uint32_le(buf);
|
2015-08-19 17:12:16 +00:00
|
|
|
// Ignore length field and the name
|
2014-11-07 16:30:44 +00:00
|
|
|
ptr = 4 + len;
|
|
|
|
|
|
|
|
unsigned int dive_count = array_uint32_le(buf + ptr);
|
|
|
|
if (dive_count == 0xffffffff) {
|
|
|
|
// File version 3.0
|
|
|
|
log_version = 3;
|
|
|
|
ptr += 6;
|
|
|
|
dive_count = array_uint32_le(buf + ptr);
|
|
|
|
} else {
|
|
|
|
log_version = 2;
|
|
|
|
}
|
|
|
|
ptr += 4;
|
|
|
|
|
core: introduce divelog structure
The parser API was very annoying, as a number of tables
to-be-filled were passed in as pointers. The goal of this
commit is to collect all these tables in a single struct.
This should make it (more or less) clear what is actually
written into the divelog files.
Moreover, it should now be rather easy to search for
instances, where the global logfile is accessed (and it
turns out that there are many!).
The divelog struct does not contain the tables as substructs,
but only collects pointers. The idea is that the "divelog.h"
file can be included without all the other files describing
the numerous tables.
To make it easier to use from C++ parts of the code, the
struct implements a constructor and a destructor. Sadly,
we can't use smart pointers, since the pointers are accessed
from C code. Therfore the constructor and destructor are
quite complex.
The whole commit is large, but was mostly an automatic
conversion.
One oddity of note: the divelog structure also contains
the "autogroup" flag, since that is saved in the divelog.
This actually fixes a bug: Before, when importing dives
from a different log, the autogroup flag was overwritten.
This was probably not intended and does not happen anymore.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-11-08 20:31:08 +00:00
|
|
|
parse_dives(log_version, buf + ptr, buf_size - ptr, log->dives, log->sites);
|
2014-11-07 16:30:44 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|