Add fingerprint support for the Suunto Vyper, Spyder and Eon.
This commit is contained in:
parent
a2ccc4926d
commit
3885e69079
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user