From ed21d776ddecb68e8c42506808e6310a97b700e7 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Fri, 30 Nov 2018 19:23:53 +0100 Subject: [PATCH 1/4] Fix undefined behaviour in left shifts Due to the integer promotion rules of the C language, the unsigned char values are promoted to a signed integer (and not an unsigned integer) before being shifted. But the result of a left shift on a signed type is undefined if the resulting value can't be represented in the signed type. GCC's Undefined Behavior Sanitizer (ubsan), enabled with the option -fsanitize=undefined, detects this type of problem at runtime with the following warning: "left shift of X by Y places cannot be represented in type 'int'". Fixed with an explicit cast to unsigned integer. --- src/array.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/array.c b/src/array.c index 5574083..de15bc1 100644 --- a/src/array.c +++ b/src/array.c @@ -167,7 +167,7 @@ array_uint_be (const unsigned char data[], unsigned int n) unsigned int value = 0; for (unsigned int i = 0; i < n; ++i) { shift -= 8; - value |= data[i] << shift; + value |= (unsigned int) data[i] << shift; } return value; } @@ -178,7 +178,7 @@ array_uint_le (const unsigned char data[], unsigned int n) unsigned int shift = 0; unsigned int value = 0; for (unsigned int i = 0; i < n; ++i) { - value |= data[i] << shift; + value |= (unsigned int) data[i] << shift; shift += 8; } return value; @@ -187,21 +187,30 @@ array_uint_le (const unsigned char data[], unsigned int n) unsigned int array_uint32_be (const unsigned char data[]) { - return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; + return ((unsigned int) data[0] << 24) | + ((unsigned int) data[1] << 16) | + ((unsigned int) data[2] << 8) | + ((unsigned int) data[3] << 0); } unsigned int array_uint32_le (const unsigned char data[]) { - return data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24); + return ((unsigned int) data[0] << 0) | + ((unsigned int) data[1] << 8) | + ((unsigned int) data[2] << 16) | + ((unsigned int) data[3] << 24); } unsigned int array_uint32_word_be (const unsigned char data[]) { - return data[1] + (data[0] << 8) + (data[3] << 16) + (data[2] << 24); + return ((unsigned int) data[0] << 8) | + ((unsigned int) data[1] << 0) | + ((unsigned int) data[2] << 24) | + ((unsigned int) data[3] << 16); } @@ -218,7 +227,9 @@ array_uint32_le_set (unsigned char data[], const unsigned int input) unsigned int array_uint24_be (const unsigned char data[]) { - return (data[0] << 16) + (data[1] << 8) + data[2]; + return ((unsigned int) data[0] << 16) | + ((unsigned int) data[1] << 8) | + ((unsigned int) data[2] << 0); } @@ -234,20 +245,24 @@ array_uint24_be_set (unsigned char data[], const unsigned int input) unsigned int array_uint24_le (const unsigned char data[]) { - return data[0] + (data[1] << 8) + (data[2] << 16); + return ((unsigned int) data[0] << 0) | + ((unsigned int) data[1] << 8) | + ((unsigned int) data[2] << 16); } unsigned short array_uint16_be (const unsigned char data[]) { - return (data[0] << 8) + data[1]; + return ((unsigned int) data[0] << 8) | + ((unsigned int) data[1] << 0); } unsigned short array_uint16_le (const unsigned char data[]) { - return data[0] + (data[1] << 8); + return ((unsigned int) data[0] << 0) | + ((unsigned int) data[1] << 8); } unsigned char From ab522a4a528b7afb82f8ec8fde47b77c53ead30b Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Wed, 5 Dec 2018 19:34:59 +0100 Subject: [PATCH 2/4] Increase the internal log buffer The Atomic Aquatics Cobalt backend uses 8K data packets. Since a hexdump of such a data packet needs at least twice the size of the binary data, the internal log buffer should be increased to 16K bytes. --- src/context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context.c b/src/context.c index 58009e1..63824a5 100644 --- a/src/context.c +++ b/src/context.c @@ -41,7 +41,7 @@ struct dc_context_t { dc_logfunc_t logfunc; void *userdata; #ifdef ENABLE_LOGGING - char msg[8192 + 32]; + char msg[16384 + 32]; dc_timer_t *timer; #endif }; From 0d3d34a5c91e61341d5d200dea40fd248cb3c60a Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Wed, 5 Dec 2018 19:55:14 +0100 Subject: [PATCH 3/4] Use the travis homebrew plugin to install packages --- .travis.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 10e3edd..e4ef812 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,11 +37,10 @@ addons: packages: - libbluetooth-dev - libusb-1.0-0-dev - -install: - - if [ "$TRAVIS_OS_NAME" = "osx" ]; then - brew install hidapi libusb; - fi + homebrew: + packages: + - hidapi + - libusb script: - case $CC in From c622998fb1c813fb91cec3e812f86a29a467f229 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 9 Dec 2018 10:43:40 +0100 Subject: [PATCH 4/4] Fix the Cobalt 2 memory size The Cobalt 2 has a bit more flash memory available for storing dives compared to the original Cobalt 1. This larger amount of memory can cause the progress events to exceed past 100% if there are many dives present. This will trigger the assert in the event code and crash the application. --- src/atomics_cobalt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/atomics_cobalt.c b/src/atomics_cobalt.c index 21d5896..e907b77 100644 --- a/src/atomics_cobalt.c +++ b/src/atomics_cobalt.c @@ -43,13 +43,17 @@ #define EXITCODE(rc) (rc == LIBUSB_ERROR_TIMEOUT ? DC_STATUS_TIMEOUT : DC_STATUS_IO) +#define COBALT1 0 +#define COBALT2 2 + #define VID 0x0471 #define PID 0x0888 #define TIMEOUT 2000 #define FP_OFFSET 20 -#define SZ_MEMORY (29 * 64 * 1024) +#define SZ_MEMORY1 (29 * 64 * 1024) // Cobalt 1 +#define SZ_MEMORY2 (41 * 64 * 1024) // Cobalt 2 #define SZ_VERSION 14 typedef struct atomics_cobalt_device_t { @@ -350,9 +354,12 @@ atomics_cobalt_device_foreach (dc_device_t *abstract, dc_dive_callback_t callbac { atomics_cobalt_device_t *device = (atomics_cobalt_device_t *) abstract; + // Get the model number. + unsigned int model = array_uint16_le (device->version + 12); + // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; - progress.maximum = SZ_MEMORY + 2; + progress.maximum = (model == COBALT2 ? SZ_MEMORY2 : SZ_MEMORY1) + 2; device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); // Emit a vendor event.