diff --git a/NEWS b/NEWS
index 938041d..7c03239 100644
--- a/NEWS
+++ b/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)
==========================
diff --git a/configure.ac b/configure.ac
index 235e8ba..a48b734 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,8 +64,10 @@ AM_CONDITIONAL([ENABLE_DOC], [test "x$enable_doc" = "xyes"])
AC_PROG_CC
AC_PROG_CC_C99
AC_CHECK_PROGS([DOXYGEN], [doxygen])
+AC_CHECK_PROGS([MANDOC], [mandoc])
AM_CONDITIONAL([HAVE_DOXYGEN],[test -n "$DOXYGEN"])
+AM_CONDITIONAL([HAVE_MANDOC],[test -n "$MANDOC"])
# Enable automake silent build rules.
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([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.
AC_SUBST([DC_VERSION],[dc_version])
AC_SUBST([DC_VERSION_MAJOR],[dc_version_major])
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
index 7020e2e..fbaa991 100644
--- a/doc/man/Makefile.am
+++ b/doc/man/Makefile.am
@@ -1,4 +1,4 @@
-dist_man_MANS = \
+MANPAGES = \
dc_buffer_append.3 \
dc_buffer_free.3 \
dc_buffer_get_data.3 \
@@ -32,3 +32,18 @@ dist_man_MANS = \
dc_parser_samples_foreach.3 \
dc_parser_set_data.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)
diff --git a/examples/output_xml.c b/examples/output_xml.c
index 237f929..5153fc8 100644
--- a/examples/output_xml.c
+++ b/examples/output_xml.c
@@ -142,7 +142,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
case DC_SAMPLE_VENDOR:
fprintf (sampledata->ostream, " ", value.vendor.type, value.vendor.size);
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, "\n");
break;
case DC_SAMPLE_SETPOINT:
diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4
new file mode 100644
index 0000000..5b6f1af
--- /dev/null
+++ b/m4/ax_append_compile_flags.m4
@@ -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
+#
+# 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 .
+#
+# 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
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
new file mode 100644
index 0000000..e8c5312
--- /dev/null
+++ b/m4/ax_append_flag.m4
@@ -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
+# Copyright (c) 2011 Maarten Bosmans
+#
+# 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 .
+#
+# 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
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000..dcabb92
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -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
+# Copyright (c) 2011 Maarten Bosmans
+#
+# 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 .
+#
+# 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
diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4
new file mode 100644
index 0000000..17c3eab
--- /dev/null
+++ b/m4/ax_require_defined.m4
@@ -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
+#
+# 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
diff --git a/src/bluetooth.c b/src/bluetooth.c
index bc9ffe0..01a3e96 100644
--- a/src/bluetooth.c
+++ b/src/bluetooth.c
@@ -571,7 +571,7 @@ dc_bluetooth_write (dc_bluetooth_t *device, const void *data, size_t size, size_
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) {
s_errcode_t errcode = S_ERRNO;
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:
- 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:
if (actual)
diff --git a/src/descriptor.c b/src/descriptor.c
index 01dbd69..a8c8a1a 100644
--- a/src/descriptor.c
+++ b/src/descriptor.c
@@ -290,10 +290,11 @@ static const dc_descriptor_t g_descriptors[] = {
{"Shearwater", "Predator", DC_FAMILY_SHEARWATER_PREDATOR, 2}, // BT
/* Shearwater Petrel family */
{"Shearwater", "Petrel", DC_FAMILY_SHEARWATER_PETREL, 3}, // BT // BLE
- {"Shearwater", "Petrel 2", DC_FAMILY_SHEARWATER_PETREL, 4}, // BT // BLE
- {"Shearwater", "Nerd", DC_FAMILY_SHEARWATER_PETREL, 5}, // BT
- {"Shearwater", "Perdix", DC_FAMILY_SHEARWATER_PETREL, 6}, // BT // BLE
- {"Shearwater", "Perdix AI", DC_FAMILY_SHEARWATER_PETREL, 7}, // BLE
+ {"Shearwater", "Petrel 2", DC_FAMILY_SHEARWATER_PETREL, 3}, // BT // BLE
+ {"Shearwater", "Nerd", DC_FAMILY_SHEARWATER_PETREL, 4}, // BT
+ {"Shearwater", "Nerd 2", DC_FAMILY_SHEARWATER_PETREL, 4}, // 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", DC_FAMILY_DIVERITE_NITEKQ, 0},
/* Citizen Hyper Aqualand */
diff --git a/src/device.c b/src/device.c
index 7980186..49f845a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -408,7 +408,7 @@ dc_device_close (dc_device_t *device)
void
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.
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.
switch (event) {
case DC_EVENT_DEVINFO:
- device->devinfo = *(dc_event_devinfo_t *) data;
+ device->devinfo = *(const dc_event_devinfo_t *) data;
break;
case DC_EVENT_CLOCK:
- device->clock = *(dc_event_clock_t *) data;
+ device->clock = *(const dc_event_clock_t *) data;
break;
default:
break;
diff --git a/src/divesystem_idive_parser.c b/src/divesystem_idive_parser.c
index ca5c2b1..24f7e53 100644
--- a/src/divesystem_idive_parser.c
+++ b/src/divesystem_idive_parser.c
@@ -272,12 +272,14 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
unsigned int beginpressure = 0;
unsigned int endpressure = 0;
+ unsigned int firmware = 0;
+ unsigned int apos4 = 0;
unsigned int nsamples = array_uint16_le (data + 1);
unsigned int samplesize = SZ_SAMPLE_IDIVE;
if (parser->model >= IX3M_EASY) {
// Detect the APOS4 firmware.
- unsigned int firmware = array_uint32_le(data + 0x2A);
- unsigned int apos4 = (firmware / 10000000) >= 4;
+ firmware = array_uint32_le(data + 0x2A);
+ apos4 = (firmware / 10000000) >= 4;
if (apos4) {
// Dive downloaded and recorded with the APOS4 firmware.
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.
samplesize = SZ_SAMPLE_IX3M;
}
+ } else {
+ firmware = array_uint32_le(data + 0x2E);
}
unsigned int offset = parser->headersize;
@@ -366,17 +370,31 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
}
// Deco stop / NDL.
- unsigned int deco = array_uint16_le (data + offset + 21);
- unsigned int tts = array_uint16_le (data + offset + 23);
- if (tts != 0xFFFF) {
- if (deco) {
+ unsigned int decostop = 0, decotime = 0, tts = 0;
+ if (apos4) {
+ decostop = array_uint16_le (data + offset + 21);
+ 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.depth = deco / 10.0;
+ sample.deco.depth = decostop / 10.0;
+ sample.deco.time = apos4 ? decotime : tts;
} else {
sample.deco.type = DC_DECO_NDL;
sample.deco.depth = 0.0;
+ sample.deco.time = tts;
}
- sample.deco.time = tts;
if (callback) callback (DC_SAMPLE_DECO, sample, userdata);
}
diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c
index 267929c..ed5c824 100644
--- a/src/hw_ostc_parser.c
+++ b/src/hw_ostc_parser.c
@@ -685,6 +685,14 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
unsigned int header = parser->header;
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.
unsigned int samplerate = 0;
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;
}
+ // 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.
hw_ostc_sample_info_t info[MAXCONFIG] = {{0}};
for (unsigned int i = 0; i < nconfig; ++i) {
diff --git a/src/irda.c b/src/irda.c
index d085ec0..1a2c38c 100644
--- a/src/irda.c
+++ b/src/irda.c
@@ -535,7 +535,7 @@ dc_irda_write (dc_irda_t *device, const void *data, size_t size, size_t *actual)
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) {
s_errcode_t errcode = S_ERRNO;
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:
- 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:
if (actual)
diff --git a/src/oceanic_common.c b/src/oceanic_common.c
index 427b326..43bc06d 100644
--- a/src/oceanic_common.c
+++ b/src/oceanic_common.c
@@ -30,7 +30,7 @@
#include "rbstream.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_INCR(a,b,l) ringbuffer_increment (a, b, l->rb_logbook_begin, l->rb_logbook_end)
diff --git a/src/serial_posix.c b/src/serial_posix.c
index 9327d96..7f07206 100644
--- a/src/serial_posix.c
+++ b/src/serial_posix.c
@@ -781,7 +781,7 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
}
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:
if (actual)
diff --git a/src/serial_win32.c b/src/serial_win32.c
index 40cddf9..540ec11 100644
--- a/src/serial_win32.c
+++ b/src/serial_win32.c
@@ -528,7 +528,7 @@ dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *act
}
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:
if (actual)
diff --git a/src/shearwater_common.c b/src/shearwater_common.c
index 2546998..58fd3a3 100644
--- a/src/shearwater_common.c
+++ b/src/shearwater_common.c
@@ -343,7 +343,7 @@ shearwater_common_transfer (shearwater_common_device_t *device, const unsigned c
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_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.
- dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
- progress.maximum = 3 + size + 1;
- device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
+ unsigned int initial = 0, current = 0, maximum = 3 + size + 1;
+ if (progress) {
+ initial = progress->current;
+ device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
+ }
// Transfer the init request.
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.
- progress.current += 3;
- device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
+ if (progress) {
+ current += 3;
+ progress->current = initial + STEP (current, maximum);
+ device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
+ }
unsigned int done = 0;
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.
- progress.current += length;
- device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
+ if (progress) {
+ current += length;
+ progress->current = initial + STEP (current, maximum);
+ device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
+ }
if (compression) {
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.
- progress.current += 1;
- device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
+ if (progress) {
+ current += 1;
+ progress->current = initial + STEP (current, maximum);
+ device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
+ }
return DC_STATUS_SUCCESS;
}
diff --git a/src/shearwater_common.h b/src/shearwater_common.h
index 406f151..4253a00 100644
--- a/src/shearwater_common.h
+++ b/src/shearwater_common.h
@@ -31,14 +31,16 @@ extern "C" {
#define ID_SERIAL 0x8010
#define ID_FIRMWARE 0x8011
-#define ID_HARDWARE_TYPE 0x8050
+#define ID_HARDWARE 0x8050
#define PREDATOR 2
#define PETREL 3
-#define PETREL2 4
-#define NERD 5
-#define PERDIX 6
-#define PERDIXAI 7
+#define NERD 4
+#define PERDIX 5
+#define PERDIXAI 6
+
+#define NSTEPS 10000
+#define STEP(i,n) ((NSTEPS * (i) + (n) / 2) / (n))
typedef struct shearwater_common_device_t {
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);
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
shearwater_common_identifier (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id);
diff --git a/src/shearwater_petrel.c b/src/shearwater_petrel.c
index 7558c54..5f38aaa 100644
--- a/src/shearwater_petrel.c
+++ b/src/shearwater_petrel.c
@@ -168,6 +168,11 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
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.
rc = shearwater_common_identifier (&device->base, buffer, ID_SERIAL);
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.
unsigned int firmware = str2num (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer), 1);
- // get the product information
- rc = shearwater_common_identifier (&device->base, buffer, ID_HARDWARE_TYPE);
+ // Read the hardware type.
+ rc = shearwater_common_identifier (&device->base, buffer, ID_HARDWARE);
if (rc != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the hardware type.");
dc_buffer_free (buffer);
@@ -209,51 +214,59 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
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.
dc_event_devinfo_t devinfo;
- if (dc_buffer_get_size (buffer) == 2) {
- 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.model = model;
devinfo.firmware = firmware;
devinfo.serial = array_uint32_be (serial);
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
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.
- 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) {
ERROR (abstract->context, "Failed to download the manifest.");
dc_buffer_free (buffer);
@@ -282,6 +295,10 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
count++;
}
+ // Update the progress state.
+ current += 1;
+ maximum -= RECORD_COUNT - count;
+
// Append the manifest records to the main buffer.
if (!dc_buffer_append (manifests, data, count * RECORD_SIZE)) {
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;
}
+ // 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.
unsigned char *data = dc_buffer_get_data (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);
// 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) {
ERROR (abstract->context, "Failed to download the dive.");
dc_buffer_free (buffer);
@@ -313,6 +337,9 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
return rc;
}
+ // Update the progress state.
+ current += 1;
+
unsigned char *buf = dc_buffer_get_data (buffer);
unsigned int len = dc_buffer_get_size (buffer);
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;
}
+ // 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 (buffer);
diff --git a/src/shearwater_predator.c b/src/shearwater_predator.c
index 42a579b..a47d414 100644
--- a/src/shearwater_predator.c
+++ b/src/shearwater_predator.c
@@ -30,9 +30,6 @@
#define ISINSTANCE(device) dc_device_isinstance((device), &shearwater_predator_device_vtable)
-#define PREDATOR 2
-#define PETREL 3
-
#define SZ_BLOCK 0x80
#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 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);
}
diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c
index 992169c..6e81083 100644
--- a/src/shearwater_predator_parser.c
+++ b/src/shearwater_predator_parser.c
@@ -65,6 +65,7 @@ struct shearwater_predator_parser_t {
unsigned int samplesize;
// Cached fields.
unsigned int cached;
+ unsigned int logversion;
unsigned int headersize;
unsigned int footersize;
unsigned int ngasmixes;
@@ -73,7 +74,6 @@ struct shearwater_predator_parser_t {
double calibration[3];
unsigned int serial;
dc_divemode_t mode;
- unsigned char logversion;
/* String fields */
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.
parser->cached = 0;
+ parser->logversion = 0;
parser->headersize = 0;
parser->footersize = 0;
parser->ngasmixes = 0;
@@ -173,6 +174,7 @@ shearwater_predator_parser_set_data (dc_parser_t *abstract, const unsigned char
// Reset the cache.
parser->cached = 0;
+ parser->logversion = 0;
parser->headersize = 0;
parser->footersize = 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
// 6 is also the oldest version that we assume in our code
- parser->logversion = 6;
+ unsigned int logversion = 6;
if (data[127] > 6)
- parser->logversion = data[127];
- INFO(abstract->context, "Shearwater log version %u\n", parser->logversion);
+ logversion = data[127];
+ INFO(abstract->context, "Shearwater log version %u\n", logversion);
memset(parser->strings, 0, sizeof(parser->strings));
@@ -437,7 +439,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
}
// Transmitter battery levels
- if (parser->logversion >= 7) {
+ if (logversion >= 7) {
// T1 at offset 27, T2 at offset 19
t1_battery |= battery_state(data + offset + 27);
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.
+ parser->logversion = logversion;
parser->headersize = headersize;
parser->footersize = footersize;
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)
// detect tank pressure
if (parser->logversion >= 7) {
- // Pressure (2 psi).
- // 0xFFFF is not paired / no coms for 90 seconds
- // 0xFFFE no coms for 30 seconds
- // top 4 bits battery level:
- // 0 - normal, 1 - critical, 2 - warning
+ // Tank pressure
+ // Values above 0xFFF0 are special codes:
+ // 0xFFFF AI is off
+ // 0xFFFE No comms for 90 seconds+
+ // 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);
- if ((pressure & 0xFFF0) != 0xFFF0) {
+ if (pressure < 0xFFF0) {
pressure &= 0x0FFF;
sample.pressure.tank = 0;
sample.pressure.value = pressure * 2 * PSI / BAR;
if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
}
pressure = array_uint16_be (data + offset + 19);
- if ((pressure & 0xFFF0) != 0xFFF0) {
+ if (pressure < 0xFFF0) {
pressure &= 0x0FFF;
sample.pressure.tank = 1;
sample.pressure.value = pressure * 2 * PSI / BAR;
if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata);
}
+
// 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];
if (callback) callback (DC_SAMPLE_RBT, sample, userdata);
}
diff --git a/src/suunto_common2.c b/src/suunto_common2.c
index 80b2477..4aa1699 100644
--- a/src/suunto_common2.c
+++ b/src/suunto_common2.c
@@ -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 VTABLE(abstract) ((suunto_common2_device_vtable_t *) abstract->vtable)
+#define VTABLE(abstract) ((const suunto_common2_device_vtable_t *) abstract->vtable)
void
suunto_common2_device_init (suunto_common2_device_t *device)
diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c
index 0f656ad..f4dcc2b 100644
--- a/src/suunto_eonsteel.c
+++ b/src/suunto_eonsteel.c
@@ -31,8 +31,12 @@
#include "usbhid.h"
#include "platform.h"
+#define EONSTEEL 0
+#define EONCORE 1
+
typedef struct suunto_eonsteel_device_t {
dc_device_t base;
+ unsigned int model;
unsigned int magic;
unsigned short seq;
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_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 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, /* dump */
suunto_eonsteel_device_foreach, /* foreach */
- suunto_eonsteel_timesync, /* timesync */
+ suunto_eonsteel_device_timesync, /* timesync */
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;
// Set up the magic handshake fields
+ eon->model = model;
eon->magic = INIT_MAGIC;
eon->seq = INIT_SEQ;
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;
char pathname[64];
unsigned int time;
- unsigned int count = 0;
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
- if (get_file_list(eon, &de) < 0)
- return DC_STATUS_IO;
-
// Emit a device info event.
dc_event_devinfo_t devinfo;
- devinfo.model = 0;
+ devinfo.model = eon->model;
devinfo.firmware = array_uint32_be (eon->version + 0x20);
devinfo.serial = array_convert_str2num(eon->version + 0x10, 16);
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
- count = count_dir_entries(de);
- if (count == 0) {
+ if (get_file_list(eon, &de) < 0)
+ return DC_STATUS_IO;
+
+ if (de == NULL) {
return DC_STATUS_SUCCESS;
}
file = dc_buffer_new(0);
- progress.maximum = count;
+ progress.maximum = count_dir_entries(de);
progress.current = 0;
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;
}
-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;
- unsigned char result[64], cmd[64];
- int year, month, day;
- int hour, min, sec, msec;
+ unsigned char result[64], cmd[8];
+ unsigned int year, month, day;
+ unsigned int hour, min, msec;
int rc;
year = datetime->year;
@@ -903,23 +906,23 @@ static dc_status_t suunto_eonsteel_timesync(dc_device_t *abstract, const dc_date
day = datetime->day;
hour = datetime->hour;
min = datetime->minute;
- sec = datetime->second;
+ msec = datetime->second * 1000;
- INFO(eon->base.context, "SET_TIME: %d/%d/%d %d:%02d:%02d.%03d",
- year, month, day, hour, min, sec, msec);
-
- msec = sec * 1000;
-
- cmd[0] = year & 255;
+ cmd[0] = year & 0xFF;
cmd[1] = year >> 8;
cmd[2] = month;
cmd[3] = day;
cmd[4] = hour;
cmd[5] = min;
- cmd[6] = msec & 255;
+ cmd[6] = msec & 0xFF;
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
diff --git a/src/usbhid.c b/src/usbhid.c
index 06a6165..1b0931f 100644
--- a/src/usbhid.c
+++ b/src/usbhid.c
@@ -598,7 +598,7 @@ out:
}
#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:
if (actual)