Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/output_xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
tank.gasmix);
}
if (tank.usage) {
const char *usage[] = {"none", "oxygen", "diluent", "sidemount"};
const char *usage[] = {"none", "sidemount", "included", "excluded"};
fprintf (output->ostream,
" <usage>%s</usage>\n",
usage[tank.usage]);
Expand Down
8 changes: 7 additions & 1 deletion include/libdivecomputer/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,14 @@ typedef unsigned int dc_tankinfo_t;
*/

typedef enum dc_tank_usage_t {
DC_TANK_USAGE_NONE,
DC_TANK_USAGE_NONE, /* Not specified, or unknown. */
DC_TANK_USAGE_SIDEMOUNT,
DC_TANK_USAGE_INCLUDED, /* The dive computer counts this tank towards
the diver's own gas consumption. */
DC_TANK_USAGE_EXCLUDED, /* The dive computer does not count this tank
towards the diver's own gas consumption
(for example a buddy's or a stage/deco
Comment on lines +235 to +239

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thank you. examples/output_xml.c's tank-reporting block prints tank.usage (a dc_tank_usage_t) through the array built for the unrelated dc_usage_t gas-mix mapping, {"none", "oxygen", "diluent", "sidemount"}, so DC_TANK_USAGE_INCLUDED would print as "diluent" and DC_TANK_USAGE_EXCLUDED as "sidemount".

This will be fixed by giving the tank-reporting block its own mapping, {"none", "sidemount", "included", "excluded"}, matching dc_tank_usage_t's actual enumerator order, without touching the separate gas-mix block.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been fixed in commit 590d585 ("examples: fix tank usage XML labels to match dc_tank_usage_t"), which is already part of this PR. The tank-reporting block now has its own usage[] array, {"none", "sidemount", "included", "excluded"}, matching dc_tank_usage_t's actual enumerator order, and no longer reuses the unrelated gas-mix dc_usage_t mapping.

bottle that is tracked but not included). */
} dc_tank_usage_t;

typedef struct dc_tank_t {
Expand Down
3 changes: 3 additions & 0 deletions src/field-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ dc_field_get(dc_field_cache_t *cache, dc_field_type_t type, unsigned int flags,
tank->gasmix = flags;
tank->workpressure = cache->tankworkingpressure[flags];
tank->type = cache->tankinfo[flags];
tank->usage = cache->tankusage[flags];
tank->beginpressure = 0;
tank->endpressure = 0;

return DC_STATUS_SUCCESS;
case DC_FIELD_STRING:
Expand Down
35 changes: 30 additions & 5 deletions src/garmin_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ struct garmin_sensor {
unsigned int sensor_id;
const char *sensor_name;
unsigned char sensor_enabled, sensor_units, sensor_used_for_gas_rate;
// SENSOR_PROFILE field 78 (used_for_gas_rate) is only decoded when
// the log actually contains it: the field-decoding machinery drops
// absent/invalid (0xff) values before the handler runs, and this
// whole struct is memset to zero otherwise. So a raw 0 is ambiguous
// between "device said not counted" and "device said nothing", and
// we need this separate flag to tell the two apart.
unsigned char sensor_used_for_gas_rate_valid;
unsigned int sensor_rated_pressure, sensor_reserve_pressure, sensor_volume;
};

Expand Down Expand Up @@ -855,7 +862,9 @@ DECLARE_FIELD(SENSOR_PROFILE, volume, UINT16)
}
DECLARE_FIELD(SENSOR_PROFILE, used_for_gas_rate, ENUM)
{
current_sensor(garmin)->sensor_used_for_gas_rate = data;
struct garmin_sensor *sensor = current_sensor(garmin);
sensor->sensor_used_for_gas_rate = data;
sensor->sensor_used_for_gas_rate_valid = 1;
}

DECLARE_FIELD(TANK_UPDATE, sensor, UINT32Z)
Expand Down Expand Up @@ -1725,12 +1734,28 @@ garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsi

add_gps_string(garmin, "Record GPS", &garmin->gps.RECORD);

// We have no idea about gas mixes vs tanks
// We have no idea about gas mixes vs tanks, so for now the only
// DC_FIELD_TANK member we report is "usage": whether the dive
// computer counted this tank pod's gas towards the diver's own
// consumption (SENSOR_PROFILE field 78, "used for SAC calculations").
// Volume/type/workpressure are left at their field-cache defaults.
//
// The index here matches the one used for DC_SAMPLE_PRESSURE
// (see find_tank_index()): both walk garmin->dive.sensor[].
for (int i = 0; i < garmin->dive.nr_sensor; i++) {
// DC_ASSIGN_IDX(garmin->cache, tankinfo, i, ..);
// DC_ASSIGN_IDX(garmin->cache, tanksize, i, ..);
// DC_ASSIGN_IDX(garmin->cache, tankworkingpressure, i, ..);
const struct garmin_sensor *sensor = garmin->dive.sensor + i;
dc_tank_usage_t usage = DC_TANK_USAGE_NONE;

// Field 78 is only decoded when it is actually present in the
// log; a sensor that never saw it must stay NONE here, never
// EXCLUDED.
if (sensor->sensor_used_for_gas_rate_valid)
usage = sensor->sensor_used_for_gas_rate ? DC_TANK_USAGE_INCLUDED : DC_TANK_USAGE_EXCLUDED;

garmin->cache.tankusage[i] = usage;
}
if (garmin->dive.nr_sensor)
garmin->cache.initialized |= 1u << DC_FIELD_TANK;

// Hate hate hate gasmix vs tank counts.
//
Expand Down
Loading