diff --git a/src/suunto_common.c b/src/suunto_common.c index 512e11f..7f58923 100644 --- a/src/suunto_common.c +++ b/src/suunto_common.c @@ -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; diff --git a/src/suunto_common.h b/src/suunto_common.h index 3682e04..0bc279c 100644 --- a/src/suunto_common.h +++ b/src/suunto_common.h @@ -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 } diff --git a/src/suunto_eon.c b/src/suunto_eon.c index 18e2ab1..39932ca 100644 --- a/src/suunto_eon.c +++ b/src/suunto_eon.c @@ -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); } diff --git a/src/suunto_eon.h b/src/suunto_eon.h index 710a647..57ef690 100644 --- a/src/suunto_eon.h +++ b/src/suunto_eon.h @@ -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 } diff --git a/src/suunto_vyper.c b/src/suunto_vyper.c index 5462ef8..db988e3 100644 --- a/src/suunto_vyper.c +++ b/src/suunto_vyper.c @@ -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); } } diff --git a/src/suunto_vyper.h b/src/suunto_vyper.h index 16cafc3..1764027 100644 --- a/src/suunto_vyper.h +++ b/src/suunto_vyper.h @@ -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);