Merge git://github.com/libdivecomputer/libdivecomputer into Subsurface-DS9

Merge upstream libdivecomputer updates from Jef Driesen:

 - Jef merged the EON Steel dive sorting fix we had in our branch: one
   less difference to upstream

 - Jef merged the McLean Extreme support with some updates and cleanups,
   this just takes all his changes.

 - manual pages for iostream

 - various minor fixes and updates from Jef

* git://github.com/libdivecomputer/libdivecomputer:
  Update the gitignore file
  Update the man pages for the new iostream functions
  Purge the serial port buffer during initialization
  Add support for the McLean Extreme
  Suunto Eon Steel: sort the dive list properly
  Remove the salinity compensation
  Fix the hwOS ppO2 bug for firmware v3.08
This commit is contained in:
Linus Torvalds 2020-06-25 11:24:00 -07:00
commit 6b22340ddc
40 changed files with 2197 additions and 423 deletions

26
.gitignore vendored
View File

@ -37,33 +37,7 @@ Makefile.in
/doc/html/
/doc/latex/
/examples/aladin
/examples/atom2
/examples/d9
/examples/darwin
/examples/dctool
/examples/edy
/examples/eon
/examples/frog
/examples/iconhd
/examples/leonardo
/examples/memomouse
/examples/n2ition3
/examples/nemo
/examples/ostc
/examples/ostc-fwupdate
/examples/predator
/examples/puck
/examples/sensus
/examples/sensuspro
/examples/sensusultra
/examples/smart
/examples/solution
/examples/universal
/examples/veo250
/examples/vtpro
/examples/vyper
/examples/vyper2
/include/libdivecomputer/version.h

View File

@ -17,6 +17,7 @@ MANPAGES = \
dc_descriptor_get_model.3 \
dc_descriptor_get_product.3 \
dc_descriptor_get_vendor.3 \
dc_descriptor_get_transports.3 \
dc_descriptor_iterator.3 \
dc_device_close.3 \
dc_device_foreach.3 \
@ -32,6 +33,28 @@ MANPAGES = \
dc_parser_new.3 \
dc_parser_samples_foreach.3 \
dc_parser_set_data.3 \
dc_bluetooth_open.3 \
dc_bluetooth_iterator_new.3 \
dc_bluetooth_device_get_address.3 \
dc_bluetooth_device_get_name.3 \
dc_bluetooth_addr2str.3 \
dc_bluetooth_str2addr.3 \
dc_bluetooth_device_free.3 \
dc_usbhid_open.3 \
dc_usbhid_device_get_pid.3 \
dc_usbhid_device_get_vid.3 \
dc_usbhid_iterator_new.3 \
dc_usbhid_device_free.3 \
dc_serial_open.3 \
dc_serial_device_get_name.3 \
dc_serial_iterator_new.3 \
dc_serial_device_free.3 \
dc_irda_open.3 \
dc_irda_device_get_name.3 \
dc_irda_device_get_address.3 \
dc_irda_iterator_new.3 \
dc_irda_device_free.3 \
dc_iostream_close.3 \
libdivecomputer.3
HTMLPAGES = $(MANPAGES:%=%.html)

View File

@ -0,0 +1,61 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_BLUETOOTH_ADDR2STR 3
.Os
.Sh NAME
.Nm dc_bluetooth_addr2str
.Nd Convert a bluetooth address to a string.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/bluetooth.h
.Ft "const char*"
.Fo dc_bluetooth_addr2str
.Fa "dc_bluetooth_address_t address"
.Fa "char *str"
.Fa "size_t size"
.Fc
.Sh DESCRIPTION
Convert a bluetooth address to a string.
.Pp
The bluetooth address is formatted as XX:XX:XX:XX:XX:XX, where each XX is a
hexadecimal number specifying an octet of the 48-bit address.
The minimum size for the buffer is
.Dv DC_BLUETOOTH_SIZE
bytes.
.Pp
The reverse can be done with
.Xr dc_bluetooth_str2addr 3 .
.Sh RETURN VALUES
Returns the bluetooth address represented as a string.
.Sh SEE ALSO
.Xr dc_bluetooth_str2addr 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,52 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_BLUETOOTH_DEVICE_FREE 3
.Os
.Sh NAME
.Nm dc_bluetooth_device_free
.Nd Destroy the bluetooth device and free all resources.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/bluetooth.h
.Ft void
.Fo dc_bluetooth_device_free
.Fa "dc_bluetooth_device_t *device"
.Fc
.Sh DESCRIPTION
Destroy the bluetooth device and free all resources.
The bluetooth
.Fa device
usually found by searching through
.Xr dc_bluetooth_iterator_new 3 .
.Sh SEE ALSO
.Xr dc_bluetooth_iterator_new 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,69 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_BLUETOOTH_DEVICE_GET_ADDRESS 3
.Os
.Sh NAME
.Nm dc_bluetooth_device_get_address
.Nd Get the address of a bluetooth device.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/bluetooth.h
.Ft "dc_bluetooth_address_t"
.Fo dc_bluetooth_device_get_address
.Fa "dc_bluetooth_device_t *device"
.Fc
.Sh DESCRIPTION
Get the bluetooth device address of given bluetooth
.Fa device .
Required when opening transport communication with
.Xr dc_bluetooth_open 3 .
Requires a valid
.Fa device
of type
.Ft dc_bluetooth_device_t
which can be retrieved using
.Xr dc_bluetooth_iterator_new 3 .
.Sh RETURN VALUES
Returns the bluetooth address of
.Fa device
as
.Ft dc_bluetooth_address_t
which is a 64bit integer holding the bluetooth address.
The address can be formatted as a string by using
.Xr dc_bluetooth_addr2str 3 .
.Sh SEE ALSO
.Xr dc_bluetooth_open 3 ,
.Xr dc_bluetooth_iterator_new 3 ,
.Xr dc_bluetooth_device_get_name 3 ,
.Xr dc_bluetooth_addr2str 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,61 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_BLUETOOTH_DEVICE_GET_NAME 3
.Os
.Sh NAME
.Nm dc_bluetooth_device_get_name
.Nd Get the name of a bluetooth device.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/bluetooth.h
.Ft "const char *"
.Fo dc_bluetooth_device_get_name
.Fa "dc_bluetooth_device_t *device"
.Fc
.Sh DESCRIPTION
Get the name of given bluetooth
.Fa device .
Used for displaying.
Requires a valid
.Fa bluetooth_device
of type
.Ft dc_bluetooth_device_t
which can be retrieved using
.Xr dc_bluetooth_iterator_new 3 .
.Sh RETURN VALUES
Returns the bluetooth device of
.Fa device .
.Sh SEE ALSO
.Xr dc_bluetooth_open 3 ,
.Xr dc_bluetooth_iterator_new 3 ,
.Xr dc_bluetooth_device_get_address 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,102 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_BLUETOOTH_ITERATOR_NEW 3
.Os
.Sh NAME
.Nm dc_bluetooth_iterator_new
.Nd Create an iterator to enumerate the bluetooth devices.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/bluetooth.h
.Ft dc_status_t
.Fo dc_bluetooth_iterator_new
.Fa "dc_iterator_t **iterator"
.Fa "dc_context_t *context"
.Fa "dc_descriptor_t *descriptor"
.Fc
.Sh DESCRIPTION
Iterates through the available bluetooth devices which matches the given
.Fa descriptor .
Accepts a
.Fa context
opened with
.Xr dc_context_new 3
and a
.Fa descriptor
usually found by searching through
.Xr dc_descriptor_iterator 3 .
.Pp
On returning
.Dv DC_STATUS_SUCCESS
the
.Fa iterator
will be set to an
.Ft dc_iterator_t
which can be used to iterate the available bluetooth devices using
.Xr dc_iterator_next 3 .
.Pp
The value type of the iterator is of type
.Ft dc_bluetooth_device_t .
This value can be used in functions to extract information about this specific bluetooth device, namely
.Xr dc_bluetooth_device_get_name 3
and
.Xr dc_bluetooth_device_get_address 3 .
When done the bluetooth device needs to be freed with
.Xr dc_bluetooth_device_free 3 .
.Pp
After iterating the
.Fa iterator
needs to be freed using
.Xr dc_iterator_free 3 .
.Sh RETURN VALUES
Returns
.Dv DC_STATUS_SUCCESS
on success, or another
.Ft dc_status_t
code on failure.
On
.Dv DC_STATUS_SUCCESS
the returned
.Fa iterator
needs to be freed when done using
.Xr dc_iterator_free 3 .
.Sh SEE ALSO
.Xr dc_context_new 3 ,
.Xr dc_usbhid_iterator_new 3 ,
.Xr dc_serial_iterator_new 3 ,
.Xr dc_irda_iterator_new 3 ,
.Xr dc_bluetooth_device_get_name 3 ,
.Xr dc_bluetooth_device_get_address 3 ,
.Xr dc_bluetooth_device_free 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,87 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_BLUETOOTH_OPEN 3
.Os
.Sh NAME
.Nm dc_bluetooth_open
.Nd Opens an iostream for a bluetooth device
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/bluetooth.h
.Ft dc_status_t
.Fo dc_bluetooth_open
.Fa "dc_iostream_t **iostream"
.Fa "dc_context_t *context"
.Fa "dc_bluetooth_address_t address"
.Fa "unsigned int port"
.Fc
.Sh DESCRIPTION
Opens an iostream for a bluetooth device.
Accepts a
.Fa context
opened with
.Xr dc_context_new 3 ,
a 48-bit bluetooth
.Fa address
given by
.Xr dc_bluetooth_iterator_new 3
together with
.Xr dc_bluetooth_device_get_address 3
or
.Xr dc_bluetooth_str2addr 3
and a bluetooth rfcomm
.Fa port
number (use 0 for autodetection).
.Pp
Upon returning
.Dv DC_STATUS_SUCCESS ,
the
.Fa iostream
pointer must be freed with
.Xr dc_iostream_close 3 .
.Sh RETURN VALUES
Returns
.Dv DC_STATUS_SUCCESS
on success or one of several error values on error.
On success, the
.Fa iostream
pointer is filled in with an open handle.
.Sh SEE ALSO
.Xr dc_context_new 3 ,
.Xr dc_iostream_close 3 ,
.Xr dc_serial_open 3 ,
.Xr dc_irda_open 3 ,
.Xr dc_usbhid_open 3 ,
.Xr dc_bluetooth_iterator_new 3 ,
.Xr dc_bluetooth_device_get_address 3 ,
.Xr dc_bluetooth_str2addr 3 ,
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,58 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_BLUETOOTH_STR2ADDR 3
.Os
.Sh NAME
.Nm dc_bluetooth_str2addr
.Nd Convert a string to a bluetooth address.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/bluetooth.h
.Ft "dc_bluetooth_address_t"
.Fo dc_bluetooth_addr2str
.Fa "const char *address"
.Fc
.Sh DESCRIPTION
Convert a string to a bluetooth address.
.Pp
The string
.Fa address
is expected to be in the format XX:XX:XX:XX:XX:XX,
where each XX is a hexadecimal number specifying an octet of the 48-bit address.
.Pp
The reverse can be done with
.Xr dc_bluetooth_addr2str 3 .
.Sh RETURN VALUES
Returns the bluetooth address represented as a 48-bit number.
.Sh SEE ALSO
.Xr dc_bluetooth_addr2str 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,72 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_DESCRIPTOR_GET_TRANSPORTS 3
.Os
.Sh NAME
.Nm dc_descriptor_get_transports
.Nd Gets the transports supported by the given descriptor.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/descriptor.h
.Ft "unsigned int"
.Fo dc_descriptor_get_transports
.Fa "dc_descriptor_t *descriptor"
.Fc
.Sh DESCRIPTION
Gets the transports supported by the given
.Fa descriptor .
The
.Fa descriptor
usually found by searching through
.Xr dc_descriptor_iterator 3 .
.Sh RETURN VALUES
Returns a union (bitwise OR) of the transports supported by the given
.Fa descriptor .
.Pp
The result is combination of
.Dv DC_TRANSPORT_USB ,
.Dv DC_TRANSPORT_USBHID ,
.Dv DC_TRANSPORT_BLE ,
.Dv DC_TRANSPORT_BLUETOOTH ,
.Dv DC_TRANSPORT_SERIAL ,
.Dv DC_TRANSPORT_IRDA
.Pp
To determine if a specific transport is supported use the following code
.Bd -literal -offset indent
unsigned int transports = dc_descriptor_get_transports(descriptor);
if(transports & DC_TRANSPORT_USBHID) {
// Device supports USB HID as transport
}
.Ed
.Sh SEE ALSO
.Xr dc_descriptor_iterator 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -18,7 +18,7 @@
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd January 5, 2017
.Dd June 5, 2020
.Dt DC_DEVICE_OPEN 3
.Os
.Sh NAME
@ -33,7 +33,7 @@
.Fa "dc_device_t **device"
.Fa "dc_context_t *context"
.Fa "dc_descriptor_t *descriptor"
.Fa "const char *name"
.Fa "dc_iostream_t *iostream"
.Fc
.Sh DESCRIPTION
Open a dive computer device for processing.
@ -45,19 +45,14 @@ a dive computer
.Fa descriptor
usually found by searching through
.Xr dc_descriptor_iterator 3 ,
and a platform-specific device
.Fa name
.Po
such as
.Pa /dev/ttyUSBx
on Linux,
.Pa /dev/tty.xxx
on Mac OS X,
.Pa /dev/ttyUx
on the BSDs,
and a
.Fa iostream
opened with a transport specific open function like
.Xr dc_usbhid_open 3 ,
.Xr dc_irda_open 3 ,
.Xr dc_serial_open 3 ,
or
.Pa COMx
on Microsoft Windows
.Xr dc_bluetooth_open 3
.Pc .
.Pp
Upon returning
@ -83,6 +78,10 @@ The
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
The manpages were written by
.An Kristaps Dzonsons ,
.Mt kristaps@bsd.lv .
and
.An Vincent Hagen ,
.Mt vinnie@script4web.nl

View File

@ -0,0 +1,60 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_IOSTREAM_CLOSE 3
.Os
.Sh NAME
.Nm dc_iostream_close
.Nd Close the I/O stream and free all resources.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/iostream.h
.Ft dc_status_t
.Fo dc_iostream_close
.Fa "dc_iostream_t *iostream"
.Fc
.Sh DESCRIPTION
Close the I/O stream and free all resources.
Accepts the
.Fa iostream
to close and free.
.Sh RETURN VALUES
Returns
.Dv DC_STATUS_SUCCESS
on success, or another
.Ft dc_status_t
code on failure.
.Sh SEE ALSO
.Xr dc_usbhid_open 3 ,
.Xr dc_serial_open 3 ,
.Xr dc_irda_open 3 ,
.Xr dc_bluetooth_open 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,52 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_IRDA_DEVICE_FREE 3
.Os
.Sh NAME
.Nm dc_irda_device_free
.Nd Destroy the irda device and free all resources.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/irda.h
.Ft void
.Fo dc_irda_device_free
.Fa "dc_irda_device_t *device"
.Fc
.Sh DESCRIPTION
Destroy the irda device and free all resources.
The irda
.Fa device
usually found by searching through
.Xr dc_irda_iterator_new 3 .
.Sh SEE ALSO
.Xr dc_irda_iterator_new 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,59 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_IRDA_DEVICE_GET_ADDRESS 3
.Os
.Sh NAME
.Nm dc_irda_device_get_address
.Nd Get the address of the IrDA device.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/irda.h
.Ft "unsigned int"
.Fo dc_irda_device_get_address
.Fa "dc_irda_device_t *device"
.Fc
.Sh DESCRIPTION
Get the address of the IrDA device. Return value used for opening a IrDA device using
.Xr dc_irda_open 3 .
Requires a valid irda
.Fa device
of type
.Ft dc_irda_device_t
which can be retrieved using
.Xr dc_irda_iterator_new 3 .
.Sh RETURN VALUES
Returns the IrDA address of given IrDA
.Fa device
.Sh SEE ALSO
.Xr dc_irda_open 3 ,
.Xr dc_irda_device_get_name 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,58 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_IRDA_DEVICE_GET_NAME 3
.Os
.Sh NAME
.Nm dc_irda_device_get_name
.Nd Get the address of the IrDA device.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/irda.h
.Ft "const char *"
.Fo dc_irda_device_get_name
.Fa "dc_irda_device_t *device"
.Fc
.Sh DESCRIPTION
Get the name of the IrDA device. Used for displaying.
Requires a valid irda
.Fa device
of type
.Ft dc_irda_device_t
which can be retrieved using
.Xr dc_irda_iterator_new 3 .
.Sh RETURN VALUES
Returns the IrDA name of given
.Fa irda_device
.Sh SEE ALSO
.Xr dc_irda_device_get_address 3 .
.Xr dc_irda_iterator_new 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,102 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_IRDA_ITERATOR_NEW 3
.Os
.Sh NAME
.Nm dc_irda_iterator_new
.Nd Create an iterator to enumerate the IrDA devices.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/irda.h
.Ft dc_status_t
.Fo dc_irda_iterator_new
.Fa "dc_iterator_t **iterator"
.Fa "dc_context_t *context"
.Fa "dc_descriptor_t *descriptor"
.Fc
.Sh DESCRIPTION
Iterates through the available IrDA devices which matches the given
.Fa descriptor .
Accepts a
.Fa context
opened with
.Xr dc_context_new 3
and a
.Fa descriptor
usually found by searching through
.Xr dc_descriptor_iterator 3 .
.Pp
On returning
.Dv DC_STATUS_SUCCESS
the
.Fa iterator
will be set to an
.Ft dc_iterator_t
which can be used to iterate the available IrDA devices using
.Xr dc_iterator_next 3 .
.Pp
The value type of the iterator is of type
.Ft dc_irda_device_t .
This value can be used in functions to extract information about this specific IrDA device, namely
.Xr dc_irda_device_get_name 3
and
.Xr dc_irda_device_get_address 3 .
When done the IrDA device needs to be freed with
.Xr dc_irda_device_free 3 .
.Pp
After iterating the
.Fa iterator
needs to be freed using
.Xr dc_iterator_free 3 .
.Sh RETURN VALUES
Returns
.Dv DC_STATUS_SUCCESS
on success, or another
.Ft dc_status_t
code on failure.
On
.Dv DC_STATUS_SUCCESS
the returned
.Fa iterator
needs to be freed when done using
.Xr dc_iterator_free 3 .
.Sh SEE ALSO
.Xr dc_context_new 3 ,
.Xr dc_usbhid_iterator_new 3 ,
.Xr dc_serial_iterator_new 3 ,
.Xr dc_bluetooth_iterator_new 3 ,
.Xr dc_irda_device_get_name 3 ,
.Xr dc_irda_device_get_address 3 ,
.Xr dc_irda_device_free 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

85
doc/man/dc_irda_open.3 Normal file
View File

@ -0,0 +1,85 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_IRDA_OPEN 3
.Os
.Sh NAME
.Nm dc_irda_open
.Nd Opens an iostream for a IrDA device
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/irda.h
.Ft dc_status_t
.Fo dc_irda_open
.Fa "dc_iostream_t **iostream"
.Fa "dc_context_t *context"
.Fa "unsigned int address"
.Fa "unsigned int lsap"
.Fc
.Sh DESCRIPTION
Opens an iostream for a IrDA (Infra Red) device.
Accepts a
.Fa context
opened with
.Xr dc_context_new 3 ,
.Fa address
given through
.Xr dc_irda_iterator_new 3
together with
.Xr dc_irda_device_get_address 3
, the last argument
.Fa lsap
is a port number used during the communication. Currently only Uwatec computers use IrDA comminication and for those the
.Fa lsap
can be hardcoded to 1
.Pp
Upon returning
.Dv DC_STATUS_SUCCESS ,
the
.Fa iostream
pointer must be freed with
.Xr dc_iostream_close 3 .
.Sh RETURN VALUES
Returns
.Dv DC_STATUS_SUCCESS
on success or one of several error values on error.
On success, the
.Fa iostream
pointer is filled in with an open handle.
.Sh SEE ALSO
.Xr dc_context_new 3 ,
.Xr dc_iostream_close 3 ,
.Xr dc_serial_open 3 ,
.Xr dc_usbhid_open 3 ,
.Xr dc_bluetooth_open 3 ,
.Xr dc_irda_iterator_new 3 ,
.Xr dc_irda_device_get_address 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -149,7 +149,7 @@ the tank volume units as
or
.Dv DC_TANKVOLUME_METRIC ;
.Va volume ,
the tank volume in bar or zero if the tank is
the tank volume in litres or zero if the tank is
.Dv DC_TANKVOLUME_NONE ;
.Va workpressure ,
the work pressure in bar or zero if

View File

@ -126,7 +126,7 @@ Sets the
.Fa rbt
field.
.It Dv DC_SAMPLE_HEARTBEAT
The diver's heartbeet in beats per minute.
The diver's heartbeat in beats per minute.
Sets the
.Fa heartbeat
field.

View File

@ -0,0 +1,52 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_SERIAL_DEVICE_FREE 3
.Os
.Sh NAME
.Nm dc_serial_device_free
.Nd Destroy the serial device and free all resources.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/serial.h
.Ft void
.Fo dc_serial_device_free
.Fa "dc_serial_device_t *device"
.Fc
.Sh DESCRIPTION
Destroy the serial device and free all resources.
The serial
.Fa device
usually found by searching through
.Xr dc_serial_iterator_new 3 .
.Sh SEE ALSO
.Xr dc_serial_iterator_new 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,59 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_SERIAL_DEVICE_GET_NAME 3
.Os
.Sh NAME
.Nm dc_serial_device_get_name
.Nd Get the device name of the serial device.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/serial.h
.Ft "const char *"
.Fo dc_serial_device_get_name
.Fa "dc_serial_device_t *device"
.Fc
.Sh DESCRIPTION
Get the device node of the serial device. Used when opening serial transport with
.Xr dc_serial_open 3 .
Requires a valid serial
.Fa device
of type
.Ft dc_serial_device_t
which can be retrieved using
.Xr dc_serial_iterator_new 3 .
.Sh RETURN VALUES
Returns the device name of given serial
.Fa device
.Sh SEE ALSO
.Xr dc_serial_open 3 ,
.Xr dc_serial_iterator_new 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,99 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_SERIAL_ITERATOR_NEW 3
.Os
.Sh NAME
.Nm dc_serial_iterator_new
.Nd Create an iterator to enumerate the serial devices.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/serial.h
.Ft dc_status_t
.Fo dc_serial_iterator_new
.Fa "dc_iterator_t **iterator"
.Fa "dc_context_t *context"
.Fa "dc_descriptor_t *descriptor"
.Fc
.Sh DESCRIPTION
Iterates through the available serial devices matching the given
.Fa descriptor .
Accepts a
.Fa context
opened with
.Xr dc_context_new 3
and a
.Fa descriptor
usually found by searching through
.Xr dc_descriptor_iterator 3 .
.Pp
On returning
.Dv DC_STATUS_SUCCESS
the
.Fa iterator
will be set to an
.Ft dc_iterator_t
which can be used to iterate the available serial devices using
.Xr dc_iterator_next 3 .
.Pp
The value type of the iterator is of type
.Ft dc_serial_device_t .
This value can be used in functions to extract information about this specific serial device, namely
.Xr dc_serial_device_get_name 3
When done the serial device needs to be freed with
.Xr dc_serial_device_free 3 .
.Pp
After iterating the
.Fa iterator
needs to be freed using
.Xr dc_iterator_free 3 .
.Sh RETURN VALUES
Returns
.Dv DC_STATUS_SUCCESS
on success, or another
.Ft dc_status_t
code on failure.
On
.Dv DC_STATUS_SUCCESS
the returned
.Fa iterator
needs to be freed when done using
.Xr dc_iterator_free 3 .
.Sh SEE ALSO
.Xr dc_context_new 3 ,
.Xr dc_usbhid_iterator_new 3 ,
.Xr dc_irda_iterator_new 3 ,
.Xr dc_bluetooth_iterator_new 3 ,
.Xr dc_serial_device_get_name 3 ,
.Xr dc_serial_device_free 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

80
doc/man/dc_serial_open.3 Normal file
View File

@ -0,0 +1,80 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_SERIAL_OPEN 3
.Os
.Sh NAME
.Nm dc_serial_open
.Nd Opens an iostream for a serial device
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/serial.h
.Ft dc_status_t
.Fo dc_serial_open
.Fa "dc_iostream_t **iostream"
.Fa "dc_context_t *context"
.Fa "const char *name"
.Fc
.Sh DESCRIPTION
Opens an iostream for a serial device.
Accepts a
.Fa context
opened with
.Xr dc_context_new 3
and a
.Fa name
device name, usually found through
.Xr dc_serial_iterator_new 3
with
.Xr dc_serial_device_get_name 3 .
.Pp
Upon returning
.Dv DC_STATUS_SUCCESS ,
the
.Fa iostream
pointer must be freed with
.Xr dc_iostream_close 3 .
.Sh RETURN VALUES
Returns
.Dv DC_STATUS_SUCCESS
on success or one of several error values on error.
On success, the
.Fa iostream
pointer is filled in with an open handle.
.Sh SEE ALSO
.Xr dc_context_new 3 ,
.Xr dc_iostream_close 3 ,
.Xr dc_usbhid_open 3 ,
.Xr dc_irda_open 3 ,
.Xr dc_bluetooth_open 3 ,
.Xr dc_serial_iterator_new 3 ,
.Xr dc_serial_device_get_name 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,52 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_USBHID_DEVICE_FREE 3
.Os
.Sh NAME
.Nm dc_usbhid_device_free
.Nd Destroy the USB HID device and free all resources.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/usbhid.h
.Ft void
.Fo dc_usbhid_device_free
.Fa "dc_usbhid_device_t *device"
.Fc
.Sh DESCRIPTION
Destroy the USB HID device and free all resources.
The usbhid
.Fa device
usually found by searching through
.Xr dc_usbhid_iterator_new 3 .
.Sh SEE ALSO
.Xr dc_usbhid_iterator_new 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,58 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_USBHID_DEVICE_GET_PID 3
.Os
.Sh NAME
.Nm dc_usbhid_device_get_pid
.Nd Get the product id (PID) of the USB HID device.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/usbhid.h
.Ft "unsigned int"
.Fo dc_usbhid_device_get_pid
.Fa "dc_usbhid_device_t *device"
.Fc
.Sh DESCRIPTION
Get the product id (PID) of the USB HID device. Used for displaying.
Requires a valid usbhid
.Fa device
of type
.Ft dc_usbhid_device_t
which can be retrieved using
.Xr dc_usbhid_iterator_new 3 .
.Sh RETURN VALUES
Returns the product id (PID) of given
.Fa usbhid_device
.Sh SEE ALSO
.Xr dc_usbhid_device_get_vid 3 ,
.Xr dc_usbhid_iterator_new 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,58 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_USBHID_DEVICE_GET_VID 3
.Os
.Sh NAME
.Nm dc_usbhid_device_get_vid
.Nd Get the vendor id (VID) of the USB HID device.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/usbhid.h
.Ft "unsigned int"
.Fo dc_usbhid_device_get_vid
.Fa "dc_usbhid_device_t *device"
.Fc
.Sh DESCRIPTION
Get the vendor id (VID) of the USB HID device. Used for displaying.
Requires a valid usbhid
.Fa device
of type
.Ft dc_usbhid_device_t
which can be retrieved using
.Xr dc_usbhid_iterator_new 3 .
.Sh RETURN VALUES
Returns the vendor id (VID) of given usbhid
.Fa device
.Sh SEE ALSO
.Xr dc_usbhid_device_get_vid 3 ,
.Xr dc_usbhid_iterator_new 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -0,0 +1,101 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_USBHID_ITERATOR_NEW 3
.Os
.Sh NAME
.Nm dc_usbhid_iterator_new
.Nd Create an iterator to enumerate the USB HID devices.
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/usbhid.h
.Ft dc_status_t
.Fo dc_usbhid_iterator_new
.Fa "dc_iterator_t **iterator"
.Fa "dc_context_t *context"
.Fa "dc_descriptor_t *descriptor"
.Fc
.Sh DESCRIPTION
Iterates through the available USB HID devices matching the given
.Fa descriptor .
Accepts a
.Fa context
opened with
.Xr dc_context_new 3
and a
.Fa descriptor
usually found by searching through
.Xr dc_descriptor_iterator 3 .
.Pp
On returning
.Dv DC_STATUS_SUCCESS
the
.Fa iterator
will be set to an
.Ft dc_iterator_t
which can be used to iterate the available USB HID devices using
.Xr dc_iterator_next 3 .
.Pp
The value type of the iterator is of type
.Ft dc_usbhid_device_t .
This value can be used in functions to extract information about this specific USB HID device, namely
.Xr dc_usbhid_device_get_pid 3
and
.Xr dc_usbhid_device_get_vid 3 .
When done the USB HID device needs to be freed with
.Xr dc_usbhid_device_free 3 .
.Pp
After iterating the
.Fa iterator
needs to be freed using
.Xr dc_iterator_free 3 .
.Sh RETURN VALUES
Returns
.Dv DC_STATUS_SUCCESS
on success, or another
.Ft dc_status_t
code on failure.
On
.Dv DC_STATUS_SUCCESS
the returned
.Fa iterator
needs to be freed when done using
.Xr dc_iterator_free 3 .
.Sh SEE ALSO
.Xr dc_context_new 3 ,
.Xr dc_bluetooth_iterator_new 3 ,
.Xr dc_serial_iterator_new 3 ,
.Xr dc_irda_iterator_new 3 ,
.Xr dc_usbhid_device_get_pid 3 ,
.Xr dc_usbhid_device_get_vid 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

77
doc/man/dc_usbhid_open.3 Normal file
View File

@ -0,0 +1,77 @@
.\"
.\" libdivecomputer
.\"
.\" Copyright (C) 2020 Vincent Hagen <vinnie@script4web.nl>
.\"
.\" This library is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Lesser General Public
.\" License as published by the Free Software Foundation; either
.\" version 2.1 of the License, or (at your option) any later version.
.\"
.\" This library is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
.\" Lesser General Public License for more details.
.\"
.\" You should have received a copy of the GNU Lesser General Public
.\" License along with this library; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
.\" MA 02110-1301 USA
.\"
.Dd June 5, 2020
.Dt DC_USBHID_OPEN 3
.Os
.Sh NAME
.Nm dc_usbhid_open
.Nd Opens an iostream for a USB HID device
.Sh LIBRARY
.Lb libdivecomputer
.Sh SYNOPSIS
.In libdivecomputer/usbhid.h
.Ft dc_status_t
.Fo dc_usbhid_open
.Fa "dc_iostream_t **iostream"
.Fa "dc_context_t *context"
.Fa "dc_usbhid_device_t *device"
.Fc
.Sh DESCRIPTION
Opens an iostream for a USB HID device.
Accepts a
.Fa context
opened with
.Xr dc_context_new 3
and a
.Fa device
usually found by searching through
.Xr dc_usbhid_iterator_new 3 .
.Pp
Upon returning
.Dv DC_STATUS_SUCCESS ,
the
.Fa iostream
pointer must be freed with
.Xr dc_iostream_close 3 .
.Sh RETURN VALUES
Returns
.Dv DC_STATUS_SUCCESS
on success or one of several error values on error.
On success, the
.Fa iostream
pointer is filled in with an open handle.
.Sh SEE ALSO
.Xr dc_context_new 3 ,
.Xr dc_usbhid_iterator_new 3 ,
.Xr dc_iostream_close 3 ,
.Xr dc_serial_open 3 ,
.Xr dc_irda_open 3 ,
.Xr dc_bluetooth_open 3 .
.Sh AUTHORS
The
.Lb libdivecomputer
library was written by
.An Jef Driesen ,
.Mt jef@libdivecomputer.org .
.br
This manpage is written by
.An Vincent Hagen ,
.Mt vinnie@script4web.nl .

View File

@ -41,9 +41,8 @@ these steps:
.Bl -enum
.It
Create a new context with
.Xr dc_context_new 3 .
This supplies a parse context: logging, error handling, etc.
Override the values with
.Xr dc_context_new 3
to initialize the library. Logging can be controlled with
.Xr dc_context_set_logfunc 3
and
.Xr dc_context_set_loglevel 3 .
@ -52,11 +51,28 @@ Find a descriptor for their dive computer by iterating through
.Xr dc_descriptor_iterator 3
and searching by name, vendor, or product family.
.It
Open the hardware device to which the dive computer is connected with
.Xr dc_device_open 3 ,
then invoke
Find the transport to use for the communication. To determine the supported transports use
.Xr dc_descriptor_get_transports 3 .
.It
Find the hardware device corresponding to the connected dive computer by iterating through
.Xr dc_usbhid_iterator_new 3 ,
.Xr dc_serial_iterator_new 3 ,
.Xr dc_irda_iterator_new 3
or
.Xr dc_bluetooth_iterator_new 3 .
.It
Open the transport communcations with
.Xr dc_usbhid_open 3 ,
.Xr dc_serial_open 3 ,
.Xr dc_irda_open 3
or
.Xr dc_bluetooth_open 3 .
.It
Open a connection to the dive computer with
.Xr dc_device_open 3 .
Optionally use
.Xr dc_device_set_events 3 ,
.Xr dc_device_set_fingerprint 3 ,
.Xr dc_device_set_fingerprint 3
and
.Xr dc_device_set_cancel 3
to set the logging events, last-seen fingerprint, and cancel routine,
@ -71,8 +87,9 @@ and set the parsed data with
.Xr dc_parser_set_data 3 .
.It
Get attributes of the parsed dive with
.Xr dc_parser_get_field 3 ,
then iterate through the dive's samples (recorded data) with
.Xr dc_parser_get_field 3 .
.It
Iterate through the dive's samples (recorded data) with
.Xr dc_parser_samples_foreach 3 .
.El
.Sh RETURN VALUES
@ -129,7 +146,10 @@ return
.Dv DC_STATUS_SUCCESS .
.El
.Sh SEE ALSO
.Xr dc_buffer_new 3
.Xr dc_context_new 3 ,
.Xr dc_descriptor_iterator 3
.Xr dc_device_open 3
.Xr dc_parser_new 3
.Sh AUTHORS
The
.Lb libdivecomputer

View File

@ -108,12 +108,12 @@ typedef enum dc_family_t {
DC_FAMILY_COCHRAN_COMMANDER = (14 << 16),
/* Tecdiving */
DC_FAMILY_TECDIVING_DIVECOMPUTEREU = (15 << 16),
/* Garmin */
DC_FAMILY_GARMIN = (16 << 16),
/* Deepblu */
DC_FAMILY_DEEPBLU = (17 << 16),
/* McLean */
DC_FAMILY_MCLEAN_EXTREME = (18 << 16),
DC_FAMILY_MCLEAN_EXTREME = (16 << 16),
/* Garmin */
DC_FAMILY_GARMIN = (17 << 16),
/* Deepblu */
DC_FAMILY_DEEPBLU = (18 << 16),
} dc_family_t;
#ifdef __cplusplus

View File

@ -350,6 +350,14 @@
RelativePath="..\src\mares_puck.c"
>
</File>
<File
RelativePath="..\src\mclean_extreme.c"
>
</File>
<File
RelativePath="..\src\mclean_extreme_parser.c"
>
</File>
<File
RelativePath="..\src\oceanic_atom2.c"
>
@ -724,6 +732,10 @@
RelativePath="..\src\mares_puck.h"
>
</File>
<File
RelativePath="..\src\mclean_extreme.h"
>
</File>
<File
RelativePath="..\src\oceanic_atom2.h"
>

View File

@ -384,7 +384,7 @@ static const dc_descriptor_t g_descriptors[] = {
/* Deepblu */
{"Deepblu", "Cosmiq+", DC_FAMILY_DEEPBLU, 0, DC_TRANSPORT_BLE, dc_filter_deepblu},
/* McLean Extreme */
{ "McLean", "Extreme", DC_FAMILY_MCLEAN_EXTREME, 0, DC_TRANSPORT_BLUETOOTH, dc_filter_mclean },
{ "McLean", "Extreme", DC_FAMILY_MCLEAN_EXTREME, 0, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLUETOOTH, dc_filter_mclean},
};
static int
@ -672,8 +672,7 @@ static int dc_filter_mclean(dc_transport_t transport, const void* userdata)
if (transport == DC_TRANSPORT_BLUETOOTH) {
return DC_FILTER_INTERNAL (userdata, bluetooth, 0, dc_match_name);
}
else if (transport == DC_TRANSPORT_SERIAL) {
} else if (transport == DC_TRANSPORT_SERIAL) {
return DC_FILTER_INTERNAL(userdata, rfcomm, 1, dc_match_devname);
}

View File

@ -733,14 +733,6 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
else
samplerate = data[36];
// Get the salinity factor.
unsigned int salinity = data[layout->salinity];
if (version == 0x23 || version == 0x24)
salinity += 100;
if (salinity < 100 || salinity > 104)
salinity = 100;
double hydrostatic = GRAVITY * salinity * 10.0;
// Get the number of sample descriptors.
unsigned int nconfig = 0;
if (version == 0x23 || version == 0x24)
@ -844,9 +836,9 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
if (callback) callback (DC_SAMPLE_CNS, sample, userdata);
}
// Depth (mbar).
// Depth (1/100 m).
unsigned int depth = array_uint16_le (data + offset);
sample.depth = (depth * BAR / 1000.0) / hydrostatic;
sample.depth = depth / 100.0;
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
offset += 2;
@ -996,12 +988,12 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
for (unsigned int i = 0; i < nconfig; ++i) {
if (info[i].divisor && (nsamples % info[i].divisor) == 0) {
if (length < info[i].size) {
// Due to a bug in the hwOS Tech firmware v3.03 to v3.07, and
// Due to a bug in the hwOS Tech firmware v3.03 to v3.08, and
// the hwOS Sport firmware v10.57 to v10.63, the ppO2 divisor
// is sometimes not correctly reset to zero when no ppO2
// samples are being recorded.
if (info[i].type == PPO2 && parser->hwos && parser->model != OSTC4 &&
((firmware >= OSTC3FW(3,3) && firmware <= OSTC3FW(3,7)) ||
((firmware >= OSTC3FW(3,3) && firmware <= OSTC3FW(3,8)) ||
(firmware >= OSTC3FW(10,57) && firmware <= OSTC3FW(10,63)))) {
WARNING (abstract->context, "Reset invalid ppO2 divisor to zero.");
info[i].divisor = 0;

View File

@ -1,7 +1,7 @@
/*
* libdivecomputer
*
* Copyright (C) 2018 Jef Driesen
* Copyright (C) 2020 Jef Driesen, David Carron
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -21,7 +21,6 @@
#include <string.h> // memcmp, memcpy
#include <stdlib.h> // malloc, free
#include <stdint.h>
#include "mclean_extreme.h"
#include "context-private.h"
@ -34,72 +33,34 @@
#define STX 0x7E
#define CMD_COMPUTER 0xa0 // download computer configuration
#define CMD_SETCOMPUTER 0xa1 // upload computer configuration
#define CMD_DIVE 0xa3 // download specified dive configuration and samples
#define CMD_CLOSE 0xaa // close connexion and turn off bluetooth
#define CMD_SERIALNUMBER 0x91
#define CMD_COMPUTER 0xA0
#define CMD_SET_COMPUTER 0xA1
#define CMD_DIVE 0xA3
#define CMD_CLOSE 0xAA
#define CMD_SET_TIME 0xAC
#define CMD_FIRMWARE 0xAD
#define SZ_PACKET 512 // maximum packe payload length
#define SZ_SUMMARY 7 // size of the device fingerprint
#define SZ_CFG 0x002d // size of the common dive/computer header
#define SZ_COMPUTER 0x0097 // size of the computer state dump
#define SZ_DIVE 0x005e // size of the dive state dump
#define SZ_SAMPLE 0x0004 // size of the sample state dump
#define SZ_PACKET 512
#define SZ_FINGERPRINT 7
#define SZ_CFG 0x002D
#define SZ_COMPUTER (SZ_CFG + 0x6A)
#define SZ_HEADER (SZ_CFG + 0x31)
#define SZ_SAMPLE 0x0004
// private device parsing functions //////////////////////////////////////////////////////////////////////////////////////////
#define EPOCH 946684800 // 2000-01-01 00:00:00 UTC
static uint16_t uint16(const unsigned char* buffer, int addr) { return (buffer[0 + addr] << 0) | (buffer[1 + addr] << 8); }
static uint32_t uint32(const unsigned char* buffer, int addr) { return (uint16(buffer, addr) << 0) | (uint16(buffer, addr + 2) << 16); }
static uint8_t device_format(const unsigned char* device) { return device[0x0000]; }
// static uint8_t device_gas_pO2(const unsigned char* device, int value) { return device[0x0001 + value * 2]; }
// static uint8_t device_gas_pHe(const unsigned char* device, int value) { return device[0x0001 + 1 + value * 2]; }
// static bool device_gas_enabled(const unsigned char* device, int value) { return (device[0x0011] & (1 << value)) != 0; }
// static uint8_t device_setpoint(const unsigned char* device, int value) { return device[0x0013 + value]; }
// static bool device_setpoint_enabled(const unsigned char* device, int value) { return (device[device, 0x0016] & (1 << value)) != 0; }
// static bool device_metric(unsigned char* device) { return device[0x0018] != 0; }
static uint16_t device_name(const unsigned char* device) { return uint16(device, 0x0019); }
// static uint16_t device_Vasc(const unsigned char* device) { return uint16(device, 0x001c); }
// static uint16_t device_Psurf(const unsigned char* device) { return uint16(device, 0x001e); }
// static uint8_t device_gfs_index(const unsigned char* device) { return device[0x0020]; }
// static uint8_t device_gflo(const unsigned char* device) { return device[0x0021]; }
// static uint8_t device_gfhi(const unsigned char* device) { return device[0x0022]; }
// static uint8_t device_density_index(const unsigned char* device) { return device[0x0023]; }
// static uint16_t device_ppN2_limit(const unsigned char* device) { return uint16(device, 0x0024); }
// static uint16_t device_ppO2_limit(const unsigned char* device) { return uint16(device, 0x0026); }
// static uint16_t device_ppO2_bottomlimit(const unsigned char* device) { return uint16(device, 0x0028); }
// static uint16_t device_density_limit(const unsigned char* device) { return uint16(device, 0x002a); }
// static uint8_t device_operatingmode(const unsigned char* device) { return device[0x002c]; }
// static uint16_t device_inactive_timeout(const unsigned char* device) { return uint16(device, SZ_CFG + 0x0008); }
// static uint16_t device_dive_timeout(const unsigned char* device) { return uint16(device, SZ_CFG + 0x000a); }
// static uint16_t device_log_period(const unsigned char* device) { return device[SZ_CFG + 0x000c]; }
// static uint16_t device_log_timeout(const unsigned char* device) { return uint16(device, SZ_CFG + 0x000e); }
// static uint8_t device_brightness_timeout(const unsigned char* device) { return device[SZ_CFG + 0x0010]; }
// static uint8_t device_brightness(const unsigned char* device) { return device[SZ_CFG + 0x0012]; }
// static uint8_t device_colorscheme(const unsigned char* device) { return device[SZ_CFG + 0x0013]; }
// static uint8_t device_language(const unsigned char* device) { return device[SZ_CFG + 0x0014]; }
// static uint8_t device_batterytype(const unsigned char* device) { return device[SZ_CFG + 0x0015]; }
// static uint16_t device_batterytime(const unsigned char* device) { return uint16(device, SZ_CFG + 0x0014); }
// static uint8_t device_button_sensitivity(const unsigned char* device) { return device[SZ_CFG + 0x0016]; }
// static uint8_t device_orientation(const unsigned char* device) { return device[SZ_CFG + 0x0049]; }
// static const char* device_owner(const unsigned char* device) { return (const char*)& device[SZ_CFG + 0x004a]; }
// private dive parsing functions //////////////////////////////////////////////////////////////////////////////////////////
static uint8_t dive_format(const unsigned char* dive) { return dive[0x0000]; }
static uint16_t dive_samples_cnt(const unsigned char* dive) { return uint16(dive, 0x005c); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define NSTEPS 1000
#define STEP(i,n) (NSTEPS * (i) / (n))
typedef struct mclean_extreme_device_t {
dc_device_t base;
dc_iostream_t *iostream;
unsigned char fingerprint[SZ_SUMMARY];
uint8_t data[SZ_COMPUTER];
unsigned char fingerprint[SZ_FINGERPRINT];
} mclean_extreme_device_t;
static dc_status_t mclean_extreme_device_set_fingerprint(dc_device_t *abstract, const unsigned char data[], unsigned int size);
static dc_status_t mclean_extreme_device_timesync(dc_device_t *abstract, const dc_datetime_t *datetime);
static dc_status_t mclean_extreme_device_foreach(dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
static dc_status_t mclean_extreme_device_close(dc_device_t *abstract);
@ -111,10 +72,23 @@ static const dc_device_vtable_t mclean_extreme_device_vtable = {
NULL, /* write */
NULL, /* dump */
mclean_extreme_device_foreach, /* foreach */
NULL, /* timesync */
mclean_extreme_device_timesync, /* timesync */
mclean_extreme_device_close, /* close */
};
static unsigned int
hashcode (const unsigned char data[], size_t size)
{
unsigned int result = 0;
for (size_t i = 0; i < size; ++i) {
result *= 31;
result += data[i];
}
return result;
}
static unsigned short
checksum_crc(const unsigned char data[], unsigned int size, unsigned short init)
{
@ -124,8 +98,7 @@ checksum_crc(const unsigned char data[], unsigned int size, unsigned short init)
if (crc & 0x8000) {
crc <<= 1;
crc ^= 0x1021;
}
else {
} else {
crc <<= 1;
}
}
@ -179,7 +152,7 @@ mclean_extreme_send(mclean_extreme_device_t* device, unsigned char cmd, const un
}
static dc_status_t
mclean_extreme_receive(mclean_extreme_device_t* device, unsigned char rsp, unsigned char data[], size_t max_size, size_t* actual_size)
mclean_extreme_receive(mclean_extreme_device_t *device, unsigned char rsp, unsigned char data[], size_t size, size_t *actual)
{
dc_status_t status = DC_STATUS_SUCCESS;
dc_device_t *abstract = (dc_device_t *)device;
@ -236,8 +209,8 @@ mclean_extreme_receive(mclean_extreme_device_t* device, unsigned char rsp, unsig
// Verify the length.
unsigned int length = array_uint32_le(header + 2);
if (length > max_size) {
ERROR(abstract->context, "Unexpected packet length (%u for %zu).", length, max_size);
if (length > size) {
ERROR(abstract->context, "Unexpected packet length (%u).", length);
return DC_STATUS_PROTOCOL;
}
@ -285,9 +258,129 @@ mclean_extreme_receive(mclean_extreme_device_t* device, unsigned char rsp, unsig
return DC_STATUS_PROTOCOL;
}
if (actual_size != NULL) {
if (actual == NULL) {
// Verify the actual length.
if (length != size) {
ERROR (abstract->context, "Unexpected packet length (%u).", length);
return DC_STATUS_PROTOCOL;
}
} else {
// Return the actual length.
*actual_size = length;
*actual = length;
}
return DC_STATUS_SUCCESS;
}
static dc_status_t
mclean_extreme_transfer(mclean_extreme_device_t *device, unsigned char cmd, const unsigned char data[], size_t size, unsigned char answer[], size_t asize, size_t *actual)
{
dc_status_t status = DC_STATUS_SUCCESS;
// Send the command
status = mclean_extreme_send(device, cmd, data, size);
if (status != DC_STATUS_SUCCESS) {
return status;
}
// Receive the answer
if (asize) {
status = mclean_extreme_receive(device, cmd, answer, asize, actual);
if (status != DC_STATUS_SUCCESS) {
return status;
}
}
return DC_STATUS_SUCCESS;
}
static dc_status_t
mclean_extreme_readdive (dc_device_t *abstract, dc_event_progress_t *progress, unsigned int idx, dc_buffer_t *buffer)
{
dc_status_t status = DC_STATUS_SUCCESS;
mclean_extreme_device_t *device = (mclean_extreme_device_t *) abstract;
// Erase the buffer.
dc_buffer_clear (buffer);
// Encode the logbook ID.
unsigned char id[] = {
(idx ) & 0xFF,
(idx >> 8) & 0xFF,
};
// Update and emit a progress event.
unsigned int initial = 0;
if (progress) {
initial = progress->current;
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
}
// Request the dive.
status = mclean_extreme_send (device, CMD_DIVE, id, sizeof(id));
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to send the dive command.");
return status;
}
// Read the dive header.
unsigned char header[SZ_HEADER];
status = mclean_extreme_receive (device, CMD_DIVE, header, sizeof(header), NULL);
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to receive the dive header.");
return status;
}
// Verify the format version.
unsigned int format = header[0x0000];
if (format != 0) {
ERROR(abstract->context, "Unrecognised dive format.");
return DC_STATUS_DATAFORMAT;
}
// Get the number of samples.
unsigned int nsamples = array_uint16_le (header + 0x005C);
// Calculate the total size.
unsigned int size = sizeof(header) + nsamples * SZ_SAMPLE;
// Update and emit a progress event.
if (progress) {
progress->current = initial + STEP(sizeof(header), size);
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
}
// Allocate memory for the dive.
if (!dc_buffer_resize (buffer, size)) {
ERROR (abstract->context, "Insufficient buffer space available.");
return DC_STATUS_NOMEMORY;
}
// Cache the pointer.
unsigned char *data = dc_buffer_get_data(buffer);
// Append the header.
memcpy (data, header, sizeof(header));
unsigned int nbytes = sizeof(header);
while (nbytes < size) {
// Get the maximum packet size.
size_t len = size - nbytes;
// Read the dive samples.
status = mclean_extreme_receive (device, CMD_DIVE, data + nbytes, len, &len);
if (status != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to receive the dive samples.");
return status;
}
nbytes += len;
// Update and emit a progress event.
if (progress) {
progress->current = initial + STEP(nbytes, size);
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
}
}
return DC_STATUS_SUCCESS;
@ -327,25 +420,9 @@ mclean_extreme_device_open(dc_device_t** out, dc_context_t* context, dc_iostream
goto error_free;
}
// Send the init command.
status = mclean_extreme_send(device, CMD_COMPUTER, NULL, 0);
if (status != DC_STATUS_SUCCESS) {
ERROR(context, "Failed to send the init command.");
goto error_free;
}
// Read the device info.
status = mclean_extreme_receive(device, CMD_COMPUTER, device->data, sizeof(device->data), NULL);
if (status != DC_STATUS_SUCCESS) {
ERROR(context, "Failed to receive the device info.");
goto error_free;
}
if (device_format(device->data) != 0) { /* bad device format */
status = DC_STATUS_DATAFORMAT;
ERROR(context, "Unsupported device format.");
goto error_free;
}
// Make sure everything is in a sane state.
dc_iostream_sleep (device->iostream, 100);
dc_iostream_purge (device->iostream, DC_DIRECTION_ALL);
*out = (dc_device_t *)device;
@ -376,52 +453,50 @@ mclean_extreme_device_set_fingerprint(dc_device_t* abstract, const unsigned char
{
mclean_extreme_device_t *device = (mclean_extreme_device_t *)abstract;
if (size && size != sizeof(device->fingerprint))
if (size && size != sizeof(device->fingerprint)) {
return DC_STATUS_INVALIDARGS;
}
if (size)
if (size) {
memcpy(device->fingerprint, data, sizeof(device->fingerprint));
else
} else {
memset(device->fingerprint, 0, sizeof(device->fingerprint));
}
return DC_STATUS_SUCCESS;
}
static dc_status_t
mclean_extreme_device_readsamples(dc_device_t* abstract, uint8_t* dive)
mclean_extreme_device_timesync(dc_device_t *abstract, const dc_datetime_t *datetime)
{
dc_status_t status = DC_STATUS_SUCCESS;
mclean_extreme_device_t *device = (mclean_extreme_device_t *)abstract;
int samples_cnt = (dive[0x005c] << 0) + (dive[0x005d] << 8); // number of samples to follow
dive = &dive[SZ_DIVE];
if (datetime == NULL) {
ERROR(abstract->context, "Invalid parameter specified.");
return DC_STATUS_INVALIDARGS;
}
while (samples_cnt != 0) {
unsigned char data[SZ_PACKET]; // buffer for read packet data
size_t length; // buffer for read packet length
// Get the UTC timestamp.
dc_ticks_t ticks = dc_datetime_mktime(datetime);
if (ticks == -1 || ticks < EPOCH || ticks - EPOCH > 0xFFFFFFFF) {
ERROR (abstract->context, "Invalid date/time value specified.");
return DC_STATUS_INVALIDARGS;
}
status = mclean_extreme_receive(device, CMD_DIVE, data, SZ_PACKET, &length);
// Adjust the epoch.
unsigned int timestamp = ticks - EPOCH;
// Send the command.
const unsigned char cmd[] = {
(timestamp ) & 0xFF,
(timestamp >> 8) & 0xFF,
(timestamp >> 16) & 0xFF,
(timestamp >> 24) & 0xFF
};
dc_status_t status = mclean_extreme_send(device, CMD_SET_TIME, cmd, sizeof(cmd));
if (status != DC_STATUS_SUCCESS) {
ERROR(abstract->context, "Failed to receive dive samples.");
break;
}
int packet_cnt = length / SZ_SAMPLE; // number of samples in the packet
if (packet_cnt > samples_cnt) { /* too many samples received */
status = DC_STATUS_DATAFORMAT;
ERROR(abstract->context, "Too many dive samples received.");
break;
}
if (length != packet_cnt * SZ_SAMPLE) { /* not an integer number of samples */
status = DC_STATUS_DATAFORMAT;
ERROR(abstract->context, "Partial samples received.");
break;
}
memcpy(dive, data, packet_cnt * SZ_SAMPLE); // append samples to dive buffer
dive = &dive[packet_cnt * SZ_SAMPLE]; // move buffer write cursor
samples_cnt -= packet_cnt;
ERROR(abstract->context, "Failed to send the set time command.");
return status;
}
return status;
@ -433,64 +508,88 @@ mclean_extreme_device_foreach(dc_device_t* abstract, dc_dive_callback_t callback
dc_status_t status = DC_STATUS_SUCCESS;
mclean_extreme_device_t *device = (mclean_extreme_device_t *)abstract;
// Enable progress notifications.
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
int dives_cnt = device_name(device->data);
progress.current = 0;
progress.maximum = dives_cnt;
device_event_emit(abstract, DC_EVENT_PROGRESS, &progress);
for (int i = dives_cnt - 1; i >= 0; --i) {
unsigned char data[512]; // buffer for read packet data
size_t length; // buffer for read packet length
unsigned char id[] = { (unsigned char)i, (unsigned char)(i >> 8) }; // payload for CMD_DIVE request
status = mclean_extreme_send(device, CMD_DIVE, id, sizeof(id));
// Read the firmware version.
unsigned char firmware[4] = {0};
status = mclean_extreme_transfer(device, CMD_FIRMWARE, NULL, 0, firmware, sizeof(firmware), NULL);
if (status != DC_STATUS_SUCCESS) {
ERROR(abstract->context, "Failed to send the get dive command.");
break;
}
status = mclean_extreme_receive(device, CMD_DIVE, data, 512, &length);
if (status != DC_STATUS_SUCCESS) {
ERROR(abstract->context, "Failed to receive dive header.");
break;
}
if (dive_format(data) != 0) { /* can't understand the format */
INFO(abstract->context, "Skipping unsupported dive format");
break;
}
int cnt_samples = dive_samples_cnt(data); // number of samples to follow
size_t size = SZ_DIVE + cnt_samples * SZ_SAMPLE; // total buffer size required for this dive
uint8_t* dive = (uint8_t *)malloc(size); // buffer for this dive
if (dive == NULL) {
status = DC_STATUS_NOMEMORY;
break;
}
memcpy(dive, data, SZ_DIVE); // copy data to dive buffer
status = mclean_extreme_device_readsamples(abstract, dive); // append samples to buffer
if (status != DC_STATUS_SUCCESS) { /* failed to read dive samples */
free(dive); // cleanup
break; // stop downloading
}
if (callback && !callback(dive, size, dive, sizeof(device->fingerprint), userdata)) { /* cancelled by callback */
free(dive); // cleanup
break; // stop downloading
}
free(dive);
progress.current = dives_cnt - 1 - i;
device_event_emit(abstract, DC_EVENT_PROGRESS, &progress);
}
ERROR(abstract->context, "Failed to read the firmware version.");
return status;
}
// Read the serial number.
size_t serial_len = 0;
unsigned char serial[SZ_PACKET] = {0};
status = mclean_extreme_transfer(device, CMD_SERIALNUMBER, NULL, 0, serial, sizeof(serial), &serial_len);
if (status != DC_STATUS_SUCCESS) {
ERROR(abstract->context, "Failed to read serial number.");
return status;
}
// Emit a device info event.
dc_event_devinfo_t devinfo;
devinfo.model = 0;
devinfo.firmware = array_uint32_le (firmware);
devinfo.serial = hashcode (serial, serial_len);
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
// Read the computer configuration.
unsigned char computer[SZ_COMPUTER];
status = mclean_extreme_transfer(device, CMD_COMPUTER, NULL, 0, computer, sizeof(computer), NULL);
if (status != DC_STATUS_SUCCESS) {
ERROR(abstract->context, "Failed to read the computer configuration.");
return status;
}
// Verify the format version.
unsigned int format = computer[0x0000];
if (format != 0) {
ERROR(abstract->context, "Unsupported device format.");
return DC_STATUS_DATAFORMAT;
}
// Get the number of dives.
unsigned int ndives = array_uint16_le(computer + 0x0019);
// Update and emit a progress event.
progress.current = 1 * NSTEPS;
progress.maximum = (ndives + 1) * NSTEPS;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
// Allocate a memory buffer for a single dive.
dc_buffer_t *buffer = dc_buffer_new(0);
if (buffer == NULL) {
status = DC_STATUS_NOMEMORY;
goto error_exit;
}
for (unsigned int i = 0; i < ndives; ++i) {
// Download in reverse order (newest first).
unsigned int idx = ndives - 1 - i;
// Read the dive.
status = mclean_extreme_readdive (abstract, &progress, idx, buffer);
if (status != DC_STATUS_SUCCESS) {
goto error_buffer_free;
}
// Cache the pointer.
unsigned char *data = dc_buffer_get_data(buffer);
unsigned int size = dc_buffer_get_size(buffer);
if (memcmp(data, device->fingerprint, sizeof(device->fingerprint)) == 0)
break;
if (callback && !callback (data, size, data, sizeof(device->fingerprint), userdata)) {
break;
}
}
error_buffer_free:
dc_buffer_free (buffer);
error_exit:
return status;
}

View File

@ -1,7 +1,7 @@
/*
* libdivecomputer
*
* Copyright (C) 2018 Jef Driesen
* Copyright (C) 2020 Jef Driesen, David Carron
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@ -1,7 +1,7 @@
/*
* libdivecomputer
*
* Copyright (C) 2018 Jef Driesen
* Copyright (C) 2020 Jef Driesen, David Carron
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -21,8 +21,6 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "mclean_extreme.h"
#include "context-private.h"
@ -31,70 +29,31 @@
#define ISINSTANCE(parser) dc_device_isinstance((parser), &mclean_extreme_parser_vtable)
#define SZ_CFG 0x002d // size of the common dive/computer header
#define SZ_COMPUTER 0x006a // size of the computer state dump
#define SZ_DIVE 0x005e // size of the dive state dump
#define SZ_SAMPLE 0x0004 // size of the sample state dump
#define SZ_CFG 0x002D
#define SZ_COMPUTER (SZ_CFG + 0x6A)
#define SZ_HEADER (SZ_CFG + 0x31)
#define SZ_SAMPLE 0x0004
// private dive parsing functions //////////////////////////////////////////////////////////////////////////////////////////
#define EPOCH 946684800 // 2000-01-01 00:00:00 UTC
static uint16_t uint16(const unsigned char* buffer, int addr) { return (buffer[0 + addr] << 0) | (buffer[1 + addr] << 8); }
static uint32_t uint32(const unsigned char* buffer, int addr) { return (buffer[0 + addr] << 0) | (buffer[1 + addr] << 8) | (buffer[2 + addr] << 16) | (buffer[3 + addr] << 24); }
#define REC 0
#define TEC 1
#define CCR 2
#define GAUGE 3
static uint8_t dive_format(const unsigned char* dive) { return dive[0x0000]; }
static uint8_t dive_gas_pO2(const unsigned char* dive, int value) { return dive[0x0001 + value * 2]; }
static uint8_t dive_gas_pHe(const unsigned char* dive, int value) { return dive[0x0001 + 1 + value * 2]; }
// static bool dive_gas_enabled(const unsigned char* dive, int value) { return (dive[0x0011] & (1 << value)) != 0; }
static uint8_t dive_setpoint(const unsigned char* dive, int value) { return dive[0x0013 + value]; }
// static bool dive_setpoint_enabled(const unsigned char* dive, int value) { return (dive[dive, 0x0016] & (1 << value)) != 0; }
// static bool dive_metric(const unsigned char* dive) { return dive[0x0018] != 0; }
// static uint16_t dive_name(const unsigned char* dive) { return uint16(dive, 0x0019); }
// static uint16_t dive_Vasc(const unsigned char* dive) { return uint16(dive, 0x001c); }
static uint16_t dive_Psurf(const unsigned char* dive) { return uint16(dive, 0x001e); }
// static uint8_t dive_gfs_index(const unsigned char* dive) { return dive[0x0020]; }
// static uint8_t dive_gflo(const unsigned char* dive) { return dive[0x0021]; }
// static uint8_t dive_gfhi(const unsigned char* dive) { return dive[0x0022]; }
static uint8_t dive_density_index(const unsigned char* dive) { return dive[0x0023]; }
// static uint16_t dive_ppN2_limit(const unsigned char* dive) { return uint16(dive, 0x0024); }
// static uint16_t dive_ppO2_limit(const unsigned char* dive) { return uint16(dive, 0x0026); }
// static uint16_t dive_ppO2_bottomlimit(const unsigned char* dive) { return uint16(dive, 0x0028); }
// static uint16_t dive_density_limit(const unsigned char* dive) { return uint16(dive, 0x002a); }
static uint8_t dive_operatingmode(const unsigned char* dive) { return dive[0x002c]; }
#define INVALID 0xFFFFFFFF
static uint32_t dive_logstart(const unsigned char* dive) { return uint32(dive, SZ_CFG + 0x0000); }
static uint32_t dive_divestart(const unsigned char* dive) { return uint32(dive, SZ_CFG + 0x0004); }
static uint32_t dive_diveend(const unsigned char* dive) { return uint32(dive, SZ_CFG + 0x0008); }
static uint32_t dive_logend(const unsigned char* dive) { return uint32(dive, SZ_CFG + 0x000c); }
static uint8_t dive_temp_min(const unsigned char* dive) { return dive[SZ_CFG + 0x0010]; }
static uint8_t dive_temp_max(const unsigned char* dive) { return dive[SZ_CFG + 0x0011]; }
// static uint16_t dive_pO2_min(const unsigned char* dive) { return uint16(dive, SZ_CFG + 0x0012); }
// static uint16_t dive_pO2_max(const unsigned char* dive) { return uint16(dive, SZ_CFG + 0x0014); }
static uint16_t dive_Pmax(const unsigned char* dive) { return uint16(dive, SZ_CFG + 0x0016); }
static uint16_t dive_Pav(const unsigned char* dive) { return uint16(dive, SZ_CFG + 0x0018); }
// static uint32_t ISS(const unsigned char* dive) { return uint16(dive, SZ_CFG + 0x001a); }
// static uint16_t CNS_start(const unsigned char* dive) { return uint16(dive, SZ_CFG + 0x001e); }
// static uint16_t CNS_max(const unsigned char* dive) { return uint16(dive, SZ_CFG + 0x0020); }
// static uint16_t OTU(const unsigned char* dive) { return uint16(dive, SZ_CFG + 0x0022); }
// static uint16_t tndl(const unsigned char* dive) { return uint16(dive, SZ_CFG + 0x0024); }
// static uint32_t tdeco(const unsigned char* dive) { return uint32(dive, SZ_CFG + 0x0026); }
// static uint8_t ndeco(const unsigned char* dive) { return dive[SZ_CFG + 0x002a]; }
// static uint32_t tdesat(const unsigned char* dive) { return uint32(dive, SZ_CFG + 0x002b); }
static uint16_t dive_samples_cnt(const unsigned char* dive) { return uint16(dive, 0x005c); }
// private sample parsing functions //////////////////////////////////////////////////////////////////////////////////////////
static uint16_t sample_depth(const unsigned char* dive, int n) { return uint16(dive, SZ_DIVE + n * SZ_SAMPLE + 0); }
static uint8_t sample_temperature(const unsigned char* dive, int n) { return dive[SZ_DIVE + n * SZ_SAMPLE + 2]; }
static bool sample_ccr(const unsigned char* dive, int n) { return dive[SZ_DIVE + n * SZ_SAMPLE + 3] & 0b10000000; }
static uint8_t sample_sp_index(const unsigned char* dive, int n) { return (dive[SZ_DIVE + n * SZ_SAMPLE + 3] & 0b01100000) >> 5; }
static uint8_t sample_gas_index(const unsigned char* dive, int n) { return (dive[SZ_DIVE + n * SZ_SAMPLE + 3] & 0b00011100) >> 2; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define NGASMIXES 8
typedef struct mclean_extreme_parser_t mclean_extreme_parser_t;
struct mclean_extreme_parser_t {
dc_parser_t base;
// Cached fields.
unsigned int cached;
unsigned int ngasmixes;
unsigned int gasmix[NGASMIXES];
};
static dc_status_t mclean_extreme_parser_set_data(dc_parser_t *abstract, const unsigned char *data, unsigned int size);
@ -117,8 +76,9 @@ mclean_extreme_parser_create(dc_parser_t** out, dc_context_t* context)
{
mclean_extreme_parser_t *parser = NULL;
if (out == NULL)
if (out == NULL) {
return DC_STATUS_INVALIDARGS;
}
// Allocate memory.
parser = (mclean_extreme_parser_t *)dc_parser_allocate(context, &mclean_extreme_parser_vtable);
@ -127,6 +87,13 @@ mclean_extreme_parser_create(dc_parser_t** out, dc_context_t* context)
return DC_STATUS_NOMEMORY;
}
// Set the default values.
parser->cached = 0;
parser->ngasmixes = 0;
for (unsigned int i = 0; i < NGASMIXES; ++i) {
parser->gasmix[i] = INVALID;
}
*out = (dc_parser_t *)parser;
return DC_STATUS_SUCCESS;
@ -135,18 +102,13 @@ mclean_extreme_parser_create(dc_parser_t** out, dc_context_t* context)
static dc_status_t
mclean_extreme_parser_set_data(dc_parser_t *abstract, const unsigned char *data, unsigned int size)
{
dc_status_t status = DC_STATUS_SUCCESS;
mclean_extreme_parser_t *parser = (mclean_extreme_parser_t *)abstract;
if (dive_format(data) != 0) {
status = DC_STATUS_DATAFORMAT;
ERROR(abstract->context, "Unsupported dive format.");
}
const int samples_cnt = dive_samples_cnt(data);
if (size != SZ_DIVE + samples_cnt * SZ_SAMPLE) {
ERROR(abstract->context, "Corrupt dive in memory.");
return DC_STATUS_DATAFORMAT;
// Reset the cache.
parser->cached = 0;
parser->ngasmixes = 0;
for (unsigned int i = 0; i < NGASMIXES; ++i) {
parser->gasmix[i] = INVALID;
}
return DC_STATUS_SUCCESS;
@ -155,79 +117,109 @@ mclean_extreme_parser_set_data(dc_parser_t* abstract, const unsigned char* data,
static dc_status_t
mclean_extreme_parser_get_datetime(dc_parser_t *abstract, dc_datetime_t *datetime)
{
if (datetime) {
const unsigned char* dive = abstract->data;
dc_ticks_t dc_ticks = 946684800 + dive_logstart(dive); // raw times are offsets for 1/1/2000
dc_datetime_gmtime(datetime, dc_ticks);
if (abstract->size < SZ_HEADER) {
ERROR(abstract->context, "Corrupt dive data");
return DC_STATUS_DATAFORMAT;
}
unsigned int timestamp = array_uint32_le(abstract->data + SZ_CFG + 0x0000);
dc_ticks_t ticks = (dc_ticks_t) timestamp + EPOCH;
if (!dc_datetime_gmtime (datetime, ticks))
return DC_STATUS_DATAFORMAT;
datetime->timezone = DC_TIMEZONE_NONE;
return DC_STATUS_SUCCESS;
}
static dc_status_t
mclean_extreme_parser_get_field(dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value)
{
static const double densities[] = { 1.000, 1.020, 1.030 };
static const dc_divemode_t divemodes[] = { DC_DIVEMODE_OC, DC_DIVEMODE_OC, DC_DIVEMODE_CCR, DC_DIVEMODE_GAUGE };
mclean_extreme_parser_t *parser = (mclean_extreme_parser_t *)abstract;
if (abstract->size < SZ_HEADER) {
ERROR(abstract->context, "Corrupt dive data");
return DC_STATUS_DATAFORMAT;
}
if (!parser->cached) {
dc_status_t rc = mclean_extreme_parser_samples_foreach (abstract, NULL, NULL);
if (rc != DC_STATUS_SUCCESS)
return rc;
}
const unsigned char* dive = abstract->data;
dc_gasmix_t *gasmix = (dc_gasmix_t *)value;
dc_salinity_t *salinity = (dc_salinity_t *)value;
const unsigned int psurf = array_uint16_le(abstract->data + 0x001E);
const unsigned int density_index = abstract->data[0x0023];
double density = 0;
switch (density_index) {
case 0:
density = 1.000;
break;
case 1:
density = 1.020;
break;
case 2:
density = 1.030;
break;
default:
ERROR(abstract->context, "Corrupt density index in dive data");
return DC_STATUS_DATAFORMAT;
}
if (value) {
switch (type) {
case DC_FIELD_DIVETIME:
*((unsigned int*)value) = dive_logend(dive) - dive_logstart(dive);
*((unsigned int *)value) = array_uint32_le(abstract->data + SZ_CFG + 0x000C) - array_uint32_le(abstract->data + SZ_CFG + 0x0000);
break;
case DC_FIELD_MAXDEPTH:
*((double*)value) = 0.01 * (dive_Pmax(dive) - dive_Psurf(dive)) / densities[dive_density_index(dive)];
*((double *)value) = 0.01 * (array_uint16_le(abstract->data + SZ_CFG + 0x0016) - psurf) / density;
break;
case DC_FIELD_AVGDEPTH:
*((double*)value) = 0.01 * (dive_Pav(dive) - dive_Psurf(dive)) / densities[dive_density_index(dive)];
*((double *)value) = 0.01 * (array_uint16_le(abstract->data + SZ_CFG + 0x0018) - psurf) / density;
break;
case DC_FIELD_SALINITY:
switch (dive_density_index(dive)) {
case 0: ((dc_salinity_t*)value)->type = DC_WATER_FRESH; ((dc_salinity_t*)value)->density = densities[dive_density_index(dive)]; break;
case 1: ((dc_salinity_t*)value)->type = DC_WATER_SALT; ((dc_salinity_t*)value)->density = densities[dive_density_index(dive)]; break;
case 2: ((dc_salinity_t*)value)->type = DC_WATER_SALT; ((dc_salinity_t*)value)->density = densities[dive_density_index(dive)]; break;
default: /* that's an error */ break;
salinity->density = density * 1000.0;
salinity->type = density_index == 0 ? DC_WATER_FRESH : DC_WATER_SALT;
break;
case DC_FIELD_ATMOSPHERIC:
*((double *)value) = 0.001 * array_uint16_le(abstract->data + 0x001E);
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
*((double *)value) = (double)abstract->data[SZ_CFG + 0x0010];
break;
case DC_FIELD_TEMPERATURE_MAXIMUM:
*((double *)value) = (double)abstract->data[SZ_CFG + 0x0011];
break;
case DC_FIELD_DIVEMODE:
switch (abstract->data[0x002C]) {
case REC:
case TEC:
*((dc_divemode_t *)value) = DC_DIVEMODE_OC;
break;
case CCR:
*((dc_divemode_t *)value) = DC_DIVEMODE_CCR;
break;
case GAUGE:
*((dc_divemode_t *)value) = DC_DIVEMODE_GAUGE;
break;
default:
ERROR(abstract->context, "Corrupt dive mode in dive data");
return DC_STATUS_DATAFORMAT;
}
break;
case DC_FIELD_ATMOSPHERIC:
*((double*)value) = dive_Psurf(dive) / 1000.0;
break;
// case DC_FIELD_TEMPERATURE_SURFACE:
case DC_FIELD_TEMPERATURE_MINIMUM:
*((double*)value) = dive_temp_min(dive);
break;
case DC_FIELD_TEMPERATURE_MAXIMUM:
*((double*)value) = dive_temp_max(dive);
break;
case DC_FIELD_DIVEMODE:
*((dc_divemode_t*)value) = divemodes[dive_operatingmode(dive)];
break;
//case DC_FIELD_TANK:
//case DC_FIELD_TANK_COUNT:
case DC_FIELD_GASMIX_COUNT:
*((unsigned int*)value) = 8;
*((unsigned int *)value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
gasmix->helium = 0.01 * dive_gas_pHe(dive, flags);
gasmix->oxygen = 0.01 * dive_gas_pO2(dive, flags);
gasmix->helium = 0.01 * abstract->data[0x0001 + 1 + 2 * parser->gasmix[flags]];
gasmix->oxygen = 0.01 * abstract->data[0x0001 + 0 + 2 * parser->gasmix[flags]];
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
break;
default:
return DC_STATUS_UNSUPPORTED;
}
@ -239,40 +231,86 @@ mclean_extreme_parser_get_field(dc_parser_t* abstract, dc_field_type_t type, uns
static dc_status_t
mclean_extreme_parser_samples_foreach(dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
{
const unsigned char* dive = abstract->data;
const unsigned int size = abstract->size;
mclean_extreme_parser_t *parser = (mclean_extreme_parser_t *)abstract;
const unsigned int interval = 20; // this should be dive[log end] - dive[log start]?
const int samples_cnt = dive_samples_cnt(dive); // number of samples to follow
if (abstract->size < SZ_HEADER) {
ERROR(abstract->context, "Corrupt dive data");
return DC_STATUS_DATAFORMAT;
}
if (callback) {
const unsigned int nsamples = array_uint16_le(abstract->data + 0x005C);
if (abstract->size != SZ_HEADER + nsamples * SZ_SAMPLE) {
ERROR(abstract->context, "Corrupt dive data");
return DC_STATUS_DATAFORMAT;
}
unsigned int ngasmixes = 0;
unsigned int gasmix[NGASMIXES] = {0};
unsigned int gasmix_previous = INVALID;
const unsigned int interval = 20;
unsigned int time = 0;
for (int i = 0; i < samples_cnt; ++i) {
size_t offset = SZ_HEADER;
for (unsigned int i = 0; i < nsamples; ++i) {
dc_sample_value_t sample = { 0 };
const unsigned int depth = array_uint16_le(abstract->data + offset + 0);
const unsigned int temperature = abstract->data[offset + 2];
const unsigned int flags = abstract->data[offset + 3];
const unsigned int ccr = flags & 0x80;
const unsigned int gasmix_id = (flags & 0x1C) >> 2;
const unsigned int sp_index = (flags & 0x60) >> 5;
const unsigned int setpoint = abstract->data[0x0013 + sp_index];
time += interval;
sample.time = time;
callback(DC_SAMPLE_TIME, sample, userdata);
if (callback) callback(DC_SAMPLE_TIME, sample, userdata);
sample.depth = sample_depth(dive, i) * 0.1;
callback(DC_SAMPLE_DEPTH, sample, userdata);
sample.depth = 0.1 * depth;
if (callback) callback(DC_SAMPLE_DEPTH, sample, userdata);
sample.temperature = sample_temperature(dive, i);
callback(DC_SAMPLE_TEMPERATURE, sample, userdata);
sample.temperature = temperature;
if (callback) callback(DC_SAMPLE_TEMPERATURE, sample, userdata);
sample.gasmix = sample_gas_index(dive, i);
callback(DC_SAMPLE_GASMIX, sample, userdata);
if (gasmix_id != gasmix_previous) {
// Find the gasmix in the list.
unsigned int idx = 0;
while (idx < ngasmixes) {
if (gasmix_id == gasmix[idx])
break;
idx++;
}
if (sample_ccr(dive, i)) {
const uint8_t sp_index = sample_sp_index(dive, i);
// Add it to list if not found.
if (idx >= ngasmixes) {
if (idx >= NGASMIXES) {
ERROR (abstract->context, "Maximum number of gas mixes reached.");
return DC_STATUS_DATAFORMAT;
}
gasmix[idx] = gasmix_id;
ngasmixes = idx + 1;
}
sample.setpoint = 100.0 * dive_setpoint(dive, sp_index);
sample.gasmix = idx;
if (callback) callback(DC_SAMPLE_GASMIX, sample, userdata);
gasmix_previous = gasmix_id;
}
if (ccr) {
sample.setpoint = 0.01 * setpoint;
if (callback) callback(DC_SAMPLE_SETPOINT, sample, userdata);
}
time += interval;
offset += SZ_SAMPLE;
}
// Cache the data for later use.
for (unsigned int i = 0; i < ngasmixes; ++i) {
parser->gasmix[i] = gasmix[i];
}
parser->ngasmixes = ngasmixes;
parser->cached = 1;
return DC_STATUS_SUCCESS;
}

View File

@ -376,6 +376,10 @@ tecdiving_divecomputereu_device_open (dc_device_t **out, dc_context_t *context,
goto error_free;
}
// Make sure everything is in a sane state.
dc_iostream_sleep (device->iostream, 100);
dc_iostream_purge (device->iostream, DC_DIRECTION_ALL);
// Send the init command.
status = tecdiving_divecomputereu_send (device, CMD_INIT, NULL, 0);
if (status != DC_STATUS_SUCCESS) {