Added the foreach() function for the Suunto Solution.

This commit is contained in:
Jef Driesen 2008-12-23 18:20:33 +00:00
parent c509fe9343
commit a04b9e75c6
3 changed files with 80 additions and 1 deletions

View File

@ -56,6 +56,7 @@ reefnet_sensusultra_extract_dives
suunto_d9_device_open
suunto_d9_device_reset_maxdepth
suunto_solution_device_open
suunto_solution_extract_dives
suunto_eon_device_open
suunto_eon_device_write_interval
suunto_eon_device_write_name

View File

@ -20,9 +20,11 @@
*/
#include <stdlib.h> // malloc, free
#include <assert.h> // assert
#include "device-private.h"
#include "suunto_solution.h"
#include "ringbuffer.h"
#include "serial.h"
#include "utils.h"
@ -36,6 +38,9 @@
rc == -1 ? DEVICE_STATUS_IO : DEVICE_STATUS_TIMEOUT \
)
#define RB_PROFILE_BEGIN 0x020
#define RB_PROFILE_END 0x100
typedef struct suunto_solution_device_t suunto_solution_device_t;
struct suunto_solution_device_t {
@ -44,6 +49,7 @@ struct suunto_solution_device_t {
};
static device_status_t suunto_solution_device_dump (device_t *abstract, unsigned char data[], unsigned int size, unsigned int *result);
static device_status_t suunto_solution_device_foreach (device_t *abstract, dive_callback_t callback, void *userdata);
static device_status_t suunto_solution_device_close (device_t *abstract);
static const device_backend_t suunto_solution_device_backend = {
@ -53,7 +59,7 @@ static const device_backend_t suunto_solution_device_backend = {
NULL, /* read */
NULL, /* write */
suunto_solution_device_dump, /* dump */
NULL, /* foreach */
suunto_solution_device_foreach, /* foreach */
suunto_solution_device_close /* close */
};
@ -228,3 +234,72 @@ suunto_solution_device_dump (device_t *abstract, unsigned char data[], unsigned
return DEVICE_STATUS_SUCCESS;
}
static device_status_t
suunto_solution_device_foreach (device_t *abstract, dive_callback_t callback, void *userdata)
{
if (! device_is_suunto_solution (abstract))
return DEVICE_STATUS_TYPE_MISMATCH;
unsigned char data[SUUNTO_SOLUTION_MEMORY_SIZE] = {0};
device_status_t rc = suunto_solution_device_dump (abstract, data, sizeof (data), NULL);
if (rc != DEVICE_STATUS_SUCCESS)
return rc;
return suunto_solution_extract_dives (data, sizeof (data), callback, userdata);
}
device_status_t
suunto_solution_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata)
{
assert (size >= SUUNTO_SOLUTION_MEMORY_SIZE);
unsigned char buffer[RB_PROFILE_END - RB_PROFILE_BEGIN] = {0};
// Get the end of the profile ring buffer.
unsigned int eop = data[0x18];
assert (eop >= RB_PROFILE_BEGIN && eop < RB_PROFILE_END);
assert (data[eop] == 0x82);
// The profile data is stored backwards in the ringbuffer. To locate
// the most recent dive, we start from the end of profile marker and
// traverse the ringbuffer in the opposite direction (forwards).
// Since the profile data is now processed in the "wrong" direction,
// it needs to be reversed again.
unsigned int previous = eop;
unsigned int current = eop;
for (unsigned int i = 0; i < RB_PROFILE_END - RB_PROFILE_BEGIN; ++i) {
// Move forwards through the ringbuffer.
current++;
if (current == RB_PROFILE_END)
current = RB_PROFILE_BEGIN;
// Check for an end of profile marker.
if (data[current] == 0x82)
break;
// Store the current byte into the buffer. By starting at the
// end of the buffer, the data is automatically reversed.
unsigned int idx = RB_PROFILE_END - RB_PROFILE_BEGIN - i - 1;
buffer[idx] = data[current];
// Check for an end of dive marker (of the next dive),
// to find the start of the current dive.
unsigned int peek = ringbuffer_increment (current, 2, RB_PROFILE_BEGIN, RB_PROFILE_END);
if (data[peek] == 0x80) {
unsigned int len = ringbuffer_distance (previous, current, RB_PROFILE_BEGIN, RB_PROFILE_END);
if (callback && !callback (buffer + idx, len, userdata))
return DEVICE_STATUS_SUCCESS;
previous = current;
}
}
assert (data[current] == 0x82);
return DEVICE_STATUS_SUCCESS;
}

View File

@ -33,6 +33,9 @@ extern "C" {
device_status_t
suunto_solution_device_open (device_t **device, const char* name);
device_status_t
suunto_solution_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
#ifdef __cplusplus
}
#endif /* __cplusplus */