aboutsummaryrefslogtreecommitdiffstats
path: root/smtk-import/smartrak.c
AgeCommit message (Collapse)Author
2021-09-19Re-do the libdivecomputer fingerprint save/load codeGravatar Linus Torvalds
This tries to make our fingerprinting code work better, by avoiding using the "deviceid" field that has always been unreliable because we've calculated it multiple different ways, and even for the same version of subsurface, it ends up changing in the middle (ie we calculate one value initially, then re-calculate it when we have a proper serial number string). So instead, the fingerprinting code will look up and save the fingerprint file using purely "stable" information that is available early during the download: - the device model name (which is a string with vendor and product name separated by a space) - the DC_EVENT_DEVINFO 32-bit 'serial' number (which is not necessarily a real serial number at all, but hopefully at least a unique number for the particular product) but because the model name is not necessarily a good filename (think slashes and other possibly invalid characters), we hash that model name and use the resulting hex number in the fingerprint file name. This way the fingerprint file is unambiguous at load and save time, and depends purely on libdivecomputer data. But because we also need to verify that we have the actual _dive_ associated with that fingerprint, we also need to save the final deviceid and diveid when saving the fingerprint file, so that when we load it again we can look up the dive and verify that we have it before we use the fingerprint data. To do that, the fingerprint file itself contains not just the fingerprint data from libdivecomputer, but the last 8 bytes of the file are the (subsurface) deviceid and the diveid of the dive that is associated with the fingerprint. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-08-18Clean up divecomputer 'device' handlingGravatar Linus Torvalds
We have this odd legacy notion of a divecomputer 'device', that was originally just basically the libdivecomputer 'EVENT_DEVINFO' report that was associated with each dive. So it had firmware version, deviceid, and serial number. It had also gotten extended to do 'nickname' handling, and it was all confusing, ugly and bad. It was particularly bad because it wasn't actually a 'per device' thing at all: due to the firmware field, a dive computer that got a firmware update forced a new 'device'. To make matters worse, the 'deviceid' was also almost random, because we've calculated it a couple of different ways, and libdivecomputer itself has changed how the legacy 32-bit 'serial number' is expressed. Finally, because of all these issues, we didn't even try to make the thing unique, so it really ended up being a random snapshot of the state of the dive computer at the time of a dive, and sometimes we'd pick one, and sometimes another, since they weren't really well-defined. So get rid of all this confusion. The new rules: - the actual random dive computer state at the time of a dive is kept in the dive data. So if you want to know the firmware version, it should be in the 'extra data' - the only serial number that matters is the string one in the extra data, because that's the one that actually matches what the dive computer reports, and isn't some random 32-bit integer with ambiguous formatting. - the 'device id' - the thing we match with (together with the model name, eg "Suunto EON Steel") is purely a hash of the real serial number. The device ID that libdivecomputer reports in EVENT_DEVINFO is ignored, as is the device ID we've saved in the XML or git files. If we have a serial number, the device ID will be uniquely associated with that serial number, and if we don't have one, the device ID will be zero (for 'match anything'). So now 'deviceid' is literally just a shorthand for the serial number string, and the two are joined at the hip. - the 'device' managament is _only_ used to track devices that have serial numbers _and_ nicknames. So no more different device structures just because one had a nickname and the other didn't etc. Without a serial number, the device is 'anonymous' and fundamentally cannot be distinguished from other devices of the same model, so a nickname is meaningless. And without a nickname, there is no point in creating a device data structure, since all the data is in the dive itself and the device structure wouldn't add any value.. These rules mean that we no longer have ambiguous 'device' structures, and we can never have duplicates that can confuse us. This does mean that you can't give a nickname to a device that cannot be uniquely identified with a serial number, but those are happily fairly rare (and mostly older ones). Dirk said he'd look at what it takes to give more dive computers proper serial numbers, and I already did it for the Garmin Descent family yesterday. (Honesty in advertizing: right now you can't add a nickname to a dive computer that doesn't already have one, because such a dive computer will not have a device structure. But that's a UI issue, and I'll sort that out separately) Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-11-01smtk-import: Add support for new devices modelGravatar Salvador Cuñat
Include devices Ids in the DC data. Ensure we always set a DC model string for manual dives or unsupported devices. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2020-10-25cleanup: break out event-related code into event.[c|h]Gravatar Berthold Stoeger
In an effort to reduce the size of dive.h and dive.c, break out the event related functions. Moreover event-names were handled by the profile-code, collect that also in the new source files. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2020-08-13smtk-import: Workaround segfault in mdbtools memcpy callGravatar Salvador Cuñat
Smtk2ssrf has a segfault which matches quite well glibc's CVE-2019-6488 (except for the x32 part). It came from a call to memcpy in mdb_ole_read() func, used to get the header and the profile of a dive from the database. May be it could be fixed in libmdb but Mdbtools project has been stalled for the past 5 years so ... The segfault seems to be triggered by an empty profile in the first dive in the database (a pretty common case in older Aladin DCs due to their little memmory). The only special thing here is the fact it's the first dive in the database structure (not the first by its index). We can avoid the crash if we don't call mdb_ole_read_full() func on zero sized profile field. The problem here is we can't get the size of the fields and build the MdbColumn in the same roud. Happily we just need the MdbColumn struct for the dive profile and header. So, we can change the previous approach using MdbColumns through almost all functions to a simpler one using the already bounded strings by smtk_open_table() and just using the col[n]->bind_pointer in the main function where the columns are built to be used by mdb_ole_read_full(). Reported-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2020-04-19[smtk-import] Fix useless NULL check and white space issuesGravatar Salvador Cuñat
As commented by Berthold and Dirk for previous patches. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2020-04-19[smtk-import] add some sanity checksGravatar Salvador Cuñat
Under some circustances values stored in this arrays may be NULL or even previously freed. Check them to avoid further crashes. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2020-04-19[smtk-import] Do not create cylinders structure before libdc parsingGravatar Salvador Cuñat
The d->cylinders created will be overriden by libdivecomputer parsing, resulting in 0, 1 , may be 2 cylinders depending on DC data. This is not what we want when importing a divelog, because we will miss all hand entered tanks. BTW, using get_cylinder() on tank number bigger than created, results in a NULL pointer and a crash. As we can't foresee how many tanks (or even it's positional numbers in log) a diver has used, the full 10 tanks supported by SmarTrak can be easily created and parsed using get_or_create_cylinder(), and unused cleaned later. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2020-03-11Grammar: replaces 'indexes' by 'indices'Gravatar Robert C. Helling
Grammar-nazi ran git grep -l 'indexes' | xargs sed -i '' -e 's/indexes/indices/g' to prevent future wincing when reading the source code. Unfortunatly, Qt itself is infected as in QModelIndexList QItemSelection::indexes() const Signed-off-by: Robert C. Helling <helling@atdotde.de>
2019-11-09Cylinders: access cylinders with get_cylinder()Gravatar Berthold Stoeger
Instead of accessing the cylinder table directly, use the get_cylinder() function. This gives less unwieldy expressions. But more importantly, the function does bound checking. This is crucial for now as the code hasn't be properly audited since the change to arbitrarily sized cylinder tables. Accesses of invalid cylinder indexes may lead to silent data-corruption that is sometimes not even noticed by valgrind. Returning NULL instead of an invalid pointer will make debugging much easier. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-11-09Core: remove MAX_CYLINDERS restrictionGravatar Berthold Stoeger
Instead of using fixed size arrays, use a new cylinder_table structure. The code copies the weightsystem code, but is significantly more complex because cylinders are such an integral part of the core. Two functions to access the cylinders were added: get_cylinder() and get_or_create_cylinder() The former does a simple array access and supposes that the cylinder exists. The latter is used by the parser(s) and if a cylinder with the given id does not exist, cylinders up to that id are generated. One point will make C programmers cringe: the cylinder structure is passed by value. This is due to the way the table-macros work. A refactoring of the table macros is planned. It has to be noted that the size of a cylinder_t is 64 bytes, i.e. 8 long words on a 64-bit architecture, so passing on the stack is probably not even significantly slower than passing as reference. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-08-02[smtk-import] fix mem leaks on site/location failure managementGravatar Salvador Cuñat
Signed-off-by: Salvador Cuñat <salvador,cunat@gmail.com>
2019-08-02[smtk-import] avoid infinite loop on index failureGravatar Salvador Cuñat
As Berthold points out, a failure to match the site or location index will result in an infinite loop with previous patch. With this one the loop will end after reading the last table row even if no idx is matched. But ... If we asume this situation is possible the retrieved data would be wrong, and ending the function without filling the site structure is mandatory too. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2019-08-02fix site/location build issueGravatar Salvador Cuñat
We were assuming these tables were sorted with their indexes, but it happens to be false, under some circustances at least. Reported-by: Andreas Hagberg <scubasoft@gmail.com> Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2019-07-18Core: dynamically resize weight tableGravatar Berthold Stoeger
Replace the fixed-size weightsystem table by a dynamically relocated table. Reuse the table-macros used in other parts of the code. The table stores weightsystem entries, not pointers to weightsystems. Thus, ownership of the description string is taken when adding a weightsystem. An extra function adds a cloned weightsystem at the end of the table. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-06-19Cleanup: move tag functions into own translation unitGravatar Berthold Stoeger
Make dive.h a bit slimmer. It's only a drop in the bucket - but at least when modifying tag functions not the *whole* application is rebuilt anymore. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Coding style: remove Java-style function definitionGravatar Berthold Stoeger
Remove a few cases of void fun() { ... } While touching these functions, fix a few other whitespace coding style violations. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Dive site: set UUID only on save or loadGravatar Berthold Stoeger
Since the UUID will be overwritten on save and is only used on save and load, set it only on save or load. For other created dive sites, leave the UUID field uninitialized. This means that the UUID will change between saves. Let's see how the git saver handles that. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Dive site: add dive site table parameter to dive site functionsGravatar Berthold Stoeger
To enable undo of dive site functions, it is crucial to work with different dive site tables. Therefore add a dive site table parameter to dive site functions. For now, always pass the global dive site table. Thus, this commit shouldn't alter any functionality. After this change, a simple search for dive_site_table reveals all places where the global dive site table is accessed. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-03-27Cleanup: unconstify string argument to add_to_string()Gravatar Berthold Stoeger
add_to_string() frees the original string that is passed in. This should therefore not be of "const char *" type, as the contents of the string *will* be modified (or more precisely: destroyed). Same for the congener smtk_concat_str(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09Core: Rename functions to more generic namesGravatar Berthold Stoeger
Rename - dive_get_insertion_index() -> dive_table_get_insertion_index() - unregister_dive_from_table() -> remove_from_dive_table() - get_idx_in_table() -> get_idx_in_dive_table() - sort_table() -> sort_dive_table() This will make it more straight-forward to generate these functions from macros. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-29Dive site: replace dive->dive_site_uuid by dive_siteGravatar Berthold Stoeger
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-29Dive site: return pointer to dive_site in create_dive_site_*()Gravatar Berthold Stoeger
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-29Dive site: return pointer to dive_site in get_dive_site_*()Gravatar Berthold Stoeger
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-21Add 'location_t' data structureGravatar Linus Torvalds
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-09-06[smtk-import] Apply arrays to the main smartrak_import() functionGravatar Salvador Cuñat
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2018-09-06[smtk-import] Remove now unused smtk-value-by-idx()Gravatar Salvador Cuñat
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2018-09-06[smtk-import] Apply arrays to parsing tables functionsGravatar Salvador Cuñat
And add a fuction to parse tables that are not "relational", meaning tables which are directly refered from Dives table. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2018-09-06[smtk-import] Add a function to get the size of an arrayGravatar Salvador Cuñat
We can allocate fixed size arrays for smartrak tables as its size can be known in advance. Simply reading table->num_rows is too dangereous as smartrak tables have "holes" commonly. This is, they can look like: Idx | Txt 1 | blablabla 2 | blebleble 4 | blobloblo table->num_rows would give us 3, but we need to allocate 4 to get an array like: |0|blablabla |1|blebleble |2| |3|blobloblo as the idea is to use the table index to reference the array data. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2018-08-25smtk-import: Apply lists to main smartrak_import() functionGravatar Salvador Cuñat
Previously we built arrays for the tables each time we parsed a dive. Now we simply build the lists once, and use them in each dive parsing. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2018-08-25smtk-import: move from arrys to lists while parsing tablesGravatar Salvador Cuñat
In most cases we can not foresee the maximum number of data of a given type. It can be quite low or really big (a concerned diver can store thousands of different fishes in Fish table). Moving from arrays, where size has to be preset, to linked lists seems the more logical option. Here we set a (very limited) data structure, just an index and a text fields following the format of most SmartTrak tables. Some special table, like Buddy, needs a bit of processing before placing the data in the list. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2018-08-23Cleanup: pass gasmix by valueGravatar Berthold Stoeger
In a previous commit, the get_gasmix_* functions were changed to return by value. For consistency, also pass gasmix by value. Note that on common 64-bit platforms struct gasmix is the size of a pointer [2 * 32 bit vs. 64 bit] and therefore uses the same space on the stack. On 32-bit platforms, the stack use is probably doubled, but in return a dereference is avoided. Supporting arbitrary gas-mixes (H2, Ar, ...) will be such an invasive change that going back to pointers is probably the least of our worries. This commit is a step in const-ifying input parameters (passing by value is the ultimate way of signaling that the input parameter will not be changed [unless there are references to said parameter]). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-05-14Core: introduce new subsurface-string headerGravatar Dirk Hohndel
First small step to shrinking dive.h. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-02-17Coding-style: remove superfluous parenthesesGravatar Berthold Stoeger
Mostly replace "return (expression);" by "return expression;" and one case of "function((parameter))" by "function(parameter)". Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-01-11Introduce helper function empty_string()Gravatar Berthold Stoeger
There are ca. 50 constructs of the kind same_string(s, "") to test for empty or null strings. Replace them by the new helper function empty_string(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-06-11smtk-import portability: avoid using %m[] in sscanfGravatar Salvador Cuñat
As Lubomir pointed out in his patch for datatrak.c, the format option %m for sscanf doesn't work in mingw/windows. Fortunately it's unnecessary as dates are dropped and we just get times. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-06-11smtk-import: portability: rework non portable funcsGravatar Salvador Cuñat
For different reasons some used functions aren't portable or simply are not included in mingw. This includes index, rindex, strptime, and timegm. A workaround for this is needed, if we want to build for windows using mingw based mxe environment. This patch does: - drops index and rindex in favor of strchr and strrchr - substitute strptime with a sscanf parsing - emulate timegm with a private func smtk_timegm() - remove definitions needed by strptime Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-06-11smtk-import: portability: rename DATEGravatar Salvador Cuñat
DATE happens to be defined in wtypes.h. Redefining it may be a bad idea, so move it to _DATE Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-06-11smtk-import: portability: include windows.hGravatar Salvador Cuñat
Include windows.h if we are cross building to windows Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-04-29Add SPDX header to smartrak importerGravatar Dirk Hohndel
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-04-21smtk-import: Add curly braces in nested conditionalsGravatar Salvador Cuñat
Curly braces are necessary in nested conditionals or results may not be those expected. In this case, the "else" clause applied on second "if", instead of first one. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-04-21smtk-import reuse pre-existent code and fix leakGravatar Salvador Cuñat
Use update_event_name() for bookmarks merge and free temp string. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-04-21smtk-import: Abort bookmark parsing if table doesn't openGravatar Salvador Cuñat
Do not just report the failure but abort parsing or we will get a crash Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-04-04smtk-import Avoid duplicities in bookmarksGravatar Salvador Cuñat
SmartTrak's bookmarks work in the same fashion Subsurface's do. The user may set a bookmark while underwater or set it just on the divelog software. At this time we are parsing those set in the DC twice, as we get one from libdivecomputer and another from smarttrak's database. This patch just checks if we have a bookmark event downloaded by libdivecomputer which has the same time that the one parsed from the .slg file. If so, merge the names taking the one from smarttrak. Text from smarttrak is preferred because the user may have entered some interesting note there and libdivecomputer's name is just "bookmark". Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-04-04smtk-import Fix wreck data importGravatar Salvador Cuñat
It was assumed that every data field in a wreck table was filled or zeroed. This assumption is actually false, so this patch adds testing for the existence of strings before working with them. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-03-18smtk-import fix is_same_cylinder()Gravatar Salvador Cuñat
Add return value to the gasmix condition, and fix the rest of the conditions. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-03-18smtk-import - Change cylinder import logicGravatar Salvador Cuñat
Until now, we did the cylinder import based on its initial pressure (a tank without pressure is an unused tank). Based in this assumption, we just dropped those tanks whose initial press was 0, losing user introduced tank definitions and getting some duplicities due to one cylinder being numbered (e.g.) 2 by libdivecomputer and 3 by SmartTrak. The new workflow is: get every single tank reported by SmartTrak (giving preference to libdivecomputer parsed data), then clean the cylinder table reverse order, dropping tanks without description and init or end pressures, and checkig them against the previous cylinder to do a merge, if they look the same, and try to avoid duplicities. The new logic assumes a heavier workload for the benefit of lower data loss (e.g. a user may get his/her tanks descriptions despite he/she hasn't recorded their pressures because forgot the values or had an issue with the gas transmitter). Suggested-by: Alessandro Volpi <volpial@gmail.com> Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-03-18smtk-import - Remove tank number limitationGravatar Salvador Cuñat
In the past subsurface managed up to 8 tanks, but now it manages up to 20. SmartTrak manages 10 (3 in older no trimix versions) so there is no more need to drop the last tanks. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-03-18smtk-import rework smtk_build_tank_info()Gravatar Salvador Cuñat
The cylinder info is built one by one. This way, instead of passing dive and tank number parameters, just passing a pointer to the tank been worked seems preferable. It also introduces lrint() in the function to round the doubles values obtained from libmdb for tank size and workingpressure. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
2017-03-18smtk-import - Add helper funcs to manage tank infoGravatar Salvador Cuñat
Framed in a full rework of the cylinders info import management, this funcs will be used in next patches. Functions merge_cylinder_type(), merge_cylinder_mix() and merge_cylinder_info(), have been shamelessly copied from dive.c as they have been removed by 162767aa dated 2017-03-11 just when I was going to use them. Macros MERGE_MAX() and MERGE_MIN() have just been copied from dive.c, but they could be moved to dive.h so they could be used elsewhere if needed. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>