From a24fd313ae3d98c2eb633b5170db58a667638341 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 7 Sep 2010 22:52:05 +0200 Subject: [PATCH] Add the foreach function for the Mares Icon HD. Note that this implementation will fail if the ringbuffer doesn't start at the fixed address 0xA000. This is very likely to occur once the ringbuffer is filled completely and the device starts to overwrite old data. --- src/libdivecomputer.symbols | 1 + src/mares_iconhd.c | 70 ++++++++++++++++++++++++++++++++++++- src/mares_iconhd.h | 3 ++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/libdivecomputer.symbols b/src/libdivecomputer.symbols index 3b4612f..be3d1a8 100644 --- a/src/libdivecomputer.symbols +++ b/src/libdivecomputer.symbols @@ -62,6 +62,7 @@ mares_nemo_extract_dives mares_puck_device_open mares_puck_extract_dives mares_iconhd_device_open +mares_iconhd_extract_dives oceanic_atom2_device_open oceanic_atom2_device_keepalive oceanic_veo250_device_open diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index 1aabdd2..4782e38 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -26,6 +26,7 @@ #include "device-private.h" #include "mares_iconhd.h" #include "serial.h" +#include "array.h" #include "utils.h" #define EXITCODE(rc) \ @@ -39,6 +40,7 @@ typedef struct mares_iconhd_device_t { } mares_iconhd_device_t; static device_status_t mares_iconhd_device_dump (device_t *abstract, dc_buffer_t *buffer); +static device_status_t mares_iconhd_device_foreach (device_t *abstract, dive_callback_t callback, void *userdata); static device_status_t mares_iconhd_device_close (device_t *abstract); static const device_backend_t mares_iconhd_device_backend = { @@ -48,7 +50,7 @@ static const device_backend_t mares_iconhd_device_backend = { NULL, /* read */ NULL, /* write */ mares_iconhd_device_dump, /* dump */ - NULL, /* foreach */ + mares_iconhd_device_foreach, /* foreach */ mares_iconhd_device_close /* close */ }; @@ -245,3 +247,69 @@ mares_iconhd_device_dump (device_t *abstract, dc_buffer_t *buffer) return DEVICE_STATUS_SUCCESS; } + + +static device_status_t +mares_iconhd_device_foreach (device_t *abstract, dive_callback_t callback, void *userdata) +{ + dc_buffer_t *buffer = dc_buffer_new (MARES_ICONHD_MEMORY_SIZE); + if (buffer == NULL) + return DEVICE_STATUS_MEMORY; + + device_status_t rc = mares_iconhd_device_dump (abstract, buffer); + if (rc != DEVICE_STATUS_SUCCESS) { + dc_buffer_free (buffer); + return rc; + } + + rc = mares_iconhd_extract_dives (abstract, dc_buffer_get_data (buffer), + dc_buffer_get_size (buffer), callback, userdata); + + dc_buffer_free (buffer); + + return rc; +} + + +device_status_t +mares_iconhd_extract_dives (device_t *abstract, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata) +{ + if (abstract && !device_is_mares_iconhd (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; + + if (size < MARES_ICONHD_MEMORY_SIZE) + return DEVICE_STATUS_ERROR; + + unsigned int ndives = 0; + unsigned int offset = 0xA000; + while (offset + 4 <= MARES_ICONHD_MEMORY_SIZE) { + // Get the length of the profile data. + unsigned int len = array_uint32_le (data + offset); + if (len == 0xFFFFFFFF) + break; + + offset += len; + ndives++; + } + + for (unsigned int i = 0; i < ndives; ++i) { + // Skip the older dives. + unsigned int offset = 0xA000; + unsigned int skip = ndives - i - 1; + while (skip) { + // Get the length of the profile data. + unsigned int len = array_uint32_le (data + offset); + // Move to the next dive. + offset += len; + skip--; + } + + // Get the length of the profile data. + unsigned int length = array_uint32_le (data + offset); + + if (callback && !callback (data + offset, length, NULL, 0, userdata)) + return DEVICE_STATUS_SUCCESS; + } + + return DEVICE_STATUS_SUCCESS; +} diff --git a/src/mares_iconhd.h b/src/mares_iconhd.h index 927a9df..41b8780 100644 --- a/src/mares_iconhd.h +++ b/src/mares_iconhd.h @@ -34,6 +34,9 @@ extern "C" { device_status_t mares_iconhd_device_open (device_t **device, const char* name); +device_status_t +mares_iconhd_extract_dives (device_t *abstract, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata); + parser_status_t mares_iconhd_parser_create (parser_t **parser);