Commit graph

186 commits

Author SHA1 Message Date
Linus Torvalds
6c4e890960 Clean up divecomputer 'device' handling
We have this odd legacy notion of a divecomputer 'device', that was
originally just basically the libdivecomputer 'EVENT_DEVINFO' report
that was associated with each dive.  So it had firmware version,
deviceid, and serial number.

It had also gotten extended to do 'nickname' handling, and it was all
confusing, ugly and bad.  It was particularly bad because it wasn't
actually a 'per device' thing at all: due to the firmware field, a dive
computer that got a firmware update forced a new 'device'.

To make matters worse, the 'deviceid' was also almost random, because
we've calculated it a couple of different ways, and libdivecomputer
itself has changed how the legacy 32-bit 'serial number' is expressed.

Finally, because of all these issues, we didn't even try to make the
thing unique, so it really ended up being a random snapshot of the state
of the dive computer at the time of a dive, and sometimes we'd pick one,
and sometimes another, since they weren't really well-defined.

So get rid of all this confusion.

The new rules:

 - the actual random dive computer state at the time of a dive is kept
   in the dive data. So if you want to know the firmware version, it
   should be in the 'extra data'

 - the only serial number that matters is the string one in the extra
   data, because that's the one that actually matches what the dive
   computer reports, and isn't some random 32-bit integer with ambiguous
   formatting.

 - the 'device id' - the thing we match with (together with the model
   name, eg "Suunto EON Steel") is purely a hash of the real serial
   number.

   The device ID that libdivecomputer reports in EVENT_DEVINFO is
   ignored, as is the device ID we've saved in the XML or git files. If
   we have a serial number, the device ID will be uniquely associated
   with that serial number, and if we don't have one, the device ID will
   be zero (for 'match anything').

   So now 'deviceid' is literally just a shorthand for the serial number
   string, and the two are joined at the hip.

 - the 'device' managament is _only_ used to track devices that have
   serial numbers _and_ nicknames. So no more different device
   structures just because one had a nickname and the other didn't etc.

   Without a serial number, the device is 'anonymous' and fundamentally
   cannot be distinguished from other devices of the same model, so a
   nickname is meaningless. And without a nickname, there is no point in
   creating a device data structure, since all the data is in the dive
   itself and the device structure wouldn't add any value..

These rules mean that we no longer have ambiguous 'device' structures,
and we can never have duplicates that can confuse us.

This does mean that you can't give a nickname to a device that cannot be
uniquely identified with a serial number, but those are happily fairly
rare (and mostly older ones).  Dirk said he'd look at what it takes to
give more dive computers proper serial numbers, and I already did it for
the Garmin Descent family yesterday.

(Honesty in advertizing: right now you can't add a nickname to a dive
computer that doesn't already have one, because such a dive computer
will not have a device structure.  But that's a UI issue, and I'll sort
that out separately)

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-08-18 13:22:02 -07:00
Berthold Stoeger
a988e3c135 core: initialize dive selection after resetting the data
The dive selection was initialized during data-reset. However,
this emitted a signal before all data-reset routines were run.
Ultimately, this led to access-after-free in the statistics code.

Instead, move the select_newest_visible_dive() signal from the
divelist-model to the process_loaded_dives() function. There
is no point in initializing the selection if the dive data
is cleared after all.

This change broke closing of the log, because the UI-selection
was not reset. Therefore, when clearing the data, clear the
selection before proceeding with clearing.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-03-31 13:54:23 +02:00
Robert C. Helling
7c62f7541c Use PSCR gas when computing O2 toxicity
Both the calculations for CNS and OTU did not take
into account the pO2 drop when using a PSCR. Furthermore,
there was some unit confusion due to not using internal
units.

Reported-by: arosl
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-03-12 22:24:23 +01:00
Robert C. Helling
fdcfcb1b32 Get O2 right in bailout mode
When doing OC bailout from a CCR dive, there could still
be pO2 sensor readings but those are not valid.

This fixes a problem noticed by Justin Ashworth.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-02-26 08:42:30 -08:00
Robert C. Helling
2064ce06cc Fix pO2 for CCR at shallow depths
Even when diving a CCR, the pO2 cannot exceed ambient
pressure. This only makes a difference at shallow depths.

Fix this in the calculation of OTUs and CNS.

This affects some tests that now have slightly different CNS and OTU values.

Suggested-by: Justin Ashworth
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2021-02-26 08:42:30 -08:00
Berthold Stoeger
642d9c80b3 planner: pass in_planner argument to decoMode()
To remove reliance on global state, pass an "in_planner" argument
to decoMode(). Thus, calls to in_planner() can be removed.

This is a more-or-less automated change. Ultimately it would
probably be better to pass the current deco-mode to the affected
functions instead of calling decoMode() with an in_planner
parameter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
03a7e65cf0 planner: pass in_planner argument to clear_deco()
To remove reliance on global state, pass an "in_planner" argument
to clear_deco(). Thus, calls to in_planner() can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
93ecad1b04 planner: pass in_planner argument to add_segment()
To remove reliance on global state, pass an "in_planner" argument
to add_segment(). Thus, calls to in_planner() can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-02-17 07:26:55 -08:00
Berthold Stoeger
ad1e57dd67 cleanup: constify init_decompression()
This function initializes decompression data from a dive.
The dive is not modified, therefore make it const.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-01-20 10:01:50 -08:00
Berthold Stoeger
51d0c42a5c filter: move shown_dive from divelist.c to divefilter.cpp
Arguably, the number of filtered dives is a matter of the divefilter.
Let's move it there.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
e80c0d2c60 filter: reset shown_dives in filter
The shown_dives variable was reset by the dive_list code. Arguably,
the filter should keep track of the number of shown dives, so move
the resetting there. This means adding a new "reset()" member function
to the filter and call that instead of "updateAll()" when the core
data is reset.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-29 08:34:09 -08:00
Berthold Stoeger
50b11024d6 core: keep tank infos in a dynamic table
The list of known tank types were kept in a fixed size table.
Instead, use a dynamic table with our horrendous table macros.
This is more flexible and sensible.

While doing this, clean up the TankInfoModel, which was leaking
memory.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-12-13 11:49:59 -08:00
Berthold Stoeger
b2b3544f3f core: on import remove merged dives from trip/divesite
When dives were merged on import, they were not unregistered
from their dive site and trip before being deleted. Thus, these
tables had stale pointers, which would ultimate lead to crashes.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-31 23:20:59 -07:00
Berthold Stoeger
f728923c79 cleanup: move interpolate inline function to its own header file
This is not really related to struct dive, so let's move it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
0e196310f9 cleanup: split out divecomputer functions from dive.c
Since dive.c is so huge, split out divecomputer-related functions
into divecomputer.[c|h], sample.[c|h] and extradata.[c|h].

This does not give huge compile time improvements, since
struct dive contains a struct divecomputer and therefore
dive.h has to include divecomputer.h. However, it make things
distinctly more clear.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
8212acc992 cleanup: break out event-related code into event.[c|h]
In an effort to reduce the size of dive.h and dive.c, break out
the event related functions. Moreover event-names were handled
by the profile-code, collect that also in the new source files.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:52 -07:00
Berthold Stoeger
3358bff432 cleanup: move mark_divelist_changed() to qmlmanager.cpp
Desktop does not use mark_divelist_changed() anymore - all is done
via the undo machinery. Therefore move this function (and its
counterpart unsaved_changes()) to qmlmanager.cpp.

Ultimately, it probably should be removed from there as well, but
currently I don't dare to touch all the cloud-logic!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-25 13:59:04 -07:00
Berthold Stoeger
694776eed1 cleanup: rename set_dc_nickname() to add_devices_of_dive()
The function was misnamed in that it doesn't set the nickname
of a device. Instead, it adds all (unknown) devices of a
dive to the/a device-table. Let's call it appropriately.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
39a4090c0a devices: add devices in Command::importTable()
Add a device_table parameters to Command::importTable() and
add_imported_dives(). The content of this table will be added
to the global device list (respectively removed on undo).

This is currently a no-op, as the parser doesn't yet fill
out the device table, but adds devices directly to the global
device table.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-24 09:51:37 -07:00
Berthold Stoeger
c046742288 cleanup: rename clear_device_nodes() to clear_device_table()
For consistency with all the other clear_*_table functions
(dive, trip, dive_site, ...)

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-17 09:04:20 -07:00
Berthold Stoeger
8549f24c91 core: add device_table parameter to device table functions
Instead of accessing the global device table directly, add a parameter
to all device-table accessing functions. This makes all places in
the code that access the global device table grep-able, which is
necessary to include the device-table code in the undo system.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-10-16 14:26:37 -07:00
Berthold Stoeger
937fdb500b filter: add primitive filter presets
Add a rudimentary list of filter presets to the core. The list
is sorted by name. Access is provided via a C interface so that
the presets can be written to the git and XML logs. Internally,
the list is realized by a C++ vector for convenience (euphemism for
laziness).

Morover, a C++ interface is provided for the UI. Currently names of
the presets cannot be edited, since this would mean that the order
of the list changes. This may be implemented later if required.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-09-29 16:13:03 -07:00
Berthold Stoeger
f24fe10765 core: fix dive renumbering logic on import
0249e12 split up the dive import logic in multiple steps. Thereby,
the one of the conditions for renumbering the imported dives (is
the last old dive numbered) got messed up: The first number of the
new dive was compared to the total number of old dives, which makes
no sense.

- Simply check for the number of the last existing dive (if any).
- Don't remember the number of old dives - the original table is
  not modified anyway.

Fixes #2731

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-08-17 13:21:49 -07:00
Berthold Stoeger
fb6210a99a cleanup: invert control-flow when resetting the core structures
To reset the core data structures, the mobile and desktop UIs
were calling into the dive-list models, which then reset the
core data structures, themselves and the unrelated
locationinformation model. The UI code then reset various other
things, such as the TankInformation model or the map. . This was
unsatisfying from a control-flow perspective, as the models should
display the core data, not act on it. Moreover, this meant lots
of intricate intermodule-dependencies.

Thus, straighten up the control flow: give the C core the
possibility to send a "all data reset" event. And do that
in those functions that reset the core data structures.
Let each module react to this event by itself. This removes
inter-module dependencies. For example, the MainWindow now
doesn't have to reset the TankInfoModel or the MapWidget.

Then, to reset the core data structures, let the UI code
simply directly call the respective core functions.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-07 08:43:27 -07:00
Berthold Stoeger
f961ec7a8b selection: introduce clear_selection() function
The DiveListView would touch the selection-innards directly.
Let's encapsulate that. Moreover, take care to reset the trip
selection when resetting the core data.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-03 15:02:21 -07:00
Berthold Stoeger
32d87db8b3 cleanup: remove unused function append_dive()
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-02 14:52:51 +02:00
Berthold Stoeger
95284c026e cleanup: move dive_table from dive.h to divelist.h
This allows us to decouple dive.h and divelist.h, a small step in
include disentangling.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-05-01 09:42:31 -07:00
Berthold Stoeger
d8fabd241c cleanup: move clearing of event names to clear_dive_file_data()
Move this to the core so that desktop and mobile don't have
to call this explicitly. Matter of fact, mobile didn't call
this. It is unclear, whether that was even used on mobile,
though.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-04-24 10:40:12 -07:00
Berthold Stoeger
17526ded58 cleanup: move clearing of device nodes to clear_dive_file_data()
It makes no sense to keep the device nodes if all the other data
is cleared. Let's do this automatically and not explicitly.
This ensures that the function is also called on mobile.
Currently it was only called on desktop.

Weirdly, the parser-tests were expecting that the device nodes
were not reset by clear_dive_file_data() and therefore divecomputers
were accumulating in the test results. Thus, the additional
computers had to be removed from the expected test results.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-04-24 10:40:12 -07:00
Berthold Stoeger
103951bc78 divelist: when removing/adding a dive unregister/register fulltext
This fixes a crash: when the undo commands removed a dive from
the list, the fulltext cache was not cleared. If now the divelist
is reset and then the undo-command deleted, deletion of the owned
dive tries to remove it's fulltext cache, which doesn't exist
anymore.

For reasons of symmetry, when readding the dive, its fulltext
has to be registered.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-04-13 08:52:48 -07:00
Robert C. Helling
9feda56006 Remove extra argument and add a test
The compiler complained about this and it seems the
function does not need it.

Additional-test-suggested-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2020-04-13 09:42:29 +02:00
Berthold Stoeger
d9599589c7 fulltext: rename fulltext_reload() to fulltext_populate()
This function was named improperly: it was only used on freshly
loaded data. Indeed, attempts to use it to actually reload lead
to crashes.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-04-08 08:08:19 -07:00
Berthold Stoeger
0d78fe45c3 Core: consider invalid flag when adding dives
Adding dives uses the number of the last dive to create a new
dive number. Ignore invalid dives.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-03-20 15:20:44 -07:00
Berthold Stoeger
5bbc0fdb58 filter: compile fulltext index on mobile
The code is not used yet.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-03-01 10:21:44 -08:00
Berthold Stoeger
d3f6e032cc filter: index/unindex dives on loading or clearing logs
When loading dive data, populate the fulltext index. When clearing
dive data, free the fulltext index. When deleting a dive, remove it
from the fulltext index.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-03-01 10:21:44 -08:00
Dirk Hohndel
e1cd055111 code cleanup: add empty table structures
It seemed to make sense to combine all three types in one commit.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2020-01-10 02:37:03 +09:00
Berthold Stoeger
ae753f4c4d Cleanup: remove superfluous includes from core/divelist.c
Most of these haven't been used in a long time.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-12-04 13:00:23 +01:00
Berthold Stoeger
4b1a3a1a6e Selection: move selection functions from divelist.c to selection.c
Since we now have a selection.c translation unit, put the selection-
related functions there.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-12-04 13:00:23 +01:00
Berthold Stoeger
9ffafbc326 Filter: move num_shown logic from model to core
Since the number of shown dives is stored in the core, let's also
keep it updated there.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-19 21:13:40 -08:00
Berthold Stoeger
2d09819ddf Filter: move number of shown dives to core
We mark hidden/shown dives in the core but store the number
of shown dives in the MultiFilterSortModel. Move this datum
to the core for improved locality.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-19 21:13:40 -08:00
Berthold Stoeger
12c7c5ea96 Cleanup: move clearing of current_dive into clear_dive_file_data()
It makes no sense to have a non-NULL current_dive once all dives
have been deleted. Therefore, clear current_dive implicitly in
clear_dive_file_data() and don't depend on the caller performing
this.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-16 08:29:53 -08:00
Berthold Stoeger
794066b236 Cylinders: access cylinders with get_cylinder()
Instead of accessing the cylinder table directly, use the get_cylinder()
function. This gives less unwieldy expressions. But more importantly,
the function does bound checking. This is crucial for now as the code
hasn't be properly audited since the change to arbitrarily sized
cylinder tables. Accesses of invalid cylinder indexes may lead to
silent data-corruption that is sometimes not even noticed by
valgrind. Returning NULL instead of an invalid pointer will make
debugging much easier.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-09 19:19:04 +01:00
Berthold Stoeger
7c9f46acd2 Core: remove MAX_CYLINDERS restriction
Instead of using fixed size arrays, use a new cylinder_table structure.
The code copies the weightsystem code, but is significantly more complex
because cylinders are such an integral part of the core.

Two functions to access the cylinders were added:
get_cylinder() and get_or_create_cylinder()
The former does a simple array access and supposes that the cylinder
exists. The latter is used by the parser(s) and if a cylinder with
the given id does not exist, cylinders up to that id are generated.

One point will make C programmers cringe: the cylinder structure is
passed by value. This is due to the way the table-macros work. A
refactoring of the table macros is planned. It has to be noted that
the size of a cylinder_t is 64 bytes, i.e. 8 long words on a 64-bit
architecture, so passing on the stack is probably not even significantly
slower than passing as reference.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-09 19:19:04 +01:00
Dirk Hohndel
fd9e1d6a8a Cleanup: avoid dereferencing NULL
We should call this function with two well defined dive_or_trip structures
which means that exactly one of the two values is set in each argument. But
in order to not have bugs elsewhere leed to crashes here, be more tolerant
of malformed argumnts.

Fixes CID 350100

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-10-28 05:44:33 -07:00
Dirk Hohndel
1951371bbb Cleanup: prevent NULL dereference
This should never happen based on the logic in the callers, but just
to be on the safe side.

Should fix CID 350128

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-10-28 05:44:33 -07:00
Berthold Stoeger
6e343c734a Core: implement move functions for dive and dive_site table
To allow efficient moving of downloaded dives from the download
thread to the model, implement a general move function that
moves table data. Instantiate that function for the dive and
dive_site tables.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-10-02 08:04:49 -07:00
Stefan Fuchs
193c456f06 Fix new CNS calculation - remove error with factor of 10
Fix a typo in the new CNS calculation which introduced a error of
factor 10.

Signed-off-by: Stefan Fuchs <sfuchs@gmx.de>
2019-08-28 22:28:30 +02:00
Robert C. Helling
a0912b38bd Replace table interpolation by two line fit for CNS
We used a table lookup for CNS equivalent times. Turns
out the log of this table falls pretty much on a straight
line for po2 <= 1.5bar. We now fit this tabel two two
lines, one for <= 1.5 bar and one above. This four
parameter fit has half the sum of errors squared
than the five parameter fit using a fourth order
polynomial.

Fitting the log has the advantage that this never
crosses 0, which would have the bad effect of
resulting in negative CNS values as we divide
by the table value.

We don't adopt a maximum pO2 cut-off for the CNS calculation
but rather live with the large values that the interpolation
formula produces when extrapolating.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2019-08-20 18:32:07 +02:00
Berthold Stoeger
ba4d6ae627 Cleanup: use clear_git_id() instead of setting saved_git_id
For better encapsulation, use clear_git_id() in clear_dive_file_data()
instead of setting saved_git_id directly.

Thus, memory management of the saved_git_id value is encapsulated
and can be modified more easily.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-08-04 16:22:19 -07:00
Berthold Stoeger
a5e7f4253a Core: dynamically resize weight table
Replace the fixed-size weightsystem table by a dynamically
relocated table. Reuse the table-macros used in other parts
of the code.

The table stores weightsystem entries, not pointers to
weightsystems. Thus, ownership of the description string is
taken when adding a weightsystem. An extra function adds
a cloned weightsystem at the end of the table.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-07-18 06:01:07 -07:00