Commit graph

1663 commits

Author SHA1 Message Date
Berthold Stoeger
4d06ddd723 Dive sites: don't delete unused dive sites on save
Unused dive sites were deleted on save. This clashed with the undo
system in the following scenario:

1) Delete single-use dive site.
2) Save (dive site deleted)
3) Undo (reference to freed dive site)

Therefore, as a quick-fix, keep the referenced dive site around.
Note that this also means that empty dive sites must not be
deleted, as it might refer to a dive in the undo system. Instead
only clear references to empty dive sites in the global dive
table. Factor this functionality out, as it was common to the
XML and git savers.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-07 09:33:24 -08:00
Dirk Hohndel
da52440963 Merge branch 'shearwater_cloud' of https://github.com/mturkia/subsurface 2019-01-07 09:31:12 -08:00
Miika Turkia
fd5aad7192 Use state structure for sample rate info
Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2019-01-03 06:56:48 +02:00
Miika Turkia
9c42345494 Use correct value for PO2
averagePPO2 appears to be correct value instead of currentPPO2SetPoint.

Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2019-01-01 15:32:27 +02:00
Miika Turkia
5930cb52de Grab correct setpoint on Shearwater cloud import
Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2018-12-31 06:21:53 +02:00
Miika Turkia
01365b8c4b Use different time field as it seems to be more correct
The starTimestamp is 4 hours apart on 2 different DCs within the sample
log. DiveDate on the dive_logs table seems to be correct, but must be
converted from human readable format.

Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2018-12-30 16:31:51 +02:00
Miika Turkia
5e0f105114 Sample rate varies between dives
Seems that Shearwater cloud stores sample rate into the database and
it is not constant within the log.

Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2018-12-29 22:39:55 +02:00
Miika Turkia
2bc7aa5fc7 Initial support for Shearwater Cloud
This works to some extent to part of a sample log I received. However,
still quite a bit more work is needed.

Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2018-12-29 21:32:55 +02:00
Miika Turkia
a0d7b76dd0 Shearwater import: dive id might be large than int
I encountered this while implementing Shearwater Cloud import, but it
makes sense to increase the size for dive id for Shearwater Desktop as
well.

Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
2018-12-29 21:31:12 +02:00
Lubomir I. Ivanov
d4d9b840cc windows.c: fix wrong usage of wcslen() for utf8 conversation
wcslen() returns the number of characters in a wchar_t string.
In the case of WideCharToMultiByte() an estimate for the size of
the utf8 buffer is needed. Using wcslen() is incorrect for such a buffer,
because for any non-ASCII character the estimate will be off by 1 byte.

Call the following instead to obtain the proper UTF8 buffer size
for the conversation:
  WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL);

Also fix some missing "\n" in fprintf() calls.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2018-12-29 18:27:21 +01:00
Jan Mulder
09a7736ae1 Core: fix BT on Linux, workaround Qt bug on 5.12.0
After upgrading to Qt 5.12.0, download over BT from a DC did not work
any more. On the console the message "Connecting to port is not
supported (Uuid required)". Linus noticed earlier that we do rather
strange processing in this part of the code related to selecting port 1
or port 5. This all seems not needed (any more), but broader testing is
advised. This being stripped from the code, the mentioned error from Qt
persisted. That is strange in itself, as we did not reference port
numbers any more.

Step 2 in this commit is actually using an uuid to the call to
connectToService. Choosing an uuid seems relatively straightforward as
we can use the same one we already use for Android. That is the default
BT RFCOMM Serial Port Profile uuid. Interestingly, when changing to this
uuid we run immediately in a Qt runtime error telling us "QDBusPendingReply:
type ManagedObjectList is not registered with QtDBus.". For these 2
unexpected Qt messages, QTBUG-72742 was made. Studying the Qt source
code at this point reveals a possible workaround. Simply create a local
QBluetoothLocalDevice object, which, behind the scenes registers the Qt
internal ManagedObjectList with QtDBus.

In the meantime, Qt agrees that QTBUG-72742 is valid, and that a fix is
to be expected in a future version. At that point in time, the
declaration of the QBluetoothLocalDevice can be deleted again.

In the end, interfacing over BT works again.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-12-27 15:15:07 -08:00
Jan Mulder
ffec5f4991 Bluetooth: all states other than HostPoweredOff qualify as valid
This is an attempt to fix issue #1896. While this seems a Qt issue in
combination with very specific Android devices, this might be a fix. Do
not check for a very specific state of the local BT controller, but just
check if it is powered on.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-12-23 21:43:57 +01:00
Berthold Stoeger
99d29a7838 Cleanup: remove unused parameter was_autogen
In commit 6bf4120dbb the trip-flags
were replaced by a simple boolean. This made the was_autogen
parameter to the remove_dive_from_trip() and unregister_dive_from_trip()
functions unused. Remove these parameters.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-23 20:00:45 +01:00
Dirk Hohndel
6ba1cf8cf7 core: recognize Oceanic Pro Plus X over BLE
Just like with the Aqualung i770R in 7697003498 this name follows the
pattern of a model number in ASCII encoding, followed by the serial
number of the device.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-12-21 12:41:43 -08:00
Berthold Stoeger
bfe69239df Import: unglobalize downloadTable
To make data flow more clear, unglobalize the downloadTable object.
Make it a subobject of DownloadThread. The difficult part was making
this compatible with QML, because somehow the pointer to the
download-table has to be passed to the DiveImportedModel. Desktop would
simply pass it to the constructor. But with objects generated in QML
this is not possible. Instead, pass the table in the repopulate()
function. This seems to make sense, but for this to work, we have to
declare pointer-to-dive-table as a Q_METATYPE. And this only works
if we use a typedef, because MOC removes the "struct" from "struct
dive_table". This leads to compilation errors, because dive_table is
the symbol-name of the global dive table! Sigh.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-17 07:37:32 -08:00
Berthold Stoeger
abf942f303 Cleanup: make DCDeviceData a "normal" singleton
DCDeviceData was using that weird pattern where the instance
variable was set in the constructor. There is no apparent
reason to do so, therefore convert to a "normal" singleton.

Access that directly in QMLManager instead of saving it in
a member variable first.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-17 07:37:32 -08:00
Berthold Stoeger
6184f5d276 Core: remove count_dives_with_*() functions
The simplified filter-widget doesn't present lists of existing values
with counts. Thus, a whole slew of count_dives_with_*() functions
can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-17 07:33:45 -08:00
Robert C. Helling
ac8db01873 Show average max depth in yearly statistics
this was requested in #1854 and I think this suggestion makes sense

Fixes #1854

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-12-17 12:18:26 +01:00
Berthold Stoeger
c64c9c923b Cleanup: detangle unregister_dive() and delete_single_dive()
These two functions were called in different contexts:
- unregister_dive(): from the undo-commands to remove the dive
  from the global dive table, but not delete it. The dive was
  already removed from its trip.
- delete_single_dive(): from non-undo code. Most of it not in
  use and removed in a sibling-commit. Here, the dive is supposed
  to be removed from its trip and a new selection is calculated.

delete_single_dive() calls unregister_dive(), which removes the
dive from its trip. Move remove_dive_from_trip() from the former
to the latter and make both functions independent. Instead
of deleting the dive explicitly in delete_single_dive(), call
the delete_dive_from_table() function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-14 00:29:31 +08:00
Berthold Stoeger
dfd7f98129 Core: don't remove dive from trip in add_dive_to_trip()
All callers of add_dive_to_trip() work on freshly generated dives,
with one exception, that was redundant anyway. Therefore it is not
necessary to remove the dive from a potential previous trip. Move the
responsibility of removing the dive from a trip to the caller,
respectively remove the redundant call. Add a warning message in the
case that trip is set.

Background: On import (either download or file-import) we might not
want to add trips to the global trip-list. For example to enable undo
of import but more generally to detangle that data flow. Thus,
add_dive_to_trip() should not mingle with the global trip-list,
which it has to do if a trip is deleted because the old dive was
removed.

Analysis of the add_dive_to_trip() callers:

1) core/dive.c

pick_trip():
    called on freshly generated merged dive.

finish_split():
    called on two freshly generated split dives.

2) core/divelist.c

create_and_hookup_trip_from_dive():
    called on freshly downloaded dive in dive_cb().
    called on freshly downloaded dive in record_uemis_dive().

autogroup_dives():
    called on dive from get_dives_to_autogroup(), which only
    finds dives that are outside of trips.

combine_trips():
    unused - removed in sibling commit.

try_to_merge_into():
    this call was actually erroneous - dive was already added
    to trip in try_to_merge(). Remove call.

3) core/libdivecomputer.c

dive_cb():
    called on freshly downloaded dive.

4) core/uemis_downloader.c

record_uemis_dive():
    called on freshly downloaded dive.

5) core/load_git.c

create_new_dive():
    called on freshly allocated dive.

6) core/parse.c

dive_end():
    called on freshly parsed dive.

7) desktop-widgets/command_divelist.cpp

DiveListBase::addDive():
    called on dive which is newly added to core.

moveDiveToTrip():
    called on dive that was removed from trip a few lines above.

8) mobile-widgets/qmlmanager.cpp

QMLManager::undoDelete():
    called on dive where divetrip was reset in the previous line.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-14 00:29:31 +08:00
Berthold Stoeger
662dd823fd Cleanup: remove split_dive_*() functions
In 302f6adb79 dive-splitting was made
undo-able. To this goal, the dive-splitting functions were split in
two types: Those that operate directly on the divelist and those that
only allocate the dives. The former are not in use anymore, therefore
remove them. Since only the latter remain, remove the "_dont_insert"
appendix of the name.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-14 00:25:07 +08:00
Berthold Stoeger
10c20babae Cleanup: remove merge_two_dives() function
In 014c04f8bd merging dives was included
in the undo-system. This made the merge_two_dives() function caller-less.
Remove it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-14 00:25:07 +08:00
Berthold Stoeger
a597929c10 Cleanup: remove remove_autogen_trips() function
In f427226b3b autogrouping / removal
of autogrouping was moved into the undo-machinery. This made the
remove_autogen_trips() function caller-less. Remove it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-14 00:25:07 +08:00
Berthold Stoeger
0a3d757aab Cleanup: remove combine_trips() function
In f427226b3b a combine_trips_create()
function was introduced that combined trips without deleting the old
trips. This was necessary for making combine-trips function undo-able.

The old combine_trips() function is not used anymore. Therefore remove
it. Rename the combine_trips_create() function to combine_trips() as
no differentiation is needed anymore.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-14 00:25:07 +08:00
Berthold Stoeger
3cdc2661d2 Dive media: add media to closest dive
Currently, when selecting "Load media files even if time does not
match the dive time", the media are added to *all* selected dives.
Instead add it to the closest dive.

This seems like the less surprising behavior. Of course now if the
user really wants to add a media file to multiple dives, they will
have to do it manually.

To avoid a messy interface, this is solved by moving the iterate-
over-selected-dives loop to the core. Thus, a helper-function can
be made local to its translation unit.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-13 08:11:22 +01:00
Berthold Stoeger
4bfcf12c17 Cleanup: remove EMPTY_DIVE_STRING
EMPTY_DIVE_STRING used to be a string-literal representing missing
information ("--"). In 6985c123d4 it
was replaced by the actual empty string. Using a literal to represent
the empty string seems a bit pointless, therefore remove it completely.

Notably:
	QString(EMPTY_DIVE_STRING) -> QString()
	if (temp.isEmpty()) temp = EMPTY_DIVE_STRING; -> noop
	if (s == EMPTY_DIVE_STRING) -> if (s.isEmpty())

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-24 11:01:20 -08:00
Berthold Stoeger
d67ecf8925 Cleanup: remove redundant 'extern "C"' in dive.h
In dive.h there was a redundant 'extern "C"' block defined inside
another 'extern "C"' block. Remove.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-23 13:24:00 -08:00
Berthold Stoeger
1ebf5a99ed Filter: use hidden_by_filter also on mobile
Desktop used the hidden_in_filter flag in struct dive, mobile
used its own vector plus a new showndives member in struct dive_trip.

Unifiy these to use the same core-facility, viz. hidden_by_filter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-23 13:22:24 -08:00
Berthold Stoeger
70897dd1b7 Core: move is-single-day-trip and count-shown functions into core
These functionality was used by the desktop filter. To unify desktop
and mobile, move it into two new functions in divelist.c

Since one of them is the only caller of is_same_day() move that
likewise into divelist.c and make it of static linkage.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-23 13:22:24 -08:00
Berthold Stoeger
68414531ad Mobile: don't format trip heading for all dives
QML's ListView uses the "section" property to test if items belong to the
same section. Apparently, this must be a string and therefore we can't
pass e.g. a dive-trip object. Therefore a specially formatted string
was passed in, which was guaranteed to be unique (contained the dive-trip
pointer value) and the fully formatted trip-title and short-date.

The disadvantage of that approach is that the formatting is performed for
every dive and not every trip. Perhaps not a problem now, but it makes
it for example necessary to cache the number of filtered dives.

To be more flexible, pass in only the pointer value formatted as
hexadecimal string and provide a function to convert that string
back to a trip-pointer (in the form of a QVariant, so that it can
be passed to QML). Moreover provide two functions for formatting the
title and the short-date.

The three new functions are members of DiveListSortModel. This might not
be the perfect place, but it is easy to reach from the DiveListView.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-23 13:22:24 -08:00
Berthold Stoeger
a863386cd4 Cleanup: remove DiveObjectHelper::trip() function
The DiveObjectHelper::trip() function was
1) Misnamed: it returned the *location* of the trip
2) Not used outside of DiveObjectHelper

Remove it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-23 13:22:24 -08:00
Berthold Stoeger
9e565e3552 Cleanup: make "struct dive *" and "struct dive_trip *" Qt metatypes
Just as we did for pointer to struct dive_site, make pointers to
struct dive and struct dive_trip "Qt metatypes". This means that
they can be passed through QVariants without taking a detour via
void *.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-23 13:22:24 -08:00
willemferguson
fba6ec5ad5 Improve OTU calculations
Implement the protocol in Erik Baker's document
"Oxygen Toxicity Calculations". This code uses a
third-order polynomial approximation of Baker's
equation 2. Provision is made for
PSCR and CCR dive logs and dive plans. In the
case of dive logs, the values of o2 sensors are
used if there are data from such sensors. For CCR
only the data from the first O2 sensor is used even if
there are more than one sensor. This is a potential
weakness, but this function is probably NOT the
place to calculate mean o2 values accross all sensors
and to emulate voting logic to reject info from
aberrant sensors.

Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-11-22 02:37:14 +02:00
Berthold Stoeger
da866583fd Git parser: don't produce user-visible error on git parsing
In 64e6e435f8 the when field of struct
trip was removed. Accordingly it was not read from git repositories.
This produced a large amount of user-visible error messages.

Reinstate the trip-date and time parsing functions, but ignore
the value.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-21 12:45:29 -08:00
Berthold Stoeger
01d031383c Core: fix crash concerning removal of dives from trips
Commit 6b283e598a replaced the linked
list of dives in a trip by a table. Embarassingly, on dive deletion
the index of the dive in the table was compared for "!= 0" instead
of ">= 0". Thus, the first dive of a trip wouldn't be deleted, which
ultimately led to a crash, as different parts of the code were now
in disagreement over whether the trip is empty or not.

Fix the comparison.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-21 10:29:15 -08:00
Berthold Stoeger
6bf4120dbb Core: replace tripflag by notrip boolean
The only remaining use of the tripflag was to mark dives that
were removed explicitly from a trip, i.e. shouldn't be autogrouped.
Therefore replace the enum by a simple boolean.

Currently, there is no way of unsetting the notrip flag. But this
shouldn't result in a user-visible change.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-20 08:14:54 -08:00
Berthold Stoeger
3b9e0b5931 Core: remove ASSIGNED_TRIP trip flag
The distinction between ASSIGNED_TRIP and IN_TRIP was used to
prefer non-autogenerated trips on merging of dives. But owing
to bit rot this seem to have worked only partially anyway:
The IN_TRIP field was set in create_and_hookup_trip_from_dive()
and immediately overwritten in add_dive_to_trip() called
in the next line.

Instead, use the trip->autogen flag to check for priority and
remove the ASSIGNED_TRIP flag alltogether.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-20 08:14:54 -08:00
Berthold Stoeger
dcb2a17b7d Core: remove two unused macros
The UNGROUPED_DIVE and DIVE_IN_TRIP were never used. Remove them.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-20 08:14:54 -08:00
Berthold Stoeger
d0ac061eaf Uemis downloader: free ans_path on error
In a few instances, the ans_path was not freed on error. Fix them.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-19 13:51:03 -08:00
Berthold Stoeger
26a4fb5632 Warnings: silence new gcc warnings in uemis-downloader.c
Since upgrading to gcc 8.2 it produces noisy warnings about
potentially truncated strings. It doesn't recognize that
filenr can never become >4000. So clamp it down explicitly.

Do this by adding a function that does the assembly of the
filename path. Adding unnecessary code to silence compiler warnings
is dubious, but in this case it might be reasonable.

Fix a second instance by increasing the stack-allocated buffer
to 32 bytes. Hopefully nobody has more divespots than would
fit in a 9-decimal digit number!

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-19 13:51:03 -08:00
Berthold Stoeger
0fc58f4534 Parser: add dive to trip at end of dive-parsing
When adding the dive to its trip before having filled out "when", the
dive gets added at the first position (when=0), which is usually not
correct. Instead, add the dive to its trip when all fields are correctly
filled out.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
64e6e435f8 Core: remove "when" field of struct dive_trip
The when field gives the time of the first dive. Instead of keeping
this field in sync, replace it by a function that determines the time
of the first dive.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
243962a67a Dive list: move sort-functionality into core
To make sorting more controlled, move all sorting functions into
the core. For this, introduce a "dive_or_trip" structure, which
represents a top-level item. Adapt the DiveTripModel accordingly.
There are now three sorting functions:
	1) dive_less_than
	2) trip_less_than
	3) dive_or_trip_less_than
These should be used by all sorting code. By moving them to a
single place, the mess can hopefully be cleaned up.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
9d3a5fa997 Dive list: implement trip_less_than function
As a step towards proper sorting, introduce a trip_less_than()
function in core. It simply sorts by the first dive, which should
be unique as dives may belong to only one trip.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
6b283e598a Dive list: replace dive-list of trips by a table
The dives of each trip were kept in a list. Replace this by a
struct dive_table. This will make it significantly easier to
keep the dives of a trip in sorted state.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
bc7afebc23 Core: add add_dive_to_table() function
Up to now, dives were added to the global dive table with
add_single_dive(). Split out the funtionality to add a dive to
an arbitrary dive in the add_dive_to_table_function(). The
difference compared to record_dive_to_table is that dives
are added at a specific position or the sort-criterion given
by dive_less_than(). This will allow to use a dive tabe for trips
instead of a linked list.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Berthold Stoeger
0618aa737f Core: unify insert_trip() and insert_trip_dont_merge()
There were two versions of the insert_trip() function: one
would merge trips if a trip with the same date already existed,
the other wouldn't. The latter was introduced with the dive-list
undo work.

The problem is that the "date" of a trip (i.e. the first dive)
seems ill-defined as this is a volatile value. Moreover in
the context of making dive-import undoable this is a very
dangerous notion, as the caller needs control over when the dives
are added to a trip.

Therefore, unify these two functions and never merge trips.
The decision on merging dives now has to made by the caller.
This will be implemented in a future commit.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-18 16:50:09 -08:00
Daniel Krupp
c48056300d Fix Cressi interface ftdi opening bug
The Cressi specific PID was not used
when  serial_ftdi_open_device tried
to open the device.

Reported-by: Daniel Krupp
Signed-off-by: Daniel Krupp <daniel.krupp@gmail.com>
2018-11-18 20:01:28 +02:00
Berthold Stoeger
49d1144336 Dive list: use dive trip time as additional sort criterion
The DiveTripModel places dives after trips in chronologically
ascending mode if the dive and the trip start at the same instant.
But in the core the sort order was undefined. This could lead
to a discrepancy. Therefore, implement the same sort-criterion
in the core code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-16 16:57:14 -08:00
willemferguson
1aef22116c More accurate CNS calculations (following comments on github)
Update table of maximum oxygen exposure durations, used in CNS calulations.
This table shows the official NOAA maximum O2 exposure limits
(in seconds) for different PO2 values. It also gives
slope values for linear interpolation for intermediate PO2 values
between the tabulated PO2 values in the 1st column.
Top & bottom rows are inserted that are not in the NOAA table:
(1) For PO2 > 1.6 the same slope value as between
1.5 & 1.6 is used. This exptrapolation for PO2 > 1.6 likely
gives an underestimate above 1.6 but is better than the
value for PO2=1.6 (45 min). (2) The NOAA table only
tabulates values for PO2 >= 0.6. Since O2-uptake occurs down to
PO2=0.5, the same slope is used as for 0.7 > PO2 > 0.6.
This gives a conservative estimate for 0.6 > PO2 > 0.5. To
preserve the integer structure of the table, all slopes are
given as slope*10: divide by 10 to get the valid slope.
The columns below are:
po2 (mbar), Maximum Single Exposure (seconds), single_slope,
Maximum 24 hour Exposure (seconds), 24h_slope */

Then update Calculations of the CNS for a single dive  -
this only takes the first divecomputer into account.
The previous version of the code did a table lookup and
used the max O2 exposure for the next-higher PO2 category.
This gave a shorter max O2 exposure time and a higher CNS
contribution for a specific dive segment, resulting in a
slightly conservative value of CNS, often some 2 - 3 % too high.
This code does an interpolation for PO2 values inbetween
PO2 entries in the lookup table and therefore results in a more
accurate maximum O2 exposure time for that PO2.
The maximum O2 exposure duration for each segment
is also calculated based on the mean depth of the two
samples (start & end) that define each segment. The CNS
contribution of each segment is found by dividing the
time duration of the segment by its maximum exposure duration.
The contributions of all segments of the dive are summed to
get the total CNS% value. This is a partial implementation
of the proposals in Erik Baker's document "Oxygen Toxicity Calculations" */

Overall, this PR does not radically alter the existing CNS calculation,
it only makes it more accurate and more consistent by doing
interpolation and by using mean segment depth to find PO2.

Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>
2018-11-16 16:56:42 -08:00
Berthold Stoeger
1b77255807 Dive list: correctly translate trip date
Adapt get_trip_date_string() to use the same logic as get_dive_date_string():
Use the static "loc" object to translate date. Before, the trip
date was shown in C locale.

Reported-by: Philippe Massart <philippe@philmassart.net>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-16 16:55:55 -08:00
Berthold Stoeger
bef756073a Coding style: remove stray ';'
There was a stray semi-colon on the beginning of a line in
DiveObjectHelper.cpp. Remove it.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-12 20:55:41 -08:00
Berthold Stoeger
282e6a9f48 Cleanup: remove unsused flags in struct dive_trip
Usage of the flags expanded, selected and fixup was removed some
time ago. Remove the flags too.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-12 20:55:41 -08:00
Dirk Hohndel
cdc9666281 Core: use British translations in South Africa
For unrecognized locales we use en_US by default. It makes much more sense for
South Africa to use en_GB.

Reported-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-11-01 09:30:14 -07:00
Jan Mulder
26f6d95305 Core: Do not crash on save dives with no dive site (git storage)
And fix a crash very similar to the previous commit. When trying to
save (to git) with an empty dive site, ssrf crashes.

Again, add a simple guard to prevent this.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-31 14:51:31 +00:00
Robert C. Helling
62c57be1da Fix gasmix for OTU calculation
With the fixed sematics of get_gasmix to return the new gasmix for
the time of a gas switch (added comments to make this clear), in the
OTU calculation we need the previous gasmix for the interval up to the
current time.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-10-30 15:33:43 +01:00
Robert C. Helling
d9f2b537af Fixed get_gas_at_time for equal times
This fixes a subtle bug introduced in 5c4569247a which
unified two functions finding the gasmix at a given time
during the dive. There was a slight difference, though:
Does a gaschange exactly at that time count or not? For
the planner to work, the answer has to be in the affirmative.

Signed-off-by: Robert C. Helling <helling@atdotde.de>
2018-10-30 15:33:43 +01:00
Berthold Stoeger
a0cc02dfe8 Dive list: don't pass dive_site via uintptr_t through QML
Now that struct dive_site * is a proper Q_METATYPE it is not
necessary anymore to pass dive-sites as opaque uintptr_t types.
Simply pass a QVariants or directly via dive_site *.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
920eb7576f Dive site: pass pointer-to-dive_site via QVariant
There was this ugly pattern of passing pointers-to-dive_site via
a QVariant of void * type. This is of course inherently unsafe.

Pass these pointers using their proper types instead. This makes
it necessary to register them in Qt's meta-type system. Doing so,
fixes a bug: QML couldn't call into updateDiveSiteCoordinates()
because it didn't know the type and thus the coordinates of
the moved flag were not reflected in the divesite-dialog.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
724055f0af Dive site: replace dive->dive_site_uuid by dive_site
Replace the UUID reference of struct dive by a pointer to dive_site.
This commit is rather large in lines, but nevertheless quite simple
since most of the UUID->pointer work was done in previous commits.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
f41bb32428 Dive site: use an array of pointers in reloadMapLocations()
MapWidgetHelper::reloadMapLocations() used an array of uuids to
add dive sites to the map only once. Replace this by an array
of pointers. This is a small piece of a larger effort to remove
dive site UUIDs.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
75b5d61522 Dive site: replace UUID by pointer in mobile code
Replace UUIDs by pointers to dive-site in mobile code. In both
cases, the value is transported via a QVariant. The function
getCoordinatesForUUID(), which was only used from mobile, can
be replaced by a getCoordinatesFor() function taking a variant
supposed to contain a dive-site pointer. Likewise, the variant
of the centerOnDiveSite function is now supposed to wrap a
pointer-to-divesite.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
d674c5028f Dive site: use pointer instead of uuid in uemis_helper
Another small step in removing dive-site UUIDs: use a pointer
instead of a UUID in the "uemis_helper" structure.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
64f0902e0d Dive site: pass dive-site pointers to merge_dive_sites()
Instead of passing uuids, pass a pointer to the dive site.
This is small step in an effort to remove uuids.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
f527a70831 Dive site: pass dive-site pointer to delete_dive_site()
Instead of passing a uuid, pass a pointer to the dive site.
This is small step in an effort to remove uuids.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
8de471f90e Dive site: pass dive-site pointer to is_dive_site_used()
Instead of passing a uuid, pass a pointer to the dive site.
This is small step in an effort to remove uuids.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
14ab95608c Dive site: pass dive-site pointer to nr_of_dives_at_dive_site()
Instead of passing a uuid, pass a pointer to the dive site.
This is small step in an effort to remove uuids.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
d3a7c5448f Dive site: return pointer to dive_site in create_dive_site_*()
This changes more of the dive-site interface to return pointers
instead of UUIDs. Currently, most call sites directly extract
UUIDs afterwards. Ultimately, the UUIDs will be generally replaced
by pointers, which will then simplify these callers.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
ae6239bfec Dive site: remove uuid in Uemis' divesite-map
The uemis downloader uses a cache for location to divesite id.
Trivially, the divesite-uuid can be replaced by a pointer. This
is a tiny step to remove divesite UUIDs.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Berthold Stoeger
68961a169e Dive site: return pointer to dive_site in get_dive_site_*()
As a first step in removing dive-site uuids, change the interface
of the get_dive_site_*() functions to return pointers instead
of uuids. This makes code a bit more complicated in places where
the uuid is extracted afterwards (needed NULL check). Nevertheless,
these places should disappear once pointers instead of uuids are
stored in the dive-structures.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29 00:09:31 +00:00
Dirk Hohndel
4461b47965 qPref: reduce recompiles with every commit
Including ssrf-version.h in an include file that a lot of files depend on
caused a ton of unnecessary recompiles with every commit. This should reduce
that problem.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-27 07:16:01 -07:00
Berthold Stoeger
b02fd072e7 Cleanup: remove dead code in qthelper.cpp
The reverseGeoLookup() function defined in qthelper.cpp has long
ago moved to its own compilation unit. It is not even defined in
the headers anymore. Remove it and the now unnecessary <QNetwork*>
includes.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-26 17:50:52 +01:00
Dirk Hohndel
89a242976f core: use nr of dives shown in tripMeta info
When creating a trip header (as it is used in the mobile app right now), we need
to show the number of dives shown, not the total number of dives in that trip.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-25 23:24:22 +01:00
Dirk Hohndel
f7b1c762a9 core: add seperate number of dives shown to the trip structure
We assume that any dive that gets added to a trip initially gets shown. The
filter logic then needs to make sure it adjusts this number (which then makes
it easy to tell the user how many dives of that trip are visible with the
current filter).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-25 23:24:22 +01:00
Dirk Hohndel
66184d58e8 core: add ability to get underlying dive to DiveObjectHelper
This feels a bit like cheating, but if we need to be able to make modifications
to the underlying dive and only have the helper object (for example inside of a
view model), doing everything through the helper object can turn into a real
performance issue.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-25 23:24:22 +01:00
Dirk Hohndel
40536286d2 Mobile/filtering: add fullTextNoNotes to the dive object helper
This way we can filter with and without the notes.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-23 22:45:30 +01:00
Dirk Hohndel
eedb1ce0ea Mobile/filtering: add two preferences for filtering
With this we can make it configurable if the search should include the notes field
and if the search should be case sensitive or not.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-23 22:45:30 +01:00
Dirk Hohndel
2fe1750bf8 Mobile/filter: add marker between entries in full text search
Otherwise we could match the end of one string and the beginning of the next,
so having a buddy name Linus and a dive master named Alvin would be matched
by USA.

Also add Notes to the full text search (I had forgotten those earlier).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-23 22:45:29 +01:00
Dirk Hohndel
8f7633eff8 Mobile/filtering: full text filter, instead of just dive site
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-23 22:45:29 +01:00
Berthold Stoeger
954553b878 Parser: remove static variable location in import-cobalt.c
A static variable was used to collect two parts of the location
string. Instead, explicitly store these two parts in two different
strings and concetenate them. One fewer variable and the program
flow is thus hopefully more clear.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-23 08:06:28 +01:00
Berthold Stoeger
138f27f65d Parser: make parser (mostly) reentrant
Introduce a parser_state structure, which describes (most) of the
global parser state. Create such a structure in the entry routines
to the parser and pass it down to the individual functions. The
parser state is initialized and freed with the init_parser_state()
and free_parser_state() functions.

The main benefits are:
1) Isolation of parser state.
2) Keeping the global name space tidy.
3) Prevent memory leaks which could happen in truncated files by
   freeing all the parser state after parse.

A somewhat controversial point might be that the individual
parsing functions are split in those that need parser-state and
those that don't. This means that there are now two versions of
the MATCH macro, viz. one for the former and one for the latter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-23 08:06:17 +01:00
Berthold Stoeger
343808271c Core: accept NULL-pointer in free_trip() and free_divesite()
This is consistent with most other free_*() functions in the core
code and will make cleanup of parser state less verbose.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-23 08:06:17 +01:00
Berthold Stoeger
46bf8bf2fa Core: export free_picture()
Export the free_picture() function from dive.c. The parser may need
this in case of truncated files to free its temporary resources.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-23 08:06:17 +01:00
Berthold Stoeger
ee0fc25cf3 Parser: remove webservice related code
Recently, the subsurface webservice was removed. Remove the corresponding
code in the parser. This removes a static variable, which was used
to generate unique dive-site ids.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-22 09:07:27 -04:00
Berthold Stoeger
bca9c8f88c Parser: free city and country after use
The variables country and city used in divinglog_place()
were never freed. Free them when the pointers are reset.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-21 19:56:02 +03:00
Berthold Stoeger
9025694d12 Parser: free old string in utf8_string
The utf8_string() function is used to extract whitespace-trimmed
strings. The function would happily overwrite the pointer to
the old string, which could therefore leak (suppose an XML has
redundant attributes).

Therefore preemtively free the string output parameter. This makes
it of course necessary to only pass in NULL-initialized pointers
or pointers to owned string.

The code survives the current set of parser-tests.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-21 19:56:02 +03:00
Linus Torvalds
28e3413ff6 Add 'location_t' data structure
Instead of having people treat latitude and longitude as separate
things, just add a 'location_t' data structure that contains both.

Almost all cases want to always act on them together.

This is really just prep-work for adding a few more locations that we
track: I want to add a entry/exit location to each dive (independent of
the dive site) because of how the Garmin Descent gives us the
information (and hopefully, some day, other dive computers too).

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-21 19:55:09 +03:00
Jan Mulder
66c4397efd Preferences: wire-up the deco parameters
The deco parameters need special treatment to wire them up to the
underlying deco model code. And with the new preferences setup this
is a lot of boilerplate.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-19 06:25:32 -04:00
Berthold Stoeger
5a65bb75da Parser: don't leak extra data key/value pairs
On parsing of dive computer extra data, key/value pairs are stored
in global state. They are added to the dive computer with
add_extra_data(), which makes a copy of the string. The local
copies of the strings are never freed.

free() the strings after storing them. The data still leaks in case
of unfinished parsing of extra_data tags, but this will be
taken care of in a subsequent commit.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-16 06:20:46 -04:00
Berthold Stoeger
6fd663f9b3 Core: use free_dc_contents() in delete_current_divecomputer()
delete_current_divecomputer() had some duplicate code to release
dive-computer resources. Use the free_dc_contents() function instead.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-16 06:20:33 -04:00
Berthold Stoeger
065c41b834 Core: copy / free serial and fw_version items of struct divecomputer
The serial and fw_version strings of struct divecomputer were copied
by pointer. This worked because they were never freed or modified.
Instead, do a deep copy of the strings and free them when appropriate.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-16 06:20:33 -04:00
Berthold Stoeger
c61cf991e0 Core: copy and free extra_data of dive computer structure
On dive computer copy, the extra data (a list of key/value pairs)
was simply copied as a pointer. This worked because the list was
never freed nor modified. Copy and free the list on dive computer
copy and free, respectively.

This made it necessary to move the STRUCTURE_LIST_* macros up in
the dive.c file.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-16 06:20:33 -04:00
Berthold Stoeger
763c3683e5 Core: fix broken commit e5dca8228e
In commit e5dca8228e a fixed order
of the arguments to merge_dives() was introduced: first dive old,
second dive downloaded. This made the dl variable, which pointed
to the downloaded dive useless. One instance was forgotten, which
led to a null-dereference.

Remove.

Reported-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-15 21:00:45 -04:00
Berthold Stoeger
7f49e43d76 Cleanup: make xml_parsing_units local to parse-xml.c
xml_parsing_units stores the units of the currently parsed XML
file. It is not used outside of parse-xml.c. Therefore, make
it of static linkage and remove the declaration from dive.h.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15 21:00:17 -04:00
Berthold Stoeger
253510c555 Cleanup: remove apparently dead code in sanitize_cylinder_type()
sanitize_cylinder_type(), which is indirectly called from fixup_dive(),
had ft^3 -> mliter conversion code, which was executed on the
condition "xml_parsing_units.volume == CUFT".

But nowhere in the code base would xml_parsing_units.volume ever be
set to non-metric. Moreover, xml_parsing_units reflects the units
of the latest parsed XML file, but fixup_dive() is called in numerous
contexts not related to XML parsing. Therefore, the whole piece of
code seems highly questionable.

Remove this code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15 21:00:17 -04:00
Berthold Stoeger
08827cc5f6 Parser: fix leakage of dive-site and dive data
Dive site data was collected in "cur_dive_site", which was then
merged into an existing or a new dive site. But only the struct
dive_site pointed to by "cur_dive_site" and the taxonomy data
were freed, not the textual data such as name or description.
Therefore, split out the approrpriate free-ing from the
delete_dive_site() function and call that instead of a simple
free().

A similar situation occured for dives that would not be added
to the dive-table because they were deemed incomplete. Use
free_dive() here instead of a simple free() too.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15 20:59:55 -04:00
Linus Torvalds
a2028cd6ef deco: _really_ make sure the deco state is fully initialized
I incorrectly thought that 'ci_pointing_to_guiding_tissue' was the only
missing initialization, because that is the only one valgrind pointed at.

... that is, until I started looking at a few more dives, which showed
that there were other parts tht weren't initialized either, like

        double tolerated_by_tissue[16];
        double tissue_inertgas_saturation[16];
        double crushing_onset_tension[16];            // total inert gas tension in the t* moment

so just make sure to clear the whole data structure, to avoid any random
behavior due to uninitialized deco state.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-15 20:57:25 -04:00
Berthold Stoeger
0e00d40ead Selection: always make newly selected dive the current dive
In select_dive(), the selected dive would only be made the
current dive, if it wasn't previously selected. If multiple
dives were selected and the user clicked on one of them which
is not the current dive, then the current dive would be
deselected and thus not be the current dive anymore. The
only remaining dive would not be made the current dive,
because it was already selected. End result: null dive shown.

Therefore, always make the selected dive the current dive,
even if it is already selected.

Fixes #1792

Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15 20:57:10 -04:00
Berthold Stoeger
813c570524 Core: copy whole list in copy_dc_renumber()
copy_dc_renumber() is an internal function to copy dive computers
and renumber the cylinders. Since only the structure was copied,
in the case of multi-dc dives, the merged dives shared the same
computer. If one of them was freed, use-after-free crashes would happen.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15 20:55:03 -04:00
Linus Torvalds
193a7d3a56 deco: make sure deco state is fully initialized
This shouldn't have caused any issues, but it made for valgrind noise. So fix it.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-15 21:21:05 +02:00
Dirk Hohndel
a20626a874 Bluetooth cleanup: remove pointless download_mode
This was used to track whether we had selected the native BT mode in the
download dialog. But the information is redundant as we can tell from the
device name whether this is a BT/BLE download or not.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-15 19:46:18 +02:00
Berthold Stoeger
a58908df8e Dive import: reset current_dive in process_imported_dives()
process_imported_dives() might delete the currently selected
dives. This could lead to use-after-free problems. Therefore,
reset the currently selected dive to the last dive.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15 12:50:44 -04:00
Berthold Stoeger
2775e7e991 Dive import: remove dive-to-be added from trip before deletion
On dive import, dives to be added may be merged into already
existing dives. In such a case, the dive to be added is deleted.
Before doing so, it must be removed from the trip is belongs to
to avoid corruption of the trip-list.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15 12:50:44 -04:00
Berthold Stoeger
207ca0f94e Dive list: make deep copy of picture list on merge
On merging make a deep copy of the picture list, to avoid a use-after-free
crash after the orginal dive is deleted.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15 12:50:44 -04:00
Berthold Stoeger
471fc1dfc8 Dive list: fix crash on dive import
In commit 8c2383b495 dive merging was
changed to not modify the original dive. On import, dives were then
merged and the original deleted. The merge_weightsystem_info() was
not adapted accordingly (deep copy of string instead of pointer),
leading to a use-after-free crash.

Resolve this by doing a deep copy.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-15 12:50:44 -04:00
Berthold Stoeger
cf4d32c6e8 Cleanup: constify get_dive_gas() and get_dive_gas_string()
There's no reason for the dive input-parameter being non-const.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14 15:57:14 -04:00
Berthold Stoeger
444354ec9b Cleanup: free all data in clear_table()
Instead of calling free() on all dives, call free_dive() which also
frees additional allocated data, not only the dive struct.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14 15:55:07 -04:00
Berthold Stoeger
0b57b8d59f Cleanup: move clear_table() to divesite.c
There were two declaration of clear_table(), one in dive.h and one
in parse.h. The definition was in parse.c. Since the parser doesn't
even use the function, move the function and its declaration to
divelist.[ch] and remove the redundant declaration in dive.h.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14 15:55:07 -04:00
Berthold Stoeger
b01cba13c5 Parser: remove global variable dive_id
This variable was only used in the divinglog_dive() function. There,
it was initialized right at the beginning and therefore there seems
to be no point in conserving its value across function-calls.
Make the variable local and remove the global version.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14 15:55:07 -04:00
Berthold Stoeger
8ddbe50d29 Cleanup: remove rebasing artefacts
Embarrassingly, the header-comment in divelist.c contained a rebasing
artefact.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14 15:55:07 -04:00
Jan Mulder
ac9bab7e2f Autogroup only when selected
Comits f427226b3b and 43c3885249 of the undo series introduced 2 calls
of autogroup_dives() without checking the autogroup global boolean.
This is a bug. An import from DC (for example) then triggers an
autogrouping, the divelist is autogrouped, and the UI button
is off.

This commit solves this. I've chosen for a guard in the autogroup_dives()
that now is a no-op when called when the user did not select autogrouping.
In additon, simplified the other calls to this function, as we do
not need to check before calling any more.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-14 09:22:56 +02:00
Berthold Stoeger
8815f77ea0 Dive site: use own copy of taxonomy in dive-site-edit widget
The dive-site-edit widget uses a copy of the to-be-edited site
to compare with old values. Generally, this seems overkill
(the original dive-site can be used for such a comparison).
But one place where it can't simply be removed is the taxonomy,
because the widget needs a place to store the unsaved data.

Change the code to use an explicit taxonomy structure instead
of the one provided in the copy. This should ultimately allow
removal of the latter.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-13 21:41:41 -04:00
Berthold Stoeger
5d3967ce84 Dive site: un-globalize displayed_dive_site
The global object displayed_dive_site is used a a backing-store
by the dive-site-edit widget. All external accesses were removed,
therefore make the object local to the widget.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-13 21:41:41 -04:00
Berthold Stoeger
954820aa81 Dive site: explicitly init displayed_dive_site on show widget
The global object "displayed_dive_site" is used to store the
old dive site data for the edit-dive-site widget. The fields
of the widget were initialized from this object in the show
event. Therefore the object was updated in numerous parts of
the code to make sure that it was up-to-date. Instead, move
the initialization of the object to the function that also
initiatlizes the fields. Call this function explicitly before
showing the widget.

This makes the data-fow distinctly easier to understand.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-13 21:41:41 -04:00
Dirk Hohndel
7697003498 core: recognize Aqualung i770R over BLE
The name seems crazy until you realize that FQ is 0x4651 which is the model
number of the i770R. And the six digits are the serial number of the device.
Still crazy, but at least now you understand WHY.

Thanks to Jef for decoding that.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12 10:10:06 -07:00
Dirk Hohndel
c8fec97695 Bluetooth: add helper to separate BT name and address
And restructure the existing "isBtAddress()" function in the process.
Also add more tests.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12 08:22:44 -07:00
Dirk Hohndel
7512a6e915 Bluetooth: restart scan for different device on macOS
This makes no sense, but apparently we need to start a fresh scan in order to be able
to talk to a different BLE dive computer on the Mac.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12 08:22:44 -07:00
Dirk Hohndel
497c1248d4 Bluetooth: wait until we actually have device info
On macOS, we cannot connect to a BT/BLE device until we have scanned it. Right
now this just sits quietly and waits, which given how long this can take is
rather unsatisfying and might look like Subsurface is hung.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12 08:22:44 -07:00
Dirk Hohndel
9491c96103 Bluetooth: start discovery if address isn't already known
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12 08:22:44 -07:00
Dirk Hohndel
2954bc5f22 Bluetooth: move declaration and make variable file scoped
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12 08:22:44 -07:00
Dirk Hohndel
a5416b9bea Bluetooth: remember all data during a scan on macOS
Since we trigger a scan even without the dialog to pick the right
device, we need to remember all devices that we find.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12 08:22:44 -07:00
Dirk Hohndel
2ba3eab319 Bluetooth: discovery should always scan on macOS as well
Instead of only starting the scan when explicitly asked to do so in the BT
dialog, create the discovery agent when the download dialog opens, since on
macOS we cannot connect to a device without having scanned for it first.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12 08:22:44 -07:00
Dirk Hohndel
0cfd76740b core: helper function to recognize BT/BLE addresses
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-12 08:22:44 -07:00
Berthold Stoeger
ad57871a2c Geo lookup: don't pass arguments / result via global object
The reverseGeoLookup() fetches dive-site data via GPS coordinates.
The coordinates and the result were passed via the global
"displayed_dive_site" object. To make data-flow more clear,
pass data as in and out parameters instead.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:25:02 -07:00
Berthold Stoeger
04ad9c885d Geo lookup: make the reply a managed-pointer
By making reply a std::unique_ptr<>, the function can be quit
from any point and the reply will be freed. This is valid according
to Qt's documentation as we're not deleting during signal processing.

This commit fixes a leak: reply was overwritten with the address of
a new object without freeing the old object.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:25:02 -07:00
Berthold Stoeger
cb2f09a8e3 Geo lookup: make the QNetworkAccessManager a static object
According to Qt's docs, the QNetworkAccessManager is supposed
to be a long-living object. Therefore, don't create one on
every geo-lookup, but a single object for all geo-lookups.

By making the object function-local it is only initiaized
on first use. Morover this limits the amount of concurrent
geo lookups.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:25:02 -07:00
Berthold Stoeger
ce8199cdfd Cleanup: remove ReverseGeoLookupThread
Fetching the taxonomy from GPS coordinates was implemented in
a QThread. But the only access to the main function was a
direct call to run(). Thus, the thread was *never* started.
The function call was always asynchronous [it was using an
event loop though, so the UI doesn't hang]. Notably this
means that the signals connected to the thread would never
fire. And the spinner would never be activated.

Thus:
1) Turn the thread into a simple function.
2) Remove the spinner.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:25:02 -07:00
Berthold Stoeger
f836b9ae97 Dive list: unify sorting in core and Qt-model
Ultimately, we want to use a single dive-list and not replicate
it in the Qt-model code. To this goal, let's start with using
the same sort function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
8c2383b495 Undo: don't modify source-dives on merge
For undo, it is crucial that commands don't modify existing dives.
Unfortunately, dive merging would write into the data-structures
of the to-be-merged dives. To prevent it from doing so, make the
input dives const-pointers.

This led to a whole cascade of functions that had to take const
and significant churn.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
7067e33596 Undo: select dives after add, remove, merge, split dive commands
Select the proper dives after the add, remove, split and merge
dives commands on undo *and* redo. Generally, select the added
dives. For undo of add, remember the pre-addition selection.
For redo of remove, select the closest dive to the first removed
dive.

The biggest part of the commit is the signal-interface between
the dive commands and the dive-list model and dive-list view.
This is done in two steps:
1) To the DiveTripModel in batches of trips. The dive trip model
   transforms the dives into indices.
2) To the DiveListView. The DiveListView has to translate the
   DiveTripModel indexes to actual indexes via its QSortFilterProxy-
   model.

For code-reuse, derive all divelist-changing commands from a new base-class,
which has a flag that describes whether the divelist changed. The helper
functions which add and remove dives are made members of the base class and
set the flag is a selected dive is added or removed.

To properly detect when the current dive was deleted it
became necessary to turn the current dive from an index
to a pointer, because indices are not stable.

Unfortunately, in some cases an index was expected and these
places now have to transform the dive into an index. These
should be converted in due course.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
23db0ba68d Dive list view: replace signal-magic by flag
In DiveListView, we have a very fundamental problem: When
On the one hand, we get informed of user-selection in the
DiveListView::selectionChanged() slot. This has to set the
correct flags in the C-backend.

On the other hand, sometimes we have to set the selection
programatically, e.g. when selecting a trip. This is done
by calling QItemSelectionModel::select().

But: this will *also* call into the above slot, in which
we can't tell whether it was a user interaction or an
internal call. This can lead to either infinite loops or
very inefficient behavior, because the current dive
is set numerous times.

The current code is aware of that and disconnects the
corresponding signal. This is scary, as these signals are
set internally by the model and view. Replace this
by a global "command executing" flag in DiveListNotifier.
The flag is set using a "marker" class, which resets the flag
once it goes out of scope (cf. RAII pattern).

In DiveListView, only process a selection if the flag is not
set. Otherwise simply call the QTreeView base class, to reflect
the new selection in the UI.

To have a common point for notifications of selection changes,
add such a signal to DiveListNotifier. This signal will be
used by the DiveListView as well as the Command-objects.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
0d98da5261 Dive list: remember selected dives
Don't delesect dives, when unregistering them from the backend.
If a previously selected dive is added, select it in the dive-list.
For this purpose introduce a SELECTED_ROLE to query the DiveTripModel
for selected dives.

Unfortunately, when adding multiple selected dives, current_dive_changed
is called for each of them, making this very slow. This will have
to be fixed in subsequent commits.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
63b65a7e20 Undo: implement autogrouping of trips in DiveAdd
If the autogroup flag is set, search for appropriate trips in
DiveAdd() and add the dive to this trip. If no trip exists, add
a new trip.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
ec7d85835f Dive list: implement proper Qt-model semantics for DiveTripModel
Previously, each dive-list modifying function would lead to a
full model reset. Instead, implement proper Qt-model semantics
using beginInsertRows()/endInsertRows(), beginRemoveRows()/
endRemoveRows(), dataChange().

To do so, a DiveListNotifer singleton is generatated, which
broadcasts all changes to the dive-list. Signals are sent by
the commands and received by the DiveTripModel. Signals are
batched by dive-trip. This seems to be an adequate compromise
for the two kinds of list-views (tree and list). In the common
usecase mostly dives of a single trip are affected.

Thus, batching of dives is performed in two positions:
- At command-level to batch by trip
- In DiveTripModel to feed batches of contiguous elements
  to Qt's begin*/end*-functions.

This is conceptually simple, but rather complex code. To avoid
repetition of complex loops, the batching is implemented in
templated-functions, which are passed lambda-functions, which
are called for each batch.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
6ac4ddbeed Core: introduce insert_trip_dont_merge() function
insert_trip() adds a trip to the backend, but merges trips if
there exists a trip with the same date. This is a disaster
for the MergeTrips command, because this command adds a new
trip and removes the previous two. Of course if the added trip
is merged, this cannot work.

Therefore, add an insert_trip_dont_merge() function, which
adds the trip, but doesn't merge.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
f427226b3b Undo: make diverse trip-related operations undo-able
AddDivesToTrip, CreateTrip, AutogroupDives, RemoveAutogenTrips
and MergeTrips basically all did the same thing as RemoveDivesFromTrip,
which was already implemented. Thus, factor our the common functionality
and hook it up to make all these functions undo-able.

Don't do the autogroup-call everytime the dive-list is rebuilt
(that would create innumberable undo-actions), but only on dive-load /
import or if expressly asked by the user [by switching the autogroup
flag].

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
014c04f8bd Undo: implement rudimentary support for undo of dive-merging
For this, an output-parameter was added to the backend merge_dives()
function. When non-zero, instead of adding the merged dive to
the preferred trip, the preferred trip is returned to the caller.

Since the new UndoObject, just like the delete-dives UndoObject,
needs to remove/readd a set of dives, the corresponding functionality
was split-off in a helper function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
302f6adb79 Undo: implement rudimentary support for undo of dive-splitting
For this, the core functionality of the split_dive() and
split_dive_at_time() functions were split out into new
split_dive_dont_insert() and split_dive_at_time_dont_insert(),
which do not add the new dives to the log. Thus, the undo-command
can take ownership of these dives, without having to remove them
first.

The split-dive functionality is temporarily made desktop-only
until mobile also supports "UndoObjects".

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
12df9faaa2 Undo: implement undo of manual dive-creation
Play manual addition of dives via an UndoCommand. Since this does in
large parts the same thing as undo/redo of dive deletion (just the
other way round and only a single instead of multiple dive), factor
out the functions that add/delete dives and take care of trips.

The UI-interaction is just mindless copy&paste and will have to
be adapted.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Berthold Stoeger
403dd5a891 Undo: fix multi-level undo of delete-dive and remove-dive-from-trip
The original undo-code was fundamentally broken. Not only did it leak
resources (copied trips were never freed), it also kept references
to trips or dives that could be changed by other commands. Thus,
anything more than a single undo could lead to crashes.

Two ways of fixing this were considered
1) Don't store pointers, but unique dive-ids and trip-ids.
   Whereas such unique ids exist for dives, they would have to be
   implemented for trips.
2) Don't free objects in the backend.
   Instead, take ownership of deleted objects in the undo-object.
   Thus, all references in previous undo-objects are guaranteed to
   still exist (unless the objects are deleted elsewhere).

After some contemplation, the second method was chosen, because
it is significantly less intrusive. While touching the undo-objects,
clearly separate backend from ui-code, such that they can ultimately
be reused for mobile.

Note that if other parts of the code delete dives, crashes can still
be provoked. Notable examples are split/merge dives. These will have
to be fixed later. Nevertheless, the new code is a significant
improvement over the old state.

While touching the code, implement proper translation string based
on Qt's plural-feature (using %n).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11 16:22:27 -07:00
Jan Mulder
8034af5ad5 QML UI: do not try to download from DC with empty vendor/product
Disable the Download button when one of the fields vendor, product,
connection is not filled in. The app will crash when trying.
In addition, make the underlying core code to actual download
more safe by checking this, and silently fail instead of crash.
And, yes, this is a double fix in this scenario, but the core code
is used in more places, so better safe than sorry.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-10 06:27:21 -07:00
Jocke
0f588f5227 Substring match BT address
Since a known DC will have the name prepended to the BT/BLE addresss
we need to substring match the BT address.

Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
2018-10-09 21:04:23 -07:00
Jocke
c70225f575 Mobile RememberDCs: save device address
By saving the device address together with the vendor and product we fix the 
corner case where a user with two DCs would not get quick select buttons if they
where the same vendor and model.

Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
2018-10-09 21:04:23 -07:00
Jocke
636505f818 BT OSTC 3 should be reported as OSTC Plus
Report BT/BLE capable OSTC 3/3+ as OSTC PLus as it is required to get a 
functional download.

Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
2018-10-09 21:04:23 -07:00
Berthold Stoeger
50e42bffa1 Dive sites: don't add dummy entries to LocationInformationModel
The LocationInformationModel added two dummy sites to the front
of the list (add new dive site). This was never used - desktop
uses its own model, mobile only extracts the list of dive site
names with a custom function. Remove this functionality.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-09 21:00:44 -07:00
Jan Mulder
91c8a2fa5c Prefs: add bool preference cloud_auto_sync [1/3]
With removal of the git_local_only from the preferences (see
ae653703a5), the users choice, in the mobile app, was not
stored any more in between sessions. This resulted in issue
1725.

So, in order to store that user preference, we need a new
preference. This is added here, but its not yet hooked up
in the app yet. This deals only with the preference handling.
And adapted tests are included.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-09 10:03:21 -07:00
Dirk Hohndel
1c8b73b36f libdivecomputer: remove ifdefs for ancient versions
We bundle our version of libdivecomputer and don't expect Subsurface to work
with a different version, certainly not with something older than 0.5.

I kept the checks for SAMPLE_EVENT_STRING and DC_FIELD_STRING and DC_SAMPLE_TTS
because maybe there's a situation where being able to compile with a current
upstream version is useful.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-08 23:06:09 +03:00
Linus Torvalds
d2d9821170 Fix warning about unused variables
Commit 810903bdb9 ("Import: pass a dive table to process_imported_dives()")
introduced the variables

        struct dive *old_dive, *merged;

into process_imported_dives(), but never used them.  It seems to be an
artifact of having split the function to use the try_to_merge_into()
helper function (that has those same variable names and _does_ use
them), but forgetting the original variables from the pre-split case.

Gcc understandably warns about it:

  core/divelist.c: In function ‘process_imported_dives’:
  core/divelist.c:1351:26: warning: unused variable ‘merged’ [-Wunused-variable]
    struct dive *old_dive, *merged;
                            ^~~~~~
  core/divelist.c:1351:15: warning: unused variable ‘old_dive’ [-Wunused-variable]
    struct dive *old_dive, *merged;
                 ^~~~~~~~

and the trivial fix is to just remove that line that declares the stale
and unused variables.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-08 00:10:29 +03:00
Linus Torvalds
7618240009 ftdi: make the timeout be based on actual real time
bperrybap reported on github that the ftdi timeouts can be excessive:

  "the timeout period while waiting for read data to be 10x or even 100x
   longer than it should be when there are read issues on the data cable
   particularly when using Android and USB OTG cables. i.e. a 5 second
   read timeout for not receiving data can be as long as 7 minutes"

and the reason is that the code at one point tried to use the regular
"gettimeofday()" to handle timeouts, but that doesn't exist in Windows.

We already have Windows-specific code to sleep for a number of
milliseconds in "ftdi_serial_sleep()", let's just extend that same
concept and add a "ftdi_serial_get_msec()" that returns the number of
msec's since some arbitrary point in time.

On Windows, that's just "GetTickCount()", and in sane environments it's
just a trivial wrapper around gettimeofday() to turn sec/usec into msec.

NOTE! The actual msec value doesn't have any meaning.  Only the
difference between two calls to ftdi_serial_get_msec() is meaningful.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-08 00:10:29 +03:00
Linus Torvalds
9e3a22c522 qt-ble: add 'get_name()' function to expose the BLE name to libdivecomputer
Some divecomputer backends (ok, right now really only the Aqualung i770R
and i300C) want to know the bluetooth name of the dive computer they
connect to, because the name contains identifying information like the
serial number.

This just adds the support for that to our Qt BLE code.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-08 00:10:29 +03:00
Berthold Stoeger
424558cf89 Leak fix: free taxonomy data in delete_dive_site()
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-07 23:40:37 +03:00
Berthold Stoeger
df16866292 Statistics: only consider selected dives in HTML export statistics
If only selected dives were exported into HTML, the statistics would
nevertheless cover all dives. A counter-intuitive behavior. Fix by
adding a selected_only flag to calculate_stats_summary().

Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-07 17:50:51 +03:00
Berthold Stoeger
b61f6f66d8 Statistics: un-globalize stats_selection
The statistics of the selected dives were calculated
a) into a global objects and
b) at a completely different place than where they're used.

There's no plausible reason for either. There fore render
into a caller-provided structure at the place of use.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-07 17:50:51 +03:00
Berthold Stoeger
97991e2b9f Statistics: remove global state / calculate only when needed
Statistics were calculated into global variables every time the
current dive was changed.

Calculate statistics only when needed and into a structure
provided by the caller.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-07 17:50:51 +03:00
Berthold Stoeger
90b019bc8d Core: remove dive->downloaded flag
This flag had two distinct uses:
 - signal that dives were downloaded, not imported
 - use to mark imported dives

Both are not used anymore, therefore remove the flag.
The uemis downloaded misused the flag to mark deleted
dives. Instead misuse the "hidden_by_filter" flag.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-06 19:47:06 -07:00
Berthold Stoeger
6dc1dcaea5 Import: pass "downloaded" parameter to process_imported_dives()
process_imported_dives() is more efficient for downloaded than for
imported (from a file) dives, because it checks only the divecomputer
of the first dive.

This condition is checked via the "downloaded" flag of the first
dive. Instead, pass an argument to process_imported_dives().

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-06 19:47:06 -07:00
Berthold Stoeger
e5dca8228e Import: remove dive->downloaded logic
Dive importing is now performed via a distinct table which is
merged into the main dive table. Thus, it is known which of the
dive is new and which is old. This information can now be
implicitely encoded in the parameter-position of merge_dive()
[i.e. pass old as first and new as second dive].

This makes marking of downloaded dives via a flag unnecessary.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-06 19:47:06 -07:00
Berthold Stoeger
ab14889563 Core: remove preexisting field from struct dive_table
Dives are now in all cases imported via distinct dive_tables.
Therefore the "preexisting" marker is useless. Remove.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-06 19:47:06 -07:00
Berthold Stoeger
810903bdb9 Import: pass a dive table to process_imported_dives()
Dives were directly imported into the global dive table and then
merged in process_imported_dives(). Make this interface more flexible,
by passing an independent dive table.

The dive table of the to-be-imported dives will be sorted and merged.
Then each dive is inserted in a one-by-one manner to into the global
dive table.

This actually introduces (at least) two functional changes:
1) If a new dive spans two old dives, it will only be merged to the
   first dive. But this seems like a pathological case, which is of
   dubious value anyway.
2) Dives unrelated to the import will not be merged. The old code
   would happily merge dives that were not even close to the
   newly imported dives. A surprising behavior.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-06 19:47:06 -07:00
Berthold Stoeger
c32e71e64d Dive information: fix surface interval calculation
The old surface interval calculation had fundamental issues:

1) process_all_dives(), which calculates the statistics over *all*
   dives was used to get the pointer to the previous dive.
2) If two dives in the table had the same time, one of those would
   have been considered the "previous" dive.
3) If the dive, for which the surface interval is calculated is
   not yet in the table, no previous dive would be determined.

Fix all this by creating a get_surface_interval() function and
removing the "get previous dive" functionality of process_all_dives().
Remove the process_all_dives() call from TabDiveInformation::updateData().

Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-07 05:41:48 +03:00
Linus Torvalds
cd55344410 qt-ble: add support for libdivecomputer 'set_timeout()' function
Because some BLE operations can be very slow (device and service
discovery etc), we have some rather excessive default timeout for BLE
(currently set to 12 seconds).

But once we actually have started doing IO, that long timeout can be a
big performance problem, when the libdivecomputer backend has support
for retry and packet loss.

For that reason, libdivecomputer has a 'set_timeout()' function that
allows the divecomputer backend to say how quickly it expects the dive
computer to answer before the backend will start resending packets.

Let's just implement that for the actual IO side of BLE too.  The
default timeout value remains the general BLE timeout, and this only
affects the actual IO phase, but it improves things enormously for the
case where there is packet loss at that point.

For example, on the Aqualung i770R, the timeout for packet loss ends up
now being just one second rather than the full 12 seconds of default BLE
timeout.  Which gets the retry going much faster.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-06 19:38:28 -07:00
Linus Torvalds
88f4c06b99 qt-ble: add support to wait for descriptor write completion
When we enable notifications, we actually want to make sure to wait for
that write to have completed before we start communicating with the
device, because otherwise we might lose notification events.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-06 19:38:28 -07:00
Linus Torvalds
ec532b8f59 qt-ble: move basic uuid filtering back to service discovery
In commit 30fb7bf35c ("qt-ble: set up infrastructure for better
preferred service choice") I moved the service filtering from the
addService() callback into the "select_preferred_service()" function
that picks the right service for the device.

That was nice for debugging, since it meant that we showed the details
of _all_ services, but it also meant that we ended up starting service
discovery on _all_ services, whether they looked at all interesting or
not.

And that can make the BLE device discovery process quite a bit slower.

The debugging advantage is real, but honestly, service discovery can
generally be better done with specialized tools like the Nordic nRF app,
so the debugging advantage of just listing all the details of all the
services is not really worth the discovery slowdown in general.

So move the basic "filter by uuid" back to the service discovery phase,
and don't bother starting service detail discovery for the services that
we can dismiss immediately just based on the service UUID.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-06 19:38:28 -07:00
Linus Torvalds
ebee0c4c24 Fix error handling for libdivecomputer import
The error handling was incorrect for the case where we successfully
opened the libdivecomputer iostream in divecomputer_device_open(), but
the dc_device_open() call failed.

When the dc_device_open() failed, we would (correctly) not do the
dc_device_close() but we would _also_ not do the dc_iostream_close() to
close the underlying file descriptor, which is wrong.

Normally this isn't all that noticeable, partly because the common case
is that dc_device_open() succeeds if you actually do have a dive
computer connected, but also because most of the time it just leaked a
file descriptor or something like that.

However, particularly for the POSIX serial device case, libdivecomputer
does a

	ioctl(device->fd, TIOCEXCL, NULL)

call to make serial opens exclusive.  This is what we want - but if we
then fail at closing the serial file descriptor, we won't be able to
retry the import at all because now the next open will fail with EBUSY.

So the error handling was incorrect, and while it doesn't usually matter
all that much, it can be quite noticeable particularly when you have
transient errors.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-06 19:38:14 -07:00
Berthold Stoeger
420aab9454 Cleanup: don't produce no-dives error message in libdivecomputer.c
If no dives were downloaded in do_libdivecomputer_import(), an
error message would be produced. To check for downloaded dives,
the function would access the global downloadTable instead of
the actual table the dives are imported to (at the moment the
same - but the interface allows for a different table).

Move the error-creation to the caller to avoid this situation.
An alternative option would be to check the actual table the
dives were supposed to be downloaded to. But from a program-logic
point of view "no dives" does not seem like an error condition.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-05 04:09:02 +03:00
Berthold Stoeger
8a18396104 Cleanup: don't access downloadTable directly in Uemis-downloader
The Uemis downloader determines the dive-number to be downloaded
by either checking the download-table [interrupted connection] or
the global dive table [fresh download].

The downloadTable is passed in the device data structure, but
in the function to determine the latest dive, the global
downloadTable is accessed directly [thus supposing that this
table was passed in device data].

Instead, use the table from device data to avoid funny surprises
should we change to a non-global download table.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-05 04:07:22 +03:00
Berthold Stoeger
9788d73d48 Import: remove unnecessary processing of dives in DAN import
On DAN-file import after each dive except the first, the dive-list
was processed. This seem bogus and inefficient. An artefact from
old code? In any case, remove.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-04 07:37:28 +02:00
Dirk Hohndel
79d0185c62 Bluetooth: use_random_address helper isn't needed on Windows
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-10-01 15:55:19 -07:00
Jocke
a8953da02d Mobile download from DC: show the correct DC rather than the latest
Since we now keep track of up to 4 DCs we don't want to display the last used one
but rather the one that is connected.

Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
2018-10-01 06:32:41 -07:00
Dirk Hohndel
0422cd3662 Bluetooth: don't use random addresses on Windows
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-30 08:09:37 -07:00
Dirk Hohndel
1f59629a76 Bluetooth: use standard Qt code on Windows
We shouldn't need our hand crafted code anymore.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-30 08:09:37 -07:00
Berthold Stoeger
d3d06bc580 Cleanup: split out free_dive() function from delete_single_dive()
Currently, we can only delete dives that are indexed in the main
dive table. In the future, we will have to delete dives outside
of this table (e.g. for undo). Therefore, split out the free_dive()
function from delete_single_dive(), which takes an index into
the main dive table.

In the process, adopt the dive freeing-code from clear_dive(),
which frees more data than the code in delete_single_dive().
This potentially fixes a memory-leak.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-29 15:24:08 -07:00
Berthold Stoeger
574065b314 Cleanup: reinstate override modifiers
This reverts commit 1c4a859c8d,
where the override modifiers were removed owing to the noisy
"inconsistent override modifiers" which is default-on in clang.

This warning was disabled in 77577f717f,
so we can reinstate the overrides.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-29 15:23:25 -07:00
Dirk Hohndel
7c320854b3 Bluetooth: turn on logging earlier
This way we should get logging output for the discovery phase as well.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-29 14:16:37 -07:00
Berthold Stoeger
32a4ce6169 Parser: parse text-based files into arbitrary table
In d815e0c947 a dive_table pointer
was added to the parsing functions to allow parsing into tables
other than the global dive table. This will be necessary for undo of
import and implementation a cleaner interface. A few cases, notably
CSV and proprietary formats were forgotten.

Implement parsing into arbitrary tables also for these cases.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-28 15:06:00 -07:00
Berthold Stoeger
3137fbe973 Cleanup: remove redundant prototypes from dive.h
A few of these prototypes were already in import-csv.h.
Put them in an 'extern "C" { ... }' block.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-28 07:47:39 -07:00
Berthold Stoeger
2e6df623bb Cleanup: Make add_sample_data() local to translation unit
This function in parse_csv.c was not used anywhere. Make
it of static linkage.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-28 07:47:39 -07:00
Linus Torvalds
890d4c3d64 qt-ble: allow reading of partial packet data
The existing BLE dive computers treat BLE as the packetized protocol it
is, and read whole packets at a time.

However, the Mares BlueLink backend treats it as just a basic "serial
over BLE" transport, and for historical reasons reads the reply packets
in smaller chunks.

This allows that kind of IO behavior, where if the divecomputer backend
reads just a part of a packet, we'll split the packet, return the part
the user asked for, and push back the leftover packet onto the received
packet queue.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-09-26 12:13:20 -07:00
Linus Torvalds
8426024b76 Allow XML sample times to have hh:mm:sec format
We traditionally only allow samples to have a time format of 'mm:ss', so
if you have a dive over an hour, you would just have a minutes field
larger than 60 minutes.

But Matthew Critchley is trying to import some dives from his VMS
Redbare CCR, and the sample timestamp format he has is of the type
'hh:mm:ss'.

That could be fixed by a xslt translation, but there's no real reason
why we couldn't just support that format too.

Reported-by: Matthew Critchley <matthew.s.critchley@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-09-26 12:13:20 -07:00
Linus Torvalds
05fe19a23f qt-ble: add BLE packet debugging code
This is perhaps overly verbose, but the timing details helped figure out
some EON Core download issues, and it's nice to see when things actually
happen.

It's also good to see when the data actually enters our queues, and when
we read and write the packets.  That might help debug the issues Fabio
is seeing with the Mares Bluelink.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-09-25 16:41:13 -07:00
Linus Torvalds
0ba105d2a7 qt-ble: only connect the signals to the preferred service
We used to just find all services and connect the characteristics change
signal etc to them all, but we really only care about the actual
preferred service that we'll be using.

So move the qt ble signal connection to after we've selected the
preferred service that we will actually be enabling notifications on and
do the writes to.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-09-25 16:41:13 -07:00
Berthold Stoeger
cc4f48be3f Metadata: rudimentary support for XMP metadataa in MP4-based videos
XMP is a media-metadata standard based on XML which may be used
across a variety of media formats. Some video-processing software
writes XMP data without updating the native metadata fields.
Therefore, we should aim at reading XMP metadata and give priority
of XMP data over native fields.

Pros:
	- Support for *all* common media formats.
Cons:
	- XML (complex, verbose, chaotic).
	- Does not even come close to fulfilling its promise of being
	  well defined (see below).

Implement a simple XMP-parser using libxml2. Connect the XMP-parser to
the existing Quicktime/MP4 parser.

First problem encountered: According to the spec, XMP data supposed
to be put in the 'XMP_' atom. But for example exiftools instead
writes an 'uuid' atom with a special 16-byte uid. Implement both,
more options will probably follow.

Second problem: two versions of recording the creation date were found
  1) The content of a <exif:DateTimeOriginal> tag.
  2) The xmp::CreateDate attribute of a <rdf:Description> tag.

Here too, more versions are expected to surface and will have
to be supported in due course (with an obvious priority problem).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-25 14:59:14 -07:00
Jan Mulder
5480d08d15 cleanup: do not compare doubles like this
Cleanup another possibly dangerous compare of doubles.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-09-25 16:01:39 +02:00
Dirk Hohndel
619289074b qPref: don't compare doubles for equality
This is a much safer way to do this.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-25 15:58:17 +02:00
Dirk Hohndel
617019bc6b qPref: add mobile_scale preference
We use that in the mobile app to scale the whole app, as all sizes there
are relative to the default font.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-25 15:58:17 +02:00
Linus Torvalds
1b16d570a1 qt-ble: re-organize how we pick the GATT characteristics to read and write
We used to just blindly pick "first" and "last" characteristic from the
preferred service, and that was stupid but happened to work for the dive
computers we supported.  Note that for some of them, "first" and "last"
was actually the *same* characteristic, since it could be a single one
that supported both.

However, this first/last hack definitely doesn't work for the Mares
BlueLink BLE dongle, and it's really all pretty wrong anyway.

So re-organize the code to actually look at the properties of the
characteristics.  I don't have a BlueLink to test with, but my EON Core
and Shearwater Perdix AI are still happy with this, and the code
conceptually makes a lot more sense.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-09-24 17:12:58 -07:00
Dirk Hohndel
02fc78570e macOS: always list 'FTDI' as a serial connection
We now link against the user space FTDI driver.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-24 18:51:21 +02:00
Jan Mulder
1f0a6019da cleanup: remove more GPS webservice code
And remove some includes and defines that are not used any more after
removal of the GPS webservice code.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-09-24 07:20:25 -07:00
Jan Mulder
fc812ea130 core: fix connect call
Fix multiple run-time errors in connect call introduced in 504e912512.
1) Set the proper signature of the signal. 2) make the used slot
a real slot (so move it to the proper section in the header) and
3) set the proper signature for the slot.

Highly unlikely that normal users notice the runtime errors and
possibly unwantend behavior, as this all deals with the subtile GPS
service update threshold.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-09-24 07:20:25 -07:00
Linus Torvalds
30fb7bf35c qt-ble: set up infrastructure for better preferred service choice
We used to just pick the first non-standard service we found (with a
special case for the Heinrichs Weikamp dive computers that have an
actual registered standard service).

We then waited for that service to finish discovery, and started using
it.

This changes the logic to wait for _all_ services to finish discovery,
and then after that we pick the one we like best.  Right now the rule
for picking a preferred service is the same one we had before, but the
difference is that we now have the full discovery data, so we *could* do
something better.

Plus this makes our debug messages a lot more legible, when we don't
have the mix of overlapping service discovery with the actual IO we do
to the preferred service.

NOTE! This doesn't much matter for most of the dive computers that we
currently support BLE for.  They don't tend to have a lot of odd
services.

But at least both the Mares BlueLink and the Garmin Descent both have
multiple services and it's not obvious which one to use, and this will
make it not only easier to debug those, it will make it easier to pick
the right preferred service descriptor to use.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-09-23 17:29:05 -07:00
Linus Torvalds
594f13eeaf qt-ble: use the WAITFOR() macro rather than open-coding wait loops
This is not only much clearer (and smaller code), but it also lowers the
latency for the waiting, since we don't always wait for the full 100ms.

Get rid of the now unused "waitfor()" function that just unconditionally
waited for 100ms.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-09-23 17:29:05 -07:00
Berthold Stoeger
35b8a4f404 Core: split process_dives() in post-import and post-load versions
process_dives() is used to post-process the dive table after loading
or importing. The first parameter states whether this was after
load or import.

Especially in the light of undo, load and import are fundamentally
different things. Notably, that latter should be undo-able, whereas
the former is not. Therefore, as a first step to make import undo-able,
split the function in two versions and remove the first parameter.

It turns out the the load-version is very light. It only sets the
DC nicknames and sorts the dive-table. There seems to be no reason
to merge dives.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-23 11:50:53 -07:00
Dirk Hohndel
0ae57cfe92 Mobile/remember DCs: try to match device names
We only store the address part of the connection name, so don't try to find an
exact match, try to find the sub-string.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-23 11:49:30 -07:00
Dirk Hohndel
413b05ab89 Desktop/remember DCs: move non-UI-specific code into the core layer
This way we can use the same functionality from the mobile UI as well.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-23 11:49:30 -07:00
Dirk Hohndel
77a5c9ac65 qPref: add ability to remember recently used dive computers
This does feel clumsy and complicated. This is a lot of special case
handling and a lot of boilerplate for something that really should be
quite simple.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-23 11:49:30 -07:00
Berthold Stoeger
9c8deef477 Trivial: un-static function-local buffer
In visit_on_node() in core/parse-xml.c the name is extracted into
a static buffer. There seems to be no need for this being static,
as the name is only passed to the entry() function which (hopefully)
does not store a reference to the name anywhere.

If it does, this would need a *big* *fat* comment.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-22 14:44:34 -07:00
Linus Torvalds
d2b8088cd8 Actually create a UUID when creating a dive site during download
The existing code creates a deterministic ID (not exactly "unique") in order to
help us avoid merge conflicts in git-storage mode. But as a side effect, if we
re-download the same dive twice from a dive computer that supports GPS (right
now only the Garmin Descent Mk1) we are guaranteed to create the same dive site
uuid when we do this. So when we download a dive - whether we will actually
*use* that dive later or not - we will be filling in the dive site information
with the data we got from the dive computer.

... and in the process we will be overwriting any data that was filled in
manually. The name of the dive site, but also possibly even the GPS of the dive
site (maybe the user decided to edit that using the map, because while the
automatically downloaded GPS data was "correct", maybe the user wanted to
change it to be the actual under-water location using the satellite data,
rather than the place where you started the dive or where you surfaced).

In order to avoid this collision, this patch just makes the libdivecomputer
download not use the dive time, but "time of download" for the dive site time,
and thus effectively generate a new uuid for every download.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-22 14:17:24 -07:00
Berthold Stoeger
21b1550739 Dive media: on import read metadata only once
On import of dive media, the timestamp is read from the
metadata to check if the image belongs to the selected dives.
The pictures are then listed in a dialog.

Currently, the metadata is read twice if images are outside
of a dive: once in picture_check_valid() and if it turns
out that the picture is not valid again in picture_get_time()
to display the proper timestamp.

Even though metadata-extraction is reasonably fast, this is
a bit of an embarrassment.

Instead, read the timestamps only once in the constructor of
the dialog and from then on only used these timestamps. Keep
the timestamps in a QVector. Rename the picture_check_valid()
function to picture_check_valid_time() and pass a timestamp
instead of a filename.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-19 14:44:34 -07:00
Berthold Stoeger
92deb7aa70 Cleanup: make surface sample in merge_one_sample() non-static
The merge_one_sample() function adds a sample to the destination
dive if dives are merged. For long periods between samples at surface
depths, it adds a surface interval.

To decrease the number of global objects, make the sample structure
non-static. Of course, initialization of an on-stack structure is
slower. Therefore move it into the corresponding if. Thus, the
structure will be initialized only once per surface-interval.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-09-19 14:43:54 -07:00
Jocke
148bc8fbf1 Mobile: always update the preferences when set_unit_system is called
Unit_system is read from git storage but units are set from locale when the
app starts. To prevent a miss-match between unit and unit_system we have to
always update the preferences variable when set_unit_system is called so that
the user doesn't end up with imperial units when the preferences say metric.

Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-09-19 14:41:34 -07:00