Merge tag 'v0.6.0' of git://git.libdivecomputer.org/libdivecomputer into Subsurface-branch
Sync up with upstream cersion 0.6.0. Annoying merge, mainly because a lof of the changes Jef had done are actually changes that came from our Subsurface branch, but in a different form, because Jef doesn't actually take patches directly from us. Why? I don't know. * tag 'v0.6.0' of git://git.libdivecomputer.org/libdivecomputer: Release version 0.6.0 Fix some potential buffer overflows Fix some casts with constant pointers Enable some useful compiler warnings by default Generate html documentation from the manpages Fix the decoding of the ndl/deco information Decode the firmware version for the iDive series Add support for the Suunto Eon Core Locate the most recent dive Add EON Steel time sync capability Improve the progress events Detect the model number using the hardware type Shearwater: add support for remaining gas time Shearwater: extract tank sensor data for log version 7 Shearwater: extract log version from header
This commit is contained in:
commit
54f6bff929
37
NEWS
37
NEWS
@ -1,3 +1,40 @@
|
|||||||
|
Version 0.6.0 (2017-11-24)
|
||||||
|
==========================
|
||||||
|
|
||||||
|
The v0.6.0 release adds support for several new devices, introduces two
|
||||||
|
new features and fixes a couple of bugs. There are a few minor backwards
|
||||||
|
incompatible changes, but most applications won't be affected by those.
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
* Add support for new backends:
|
||||||
|
- g2: Scubapro G2, Aladin Sport Matrix, Aladin Square
|
||||||
|
* Add support for many new devices:
|
||||||
|
- Aqualung: i200, i750TC
|
||||||
|
- Cochran: Commander I, II and TM
|
||||||
|
- Cressi: Drake
|
||||||
|
- Hollis: DG02
|
||||||
|
- Mares: Quad
|
||||||
|
- Oceanic: F10
|
||||||
|
- Ratio: iX3M and iDive series
|
||||||
|
- Suunto: D4f, Eon Core
|
||||||
|
- Uwatec: Aladin Tec 3G
|
||||||
|
* Add basic timezone support
|
||||||
|
* Add support for synchronizing the device clock
|
||||||
|
* Document the public api with man pages
|
||||||
|
|
||||||
|
Removed/changed features:
|
||||||
|
|
||||||
|
* Remove the deprecated gas change events
|
||||||
|
* Remove the deprecated vendor_product_parser_create(),
|
||||||
|
vendor_product_device_open() and vendor_product_extract_dives()
|
||||||
|
functions from the public api
|
||||||
|
* Remove the hw_{frog,ostc,ostc3}_device_clock() functions
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Many small improvements
|
||||||
|
|
||||||
Version 0.5.0 (2016-09-30)
|
Version 0.5.0 (2016-09-30)
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
|||||||
19
configure.ac
19
configure.ac
@ -64,8 +64,10 @@ AM_CONDITIONAL([ENABLE_DOC], [test "x$enable_doc" = "xyes"])
|
|||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AC_PROG_CC_C99
|
AC_PROG_CC_C99
|
||||||
AC_CHECK_PROGS([DOXYGEN], [doxygen])
|
AC_CHECK_PROGS([DOXYGEN], [doxygen])
|
||||||
|
AC_CHECK_PROGS([MANDOC], [mandoc])
|
||||||
|
|
||||||
AM_CONDITIONAL([HAVE_DOXYGEN],[test -n "$DOXYGEN"])
|
AM_CONDITIONAL([HAVE_DOXYGEN],[test -n "$DOXYGEN"])
|
||||||
|
AM_CONDITIONAL([HAVE_MANDOC],[test -n "$MANDOC"])
|
||||||
|
|
||||||
# Enable automake silent build rules.
|
# Enable automake silent build rules.
|
||||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||||
@ -169,6 +171,23 @@ AC_FUNC_STRERROR_R
|
|||||||
AC_CHECK_FUNCS([localtime_r gmtime_r timegm _mkgmtime])
|
AC_CHECK_FUNCS([localtime_r gmtime_r timegm _mkgmtime])
|
||||||
AC_CHECK_FUNCS([getopt_long])
|
AC_CHECK_FUNCS([getopt_long])
|
||||||
|
|
||||||
|
# Checks for supported compiler options.
|
||||||
|
AX_APPEND_COMPILE_FLAGS([ \
|
||||||
|
-pedantic \
|
||||||
|
-Wall \
|
||||||
|
-Wextra \
|
||||||
|
-Wshadow \
|
||||||
|
-Wrestrict \
|
||||||
|
-Wformat=2 \
|
||||||
|
-Wwrite-strings \
|
||||||
|
-Wcast-qual \
|
||||||
|
-Wpointer-arith \
|
||||||
|
-Wstrict-prototypes \
|
||||||
|
-Wmissing-prototypes \
|
||||||
|
-Wmissing-declarations \
|
||||||
|
-Wno-unused-parameter \
|
||||||
|
])
|
||||||
|
|
||||||
# Versioning.
|
# Versioning.
|
||||||
AC_SUBST([DC_VERSION],[dc_version])
|
AC_SUBST([DC_VERSION],[dc_version])
|
||||||
AC_SUBST([DC_VERSION_MAJOR],[dc_version_major])
|
AC_SUBST([DC_VERSION_MAJOR],[dc_version_major])
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
dist_man_MANS = \
|
MANPAGES = \
|
||||||
dc_buffer_append.3 \
|
dc_buffer_append.3 \
|
||||||
dc_buffer_free.3 \
|
dc_buffer_free.3 \
|
||||||
dc_buffer_get_data.3 \
|
dc_buffer_get_data.3 \
|
||||||
@ -32,3 +32,18 @@ dist_man_MANS = \
|
|||||||
dc_parser_samples_foreach.3 \
|
dc_parser_samples_foreach.3 \
|
||||||
dc_parser_set_data.3 \
|
dc_parser_set_data.3 \
|
||||||
libdivecomputer.3
|
libdivecomputer.3
|
||||||
|
|
||||||
|
HTMLPAGES = $(MANPAGES:%=%.html)
|
||||||
|
|
||||||
|
dist_man_MANS = $(MANPAGES)
|
||||||
|
|
||||||
|
if HAVE_MANDOC
|
||||||
|
doc_DATA = $(HTMLPAGES)
|
||||||
|
endif
|
||||||
|
|
||||||
|
SUFFIXES = .3 .3.html
|
||||||
|
|
||||||
|
.3.3.html:
|
||||||
|
$(AM_V_GEN) $(MANDOC) -Thtml -Ostyle=mandoc.css,man=%N.%S.html $< > $@
|
||||||
|
|
||||||
|
CLEANFILES = $(HTMLPAGES)
|
||||||
|
|||||||
@ -142,7 +142,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
|
|||||||
case DC_SAMPLE_VENDOR:
|
case DC_SAMPLE_VENDOR:
|
||||||
fprintf (sampledata->ostream, " <vendor type=\"%u\" size=\"%u\">", value.vendor.type, value.vendor.size);
|
fprintf (sampledata->ostream, " <vendor type=\"%u\" size=\"%u\">", value.vendor.type, value.vendor.size);
|
||||||
for (unsigned int i = 0; i < value.vendor.size; ++i)
|
for (unsigned int i = 0; i < value.vendor.size; ++i)
|
||||||
fprintf (sampledata->ostream, "%02X", ((unsigned char *) value.vendor.data)[i]);
|
fprintf (sampledata->ostream, "%02X", ((const unsigned char *) value.vendor.data)[i]);
|
||||||
fprintf (sampledata->ostream, "</vendor>\n");
|
fprintf (sampledata->ostream, "</vendor>\n");
|
||||||
break;
|
break;
|
||||||
case DC_SAMPLE_SETPOINT:
|
case DC_SAMPLE_SETPOINT:
|
||||||
|
|||||||
67
m4/ax_append_compile_flags.m4
Normal file
67
m4/ax_append_compile_flags.m4
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# https://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
|
||||||
|
# ============================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# For every FLAG1, FLAG2 it is checked whether the compiler works with the
|
||||||
|
# flag. If it does, the flag is added FLAGS-VARIABLE
|
||||||
|
#
|
||||||
|
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
|
||||||
|
# CFLAGS) is used. During the check the flag is always added to the
|
||||||
|
# current language's flags.
|
||||||
|
#
|
||||||
|
# If EXTRA-FLAGS is defined, it is added to the current language's default
|
||||||
|
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
|
||||||
|
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
|
||||||
|
# force the compiler to issue an error when a bad flag is given.
|
||||||
|
#
|
||||||
|
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
|
||||||
|
#
|
||||||
|
# NOTE: This macro depends on the AX_APPEND_FLAG and
|
||||||
|
# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with
|
||||||
|
# AX_APPEND_LINK_FLAGS.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
# option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General
|
||||||
|
# Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 6
|
||||||
|
|
||||||
|
AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
|
||||||
|
[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG])
|
||||||
|
AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
|
||||||
|
for flag in $1; do
|
||||||
|
AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4])
|
||||||
|
done
|
||||||
|
])dnl AX_APPEND_COMPILE_FLAGS
|
||||||
71
m4/ax_append_flag.m4
Normal file
71
m4/ax_append_flag.m4
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
|
||||||
|
# added in between.
|
||||||
|
#
|
||||||
|
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
|
||||||
|
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
|
||||||
|
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
|
||||||
|
# FLAG.
|
||||||
|
#
|
||||||
|
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||||
|
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
# option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General
|
||||||
|
# Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 7
|
||||||
|
|
||||||
|
AC_DEFUN([AX_APPEND_FLAG],
|
||||||
|
[dnl
|
||||||
|
AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
|
||||||
|
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
|
||||||
|
AS_VAR_SET_IF(FLAGS,[
|
||||||
|
AS_CASE([" AS_VAR_GET(FLAGS) "],
|
||||||
|
[*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
|
||||||
|
[
|
||||||
|
AS_VAR_APPEND(FLAGS,[" $1"])
|
||||||
|
AC_RUN_LOG([: FLAGS="$FLAGS"])
|
||||||
|
])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AS_VAR_SET(FLAGS,[$1])
|
||||||
|
AC_RUN_LOG([: FLAGS="$FLAGS"])
|
||||||
|
])
|
||||||
|
AS_VAR_POPDEF([FLAGS])dnl
|
||||||
|
])dnl AX_APPEND_FLAG
|
||||||
74
m4/ax_check_compile_flag.m4
Normal file
74
m4/ax_check_compile_flag.m4
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Check whether the given FLAG works with the current language's compiler
|
||||||
|
# or gives an error. (Warnings, however, are ignored)
|
||||||
|
#
|
||||||
|
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||||
|
# success/failure.
|
||||||
|
#
|
||||||
|
# If EXTRA-FLAGS is defined, it is added to the current language's default
|
||||||
|
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
|
||||||
|
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
|
||||||
|
# force the compiler to issue an error when a bad flag is given.
|
||||||
|
#
|
||||||
|
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
|
||||||
|
#
|
||||||
|
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||||
|
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||||
|
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
# option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General
|
||||||
|
# Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 5
|
||||||
|
|
||||||
|
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
|
||||||
|
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
|
||||||
|
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
|
||||||
|
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
|
||||||
|
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
|
||||||
|
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
|
||||||
|
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
|
||||||
|
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||||
|
[AS_VAR_SET(CACHEVAR,[no])])
|
||||||
|
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
|
||||||
|
AS_VAR_IF(CACHEVAR,yes,
|
||||||
|
[m4_default([$2], :)],
|
||||||
|
[m4_default([$3], :)])
|
||||||
|
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||||
|
])dnl AX_CHECK_COMPILE_FLAGS
|
||||||
37
m4/ax_require_defined.m4
Normal file
37
m4/ax_require_defined.m4
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_REQUIRE_DEFINED(MACRO)
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
|
||||||
|
# been defined and thus are available for use. This avoids random issues
|
||||||
|
# where a macro isn't expanded. Instead the configure script emits a
|
||||||
|
# non-fatal:
|
||||||
|
#
|
||||||
|
# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
|
||||||
|
#
|
||||||
|
# It's like AC_REQUIRE except it doesn't expand the required macro.
|
||||||
|
#
|
||||||
|
# Here's an example:
|
||||||
|
#
|
||||||
|
# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
|
||||||
|
#
|
||||||
|
# Copying and distribution of this file, with or without modification, are
|
||||||
|
# permitted in any medium without royalty provided the copyright notice
|
||||||
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
|
# warranty.
|
||||||
|
|
||||||
|
#serial 2
|
||||||
|
|
||||||
|
AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
|
||||||
|
m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
|
||||||
|
])dnl AX_REQUIRE_DEFINED
|
||||||
@ -571,7 +571,7 @@ dc_bluetooth_write (dc_bluetooth_t *device, const void *data, size_t size, size_
|
|||||||
break; // Timeout.
|
break; // Timeout.
|
||||||
}
|
}
|
||||||
|
|
||||||
s_ssize_t n = send (device->fd, (char*) data + nbytes, size - nbytes, 0);
|
s_ssize_t n = send (device->fd, (const char *) data + nbytes, size - nbytes, 0);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
s_errcode_t errcode = S_ERRNO;
|
s_errcode_t errcode = S_ERRNO;
|
||||||
if (errcode == S_EINTR || errcode == S_EAGAIN)
|
if (errcode == S_EINTR || errcode == S_EAGAIN)
|
||||||
@ -591,7 +591,7 @@ dc_bluetooth_write (dc_bluetooth_t *device, const void *data, size_t size, size_
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (unsigned char *) data, nbytes);
|
HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (const unsigned char *) data, nbytes);
|
||||||
|
|
||||||
out_invalidargs:
|
out_invalidargs:
|
||||||
if (actual)
|
if (actual)
|
||||||
|
|||||||
@ -290,10 +290,11 @@ static const dc_descriptor_t g_descriptors[] = {
|
|||||||
{"Shearwater", "Predator", DC_FAMILY_SHEARWATER_PREDATOR, 2}, // BT
|
{"Shearwater", "Predator", DC_FAMILY_SHEARWATER_PREDATOR, 2}, // BT
|
||||||
/* Shearwater Petrel family */
|
/* Shearwater Petrel family */
|
||||||
{"Shearwater", "Petrel", DC_FAMILY_SHEARWATER_PETREL, 3}, // BT // BLE
|
{"Shearwater", "Petrel", DC_FAMILY_SHEARWATER_PETREL, 3}, // BT // BLE
|
||||||
{"Shearwater", "Petrel 2", DC_FAMILY_SHEARWATER_PETREL, 4}, // BT // BLE
|
{"Shearwater", "Petrel 2", DC_FAMILY_SHEARWATER_PETREL, 3}, // BT // BLE
|
||||||
{"Shearwater", "Nerd", DC_FAMILY_SHEARWATER_PETREL, 5}, // BT
|
{"Shearwater", "Nerd", DC_FAMILY_SHEARWATER_PETREL, 4}, // BT
|
||||||
{"Shearwater", "Perdix", DC_FAMILY_SHEARWATER_PETREL, 6}, // BT // BLE
|
{"Shearwater", "Nerd 2", DC_FAMILY_SHEARWATER_PETREL, 4}, // BLE
|
||||||
{"Shearwater", "Perdix AI", DC_FAMILY_SHEARWATER_PETREL, 7}, // BLE
|
{"Shearwater", "Perdix", DC_FAMILY_SHEARWATER_PETREL, 5}, // BT // BLE
|
||||||
|
{"Shearwater", "Perdix AI", DC_FAMILY_SHEARWATER_PETREL, 6}, // BLE
|
||||||
/* Dive Rite NiTek Q */
|
/* Dive Rite NiTek Q */
|
||||||
{"Dive Rite", "NiTek Q", DC_FAMILY_DIVERITE_NITEKQ, 0},
|
{"Dive Rite", "NiTek Q", DC_FAMILY_DIVERITE_NITEKQ, 0},
|
||||||
/* Citizen Hyper Aqualand */
|
/* Citizen Hyper Aqualand */
|
||||||
|
|||||||
@ -408,7 +408,7 @@ dc_device_close (dc_device_t *device)
|
|||||||
void
|
void
|
||||||
device_event_emit (dc_device_t *device, dc_event_type_t event, const void *data)
|
device_event_emit (dc_device_t *device, dc_event_type_t event, const void *data)
|
||||||
{
|
{
|
||||||
dc_event_progress_t *progress = (dc_event_progress_t *) data;
|
const dc_event_progress_t *progress = (const dc_event_progress_t *) data;
|
||||||
|
|
||||||
// Check the event data for errors.
|
// Check the event data for errors.
|
||||||
switch (event) {
|
switch (event) {
|
||||||
@ -436,10 +436,10 @@ device_event_emit (dc_device_t *device, dc_event_type_t event, const void *data)
|
|||||||
// Cache the event data.
|
// Cache the event data.
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case DC_EVENT_DEVINFO:
|
case DC_EVENT_DEVINFO:
|
||||||
device->devinfo = *(dc_event_devinfo_t *) data;
|
device->devinfo = *(const dc_event_devinfo_t *) data;
|
||||||
break;
|
break;
|
||||||
case DC_EVENT_CLOCK:
|
case DC_EVENT_CLOCK:
|
||||||
device->clock = *(dc_event_clock_t *) data;
|
device->clock = *(const dc_event_clock_t *) data;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -272,12 +272,14 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
|
|||||||
unsigned int beginpressure = 0;
|
unsigned int beginpressure = 0;
|
||||||
unsigned int endpressure = 0;
|
unsigned int endpressure = 0;
|
||||||
|
|
||||||
|
unsigned int firmware = 0;
|
||||||
|
unsigned int apos4 = 0;
|
||||||
unsigned int nsamples = array_uint16_le (data + 1);
|
unsigned int nsamples = array_uint16_le (data + 1);
|
||||||
unsigned int samplesize = SZ_SAMPLE_IDIVE;
|
unsigned int samplesize = SZ_SAMPLE_IDIVE;
|
||||||
if (parser->model >= IX3M_EASY) {
|
if (parser->model >= IX3M_EASY) {
|
||||||
// Detect the APOS4 firmware.
|
// Detect the APOS4 firmware.
|
||||||
unsigned int firmware = array_uint32_le(data + 0x2A);
|
firmware = array_uint32_le(data + 0x2A);
|
||||||
unsigned int apos4 = (firmware / 10000000) >= 4;
|
apos4 = (firmware / 10000000) >= 4;
|
||||||
if (apos4) {
|
if (apos4) {
|
||||||
// Dive downloaded and recorded with the APOS4 firmware.
|
// Dive downloaded and recorded with the APOS4 firmware.
|
||||||
samplesize = SZ_SAMPLE_IX3M_APOS4;
|
samplesize = SZ_SAMPLE_IX3M_APOS4;
|
||||||
@ -289,6 +291,8 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
|
|||||||
// Dive downloaded and recorded with an older firmware.
|
// Dive downloaded and recorded with an older firmware.
|
||||||
samplesize = SZ_SAMPLE_IX3M;
|
samplesize = SZ_SAMPLE_IX3M;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
firmware = array_uint32_le(data + 0x2E);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int offset = parser->headersize;
|
unsigned int offset = parser->headersize;
|
||||||
@ -366,17 +370,31 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Deco stop / NDL.
|
// Deco stop / NDL.
|
||||||
unsigned int deco = array_uint16_le (data + offset + 21);
|
unsigned int decostop = 0, decotime = 0, tts = 0;
|
||||||
unsigned int tts = array_uint16_le (data + offset + 23);
|
if (apos4) {
|
||||||
if (tts != 0xFFFF) {
|
decostop = array_uint16_le (data + offset + 21);
|
||||||
if (deco) {
|
decotime = array_uint16_le (data + offset + 23);
|
||||||
|
tts = array_uint16_le (data + offset + 25);
|
||||||
|
if (tts == 0x7FFF) {
|
||||||
|
tts = INVALID;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
decostop = array_uint16_le (data + offset + 21);
|
||||||
|
tts = array_uint16_le (data + offset + 23);
|
||||||
|
if (tts == 0xFFFF) {
|
||||||
|
tts = INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tts != INVALID) {
|
||||||
|
if (decostop) {
|
||||||
sample.deco.type = DC_DECO_DECOSTOP;
|
sample.deco.type = DC_DECO_DECOSTOP;
|
||||||
sample.deco.depth = deco / 10.0;
|
sample.deco.depth = decostop / 10.0;
|
||||||
|
sample.deco.time = apos4 ? decotime : tts;
|
||||||
} else {
|
} else {
|
||||||
sample.deco.type = DC_DECO_NDL;
|
sample.deco.type = DC_DECO_NDL;
|
||||||
sample.deco.depth = 0.0;
|
sample.deco.depth = 0.0;
|
||||||
|
sample.deco.time = tts;
|
||||||
}
|
}
|
||||||
sample.deco.time = tts;
|
|
||||||
if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
|
if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -685,6 +685,14 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
|||||||
unsigned int header = parser->header;
|
unsigned int header = parser->header;
|
||||||
const hw_ostc_layout_t *layout = parser->layout;
|
const hw_ostc_layout_t *layout = parser->layout;
|
||||||
|
|
||||||
|
// Check the header length.
|
||||||
|
if (version == 0x23 || version == 0x24) {
|
||||||
|
if (size < header + 5) {
|
||||||
|
ERROR (abstract->context, "Buffer overflow detected!");
|
||||||
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get the sample rate.
|
// Get the sample rate.
|
||||||
unsigned int samplerate = 0;
|
unsigned int samplerate = 0;
|
||||||
if (version == 0x23 || version == 0x24)
|
if (version == 0x23 || version == 0x24)
|
||||||
@ -711,6 +719,14 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
|||||||
return DC_STATUS_DATAFORMAT;
|
return DC_STATUS_DATAFORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the header length.
|
||||||
|
if (version == 0x23 || version == 0x24) {
|
||||||
|
if (size < header + 5 + 3 * nconfig) {
|
||||||
|
ERROR (abstract->context, "Buffer overflow detected!");
|
||||||
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get the extended sample configuration.
|
// Get the extended sample configuration.
|
||||||
hw_ostc_sample_info_t info[MAXCONFIG] = {{0}};
|
hw_ostc_sample_info_t info[MAXCONFIG] = {{0}};
|
||||||
for (unsigned int i = 0; i < nconfig; ++i) {
|
for (unsigned int i = 0; i < nconfig; ++i) {
|
||||||
|
|||||||
@ -535,7 +535,7 @@ dc_irda_write (dc_irda_t *device, const void *data, size_t size, size_t *actual)
|
|||||||
break; // Timeout.
|
break; // Timeout.
|
||||||
}
|
}
|
||||||
|
|
||||||
s_ssize_t n = send (device->fd, (char*) data + nbytes, size - nbytes, 0);
|
s_ssize_t n = send (device->fd, (const char *) data + nbytes, size - nbytes, 0);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
s_errcode_t errcode = S_ERRNO;
|
s_errcode_t errcode = S_ERRNO;
|
||||||
if (errcode == S_EINTR || errcode == S_EAGAIN)
|
if (errcode == S_EINTR || errcode == S_EAGAIN)
|
||||||
@ -555,7 +555,7 @@ dc_irda_write (dc_irda_t *device, const void *data, size_t size, size_t *actual)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (unsigned char *) data, nbytes);
|
HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (const unsigned char *) data, nbytes);
|
||||||
|
|
||||||
out_invalidargs:
|
out_invalidargs:
|
||||||
if (actual)
|
if (actual)
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
#include "rbstream.h"
|
#include "rbstream.h"
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
|
||||||
#define VTABLE(abstract) ((oceanic_common_device_vtable_t *) abstract->vtable)
|
#define VTABLE(abstract) ((const oceanic_common_device_vtable_t *) abstract->vtable)
|
||||||
|
|
||||||
#define RB_LOGBOOK_DISTANCE(a,b,l) ringbuffer_distance (a, b, 0, l->rb_logbook_begin, l->rb_logbook_end)
|
#define RB_LOGBOOK_DISTANCE(a,b,l) ringbuffer_distance (a, b, 0, l->rb_logbook_begin, l->rb_logbook_end)
|
||||||
#define RB_LOGBOOK_INCR(a,b,l) ringbuffer_increment (a, b, l->rb_logbook_begin, l->rb_logbook_end)
|
#define RB_LOGBOOK_INCR(a,b,l) ringbuffer_increment (a, b, l->rb_logbook_begin, l->rb_logbook_end)
|
||||||
|
|||||||
@ -781,7 +781,7 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (unsigned char *) data, nbytes);
|
HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (const unsigned char *) data, nbytes);
|
||||||
|
|
||||||
out_invalidargs:
|
out_invalidargs:
|
||||||
if (actual)
|
if (actual)
|
||||||
|
|||||||
@ -528,7 +528,7 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (unsigned char *) data, dwWritten);
|
HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (const unsigned char *) data, dwWritten);
|
||||||
|
|
||||||
out_invalidargs:
|
out_invalidargs:
|
||||||
if (actual)
|
if (actual)
|
||||||
|
|||||||
@ -343,7 +343,7 @@ shearwater_common_transfer (shearwater_common_device_t *device, const unsigned c
|
|||||||
|
|
||||||
|
|
||||||
dc_status_t
|
dc_status_t
|
||||||
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression)
|
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression, dc_event_progress_t *progress)
|
||||||
{
|
{
|
||||||
dc_device_t *abstract = (dc_device_t *) device;
|
dc_device_t *abstract = (dc_device_t *) device;
|
||||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||||
@ -371,9 +371,11 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enable progress notifications.
|
// Enable progress notifications.
|
||||||
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
unsigned int initial = 0, current = 0, maximum = 3 + size + 1;
|
||||||
progress.maximum = 3 + size + 1;
|
if (progress) {
|
||||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
initial = progress->current;
|
||||||
|
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
|
||||||
|
}
|
||||||
|
|
||||||
// Transfer the init request.
|
// Transfer the init request.
|
||||||
rc = shearwater_common_transfer (device, req_init, sizeof (req_init), response, 3, &n);
|
rc = shearwater_common_transfer (device, req_init, sizeof (req_init), response, 3, &n);
|
||||||
@ -388,8 +390,11 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update and emit a progress event.
|
// Update and emit a progress event.
|
||||||
progress.current += 3;
|
if (progress) {
|
||||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
current += 3;
|
||||||
|
progress->current = initial + STEP (current, maximum);
|
||||||
|
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int done = 0;
|
unsigned int done = 0;
|
||||||
unsigned char block = 1;
|
unsigned char block = 1;
|
||||||
@ -416,8 +421,11 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update and emit a progress event.
|
// Update and emit a progress event.
|
||||||
progress.current += length;
|
if (progress) {
|
||||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
current += length;
|
||||||
|
progress->current = initial + STEP (current, maximum);
|
||||||
|
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
|
||||||
|
}
|
||||||
|
|
||||||
if (compression) {
|
if (compression) {
|
||||||
if (shearwater_common_decompress_lre (response + 2, length, buffer, &done) != 0) {
|
if (shearwater_common_decompress_lre (response + 2, length, buffer, &done) != 0) {
|
||||||
@ -455,8 +463,11 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update and emit a progress event.
|
// Update and emit a progress event.
|
||||||
progress.current += 1;
|
if (progress) {
|
||||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
current += 1;
|
||||||
|
progress->current = initial + STEP (current, maximum);
|
||||||
|
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
|
||||||
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,14 +31,16 @@ extern "C" {
|
|||||||
|
|
||||||
#define ID_SERIAL 0x8010
|
#define ID_SERIAL 0x8010
|
||||||
#define ID_FIRMWARE 0x8011
|
#define ID_FIRMWARE 0x8011
|
||||||
#define ID_HARDWARE_TYPE 0x8050
|
#define ID_HARDWARE 0x8050
|
||||||
|
|
||||||
#define PREDATOR 2
|
#define PREDATOR 2
|
||||||
#define PETREL 3
|
#define PETREL 3
|
||||||
#define PETREL2 4
|
#define NERD 4
|
||||||
#define NERD 5
|
#define PERDIX 5
|
||||||
#define PERDIX 6
|
#define PERDIXAI 6
|
||||||
#define PERDIXAI 7
|
|
||||||
|
#define NSTEPS 10000
|
||||||
|
#define STEP(i,n) ((NSTEPS * (i) + (n) / 2) / (n))
|
||||||
|
|
||||||
typedef struct shearwater_common_device_t {
|
typedef struct shearwater_common_device_t {
|
||||||
dc_device_t base;
|
dc_device_t base;
|
||||||
@ -55,7 +57,7 @@ dc_status_t
|
|||||||
shearwater_common_transfer (shearwater_common_device_t *device, const unsigned char input[], unsigned int isize, unsigned char output[], unsigned int osize, unsigned int *actual);
|
shearwater_common_transfer (shearwater_common_device_t *device, const unsigned char input[], unsigned int isize, unsigned char output[], unsigned int osize, unsigned int *actual);
|
||||||
|
|
||||||
dc_status_t
|
dc_status_t
|
||||||
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression);
|
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression, dc_event_progress_t *progress);
|
||||||
|
|
||||||
dc_status_t
|
dc_status_t
|
||||||
shearwater_common_identifier (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id);
|
shearwater_common_identifier (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id);
|
||||||
|
|||||||
@ -168,6 +168,11 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
|||||||
return DC_STATUS_NOMEMORY;
|
return DC_STATUS_NOMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable progress notifications.
|
||||||
|
unsigned int current = 0, maximum = 0;
|
||||||
|
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
||||||
|
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||||
|
|
||||||
// Read the serial number.
|
// Read the serial number.
|
||||||
rc = shearwater_common_identifier (&device->base, buffer, ID_SERIAL);
|
rc = shearwater_common_identifier (&device->base, buffer, ID_SERIAL);
|
||||||
if (rc != DC_STATUS_SUCCESS) {
|
if (rc != DC_STATUS_SUCCESS) {
|
||||||
@ -200,8 +205,8 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
|||||||
// Convert to a number.
|
// Convert to a number.
|
||||||
unsigned int firmware = str2num (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer), 1);
|
unsigned int firmware = str2num (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer), 1);
|
||||||
|
|
||||||
// get the product information
|
// Read the hardware type.
|
||||||
rc = shearwater_common_identifier (&device->base, buffer, ID_HARDWARE_TYPE);
|
rc = shearwater_common_identifier (&device->base, buffer, ID_HARDWARE);
|
||||||
if (rc != DC_STATUS_SUCCESS) {
|
if (rc != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to read the hardware type.");
|
ERROR (abstract->context, "Failed to read the hardware type.");
|
||||||
dc_buffer_free (buffer);
|
dc_buffer_free (buffer);
|
||||||
@ -209,51 +214,59 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert and map to the model number.
|
||||||
|
unsigned int hardware = array_uint_be (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer));
|
||||||
|
unsigned int model = 0;
|
||||||
|
switch (hardware) {
|
||||||
|
case 0x0101:
|
||||||
|
case 0x0202:
|
||||||
|
model = PREDATOR;
|
||||||
|
break;
|
||||||
|
case 0x0606:
|
||||||
|
case 0x0A0A: // Nerd 1
|
||||||
|
case 0x0E0D: // Nerd 2
|
||||||
|
model = NERD;
|
||||||
|
break;
|
||||||
|
case 0x0404:
|
||||||
|
case 0x0909: // Petrel 1
|
||||||
|
case 0x0B0B: // Petrel 1 (newer hardware)
|
||||||
|
model = PETREL;
|
||||||
|
break;
|
||||||
|
case 0x0505:
|
||||||
|
case 0x0808: // Petrel 2
|
||||||
|
model = PETREL;
|
||||||
|
break;
|
||||||
|
case 0x0707: // documentation list 0C0D for both Perdix and Perdix AI :-(
|
||||||
|
model = PERDIX;
|
||||||
|
break;
|
||||||
|
case 0x0C0C:
|
||||||
|
case 0x0C0D:
|
||||||
|
case 0x0D0D:
|
||||||
|
model = PERDIXAI;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
model = PETREL;
|
||||||
|
WARNING (abstract->context, "Unknown hardware type %04x. Assuming Petrel.", hardware);
|
||||||
|
}
|
||||||
|
|
||||||
// Emit a device info event.
|
// Emit a device info event.
|
||||||
dc_event_devinfo_t devinfo;
|
dc_event_devinfo_t devinfo;
|
||||||
if (dc_buffer_get_size (buffer) == 2) {
|
devinfo.model = model;
|
||||||
unsigned short model_code = array_uint16_be(dc_buffer_get_data (buffer));
|
|
||||||
switch (model_code) {
|
|
||||||
case 0x0101:
|
|
||||||
case 0x0202:
|
|
||||||
devinfo.model = PREDATOR;
|
|
||||||
break;
|
|
||||||
case 0x0606:
|
|
||||||
case 0x0A0A:
|
|
||||||
devinfo.model = NERD;
|
|
||||||
break;
|
|
||||||
case 0x0404:
|
|
||||||
case 0x0909:
|
|
||||||
case 0x0B0B:
|
|
||||||
devinfo.model = PETREL;
|
|
||||||
break;
|
|
||||||
case 0x0505:
|
|
||||||
case 0x0808:
|
|
||||||
devinfo.model = PETREL2;
|
|
||||||
break;
|
|
||||||
case 0x0707: // documentation list 0C0D for both Perdix and Perdix AI :-(
|
|
||||||
devinfo.model = PERDIX;
|
|
||||||
break;
|
|
||||||
case 0x0C0C:
|
|
||||||
case 0x0C0D:
|
|
||||||
case 0x0D0D:
|
|
||||||
devinfo.model = PERDIXAI;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
devinfo.model = PETREL;
|
|
||||||
ERROR (abstract->context, "Unknown model code - assuming Petrel.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
devinfo.model = PERDIX;
|
|
||||||
ERROR (abstract->context, "Failed to read hardware type - assuming Petrel.");
|
|
||||||
}
|
|
||||||
devinfo.firmware = firmware;
|
devinfo.firmware = firmware;
|
||||||
devinfo.serial = array_uint32_be (serial);
|
devinfo.serial = array_uint32_be (serial);
|
||||||
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
// Update the progress state.
|
||||||
|
// Assume the worst case scenario of a full manifest, and adjust the
|
||||||
|
// value with the actual number of dives after the manifest has been
|
||||||
|
// processed.
|
||||||
|
maximum += 1 + RECORD_COUNT;
|
||||||
|
|
||||||
// Download a manifest.
|
// Download a manifest.
|
||||||
rc = shearwater_common_download (&device->base, buffer, MANIFEST_ADDR, MANIFEST_SIZE, 0);
|
progress.current = NSTEPS * current;
|
||||||
|
progress.maximum = NSTEPS * maximum;
|
||||||
|
rc = shearwater_common_download (&device->base, buffer, MANIFEST_ADDR, MANIFEST_SIZE, 0, &progress);
|
||||||
if (rc != DC_STATUS_SUCCESS) {
|
if (rc != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to download the manifest.");
|
ERROR (abstract->context, "Failed to download the manifest.");
|
||||||
dc_buffer_free (buffer);
|
dc_buffer_free (buffer);
|
||||||
@ -282,6 +295,10 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the progress state.
|
||||||
|
current += 1;
|
||||||
|
maximum -= RECORD_COUNT - count;
|
||||||
|
|
||||||
// Append the manifest records to the main buffer.
|
// Append the manifest records to the main buffer.
|
||||||
if (!dc_buffer_append (manifests, data, count * RECORD_SIZE)) {
|
if (!dc_buffer_append (manifests, data, count * RECORD_SIZE)) {
|
||||||
ERROR (abstract->context, "Insufficient buffer space available.");
|
ERROR (abstract->context, "Insufficient buffer space available.");
|
||||||
@ -295,6 +312,11 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update and emit a progress event.
|
||||||
|
progress.current = NSTEPS * current;
|
||||||
|
progress.maximum = NSTEPS * maximum;
|
||||||
|
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||||
|
|
||||||
// Cache the buffer pointer and size.
|
// Cache the buffer pointer and size.
|
||||||
unsigned char *data = dc_buffer_get_data (manifests);
|
unsigned char *data = dc_buffer_get_data (manifests);
|
||||||
unsigned int size = dc_buffer_get_size (manifests);
|
unsigned int size = dc_buffer_get_size (manifests);
|
||||||
@ -305,7 +327,9 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
|||||||
unsigned int address = array_uint32_be (data + offset + 20);
|
unsigned int address = array_uint32_be (data + offset + 20);
|
||||||
|
|
||||||
// Download the dive.
|
// Download the dive.
|
||||||
rc = shearwater_common_download (&device->base, buffer, DIVE_ADDR + address, DIVE_SIZE, 1);
|
progress.current = NSTEPS * current;
|
||||||
|
progress.maximum = NSTEPS * maximum;
|
||||||
|
rc = shearwater_common_download (&device->base, buffer, DIVE_ADDR + address, DIVE_SIZE, 1, &progress);
|
||||||
if (rc != DC_STATUS_SUCCESS) {
|
if (rc != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to download the dive.");
|
ERROR (abstract->context, "Failed to download the dive.");
|
||||||
dc_buffer_free (buffer);
|
dc_buffer_free (buffer);
|
||||||
@ -313,6 +337,9 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the progress state.
|
||||||
|
current += 1;
|
||||||
|
|
||||||
unsigned char *buf = dc_buffer_get_data (buffer);
|
unsigned char *buf = dc_buffer_get_data (buffer);
|
||||||
unsigned int len = dc_buffer_get_size (buffer);
|
unsigned int len = dc_buffer_get_size (buffer);
|
||||||
if (callback && !callback (buf, len, buf + 12, sizeof (device->fingerprint), userdata))
|
if (callback && !callback (buf, len, buf + 12, sizeof (device->fingerprint), userdata))
|
||||||
@ -321,6 +348,11 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
|||||||
offset += RECORD_SIZE;
|
offset += RECORD_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update and emit a progress event.
|
||||||
|
progress.current = NSTEPS * current;
|
||||||
|
progress.maximum = NSTEPS * maximum;
|
||||||
|
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||||
|
|
||||||
dc_buffer_free (manifests);
|
dc_buffer_free (manifests);
|
||||||
dc_buffer_free (buffer);
|
dc_buffer_free (buffer);
|
||||||
|
|
||||||
|
|||||||
@ -30,9 +30,6 @@
|
|||||||
|
|
||||||
#define ISINSTANCE(device) dc_device_isinstance((device), &shearwater_predator_device_vtable)
|
#define ISINSTANCE(device) dc_device_isinstance((device), &shearwater_predator_device_vtable)
|
||||||
|
|
||||||
#define PREDATOR 2
|
|
||||||
#define PETREL 3
|
|
||||||
|
|
||||||
#define SZ_BLOCK 0x80
|
#define SZ_BLOCK 0x80
|
||||||
#define SZ_MEMORY 0x20080
|
#define SZ_MEMORY 0x20080
|
||||||
|
|
||||||
@ -136,7 +133,12 @@ shearwater_predator_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
|
|||||||
return DC_STATUS_NOMEMORY;
|
return DC_STATUS_NOMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return shearwater_common_download (device, buffer, 0xDD000000, SZ_MEMORY, 0);
|
// Enable progress notifications.
|
||||||
|
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
||||||
|
progress.current = 0;
|
||||||
|
progress.maximum = NSTEPS;
|
||||||
|
|
||||||
|
return shearwater_common_download (device, buffer, 0xDD000000, SZ_MEMORY, 0, &progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -65,6 +65,7 @@ struct shearwater_predator_parser_t {
|
|||||||
unsigned int samplesize;
|
unsigned int samplesize;
|
||||||
// Cached fields.
|
// Cached fields.
|
||||||
unsigned int cached;
|
unsigned int cached;
|
||||||
|
unsigned int logversion;
|
||||||
unsigned int headersize;
|
unsigned int headersize;
|
||||||
unsigned int footersize;
|
unsigned int footersize;
|
||||||
unsigned int ngasmixes;
|
unsigned int ngasmixes;
|
||||||
@ -73,7 +74,6 @@ struct shearwater_predator_parser_t {
|
|||||||
double calibration[3];
|
double calibration[3];
|
||||||
unsigned int serial;
|
unsigned int serial;
|
||||||
dc_divemode_t mode;
|
dc_divemode_t mode;
|
||||||
unsigned char logversion;
|
|
||||||
|
|
||||||
/* String fields */
|
/* String fields */
|
||||||
dc_field_string_t strings[MAXSTRINGS];
|
dc_field_string_t strings[MAXSTRINGS];
|
||||||
@ -151,6 +151,7 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig
|
|||||||
|
|
||||||
// Set the default values.
|
// Set the default values.
|
||||||
parser->cached = 0;
|
parser->cached = 0;
|
||||||
|
parser->logversion = 0;
|
||||||
parser->headersize = 0;
|
parser->headersize = 0;
|
||||||
parser->footersize = 0;
|
parser->footersize = 0;
|
||||||
parser->ngasmixes = 0;
|
parser->ngasmixes = 0;
|
||||||
@ -173,6 +174,7 @@ shearwater_predator_parser_set_data (dc_parser_t *abstract, const unsigned char
|
|||||||
|
|
||||||
// Reset the cache.
|
// Reset the cache.
|
||||||
parser->cached = 0;
|
parser->cached = 0;
|
||||||
|
parser->logversion = 0;
|
||||||
parser->headersize = 0;
|
parser->headersize = 0;
|
||||||
parser->footersize = 0;
|
parser->footersize = 0;
|
||||||
parser->ngasmixes = 0;
|
parser->ngasmixes = 0;
|
||||||
@ -366,10 +368,10 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
|
|||||||
|
|
||||||
// Log versions before 6 weren't reliably stored in the data, but
|
// Log versions before 6 weren't reliably stored in the data, but
|
||||||
// 6 is also the oldest version that we assume in our code
|
// 6 is also the oldest version that we assume in our code
|
||||||
parser->logversion = 6;
|
unsigned int logversion = 6;
|
||||||
if (data[127] > 6)
|
if (data[127] > 6)
|
||||||
parser->logversion = data[127];
|
logversion = data[127];
|
||||||
INFO(abstract->context, "Shearwater log version %u\n", parser->logversion);
|
INFO(abstract->context, "Shearwater log version %u\n", logversion);
|
||||||
|
|
||||||
memset(parser->strings, 0, sizeof(parser->strings));
|
memset(parser->strings, 0, sizeof(parser->strings));
|
||||||
|
|
||||||
@ -437,7 +439,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Transmitter battery levels
|
// Transmitter battery levels
|
||||||
if (parser->logversion >= 7) {
|
if (logversion >= 7) {
|
||||||
// T1 at offset 27, T2 at offset 19
|
// T1 at offset 27, T2 at offset 19
|
||||||
t1_battery |= battery_state(data + offset + 27);
|
t1_battery |= battery_state(data + offset + 27);
|
||||||
t2_battery |= battery_state(data + offset + 19);
|
t2_battery |= battery_state(data + offset + 19);
|
||||||
@ -461,6 +463,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cache the data for later use.
|
// Cache the data for later use.
|
||||||
|
parser->logversion = logversion;
|
||||||
parser->headersize = headersize;
|
parser->headersize = headersize;
|
||||||
parser->footersize = footersize;
|
parser->footersize = footersize;
|
||||||
parser->ngasmixes = ngasmixes;
|
parser->ngasmixes = ngasmixes;
|
||||||
@ -690,27 +693,38 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
|
|||||||
// for logversion 7 and newer (introduced for Perdix AI)
|
// for logversion 7 and newer (introduced for Perdix AI)
|
||||||
// detect tank pressure
|
// detect tank pressure
|
||||||
if (parser->logversion >= 7) {
|
if (parser->logversion >= 7) {
|
||||||
// Pressure (2 psi).
|
// Tank pressure
|
||||||
// 0xFFFF is not paired / no coms for 90 seconds
|
// Values above 0xFFF0 are special codes:
|
||||||
// 0xFFFE no coms for 30 seconds
|
// 0xFFFF AI is off
|
||||||
// top 4 bits battery level:
|
// 0xFFFE No comms for 90 seconds+
|
||||||
// 0 - normal, 1 - critical, 2 - warning
|
// 0xFFFD No comms for 30 seconds
|
||||||
|
// 0xFFFC Transmitter not paired
|
||||||
|
// For regular values, the top 4 bits contain the battery
|
||||||
|
// level (0=normal, 1=critical, 2=warning), and the lower 12
|
||||||
|
// bits the tank pressure in units of 2 psi.
|
||||||
unsigned int pressure = array_uint16_be (data + offset + 27);
|
unsigned int pressure = array_uint16_be (data + offset + 27);
|
||||||
if ((pressure & 0xFFF0) != 0xFFF0) {
|
if (pressure < 0xFFF0) {
|
||||||
pressure &= 0x0FFF;
|
pressure &= 0x0FFF;
|
||||||
sample.pressure.tank = 0;
|
sample.pressure.tank = 0;
|
||||||
sample.pressure.value = pressure * 2 * PSI / BAR;
|
sample.pressure.value = pressure * 2 * PSI / BAR;
|
||||||
if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
|
if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
|
||||||
}
|
}
|
||||||
pressure = array_uint16_be (data + offset + 19);
|
pressure = array_uint16_be (data + offset + 19);
|
||||||
if ((pressure & 0xFFF0) != 0xFFF0) {
|
if (pressure < 0xFFF0) {
|
||||||
pressure &= 0x0FFF;
|
pressure &= 0x0FFF;
|
||||||
sample.pressure.tank = 1;
|
sample.pressure.tank = 1;
|
||||||
sample.pressure.value = pressure * 2 * PSI / BAR;
|
sample.pressure.value = pressure * 2 * PSI / BAR;
|
||||||
if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
|
if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gas time remaining in minutes
|
// Gas time remaining in minutes
|
||||||
if (data[offset + 21] < 0xFBu) {
|
// Values above 0xF0 are special codes:
|
||||||
|
// 0xFF Not paired
|
||||||
|
// 0xFE No communication
|
||||||
|
// 0xFD Not available in current mode
|
||||||
|
// 0xFC Not available because of DECO
|
||||||
|
// 0xFB Tank size or max pressure haven’t been set up
|
||||||
|
if (data[offset + 21] < 0xF0) {
|
||||||
sample.rbt = data[offset + 21];
|
sample.rbt = data[offset + 21];
|
||||||
if (callback) callback (DC_SAMPLE_RBT, sample, userdata);
|
if (callback) callback (DC_SAMPLE_RBT, sample, userdata);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#define RB_PROFILE_DISTANCE(l,a,b,m) ringbuffer_distance (a, b, m, l->rb_profile_begin, l->rb_profile_end)
|
#define RB_PROFILE_DISTANCE(l,a,b,m) ringbuffer_distance (a, b, m, l->rb_profile_begin, l->rb_profile_end)
|
||||||
|
|
||||||
#define VTABLE(abstract) ((suunto_common2_device_vtable_t *) abstract->vtable)
|
#define VTABLE(abstract) ((const suunto_common2_device_vtable_t *) abstract->vtable)
|
||||||
|
|
||||||
void
|
void
|
||||||
suunto_common2_device_init (suunto_common2_device_t *device)
|
suunto_common2_device_init (suunto_common2_device_t *device)
|
||||||
|
|||||||
@ -31,8 +31,12 @@
|
|||||||
#include "usbhid.h"
|
#include "usbhid.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
|
#define EONSTEEL 0
|
||||||
|
#define EONCORE 1
|
||||||
|
|
||||||
typedef struct suunto_eonsteel_device_t {
|
typedef struct suunto_eonsteel_device_t {
|
||||||
dc_device_t base;
|
dc_device_t base;
|
||||||
|
unsigned int model;
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
unsigned short seq;
|
unsigned short seq;
|
||||||
unsigned char version[0x30];
|
unsigned char version[0x30];
|
||||||
@ -73,7 +77,7 @@ struct directory_entry {
|
|||||||
|
|
||||||
static dc_status_t suunto_eonsteel_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
static dc_status_t suunto_eonsteel_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
|
||||||
static dc_status_t suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
static dc_status_t suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
|
||||||
static dc_status_t suunto_eonsteel_timesync(dc_device_t *abstract, const dc_datetime_t *datetime);
|
static dc_status_t suunto_eonsteel_device_timesync(dc_device_t *abstract, const dc_datetime_t *datetime);
|
||||||
static dc_status_t suunto_eonsteel_device_close(dc_device_t *abstract);
|
static dc_status_t suunto_eonsteel_device_close(dc_device_t *abstract);
|
||||||
|
|
||||||
static const dc_device_vtable_t suunto_eonsteel_device_vtable = {
|
static const dc_device_vtable_t suunto_eonsteel_device_vtable = {
|
||||||
@ -84,7 +88,7 @@ static const dc_device_vtable_t suunto_eonsteel_device_vtable = {
|
|||||||
NULL, /* write */
|
NULL, /* write */
|
||||||
NULL, /* dump */
|
NULL, /* dump */
|
||||||
suunto_eonsteel_device_foreach, /* foreach */
|
suunto_eonsteel_device_foreach, /* foreach */
|
||||||
suunto_eonsteel_timesync, /* timesync */
|
suunto_eonsteel_device_timesync, /* timesync */
|
||||||
suunto_eonsteel_device_close /* close */
|
suunto_eonsteel_device_close /* close */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -740,6 +744,7 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char
|
|||||||
return DC_STATUS_NOMEMORY;
|
return DC_STATUS_NOMEMORY;
|
||||||
|
|
||||||
// Set up the magic handshake fields
|
// Set up the magic handshake fields
|
||||||
|
eon->model = model;
|
||||||
eon->magic = INIT_MAGIC;
|
eon->magic = INIT_MAGIC;
|
||||||
eon->seq = INIT_SEQ;
|
eon->seq = INIT_SEQ;
|
||||||
memset (eon->version, 0, sizeof (eon->version));
|
memset (eon->version, 0, sizeof (eon->version));
|
||||||
@ -812,26 +817,24 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac
|
|||||||
dc_buffer_t *file;
|
dc_buffer_t *file;
|
||||||
char pathname[64];
|
char pathname[64];
|
||||||
unsigned int time;
|
unsigned int time;
|
||||||
unsigned int count = 0;
|
|
||||||
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
||||||
|
|
||||||
if (get_file_list(eon, &de) < 0)
|
|
||||||
return DC_STATUS_IO;
|
|
||||||
|
|
||||||
// Emit a device info event.
|
// Emit a device info event.
|
||||||
dc_event_devinfo_t devinfo;
|
dc_event_devinfo_t devinfo;
|
||||||
devinfo.model = 0;
|
devinfo.model = eon->model;
|
||||||
devinfo.firmware = array_uint32_be (eon->version + 0x20);
|
devinfo.firmware = array_uint32_be (eon->version + 0x20);
|
||||||
devinfo.serial = array_convert_str2num(eon->version + 0x10, 16);
|
devinfo.serial = array_convert_str2num(eon->version + 0x10, 16);
|
||||||
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
||||||
|
|
||||||
count = count_dir_entries(de);
|
if (get_file_list(eon, &de) < 0)
|
||||||
if (count == 0) {
|
return DC_STATUS_IO;
|
||||||
|
|
||||||
|
if (de == NULL) {
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = dc_buffer_new(0);
|
file = dc_buffer_new(0);
|
||||||
progress.maximum = count;
|
progress.maximum = count_dir_entries(de);
|
||||||
progress.current = 0;
|
progress.current = 0;
|
||||||
device_event_emit(abstract, DC_EVENT_PROGRESS, &progress);
|
device_event_emit(abstract, DC_EVENT_PROGRESS, &progress);
|
||||||
|
|
||||||
@ -890,12 +893,12 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac
|
|||||||
return device_is_cancelled(abstract) ? DC_STATUS_CANCELLED : DC_STATUS_SUCCESS;
|
return device_is_cancelled(abstract) ? DC_STATUS_CANCELLED : DC_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dc_status_t suunto_eonsteel_timesync(dc_device_t *abstract, const dc_datetime_t *datetime)
|
static dc_status_t suunto_eonsteel_device_timesync(dc_device_t *abstract, const dc_datetime_t *datetime)
|
||||||
{
|
{
|
||||||
suunto_eonsteel_device_t *eon = (suunto_eonsteel_device_t *) abstract;
|
suunto_eonsteel_device_t *eon = (suunto_eonsteel_device_t *) abstract;
|
||||||
unsigned char result[64], cmd[64];
|
unsigned char result[64], cmd[8];
|
||||||
int year, month, day;
|
unsigned int year, month, day;
|
||||||
int hour, min, sec, msec;
|
unsigned int hour, min, msec;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
year = datetime->year;
|
year = datetime->year;
|
||||||
@ -903,23 +906,23 @@ static dc_status_t suunto_eonsteel_timesync(dc_device_t *abstract, const dc_date
|
|||||||
day = datetime->day;
|
day = datetime->day;
|
||||||
hour = datetime->hour;
|
hour = datetime->hour;
|
||||||
min = datetime->minute;
|
min = datetime->minute;
|
||||||
sec = datetime->second;
|
msec = datetime->second * 1000;
|
||||||
|
|
||||||
INFO(eon->base.context, "SET_TIME: %d/%d/%d %d:%02d:%02d.%03d",
|
cmd[0] = year & 0xFF;
|
||||||
year, month, day, hour, min, sec, msec);
|
|
||||||
|
|
||||||
msec = sec * 1000;
|
|
||||||
|
|
||||||
cmd[0] = year & 255;
|
|
||||||
cmd[1] = year >> 8;
|
cmd[1] = year >> 8;
|
||||||
cmd[2] = month;
|
cmd[2] = month;
|
||||||
cmd[3] = day;
|
cmd[3] = day;
|
||||||
cmd[4] = hour;
|
cmd[4] = hour;
|
||||||
cmd[5] = min;
|
cmd[5] = min;
|
||||||
cmd[6] = msec & 255;
|
cmd[6] = msec & 0xFF;
|
||||||
cmd[7] = msec >> 8;
|
cmd[7] = msec >> 8;
|
||||||
|
|
||||||
return send_receive(eon, CMD_SET_TIME, 8, cmd, sizeof(result), result);
|
rc = send_receive(eon, CMD_SET_TIME, sizeof(cmd), cmd, sizeof(result), result);
|
||||||
|
if (rc < 0) {
|
||||||
|
return DC_STATUS_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DC_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dc_status_t
|
static dc_status_t
|
||||||
|
|||||||
@ -598,7 +598,7 @@ out:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HEXDUMP (usbhid->context, DC_LOGLEVEL_INFO, "Write", (unsigned char *) data, nbytes);
|
HEXDUMP (usbhid->context, DC_LOGLEVEL_INFO, "Write", (const unsigned char *) data, nbytes);
|
||||||
|
|
||||||
out_invalidargs:
|
out_invalidargs:
|
||||||
if (actual)
|
if (actual)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user