Add fingerprint support for the Suunto Vyper, Spyder and Eon.

This commit is contained in:
Jef Driesen 2009-02-23 13:04:26 +00:00
parent a2ccc4926d
commit 3885e69079
6 changed files with 104 additions and 13 deletions

View File

@ -27,7 +27,7 @@
device_status_t
suunto_common_extract_dives (const unsigned char data[], unsigned int begin, unsigned int end, unsigned int eop, unsigned int peek, dive_callback_t callback, void *userdata)
suunto_common_extract_dives (device_t *device, const unsigned char data[], unsigned int begin, unsigned int end, unsigned int eop, unsigned int peek, fp_compare_t fp_compare, dive_callback_t callback, void *userdata)
{
assert (eop >= begin && eop < end);
assert (data[eop] == 0x82);
@ -61,6 +61,9 @@ suunto_common_extract_dives (const unsigned char data[], unsigned int begin, uns
memcpy (buffer, data + current, len);
}
if (device && fp_compare && fp_compare (device, buffer, len) == 0)
return DEVICE_STATUS_SUCCESS;
if (callback && !callback (buffer, len, userdata))
return DEVICE_STATUS_SUCCESS;

View File

@ -22,14 +22,16 @@
#ifndef SUUNTO_COMMON_H
#define SUUNTO_COMMON_H
#include "device.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "device.h"
typedef int (*fp_compare_t) (device_t *device, const unsigned char data[], unsigned int size);
device_status_t
suunto_common_extract_dives (const unsigned char data[], unsigned int begin, unsigned int end, unsigned int eop, unsigned int peek, dive_callback_t callback, void *userdata);
suunto_common_extract_dives (device_t *device, const unsigned char data[], unsigned int begin, unsigned int end, unsigned int eop, unsigned int peek, fp_compare_t fp_compare, dive_callback_t callback, void *userdata);
#ifdef __cplusplus
}

View File

@ -40,20 +40,25 @@
rc == -1 ? DEVICE_STATUS_IO : DEVICE_STATUS_TIMEOUT \
)
#define FP_OFFSET 6
#define FP_SIZE 5
typedef struct suunto_eon_device_t suunto_eon_device_t;
struct suunto_eon_device_t {
device_t base;
struct serial *port;
unsigned char fingerprint[FP_SIZE];
};
static device_status_t suunto_eon_device_set_fingerprint (device_t *abstract, const unsigned char data[], unsigned int size);
static device_status_t suunto_eon_device_dump (device_t *abstract, unsigned char data[], unsigned int size, unsigned int *result);
static device_status_t suunto_eon_device_foreach (device_t *abstract, dive_callback_t callback, void *userdata);
static device_status_t suunto_eon_device_close (device_t *abstract);
static const device_backend_t suunto_eon_device_backend = {
DEVICE_TYPE_SUUNTO_EON,
NULL, /* set_fingerprint */
suunto_eon_device_set_fingerprint, /* set_fingerprint */
NULL, /* handshake */
NULL, /* version */
NULL, /* read */
@ -91,6 +96,7 @@ suunto_eon_device_open (device_t **out, const char* name)
// Set the default values.
device->port = NULL;
memset (device->fingerprint, 0, FP_SIZE);
// Open the device.
int rc = serial_open (&device->port, name);
@ -152,6 +158,26 @@ suunto_eon_device_close (device_t *abstract)
}
static device_status_t
suunto_eon_device_set_fingerprint (device_t *abstract, const unsigned char data[], unsigned int size)
{
suunto_eon_device_t *device = (suunto_eon_device_t*) abstract;
if (! device_is_suunto_eon (abstract))
return DEVICE_STATUS_TYPE_MISMATCH;
if (size && size != FP_SIZE)
return DEVICE_STATUS_ERROR;
if (size)
memcpy (device->fingerprint, data, FP_SIZE);
else
memset (device->fingerprint, 0, FP_SIZE);
return DEVICE_STATUS_SUCCESS;
}
static device_status_t
suunto_eon_device_dump (device_t *abstract, unsigned char data[], unsigned int size, unsigned int *result)
{
@ -223,7 +249,7 @@ suunto_eon_device_foreach (device_t *abstract, dive_callback_t callback, void *u
devinfo.serial = (data[244 + 0] << 16) + (data[244 + 1] << 8) + data[244 + 2];
device_event_emit (abstract, DEVICE_EVENT_DEVINFO, &devinfo);
return suunto_eon_extract_dives (data, sizeof (data), callback, userdata);
return suunto_eon_extract_dives (abstract, data, sizeof (data), callback, userdata);
}
@ -271,8 +297,17 @@ suunto_eon_device_write_interval (device_t *abstract, unsigned char interval)
}
static int
fp_compare (device_t *abstract, const unsigned char data[], unsigned int size)
{
suunto_eon_device_t *device = (suunto_eon_device_t*) abstract;
return memcmp (data + FP_OFFSET, device->fingerprint, FP_SIZE);
}
device_status_t
suunto_eon_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata)
suunto_eon_extract_dives (device_t *abstract, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata)
{
assert (size >= SUUNTO_EON_MEMORY_SIZE);
@ -285,5 +320,5 @@ suunto_eon_extract_dives (const unsigned char data[], unsigned int size, dive_ca
eop++;
}
return suunto_common_extract_dives (data, 0x100, SUUNTO_EON_MEMORY_SIZE, eop, 3, callback, userdata);
return suunto_common_extract_dives (abstract, data, 0x100, SUUNTO_EON_MEMORY_SIZE, eop, 3, fp_compare, callback, userdata);
}

View File

@ -40,7 +40,7 @@ device_status_t
suunto_eon_device_write_interval (device_t *device, unsigned char interval);
device_status_t
suunto_eon_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
suunto_eon_extract_dives (device_t *device, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
#ifdef __cplusplus
}

View File

@ -44,14 +44,20 @@
#define HDR_DEVINFO_BEGIN (HDR_DEVINFO_SPYDER)
#define HDR_DEVINFO_END (HDR_DEVINFO_VYPER + 6)
#define FP_OFFSET_VYPER 9
#define FP_OFFSET_SPYDER 7
#define FP_SIZE 5
typedef struct suunto_vyper_device_t suunto_vyper_device_t;
struct suunto_vyper_device_t {
device_t base;
struct serial *port;
unsigned int delay;
unsigned char fingerprint[FP_SIZE];
};
static device_status_t suunto_vyper_device_set_fingerprint (device_t *abstract, const unsigned char data[], unsigned int size);
static device_status_t suunto_vyper_device_read (device_t *abstract, unsigned int address, unsigned char data[], unsigned int size);
static device_status_t suunto_vyper_device_write (device_t *abstract, unsigned int address, const unsigned char data[], unsigned int size);
static device_status_t suunto_vyper_device_dump (device_t *abstract, unsigned char data[], unsigned int size, unsigned int *result);
@ -60,7 +66,7 @@ static device_status_t suunto_vyper_device_close (device_t *abstract);
static const device_backend_t suunto_vyper_device_backend = {
DEVICE_TYPE_SUUNTO_VYPER,
NULL, /* set_fingerprint */
suunto_vyper_device_set_fingerprint, /* set_fingerprint */
NULL, /* handshake */
NULL, /* version */
suunto_vyper_device_read, /* read */
@ -99,6 +105,7 @@ suunto_vyper_device_open (device_t **out, const char* name)
// Set the default values.
device->port = NULL;
device->delay = 500;
memset (device->fingerprint, 0, FP_SIZE);
// Open the device.
int rc = serial_open (&device->port, name);
@ -180,6 +187,26 @@ suunto_vyper_device_set_delay (device_t *abstract, unsigned int delay)
}
static device_status_t
suunto_vyper_device_set_fingerprint (device_t *abstract, const unsigned char data[], unsigned int size)
{
suunto_vyper_device_t *device = (suunto_vyper_device_t*) abstract;
if (! device_is_suunto_vyper (abstract))
return DEVICE_STATUS_TYPE_MISMATCH;
if (size && size != FP_SIZE)
return DEVICE_STATUS_ERROR;
if (size)
memcpy (device->fingerprint, data, FP_SIZE);
else
memset (device->fingerprint, 0, FP_SIZE);
return DEVICE_STATUS_SUCCESS;
}
static device_status_t
suunto_vyper_send (suunto_vyper_device_t *device, const unsigned char command[], unsigned int csize)
{
@ -540,6 +567,8 @@ suunto_vyper_device_dump (device_t *abstract, unsigned char data[], unsigned int
static device_status_t
suunto_vyper_device_foreach (device_t *abstract, dive_callback_t callback, void *userdata)
{
suunto_vyper_device_t *device = (suunto_vyper_device_t*) abstract;
if (! device_is_suunto_vyper (abstract))
return DEVICE_STATUS_TYPE_MISMATCH;
@ -598,6 +627,10 @@ suunto_vyper_device_foreach (device_t *abstract, dive_callback_t callback, void
if (nbytes == 0)
return DEVICE_STATUS_SUCCESS;
unsigned int fp_offset = (vyper ? FP_OFFSET_VYPER : FP_OFFSET_SPYDER);
if (memcmp (data + offset + fp_offset, device->fingerprint, FP_SIZE) == 0)
return DEVICE_STATUS_SUCCESS;
if (callback && !callback (data + offset, nbytes, userdata))
return DEVICE_STATUS_SUCCESS;
@ -609,8 +642,26 @@ suunto_vyper_device_foreach (device_t *abstract, dive_callback_t callback, void
}
static int
fp_compare_vyper (device_t *abstract, const unsigned char data[], unsigned int size)
{
suunto_vyper_device_t *device = (suunto_vyper_device_t*) abstract;
return memcmp (data + FP_OFFSET_VYPER, device->fingerprint, FP_SIZE);
}
static int
fp_compare_spyder (device_t *abstract, const unsigned char data[], unsigned int size)
{
suunto_vyper_device_t *device = (suunto_vyper_device_t*) abstract;
return memcmp (data + FP_OFFSET_SPYDER, device->fingerprint, FP_SIZE);
}
device_status_t
suunto_vyper_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata)
suunto_vyper_extract_dives (device_t *abstract, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata)
{
assert (size >= SUUNTO_VYPER_MEMORY_SIZE);
@ -620,9 +671,9 @@ suunto_vyper_extract_dives (const unsigned char data[], unsigned int size, dive_
if (vyper) {
unsigned int eop = (data[0x51] << 8) + data[0x52];
return suunto_common_extract_dives (data, 0x71, SUUNTO_VYPER_MEMORY_SIZE, eop, 5, callback, userdata);
return suunto_common_extract_dives (abstract, data, 0x71, SUUNTO_VYPER_MEMORY_SIZE, eop, 5, fp_compare_vyper, callback, userdata);
} else {
unsigned int eop = (data[0x1C] << 8) + data[0x1D];
return suunto_common_extract_dives (data, 0x4C, SUUNTO_VYPER_MEMORY_SIZE, eop, 3, callback, userdata);
return suunto_common_extract_dives (abstract, data, 0x4C, SUUNTO_VYPER_MEMORY_SIZE, eop, 3, fp_compare_spyder, callback, userdata);
}
}

View File

@ -42,7 +42,7 @@ device_status_t
suunto_vyper_device_read_dive (device_t *device, unsigned char data[], unsigned int size, unsigned int *result, int init);
device_status_t
suunto_vyper_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
suunto_vyper_extract_dives (device_t *device, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
parser_status_t
suunto_vyper_parser_create (parser_t **parser);