diff --git a/examples/uwatec_aladin_test.c b/examples/uwatec_aladin_test.c index 6669d9f..14fcbf1 100644 --- a/examples/uwatec_aladin_test.c +++ b/examples/uwatec_aladin_test.c @@ -1,6 +1,6 @@ #include // fopen, fwrite, fclose -#include "uwatec.h" +#include "uwatec_aladin.h" #include "utils.h" #define WARNING(expr) \ @@ -11,21 +11,21 @@ int test_dump_memory (const char* name, const char* filename) { - aladin *device = NULL; + device_t *device = NULL; unsigned char data[UWATEC_ALADIN_MEMORY_SIZE] = {0}; - message ("uwatec_aladin_open\n"); - int rc = uwatec_aladin_open (&device, name); - if (rc != UWATEC_SUCCESS) { + message ("uwatec_aladin_device_open\n"); + int rc = uwatec_aladin_device_open (&device, name); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Error opening serial port."); return rc; } - message ("uwatec_aladin_read\n"); - rc = uwatec_aladin_read (device, data, sizeof (data)); - if (rc != UWATEC_SUCCESS) { + message ("device_download\n"); + rc = device_download (device, data, sizeof (data)); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot read memory."); - uwatec_aladin_close (device); + device_close (device); return rc; } @@ -36,31 +36,35 @@ int test_dump_memory (const char* name, const char* filename) fclose (fp); } - message ("uwatec_aladin_close\n"); - rc = uwatec_aladin_close (device); - if (rc != UWATEC_SUCCESS) { + message ("device_close\n"); + rc = device_close (device); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot close device."); return rc; } - return UWATEC_SUCCESS; + return DEVICE_STATUS_SUCCESS; } const char* errmsg (int rc) { switch (rc) { - case UWATEC_SUCCESS: + case DEVICE_STATUS_SUCCESS: return "Success"; - case UWATEC_ERROR: + case DEVICE_STATUS_UNSUPPORTED: + return "Unsupported operation"; + case DEVICE_STATUS_TYPE_MISMATCH: + return "Device type mismatch"; + case DEVICE_STATUS_ERROR: return "Generic error"; - case UWATEC_ERROR_IO: + case DEVICE_STATUS_IO: return "Input/output error"; - case UWATEC_ERROR_MEMORY: + case DEVICE_STATUS_MEMORY: return "Memory error"; - case UWATEC_ERROR_PROTOCOL: + case DEVICE_STATUS_PROTOCOL: return "Protocol error"; - case UWATEC_ERROR_TIMEOUT: + case DEVICE_STATUS_TIMEOUT: return "Timeout"; default: return "Unknown error"; diff --git a/src/device.h b/src/device.h index 082dd92..61cfd56 100644 --- a/src/device.h +++ b/src/device.h @@ -12,7 +12,8 @@ typedef enum device_type_t { DEVICE_TYPE_SUUNTO_VYPER2, DEVICE_TYPE_SUUNTO_D9, DEVICE_TYPE_REEFNET_SENSUSPRO, - DEVICE_TYPE_REEFNET_SENSUSULTRA + DEVICE_TYPE_REEFNET_SENSUSULTRA, + DEVICE_TYPE_UWATEC_ALADIN } device_type_t; typedef enum device_status_t { diff --git a/src/uwatec.h b/src/uwatec.h index 252ec37..f9ddb3c 100644 --- a/src/uwatec.h +++ b/src/uwatec.h @@ -1,6 +1,8 @@ #ifndef UWATEC_H #define UWATEC_H +#include "device.h" + #define UWATEC_SUCCESS 0 #define UWATEC_ERROR -1 #define UWATEC_ERROR_IO -2 @@ -8,8 +10,6 @@ #define UWATEC_ERROR_PROTOCOL -4 #define UWATEC_ERROR_TIMEOUT -5 -typedef void (*dive_callback_t) (const unsigned char *data, unsigned int size, void *userdata); - #include "uwatec_aladin.h" #include "uwatec_memomouse.h" #include "uwatec_smart.h" diff --git a/src/uwatec_aladin.c b/src/uwatec_aladin.c index aa08370..b0a04da 100644 --- a/src/uwatec_aladin.c +++ b/src/uwatec_aladin.c @@ -1,7 +1,8 @@ #include // malloc, free #include // memcpy -#include "uwatec.h" +#include "device-private.h" +#include "uwatec_aladin.h" #include "serial.h" #include "utils.h" #include "ringbuffer.h" @@ -13,30 +14,46 @@ #define EXITCODE(rc) \ ( \ - rc == -1 ? UWATEC_ERROR_IO : UWATEC_ERROR_TIMEOUT \ + rc == -1 ? DEVICE_STATUS_IO : DEVICE_STATUS_TIMEOUT \ ) #define DISTANCE(a,b) ringbuffer_distance (a, b, 0, 0x600) -struct aladin { + +typedef struct uwatec_aladin_device_t uwatec_aladin_device_t; + +struct uwatec_aladin_device_t { + device_t base; struct serial *port; }; +static const device_backend_t uwatec_aladin_device_backend; -int -uwatec_aladin_open (aladin **out, const char* name) +static int +device_is_uwatec_aladin (device_t *abstract) +{ + if (abstract == NULL) + return 0; + + return abstract->backend == &uwatec_aladin_device_backend; +} + + +device_status_t +uwatec_aladin_device_open (device_t **out, const char* name) { if (out == NULL) - return UWATEC_ERROR; + return DEVICE_STATUS_ERROR; // Allocate memory. - struct aladin *device = malloc (sizeof (struct aladin)); + uwatec_aladin_device_t *device = malloc (sizeof (uwatec_aladin_device_t)); if (device == NULL) { WARNING ("Failed to allocate memory."); - return UWATEC_ERROR_MEMORY; + return DEVICE_STATUS_MEMORY; } // Set the default values. + device->base.backend = &uwatec_aladin_device_backend; device->port = NULL; // Open the device. @@ -44,7 +61,7 @@ uwatec_aladin_open (aladin **out, const char* name) if (rc == -1) { WARNING ("Failed to open the serial port."); free (device); - return UWATEC_ERROR_IO; + return DEVICE_STATUS_IO; } // Set the serial communication protocol (19200 8N1). @@ -53,7 +70,7 @@ uwatec_aladin_open (aladin **out, const char* name) WARNING ("Failed to set the terminal attributes."); serial_close (device->port); free (device); - return UWATEC_ERROR_IO; + return DEVICE_STATUS_IO; } // Set the timeout for receiving data (INFINITE). @@ -61,7 +78,7 @@ uwatec_aladin_open (aladin **out, const char* name) WARNING ("Failed to set the timeout."); serial_close (device->port); free (device); - return UWATEC_ERROR_IO; + return DEVICE_STATUS_IO; } // Clear the RTS line and set the DTR line. @@ -70,31 +87,33 @@ uwatec_aladin_open (aladin **out, const char* name) WARNING ("Failed to set the DTR/RTS line."); serial_close (device->port); free (device); - return UWATEC_ERROR_IO; + return DEVICE_STATUS_IO; } - *out = device; + *out = (device_t*) device; - return UWATEC_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int -uwatec_aladin_close (aladin *device) +static device_status_t +uwatec_aladin_device_close (device_t *abstract) { - if (device == NULL) - return UWATEC_SUCCESS; + uwatec_aladin_device_t *device = (uwatec_aladin_device_t*) abstract; + + if (! device_is_uwatec_aladin (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; // Close the device. if (serial_close (device->port) == -1) { free (device); - return UWATEC_ERROR_IO; + return DEVICE_STATUS_IO; } // Free memory. free (device); - return UWATEC_SUCCESS; + return DEVICE_STATUS_SUCCESS; } @@ -138,11 +157,13 @@ uwatec_aladin_checksum (unsigned char data[], unsigned int size) } -int -uwatec_aladin_read (aladin *device, unsigned char data[], unsigned int size) +static device_status_t +uwatec_aladin_device_download (device_t *abstract, unsigned char data[], unsigned int size) { - if (device == NULL) - return UWATEC_ERROR; + uwatec_aladin_device_t *device = (uwatec_aladin_device_t*) abstract; + + if (! device_is_uwatec_aladin (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; unsigned char answer[UWATEC_ALADIN_MEMORY_SIZE + 2] = {0}; @@ -177,27 +198,27 @@ uwatec_aladin_read (aladin *device, unsigned char data[], unsigned int size) unsigned short ccrc = uwatec_aladin_checksum (answer, UWATEC_ALADIN_MEMORY_SIZE); if (ccrc != crc) { WARNING ("Unexpected answer CRC."); - return UWATEC_ERROR_PROTOCOL; + return DEVICE_STATUS_PROTOCOL; } if (size >= UWATEC_ALADIN_MEMORY_SIZE) { memcpy (data, answer, UWATEC_ALADIN_MEMORY_SIZE); } else { WARNING ("Insufficient buffer space available."); - return UWATEC_ERROR_MEMORY; + return DEVICE_STATUS_MEMORY; } - return UWATEC_SUCCESS; + return DEVICE_STATUS_SUCCESS; } #define HEADER 4 -int +device_status_t uwatec_aladin_extract_dives (const unsigned char* data, unsigned int size, dive_callback_t callback, void *userdata) { if (size < UWATEC_ALADIN_MEMORY_SIZE) - return UWATEC_ERROR; + return DEVICE_STATUS_ERROR; // The logbook ring buffer can store up to 37 dives. But // if the total number of dives is less, not all logbook @@ -291,5 +312,17 @@ uwatec_aladin_extract_dives (const unsigned char* data, unsigned int size, dive_ callback (buffer, len + 18, userdata); } - return UWATEC_SUCCESS; + return DEVICE_STATUS_SUCCESS; } + + +static const device_backend_t uwatec_aladin_device_backend = { + DEVICE_TYPE_UWATEC_ALADIN, + NULL, /* handshake */ + NULL, /* version */ + NULL, /* read */ + NULL, /* write */ + uwatec_aladin_device_download, /* download */ + NULL, /* foreach */ + uwatec_aladin_device_close /* close */ +}; diff --git a/src/uwatec_aladin.h b/src/uwatec_aladin.h index bcf5e64..b803485 100644 --- a/src/uwatec_aladin.h +++ b/src/uwatec_aladin.h @@ -5,17 +5,15 @@ extern "C" { #endif /* __cplusplus */ -typedef struct aladin aladin; +#include "device.h" #define UWATEC_ALADIN_MEMORY_SIZE 2048 -int uwatec_aladin_open (aladin **device, const char* name); +device_status_t +uwatec_aladin_device_open (device_t **device, const char* name); -int uwatec_aladin_close (aladin *device); - -int uwatec_aladin_read (aladin *device, unsigned char data[], unsigned int size); - -int uwatec_aladin_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata); +device_status_t +uwatec_aladin_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata); #ifdef __cplusplus }