Skip to content

Commit

Permalink
Fix the dc sensor index fixup
Browse files Browse the repository at this point in the history
fixup_dc_sample_sensors() would make sure that any pressure sensor
indexes were in range of the cylinders by just clearing the pressure
data if the sensor index was larger than the number of cylinders in the
dive.

That certainly makes the sensor index data consistent, but at the cost
of just dropping the sensor data entirely.

Dirk had some cases of odd sensor data (probably because of an older
version of subsurface, but possibly due to removing cylinders manually
or because of oddities with the downloader for the Atomic Aquatics
Cobalt dive computer he used), and when re-saving the dive, the pressure
data would magically just get removed due to this.

So rewrite the sensor data fixup to strive very hard to avoid throwing
pressure sensor data away.

We do this by:

 (a) generating a mask of sensor numbers seen

 (b) checking if that mask is a subset of the cylinders we have, in
     which case everything is fine.

 (c) if it's not a subset, "compress" the sensor indexes to the minimal
     range (ie if you had sensor indexes 3 and 6, rename 3 to 0, and 6
     to 1).

 (d) if it now fits in the cylinder mask we have, everything is fine

 (e) if we still have more sensors than we have cylinders, leave the
     data alone, but complain about it with SSRF_INFO() so that the user
     is notified.

That final (e) case might be for dive computers that allow reporting
pressure data for your buddy's cylinder too.  So it's odd, but not
entirely crazy, and we now will keep the data.  You may have to add a
fake cylinder to your dive to make it all make sense and avoid the
informational warning.

This whole "we clear the pressure data" was at least partly hidden by
two things:

 (1) in the git save format, we don't rewrite dives unless you've
     changed the dive some way, so old dives stay around with old data
     in the save until explicitly changed.

 (2) if you had multiple dive computers, and one dive computer does not
     have any pressure data but another one does, our profile will use
     that "other" dive computer pressure data (because often times you
     might have only one dive computer that is air integrated, but you
     still want to see the tank pressure when you look at other dive
     computers - or you have one dive computer give pressure data for
     your deco bottle, and another for your travel gas etc).

So those two facts hid the reality that we had actually cleared the tank
sensor data for Dirk's dive with the Atomic Aquatics dive computer,
because we'd still see pressure data in the profile, and the git data
would still be the old one.

Until Dirk renumbered his dives, and the data was rewritten.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
torvalds committed Sep 12, 2022
1 parent 3446dd5 commit 724527b
Showing 1 changed file with 42 additions and 1 deletion.
43 changes: 42 additions & 1 deletion core/dive.c
Original file line number Diff line number Diff line change
Expand Up @@ -1212,13 +1212,54 @@ static void fixup_no_o2sensors(struct divecomputer *dc)

static void fixup_dc_sample_sensors(struct divecomputer *dc, int nr_cylinders)
{
int cyl;
unsigned long sensor_mask = 0;
unsigned int renumber[MAX_SENSORS];

for (int i = 0; i < dc->samples; i++) {
struct sample *s = dc->sample + i;
for (int j = 0; j < MAX_SENSORS; j++) {
if (s->sensor[j] < 0 || s->sensor[j] >= nr_cylinders) {
int sensor = s->sensor[j];

if (!s->pressure[j].mbar)
continue;
// No invalid sensor ID's, please
if (sensor < 0 || sensor > MAX_SENSORS) {
s->sensor[j] = NO_SENSOR;
s->pressure[j].mbar = 0;
continue;
}
sensor_mask |= 1ul << sensor;
}
}

// No sensor data?
if (!sensor_mask)
return;

// Sensor data proper subset of cylinders?
if (sensor_mask < (1ul << nr_cylinders))
return;

// We'll need to fix up sensor numbers..
cyl = 0;
for (int i = 0; i < MAX_SENSORS; i++) {
renumber[i] = cyl;
cyl += sensor_mask & 1;
sensor_mask >>= 1;
}

if (cyl > nr_cylinders)
SSRF_INFO("fixup_dc_sample_sensors: more sensors than cylinders in dive!");

// Just rename all the sensors for this DC to the minimal ones
for (int i = 0; i < dc->samples; i++) {
struct sample *s = dc->sample + i;
for (int j = 0; j < MAX_SENSORS; j++) {
int sensor = s->sensor[j];
if (sensor < 0)
continue;
s->sensor[j] = renumber[sensor];
}
}
}
Expand Down

0 comments on commit 724527b

Please sign in to comment.