Allow custom logbook and profile functions.

By adding the logbook and profile functions to the vtable, a dive
computer backend can now easily replace the default implementation with
a custom one, without having to duplicate the common code.
This commit is contained in:
Jef Driesen 2016-04-19 22:35:31 +02:00
parent 92f84b5945
commit 9bae07551f
5 changed files with 63 additions and 37 deletions

View File

@ -32,7 +32,7 @@
#include "ringbuffer.h" #include "ringbuffer.h"
#include "checksum.h" #include "checksum.h"
#define ISINSTANCE(device) dc_device_isinstance((device), &oceanic_atom2_device_vtable) #define ISINSTANCE(device) dc_device_isinstance((device), &oceanic_atom2_device_vtable.base)
#define VTX 0x4557 #define VTX 0x4557
@ -65,15 +65,19 @@ static dc_status_t oceanic_atom2_device_read (dc_device_t *abstract, unsigned in
static dc_status_t oceanic_atom2_device_write (dc_device_t *abstract, unsigned int address, const unsigned char data[], unsigned int size); static dc_status_t oceanic_atom2_device_write (dc_device_t *abstract, unsigned int address, const unsigned char data[], unsigned int size);
static dc_status_t oceanic_atom2_device_close (dc_device_t *abstract); static dc_status_t oceanic_atom2_device_close (dc_device_t *abstract);
static const dc_device_vtable_t oceanic_atom2_device_vtable = { static const oceanic_common_device_vtable_t oceanic_atom2_device_vtable = {
sizeof(oceanic_atom2_device_t), {
DC_FAMILY_OCEANIC_ATOM2, sizeof(oceanic_atom2_device_t),
oceanic_common_device_set_fingerprint, /* set_fingerprint */ DC_FAMILY_OCEANIC_ATOM2,
oceanic_atom2_device_read, /* read */ oceanic_common_device_set_fingerprint, /* set_fingerprint */
oceanic_atom2_device_write, /* write */ oceanic_atom2_device_read, /* read */
oceanic_common_device_dump, /* dump */ oceanic_atom2_device_write, /* write */
oceanic_common_device_foreach, /* foreach */ oceanic_common_device_dump, /* dump */
oceanic_atom2_device_close /* close */ oceanic_common_device_foreach, /* foreach */
oceanic_atom2_device_close /* close */
},
oceanic_common_device_logbook,
oceanic_common_device_profile,
}; };
static const oceanic_common_version_t aeris_f10_version[] = { static const oceanic_common_version_t aeris_f10_version[] = {
@ -544,7 +548,7 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
device = (oceanic_atom2_device_t *) dc_device_allocate (context, &oceanic_atom2_device_vtable); device = (oceanic_atom2_device_t *) dc_device_allocate (context, &oceanic_atom2_device_vtable.base);
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;

View File

@ -29,6 +29,8 @@
#include "ringbuffer.h" #include "ringbuffer.h"
#include "array.h" #include "array.h"
#define VTABLE(abstract) ((oceanic_common_device_vtable_t *) abstract->vtable)
#define RB_LOGBOOK_DISTANCE(a,b,l) ringbuffer_distance (a, b, 0, l->rb_logbook_begin, l->rb_logbook_end) #define RB_LOGBOOK_DISTANCE(a,b,l) ringbuffer_distance (a, b, 0, l->rb_logbook_begin, l->rb_logbook_end)
#define RB_LOGBOOK_INCR(a,b,l) ringbuffer_increment (a, b, l->rb_logbook_begin, l->rb_logbook_end) #define RB_LOGBOOK_INCR(a,b,l) ringbuffer_increment (a, b, l->rb_logbook_begin, l->rb_logbook_end)
@ -187,7 +189,7 @@ oceanic_common_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
} }
static dc_status_t dc_status_t
oceanic_common_device_logbook (dc_device_t *abstract, dc_event_progress_t *progress, dc_buffer_t *logbook) oceanic_common_device_logbook (dc_device_t *abstract, dc_event_progress_t *progress, dc_buffer_t *logbook)
{ {
oceanic_common_device_t *device = (oceanic_common_device_t *) abstract; oceanic_common_device_t *device = (oceanic_common_device_t *) abstract;
@ -408,7 +410,7 @@ oceanic_common_device_logbook (dc_device_t *abstract, dc_event_progress_t *progr
} }
static dc_status_t dc_status_t
oceanic_common_device_profile (dc_device_t *abstract, dc_event_progress_t *progress, dc_buffer_t *logbook, dc_dive_callback_t callback, void *userdata) oceanic_common_device_profile (dc_device_t *abstract, dc_event_progress_t *progress, dc_buffer_t *logbook, dc_dive_callback_t callback, void *userdata)
{ {
oceanic_common_device_t *device = (oceanic_common_device_t *) abstract; oceanic_common_device_t *device = (oceanic_common_device_t *) abstract;
@ -655,7 +657,7 @@ oceanic_common_device_foreach (dc_device_t *abstract, dc_dive_callback_t callbac
} }
// Download the logbook ringbuffer. // Download the logbook ringbuffer.
rc = oceanic_common_device_logbook (abstract, &progress, logbook); rc = VTABLE(abstract)->logbook (abstract, &progress, logbook);
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
dc_buffer_free (logbook); dc_buffer_free (logbook);
return rc; return rc;
@ -668,7 +670,7 @@ oceanic_common_device_foreach (dc_device_t *abstract, dc_dive_callback_t callbac
} }
// Download the profile ringbuffer. // Download the profile ringbuffer.
rc = oceanic_common_device_profile (abstract, &progress, logbook, callback, userdata); rc = VTABLE(abstract)->profile (abstract, &progress, logbook, callback, userdata);
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
dc_buffer_free (logbook); dc_buffer_free (logbook);
return rc; return rc;

View File

@ -65,6 +65,12 @@ typedef struct oceanic_common_device_t {
unsigned int multipage; unsigned int multipage;
} oceanic_common_device_t; } oceanic_common_device_t;
typedef struct oceanic_common_device_vtable_t {
dc_device_vtable_t base;
dc_status_t (*logbook) (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook);
dc_status_t (*profile) (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook, dc_dive_callback_t callback, void *userdata);
} oceanic_common_device_vtable_t;
typedef unsigned char oceanic_common_version_t[PAGESIZE + 1]; typedef unsigned char oceanic_common_version_t[PAGESIZE + 1];
int int
@ -73,6 +79,12 @@ oceanic_common_match (const unsigned char *version, const oceanic_common_version
void void
oceanic_common_device_init (oceanic_common_device_t *device); oceanic_common_device_init (oceanic_common_device_t *device);
dc_status_t
oceanic_common_device_logbook (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook);
dc_status_t
oceanic_common_device_profile (dc_device_t *device, dc_event_progress_t *progress, dc_buffer_t *logbook, dc_dive_callback_t callback, void *userdata);
dc_status_t dc_status_t
oceanic_common_device_set_fingerprint (dc_device_t *device, const unsigned char data[], unsigned int size); oceanic_common_device_set_fingerprint (dc_device_t *device, const unsigned char data[], unsigned int size);

View File

@ -31,7 +31,7 @@
#include "ringbuffer.h" #include "ringbuffer.h"
#include "checksum.h" #include "checksum.h"
#define ISINSTANCE(device) dc_device_isinstance((device), &oceanic_veo250_device_vtable) #define ISINSTANCE(device) dc_device_isinstance((device), &oceanic_veo250_device_vtable.base)
#define MAXRETRIES 2 #define MAXRETRIES 2
#define MULTIPAGE 4 #define MULTIPAGE 4
@ -48,15 +48,19 @@ typedef struct oceanic_veo250_device_t {
static dc_status_t oceanic_veo250_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size); static dc_status_t oceanic_veo250_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size);
static dc_status_t oceanic_veo250_device_close (dc_device_t *abstract); static dc_status_t oceanic_veo250_device_close (dc_device_t *abstract);
static const dc_device_vtable_t oceanic_veo250_device_vtable = { static const oceanic_common_device_vtable_t oceanic_veo250_device_vtable = {
sizeof(oceanic_veo250_device_t), {
DC_FAMILY_OCEANIC_VEO250, sizeof(oceanic_veo250_device_t),
oceanic_common_device_set_fingerprint, /* set_fingerprint */ DC_FAMILY_OCEANIC_VEO250,
oceanic_veo250_device_read, /* read */ oceanic_common_device_set_fingerprint, /* set_fingerprint */
NULL, /* write */ oceanic_veo250_device_read, /* read */
oceanic_common_device_dump, /* dump */ NULL, /* write */
oceanic_common_device_foreach, /* foreach */ oceanic_common_device_dump, /* dump */
oceanic_veo250_device_close /* close */ oceanic_common_device_foreach, /* foreach */
oceanic_veo250_device_close /* close */
},
oceanic_common_device_logbook,
oceanic_common_device_profile,
}; };
static const oceanic_common_version_t oceanic_vtpro_version[] = { static const oceanic_common_version_t oceanic_vtpro_version[] = {
@ -229,7 +233,7 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
device = (oceanic_veo250_device_t *) dc_device_allocate (context, &oceanic_veo250_device_vtable); device = (oceanic_veo250_device_t *) dc_device_allocate (context, &oceanic_veo250_device_vtable.base);
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;

View File

@ -31,7 +31,7 @@
#include "ringbuffer.h" #include "ringbuffer.h"
#include "checksum.h" #include "checksum.h"
#define ISINSTANCE(device) dc_device_isinstance((device), &oceanic_vtpro_device_vtable) #define ISINSTANCE(device) dc_device_isinstance((device), &oceanic_vtpro_device_vtable.base)
#define MAXRETRIES 2 #define MAXRETRIES 2
#define MULTIPAGE 4 #define MULTIPAGE 4
@ -48,15 +48,19 @@ typedef struct oceanic_vtpro_device_t {
static dc_status_t oceanic_vtpro_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size); static dc_status_t oceanic_vtpro_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size);
static dc_status_t oceanic_vtpro_device_close (dc_device_t *abstract); static dc_status_t oceanic_vtpro_device_close (dc_device_t *abstract);
static const dc_device_vtable_t oceanic_vtpro_device_vtable = { static const oceanic_common_device_vtable_t oceanic_vtpro_device_vtable = {
sizeof(oceanic_vtpro_device_t), {
DC_FAMILY_OCEANIC_VTPRO, sizeof(oceanic_vtpro_device_t),
oceanic_common_device_set_fingerprint, /* set_fingerprint */ DC_FAMILY_OCEANIC_VTPRO,
oceanic_vtpro_device_read, /* read */ oceanic_common_device_set_fingerprint, /* set_fingerprint */
NULL, /* write */ oceanic_vtpro_device_read, /* read */
oceanic_common_device_dump, /* dump */ NULL, /* write */
oceanic_common_device_foreach, /* foreach */ oceanic_common_device_dump, /* dump */
oceanic_vtpro_device_close /* close */ oceanic_common_device_foreach, /* foreach */
oceanic_vtpro_device_close /* close */
},
oceanic_common_device_logbook,
oceanic_common_device_profile,
}; };
static const oceanic_common_version_t oceanic_vtpro_version[] = { static const oceanic_common_version_t oceanic_vtpro_version[] = {
@ -260,7 +264,7 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
device = (oceanic_vtpro_device_t *) dc_device_allocate (context, &oceanic_vtpro_device_vtable); device = (oceanic_vtpro_device_t *) dc_device_allocate (context, &oceanic_vtpro_device_vtable.base);
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;