diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-24 11:55:47 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2017-07-25 06:11:10 -0700 |
commit | adb4b66a055ca809b0a78c08f37d7feefe44e947 (patch) | |
tree | 2abdcf4ecbc9f83ffa7df11ed95b17062704adcd /core/libdivecomputer.c | |
parent | 97b770b837d53039cdebc20957b62b75840d629b (diff) | |
download | subsurface-adb4b66a055ca809b0a78c08f37d7feefe44e947.tar.gz |
Try to sanely download multiple concurrent cylinder pressures
This tries to sanely handle the case of a dive computer reporting
multiple cylinder pressures concurrently.
NOTE! There are various "interesting" situations that this whole issue
brings up:
- some dive computers may report more cylinder pressures than we have
slots for.
Currently we will drop such pressures on the floor if they come for
the same sample, but if they end up being spread across multiple
samples we will end up re-using the slots with different sensor
indexes.
That kind of slot re-use may or may not end up confusing other
subsurface logic - for example, make things believe there was a
cylidner change event.
- some dive computers might send only one sample at a time, but switch
*which* sample they send on a gas switch event. If they also report
the correct sensor number, we'll now start reporting that pressure in
the second slot.
This should all be fine, and is the RightThing(tm) to do, but is
different from what we used to do when we only ever used a single
slot.
- When people actually use multiple sensors, our old save format will
start to need fixing. Right now our save format comes from the CCR
model where the second sensor was always the Oxygen sensor.
We save that pressure fine (except we save it as "o2pressure" - just
an odd historical naming artifact), but we do *not* save the actual
sensor index, because in our traditional format that was always
implicit in the data ("it's the oxygen cylinder").
so while this code hopefully makes our libdivecomputer download do the
right thing, there *will* be further fallout from having multiple
cylinder pressure sensors. We're not done yet.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'core/libdivecomputer.c')
-rw-r--r-- | core/libdivecomputer.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/core/libdivecomputer.c b/core/libdivecomputer.c index c935ecbce..819db0226 100644 --- a/core/libdivecomputer.c +++ b/core/libdivecomputer.c @@ -307,6 +307,47 @@ static void handle_gasmix(struct divecomputer *dc, struct sample *sample, int id current_gas_index = idx; } +/* + * Adding a cylinder pressure sample field is not quite as trivial as it + * perhaps should be. + * + * We try to keep the same sensor index for the same sensor, so that even + * if the dive computer doesn't give pressure information for every sample, + * we don't move pressure information around between the different sensor + * indexes. + * + * The "prepare_sample()" function will always copy the sensor indices + * from the previous sample, so the indexes are pre-populated (but the + * pressures obviously are not) + */ +static void add_sample_pressure(struct sample *sample, int sensor, int mbar) +{ + int idx; + + if (!mbar) + return; + + /* Do we already have a slot for this sensor */ + for (idx = 0; idx < MAX_SENSORS; idx++) { + if (sensor != sample->sensor[idx]) + continue; + sample->pressure[idx].mbar = mbar; + return; + } + + /* Pick the first unused index if we couldn't reuse one */ + for (idx = 0; idx < MAX_SENSORS; idx++) { + if (sample->pressure[idx].mbar) + continue; + sample->sensor[idx] = sensor; + sample->pressure[idx].mbar = mbar; + return; + } + + /* We do not have enough slots for the pressure samples. */ + /* Should we warn the user about dropping pressure data? */ +} + void sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata) { @@ -352,15 +393,9 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata) case DC_SAMPLE_DEPTH: sample->depth.mm = lrint(value.depth * 1000); break; - case DC_SAMPLE_PRESSURE: { - int sensoridx = 0; - /* Do we already have a pressure reading? */ - if (sample->pressure[0].mbar) - sensoridx = 1; - sample->sensor[sensoridx] = value.pressure.tank; - sample->pressure[sensoridx].mbar = lrint(value.pressure.value * 1000); + case DC_SAMPLE_PRESSURE: + add_sample_pressure(sample, value.pressure.tank, lrint(value.pressure.value * 1000)); break; - } case DC_SAMPLE_GASMIX: handle_gasmix(dc, sample, value.gasmix); break; |