Allthough most dive computers always use local time and don't support
timezones at all, there are a few exceptions. There are two different
sources of timezone information:
- Some of the newer Uwatec/Scubapro devices use UTC internally and also
support a timezone setting. This UTC offset is currently taken into
account to obtain the dive date/time, but the UTC offset itself is
lost.
- Uwatec/Scubapro and Reefnet devices rely on the clock of the host
system to synchronize the internal device clock and calculate the
dive date/time. The consequence is that the resulting date/time is
always in the timezone of the host system.
In order to preserve this timezone information, the dc_datetime_t
structure is extended with a new "timezone" field, containing the UTC
offset in seconds. Devices without timezone support will set the field
to the special value DC_TIMEZONE_NONE.
The dc_datetime_localtime() and dc_datetime_gmtime() functions will
automatically populate the new field with respectively the local
timezone offset and zero. The dc_datetime_mktime() function will take
into account the new timezone field for the conversion to UTC. The
special value DC_TIMEZONE_NONE is interpreted as zero.
The vendor_product_parser_create() and vendor_product_device_open()
functions should be called indirectly, through the generic
dc_device_open() and dc_parser_new() functions. And the
vendor_product_extract_dives() functions are internal functions that
should never have been part of the public api in the first place.
In commit 864b46603963ea2f70f5166bb7a738a12fc280fc, the sample events
have been removed because we need to parse the enum string descriptor
instead of the numeric value.
The gasmix query interface considers cylinders and gas mixes independent
things, so the tank data structure has a pointer to the gasmix index.
But the EON Steel treats cylinders as just having a gasmix (and so does
subsurface, for that matter), so the gasmix index for the tank is just
the same as the tank index.
But we never filled it in, so you'd always see a "gas index" of zero,
and subsurface would end up warning each time about how the gasmix index
doesn't match the cylinder index (but because subsurface actually agreed
with EON Steel, it worked despite the warning).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Instead of hardcoding the enum values for setpoint type and gas type,
use "lookup_enum()" to actually parse the enum data and use that.
I don't think this matters right now, since the numeric translations
haven't changed, but it is the RigthThing(tm) to do.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This fixes a bug where the begin/end marker was mistakenly added as the
value instead of as flag.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The dive gas parsing cases can be split out into a helper function to
keep things more manageable. Especially since there will be a couple
more cases coming up.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
It turns out you can't hardcode the enum numbers either, since they
change from dive to dive (or possibly firmware version to firmware
version).
So do it right, and actually parse the string descriptor for the enum.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The samples that take 'enum' types need the type descriptor to parse
what the enum type means.
This doesn't actually use the data yet, I need to add parsing of the
enum descriptor string.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The previous commit fixed the cache initialization testing, and
uncovered the fact that the tank size cache initialization didn't set
the initialized bit correctly. That oversight had been hidden by the
fact that we then tested the bit wrongly, so not setting it right didn't
use to matter as long as there were other higher cache bits that were
set.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The check for whether we had initialized a field in the EON Steel cache
data structure was wrong, causing some entries to be returned
successfully even if their field had never been initialized.
In most cases, it didn't matter, since the cache data was initialized to
zero (which is a fine default for uninitialized data), so most of the
time it didn't matter.
But for the recently added dive mode field, this caused OC dives to be
returned as freedives, for example.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This does the basic divemode and setpoint parsing for the EON Steel, and
gets the CCR download right in the big picture.
The cylinder information is still confusing and incorrect, but this is a
big step in the right direction.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
.. every time I look for a new feature I add debug code to print out all
the descriptors. So let's just do it once and for all.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Sadly the data we get from the EON Steel is a bit of a mess.
It doesn't really tell us if the data is metric or imperial (it always sends
both wet volume and working pressure). And in imperial mode the Suunto
engineers seem a bit confused. The pressure given (entered on the dive computer
in psi) is sent to us not in bar, not in atm... it's "something". As far as I
can tell it's a constant factor of 1.00069182389937 different from bar.
And the wet sizes are a bit to small to get the cuft size the user entered.
But instead of trying to guess and fix the mess, we just pass it through...
So this is somewhat useful, but not really what most users will want.
Linus started this commit with a few lines that parsed the right values out of
the data stream from the Suunto EON Steel. I then added the implementation of
the infrastructure to convert the raw data and report it back to the caller.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Both the allocation and initialization of the object data structure is
now moved to a single function. The corresponding deallocation function
is intended to free objects that have been allocated, but are not fully
initialized yet. The public cleanup function shouldn't be used in such
case, because it may try to release resources that haven't been
initialized yet.
Instead of freeing the object data structure in the backend specific
cleanup function, the memory is now freed automatically in the base
class function. This reduces the amount of boilerplate code in the
backends. Backends that don't allocate any additional resources, do no
longer require a cleanup function at all.
The new gasmix sample contains the index of the active gas mix.
This new sample is intended as a replacement for the existing gas change
events (SAMPLE_EVENT_GASCHANGE and SAMPLE_EVENT_GASCHANGE2). To maintain
backwards compatibility, the legacy events are marked as deprecated but
not removed yet.
It looks like the SAMPLE_EVENT_AIRTIME is actually meant for just
airtime warnings (as in the dive computer warning about low air).
If we ever care, I think we'd need to add a new interface for this.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Now that I actually have dives with the new format and with air
integration, I could test it all out and noticed some missing pieces.
This adds parsing for gastime and ventilation events (although we don't
*do* anything with the ventilation data, I have no idea what the number
means).
Also, this fixes an annoying warning message problem, which caused these
missing events to cause a SIGSEGV rather than just a bening warning.
Stupid bug, and only went unnoticed because libdivecomputer isn't built
with format string warnings.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This gets rid of the fixed sample indexes and the hardcoded grouping
code, and replaces them with proper parsing of the type descriptions.
This should mean that the new Suunto firmware v1.1.15 is now fully
supported by libdivecomputer.
There are still parts of the event description that we should really
parse better, notably the 'enum' descriptions of what the different
enumerated types mean, because it looks like those will change too. But
that is not nearly as important as getting the basic infrastructure done
for the core sample types.
Almost accidentally, this also ends up now parsing the compass heading
event.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
I was initially fooled into thinking that the field type numbers have
some meaning: the types didn't change if the upper byte of the type
number was zero. So I assumed that meant "fixed".
But the most recent firmware update made clear that no, they aren't
fixed, and the upper byte of the type must be some other thing.
This moves some more of the parsing over to comparing the strings,
rather than looking at the type index. It still leaves the sample data
alone, and I really want to do something more efficient than comparing
the type descriptor string for that, but at least the dive header fields
are now just comparing strings.
The actual marshalling that Suunto uses also describes the encoding, and
it's all ignoring that for now.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Suunto's new v1.1.15 firmware ends up terminating some final descriptor
lines with a newline, rather than just using newlines as separators. So
the last newline may not be followed by further data, but simple be the
end of the string. Accept that case.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The EON Steel notifications and states match the libdivecomputer ones
very badly, but this tries to make sense of the ones that match. And
puts the infrastructure in to do others in the future.
Signed-off-by: Linus Torvalds <torvalds@linux-fouindation.org>
The really sad part is that the EON Steel handles gas change events
correctly, by actually saying which cylinder it switches to. But the
libdivecomputer interfaces are broken, and only contain the gas *mix*
you switch to, which is ambiguous since you could have the same mix in
multiple cylinders.
Maybe we could put the one-based cylinder index into the "flags" field?
With zero meaning "unknown". That would be a straightforward extension.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This is only the silence the "enumeration value not handled in switch"
compiler warning. There is already a check earlier on to take care of
unsupported fields, but the default case is a good practice anyway.
The array with type descriptors is populated with dynamically allocated
strings, but they are never freed anywhere. To be able to free those
strings easily, they are now initialized with NULL pointers instead of
zero length strings.
Since we're dealing with byte arrays, there's no need to use void
pointers. Using unsigned char pointers also eliminates some compiler
warnings for pointer arithmetic on void pointers.
There is no need for custom logging functions, because libdivecomputer
already has an extensive logging infrastructure, featuring conditional
compilation, multiple loglevels, customization by the application, etc.
All entry point functions (e.g. public functions or functions called
through the vtable) use the backend name as the prefix. The same applies
to the main device and parser structures.
Basic Suunto EON Steel downloading copied from my test application.
This parses all the core dive data, including sample data (time, depth,
cylinder pressure, deco information etc).
The deco information returns ceiling and TTS rather than ceiling and
"time at ceiling", because that's what the dive computer has, and I
don't see any other way to return the information.
We don't report any events yet, though.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>