From f561e591b456e4c797045720cc30ee570a164bf7 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 7 Jul 2008 12:51:29 +0000 Subject: [PATCH] Port the Reefnet Sensus Ultra to the new api. --- examples/reefnet_sensusultra_test.c | 114 +++++------ src/device.h | 3 +- src/reefnet_sensusultra.c | 294 ++++++++++++++++------------ src/reefnet_sensusultra.h | 36 ++-- 4 files changed, 252 insertions(+), 195 deletions(-) diff --git a/examples/reefnet_sensusultra_test.c b/examples/reefnet_sensusultra_test.c index 2b6b159..96cf15d 100644 --- a/examples/reefnet_sensusultra_test.c +++ b/examples/reefnet_sensusultra_test.c @@ -1,7 +1,7 @@ #include // fopen, fwrite, fclose #include // time -#include "reefnet.h" +#include "reefnet_sensusultra.h" #include "utils.h" #define WARNING(expr) \ @@ -12,21 +12,21 @@ int test_dump_memory_dives (const char* name, const char* filename) { - sensusultra *device = NULL; + device_t *device = NULL; unsigned char handshake[REEFNET_SENSUSULTRA_HANDSHAKE_SIZE] = {0}; - message ("reefnet_sensusultra_open\n"); - int rc = reefnet_sensusultra_open (&device, name); - if (rc != REEFNET_SUCCESS) { + message ("reefnet_sensusultra_device_open\n"); + int rc = reefnet_sensusultra_device_open (&device, name); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Error opening serial port."); return rc; } - message ("reefnet_sensusultra_handshake\n"); - rc = reefnet_sensusultra_handshake (device, handshake, sizeof (handshake)); - if (rc != REEFNET_SUCCESS) { + message ("device_handshake\n"); + rc = device_handshake (device, handshake, sizeof (handshake)); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot read handshake."); - reefnet_sensusultra_close (device); + device_close (device); return rc; } @@ -35,43 +35,43 @@ int test_dump_memory_dives (const char* name, const char* filename) strftime (datetime, sizeof (datetime), "%Y-%m-%dT%H:%M:%SZ", gmtime (&now)); message ("time=%lu (%s)\n", (unsigned long)now, datetime); - message ("reefnet_sensusultra_read_dives\n"); - rc = reefnet_sensusultra_read_dives (device, NULL, NULL); - if (rc != REEFNET_SUCCESS) { + message ("device_foreach\n"); + rc = device_foreach (device, NULL, NULL); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot read dives."); - reefnet_sensusultra_close (device); + device_close (device); return rc; } - message ("reefnet_sensusultra_close\n"); - rc = reefnet_sensusultra_close (device); - if (rc != REEFNET_SUCCESS) { + message ("device_close\n"); + rc = device_close (device); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot close device."); return rc; } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } int test_dump_memory_data (const char* name, const char* filename) { - sensusultra *device = NULL; + device_t *device = NULL; unsigned char data[REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE] = {0}; unsigned char handshake[REEFNET_SENSUSULTRA_HANDSHAKE_SIZE] = {0}; - message ("reefnet_sensusultra_open\n"); - int rc = reefnet_sensusultra_open (&device, name); - if (rc != REEFNET_SUCCESS) { + message ("reefnet_sensusultra_device_open\n"); + int rc = reefnet_sensusultra_device_open (&device, name); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Error opening serial port."); return rc; } - message ("reefnet_sensusultra_handshake\n"); - rc = reefnet_sensusultra_handshake (device, handshake, sizeof (handshake)); - if (rc != REEFNET_SUCCESS) { + message ("device_handshake\n"); + rc = device_handshake (device, handshake, sizeof (handshake)); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot read handshake."); - reefnet_sensusultra_close (device); + device_close (device); return rc; } @@ -80,11 +80,11 @@ int test_dump_memory_data (const char* name, const char* filename) strftime (datetime, sizeof (datetime), "%Y-%m-%dT%H:%M:%SZ", gmtime (&now)); message ("time=%lu (%s)\n", (unsigned long)now, datetime); - message ("reefnet_sensusultra_read_data\n"); - rc = reefnet_sensusultra_read_data (device, data, sizeof (data)); - if (rc != REEFNET_SUCCESS) { + message ("device_download\n"); + rc = device_download (device, data, sizeof (data)); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot read memory."); - reefnet_sensusultra_close (device); + device_close (device); return rc; } @@ -95,35 +95,35 @@ int test_dump_memory_data (const char* name, const char* filename) fclose (fp); } - message ("reefnet_sensusultra_close\n"); - rc = reefnet_sensusultra_close (device); - if (rc != REEFNET_SUCCESS) { + message ("device_close\n"); + rc = device_close (device); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot close device."); return rc; } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } int test_dump_memory_user (const char* name, const char* filename) { - sensusultra *device = NULL; + device_t *device = NULL; unsigned char data[REEFNET_SENSUSULTRA_MEMORY_USER_SIZE] = {0}; unsigned char handshake[REEFNET_SENSUSULTRA_HANDSHAKE_SIZE] = {0}; - message ("reefnet_sensusultra_open\n"); - int rc = reefnet_sensusultra_open (&device, name); - if (rc != REEFNET_SUCCESS) { + message ("reefnet_sensusultra_device_open\n"); + int rc = reefnet_sensusultra_device_open (&device, name); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Error opening serial port."); return rc; } - message ("reefnet_sensusultra_handshake\n"); - rc = reefnet_sensusultra_handshake (device, handshake, sizeof (handshake)); - if (rc != REEFNET_SUCCESS) { + message ("device_handshake\n"); + rc = device_handshake (device, handshake, sizeof (handshake)); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot read handshake."); - reefnet_sensusultra_close (device); + device_close (device); return rc; } @@ -132,11 +132,11 @@ int test_dump_memory_user (const char* name, const char* filename) strftime (datetime, sizeof (datetime), "%Y-%m-%dT%H:%M:%SZ", gmtime (&now)); message ("time=%lu (%s)\n", (unsigned long)now, datetime); - message ("reefnet_sensusultra_read_user\n"); - rc = reefnet_sensusultra_read_user (device, data, sizeof (data)); - if (rc != REEFNET_SUCCESS) { + message ("reefnet_sensusultra_device_read_user\n"); + rc = reefnet_sensusultra_device_read_user (device, data, sizeof (data)); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot read memory."); - reefnet_sensusultra_close (device); + device_close (device); return rc; } @@ -147,31 +147,35 @@ int test_dump_memory_user (const char* name, const char* filename) fclose (fp); } - message ("reefnet_sensusultra_close\n"); - rc = reefnet_sensusultra_close (device); - if (rc != REEFNET_SUCCESS) { + message ("device_close\n"); + rc = device_close (device); + if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot close device."); return rc; } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } const char* errmsg (int rc) { switch (rc) { - case REEFNET_SUCCESS: + case DEVICE_STATUS_SUCCESS: return "Success"; - case REEFNET_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 REEFNET_ERROR_IO: + case DEVICE_STATUS_IO: return "Input/output error"; - case REEFNET_ERROR_MEMORY: + case DEVICE_STATUS_MEMORY: return "Memory error"; - case REEFNET_ERROR_PROTOCOL: + case DEVICE_STATUS_PROTOCOL: return "Protocol error"; - case REEFNET_ERROR_TIMEOUT: + case DEVICE_STATUS_TIMEOUT: return "Timeout"; default: return "Unknown error"; diff --git a/src/device.h b/src/device.h index f3e1d18..082dd92 100644 --- a/src/device.h +++ b/src/device.h @@ -11,7 +11,8 @@ typedef enum device_type_t { DEVICE_TYPE_SUUNTO_VYPER, DEVICE_TYPE_SUUNTO_VYPER2, DEVICE_TYPE_SUUNTO_D9, - DEVICE_TYPE_REEFNET_SENSUSPRO + DEVICE_TYPE_REEFNET_SENSUSPRO, + DEVICE_TYPE_REEFNET_SENSUSULTRA } device_type_t; typedef enum device_status_t { diff --git a/src/reefnet_sensusultra.c b/src/reefnet_sensusultra.c index 4c7408a..c374e97 100644 --- a/src/reefnet_sensusultra.c +++ b/src/reefnet_sensusultra.c @@ -2,7 +2,8 @@ #include // malloc, free #include -#include "reefnet.h" +#include "device-private.h" +#include "reefnet_sensusultra.h" #include "serial.h" #include "utils.h" @@ -13,33 +14,48 @@ #define EXITCODE(rc) \ ( \ - rc == -1 ? REEFNET_ERROR_IO : REEFNET_ERROR_TIMEOUT \ + rc == -1 ? DEVICE_STATUS_IO : DEVICE_STATUS_TIMEOUT \ ) #define PROMPT 0xA5 #define ACCEPT PROMPT #define REJECT 0x00 -struct sensusultra { +typedef struct reefnet_sensusultra_device_t reefnet_sensusultra_device_t; + +struct reefnet_sensusultra_device_t { + device_t base; struct serial *port; unsigned int maxretries; }; +static const device_backend_t reefnet_sensusultra_device_backend; -int -reefnet_sensusultra_open (sensusultra **out, const char* name) +static int +device_is_reefnet_sensusultra (device_t *abstract) +{ + if (abstract == NULL) + return 0; + + return abstract->backend == &reefnet_sensusultra_device_backend; +} + + +device_status_t +reefnet_sensusultra_device_open (device_t **out, const char* name) { if (out == NULL) - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; // Allocate memory. - struct sensusultra *device = malloc (sizeof (struct sensusultra)); + reefnet_sensusultra_device_t *device = malloc (sizeof (reefnet_sensusultra_device_t)); if (device == NULL) { WARNING ("Failed to allocate memory."); - return REEFNET_ERROR_MEMORY; + return DEVICE_STATUS_MEMORY; } // Set the default values. + device->base.backend = &reefnet_sensusultra_device_backend; device->port = NULL; device->maxretries = 2; @@ -48,7 +64,7 @@ reefnet_sensusultra_open (sensusultra **out, const char* name) if (rc == -1) { WARNING ("Failed to open the serial port."); free (device); - return REEFNET_ERROR_IO; + return DEVICE_STATUS_IO; } // Set the serial communication protocol (115200 8N1). @@ -57,7 +73,7 @@ reefnet_sensusultra_open (sensusultra **out, const char* name) WARNING ("Failed to set the terminal attributes."); serial_close (device->port); free (device); - return REEFNET_ERROR_IO; + return DEVICE_STATUS_IO; } // Set the timeout for receiving data (3000ms). @@ -65,46 +81,50 @@ reefnet_sensusultra_open (sensusultra **out, const char* name) WARNING ("Failed to set the timeout."); serial_close (device->port); free (device); - return REEFNET_ERROR_IO; + return DEVICE_STATUS_IO; } // Make sure everything is in a sane state. serial_flush (device->port, SERIAL_QUEUE_BOTH); - *out = device; + *out = (device_t*) device; - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int -reefnet_sensusultra_close (sensusultra *device) +static device_status_t +reefnet_sensusultra_device_close (device_t *abstract) { - if (device == NULL) - return REEFNET_SUCCESS; + reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + + if (! device_is_reefnet_sensusultra (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; // Close the device. if (serial_close (device->port) == -1) { free (device); - return REEFNET_ERROR_IO; + return DEVICE_STATUS_IO; } // Free memory. free (device); - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int -reefnet_sensusultra_set_maxretries (sensusultra *device, unsigned int maxretries) +device_status_t +reefnet_sensusultra_device_set_maxretries (device_t *abstract, unsigned int maxretries) { - if (device == NULL) - return REEFNET_ERROR; + reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + + if (! device_is_reefnet_sensusultra (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; device->maxretries = maxretries; - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } static unsigned short @@ -165,8 +185,8 @@ reefnet_sensusultra_isempty (const unsigned char *data, unsigned int size) } -static int -reefnet_sensusultra_send_uchar (sensusultra *device, unsigned char value) +static device_status_t +reefnet_sensusultra_send_uchar (reefnet_sensusultra_device_t *device, unsigned char value) { // Wait for the prompt byte. unsigned char prompt = 0; @@ -179,7 +199,7 @@ reefnet_sensusultra_send_uchar (sensusultra *device, unsigned char value) // Verify the prompt byte. if (prompt != PROMPT) { WARNING ("Unexpected answer data."); - return REEFNET_ERROR_PROTOCOL; + return DEVICE_STATUS_PROTOCOL; } // Send the value to the device. @@ -189,31 +209,31 @@ reefnet_sensusultra_send_uchar (sensusultra *device, unsigned char value) return EXITCODE (rc); } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -static int -reefnet_sensusultra_send_ushort (sensusultra *device, unsigned short value) +static device_status_t +reefnet_sensusultra_send_ushort (reefnet_sensusultra_device_t *device, unsigned short value) { // Send the least-significant byte. unsigned char lsb = value & 0xFF; int rc = reefnet_sensusultra_send_uchar (device, lsb); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; // Send the most-significant byte. unsigned char msb = (value >> 8) & 0xFF; rc = reefnet_sensusultra_send_uchar (device, msb); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -static int -reefnet_sensusultra_packet (sensusultra *device, unsigned char *data, unsigned int size, unsigned int header) +static device_status_t +reefnet_sensusultra_packet (reefnet_sensusultra_device_t *device, unsigned char *data, unsigned int size, unsigned int header) { assert (size >= header + 2); @@ -229,18 +249,20 @@ reefnet_sensusultra_packet (sensusultra *device, unsigned char *data, unsigned i unsigned short ccrc = reefnet_sensusultra_checksum (data + header, size - header - 2); if (crc != ccrc) { WARNING ("Unexpected answer CRC."); - return REEFNET_ERROR_PROTOCOL; + return DEVICE_STATUS_PROTOCOL; } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int -reefnet_sensusultra_handshake (sensusultra *device, unsigned char *data, unsigned int size) +static device_status_t +reefnet_sensusultra_device_handshake (device_t *abstract, unsigned char *data, unsigned int size) { - if (device == NULL) - return REEFNET_ERROR; + reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + + if (! device_is_reefnet_sensusultra (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; // Flush the input and output buffers. serial_flush (device->port, SERIAL_QUEUE_BOTH); @@ -248,10 +270,10 @@ reefnet_sensusultra_handshake (sensusultra *device, unsigned char *data, unsigne int rc = 0; unsigned int nretries = 0; unsigned char handshake[REEFNET_SENSUSULTRA_HANDSHAKE_SIZE + 2] = {0}; - while ((rc = reefnet_sensusultra_packet (device, handshake, sizeof (handshake), 0)) != REEFNET_SUCCESS) { + while ((rc = reefnet_sensusultra_packet (device, handshake, sizeof (handshake), 0)) != DEVICE_STATUS_SUCCESS) { // Automatically discard a corrupted handshake packet, // and wait for the next one. - if (rc != REEFNET_ERROR_PROTOCOL) + if (rc != DEVICE_STATUS_PROTOCOL) return rc; // Abort if the maximum number of retries is reached. @@ -295,26 +317,26 @@ reefnet_sensusultra_handshake (sensusultra *device, unsigned char *data, unsigne memcpy (data, handshake, REEFNET_SENSUSULTRA_HANDSHAKE_SIZE); } else { WARNING ("Insufficient buffer space available."); - return REEFNET_ERROR_MEMORY; + return DEVICE_STATUS_MEMORY; } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -static int -reefnet_sensusultra_page (sensusultra *device, unsigned char *data, unsigned int size, unsigned int pagenum) +static device_status_t +reefnet_sensusultra_page (reefnet_sensusultra_device_t *device, unsigned char *data, unsigned int size, unsigned int pagenum) { if (device == NULL) - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; int rc = 0; unsigned int nretries = 0; unsigned char package[REEFNET_SENSUSULTRA_PACKET_SIZE + 4] = {0}; - while ((rc = reefnet_sensusultra_packet (device, package, sizeof (package), 2)) != REEFNET_SUCCESS) { + while ((rc = reefnet_sensusultra_packet (device, package, sizeof (package), 2)) != DEVICE_STATUS_SUCCESS) { // Automatically discard a corrupted packet, // and request a new one. - if (rc != REEFNET_ERROR_PROTOCOL) + if (rc != DEVICE_STATUS_PROTOCOL) return rc; // Abort if the maximum number of retries is reached. @@ -323,7 +345,7 @@ reefnet_sensusultra_page (sensusultra *device, unsigned char *data, unsigned int // Reject the packet. rc = reefnet_sensusultra_send_uchar (device, REJECT); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; } @@ -331,32 +353,34 @@ reefnet_sensusultra_page (sensusultra *device, unsigned char *data, unsigned int unsigned int page = package[0] + (package[1] << 8); if (page != pagenum) { WARNING ("Unexpected page number."); - return REEFNET_ERROR_PROTOCOL; + return DEVICE_STATUS_PROTOCOL; } if (size >= REEFNET_SENSUSULTRA_PACKET_SIZE) { memcpy (data, package + 2, REEFNET_SENSUSULTRA_PACKET_SIZE); } else { WARNING ("Insufficient buffer space available."); - return REEFNET_ERROR_MEMORY; + return DEVICE_STATUS_MEMORY; } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int -reefnet_sensusultra_read_data (sensusultra *device, unsigned char *data, unsigned int size) +static device_status_t +reefnet_sensusultra_device_download (device_t *abstract, unsigned char *data, unsigned int size) { - if (device == NULL) - return REEFNET_ERROR; + reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + + if (! device_is_reefnet_sensusultra (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; if (size < REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE) - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; // Send the instruction code to the device. int rc = reefnet_sensusultra_send_ushort (device, 0xB421); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; unsigned int nbytes = 0; @@ -366,34 +390,36 @@ reefnet_sensusultra_read_data (sensusultra *device, unsigned char *data, unsigne unsigned int offset = REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE - nbytes - REEFNET_SENSUSULTRA_PACKET_SIZE; rc = reefnet_sensusultra_page (device, data + offset, REEFNET_SENSUSULTRA_PACKET_SIZE, npages); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; // Accept the packet. rc = reefnet_sensusultra_send_uchar (device, ACCEPT); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; nbytes += REEFNET_SENSUSULTRA_PACKET_SIZE; npages++; } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int -reefnet_sensusultra_read_user (sensusultra *device, unsigned char *data, unsigned int size) +device_status_t +reefnet_sensusultra_device_read_user (device_t *abstract, unsigned char *data, unsigned int size) { - if (device == NULL) - return REEFNET_ERROR; + reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + + if (! device_is_reefnet_sensusultra (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; if (size < REEFNET_SENSUSULTRA_MEMORY_USER_SIZE) - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; // Send the instruction code to the device. int rc = reefnet_sensusultra_send_ushort (device, 0xB420); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; unsigned int nbytes = 0; @@ -401,150 +427,158 @@ reefnet_sensusultra_read_user (sensusultra *device, unsigned char *data, unsigne while (nbytes < REEFNET_SENSUSULTRA_MEMORY_USER_SIZE) { // Receive the packet. rc = reefnet_sensusultra_page (device, data + nbytes, REEFNET_SENSUSULTRA_PACKET_SIZE, npages); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; // Accept the packet. rc = reefnet_sensusultra_send_uchar (device, ACCEPT); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; nbytes += REEFNET_SENSUSULTRA_PACKET_SIZE; npages++; } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int -reefnet_sensusultra_write_user (sensusultra *device, const unsigned char *data, unsigned int size) +device_status_t +reefnet_sensusultra_device_write_user (device_t *abstract, const unsigned char *data, unsigned int size) { - if (device == NULL) - return REEFNET_ERROR; + reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + + if (! device_is_reefnet_sensusultra (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; assert (size >= REEFNET_SENSUSULTRA_MEMORY_USER_SIZE); // Send the instruction code to the device. int rc = reefnet_sensusultra_send_ushort (device, 0xB430); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; // Send the data to the device. for (unsigned int i = 0; i < REEFNET_SENSUSULTRA_MEMORY_USER_SIZE; ++i) { rc = reefnet_sensusultra_send_uchar (device, data[i]); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; } // Send the checksum to the device. unsigned short crc = reefnet_sensusultra_checksum (data, REEFNET_SENSUSULTRA_MEMORY_USER_SIZE); rc = reefnet_sensusultra_send_ushort (device, crc); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -static int -reefnet_sensusultra_write_internal (sensusultra *device, unsigned int code, unsigned int value) +static device_status_t +reefnet_sensusultra_write_internal (device_t *abstract, unsigned int code, unsigned int value) { - if (device == NULL) - return REEFNET_ERROR; + reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + + if (! device_is_reefnet_sensusultra (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; // Send the instruction code to the device. int rc = reefnet_sensusultra_send_ushort (device, code); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; // Send the new value to the device. rc = reefnet_sensusultra_send_ushort (device, value); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int -reefnet_sensusultra_write_interval (sensusultra *device, unsigned int value) +device_status_t +reefnet_sensusultra_device_write_interval (device_t *abstract, unsigned int value) { if (value < 1 || value > 65535) - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; - return reefnet_sensusultra_write_internal (device, 0xB410, value); + return reefnet_sensusultra_write_internal (abstract, 0xB410, value); } -int -reefnet_sensusultra_write_threshold (sensusultra *device, unsigned int value) +device_status_t +reefnet_sensusultra_device_write_threshold (device_t *abstract, unsigned int value) { if (value < 1 || value > 65535) - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; - return reefnet_sensusultra_write_internal (device, 0xB411, value); + return reefnet_sensusultra_write_internal (abstract, 0xB411, value); } -int -reefnet_sensusultra_write_endcount (sensusultra *device, unsigned int value) +device_status_t +reefnet_sensusultra_device_write_endcount (device_t *abstract, unsigned int value) { if (value < 1 || value > 65535) - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; - return reefnet_sensusultra_write_internal (device, 0xB412, value); + return reefnet_sensusultra_write_internal (abstract, 0xB412, value); } -int -reefnet_sensusultra_write_averaging (sensusultra *device, unsigned int value) +device_status_t +reefnet_sensusultra_device_write_averaging (device_t *abstract, unsigned int value) { if (value != 1 && value != 2 && value != 4) - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; - return reefnet_sensusultra_write_internal (device, 0xB413, value); + return reefnet_sensusultra_write_internal (abstract, 0xB413, value); } -int -reefnet_sensusultra_sense (sensusultra *device, unsigned char *data, unsigned int size) +device_status_t +reefnet_sensusultra_device_sense (device_t *abstract, unsigned char *data, unsigned int size) { - if (device == NULL) - return REEFNET_ERROR; + reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + + if (! device_is_reefnet_sensusultra (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; // Send the instruction code to the device. int rc = reefnet_sensusultra_send_ushort (device, 0xB440); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; // Receive the packet. unsigned char package[REEFNET_SENSUSULTRA_SENSE_SIZE + 2] = {0}; rc = reefnet_sensusultra_packet (device, package, sizeof (package), 0); - if (rc != REEFNET_SUCCESS) + if (rc != DEVICE_STATUS_SUCCESS) return rc; if (size >= REEFNET_SENSUSULTRA_SENSE_SIZE) { memcpy (data, package, REEFNET_SENSUSULTRA_SENSE_SIZE); } else { WARNING ("Insufficient buffer space available."); - return REEFNET_ERROR_MEMORY; + return DEVICE_STATUS_MEMORY; } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int -reefnet_sensusultra_read_dives (sensusultra *device, dive_callback_t callback, void *userdata) +static device_status_t +reefnet_sensusultra_device_foreach (device_t *abstract, dive_callback_t callback, void *userdata) { - if (device == NULL) - return REEFNET_ERROR; + reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + + if (! device_is_reefnet_sensusultra (abstract)) + return DEVICE_STATUS_TYPE_MISMATCH; unsigned char *data = malloc (REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE * sizeof (unsigned char)); if (data == NULL) { WARNING ("Memory allocation error."); - return REEFNET_ERROR_MEMORY; + return DEVICE_STATUS_MEMORY; } const unsigned char header[4] = {0x00, 0x00, 0x00, 0x00}; @@ -557,7 +591,7 @@ reefnet_sensusultra_read_dives (sensusultra *device, dive_callback_t callback, v // Send the instruction code to the device. int rc = reefnet_sensusultra_send_ushort (device, 0xB421); - if (rc != REEFNET_SUCCESS) { + if (rc != DEVICE_STATUS_SUCCESS) { free (data); return rc; } @@ -569,7 +603,7 @@ reefnet_sensusultra_read_dives (sensusultra *device, dive_callback_t callback, v unsigned int index = REEFNET_SENSUSULTRA_MEMORY_DATA_SIZE - nbytes - REEFNET_SENSUSULTRA_PACKET_SIZE; rc = reefnet_sensusultra_page (device, data + index, REEFNET_SENSUSULTRA_PACKET_SIZE, npages); - if (rc != REEFNET_SUCCESS) { + if (rc != DEVICE_STATUS_SUCCESS) { free (data); return rc; } @@ -600,7 +634,7 @@ reefnet_sensusultra_read_dives (sensusultra *device, dive_callback_t callback, v if (!found) { WARNING ("No stop marker present."); free (data); - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; } if (callback) @@ -614,7 +648,7 @@ reefnet_sensusultra_read_dives (sensusultra *device, dive_callback_t callback, v // Accept the packet. rc = reefnet_sensusultra_send_uchar (device, ACCEPT); - if (rc != REEFNET_SUCCESS) { + if (rc != DEVICE_STATUS_SUCCESS) { free (data); return rc; } @@ -625,11 +659,11 @@ reefnet_sensusultra_read_dives (sensusultra *device, dive_callback_t callback, v free (data); - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } -int +device_status_t reefnet_sensusultra_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata) { const unsigned char header[4] = {0x00, 0x00, 0x00, 0x00}; @@ -658,7 +692,7 @@ reefnet_sensusultra_extract_dives (const unsigned char data[], unsigned int size // Report an error if no stop marker was found. if (!found) { WARNING ("No stop marker present."); - return REEFNET_ERROR; + return DEVICE_STATUS_ERROR; } if (callback) @@ -670,5 +704,17 @@ reefnet_sensusultra_extract_dives (const unsigned char data[], unsigned int size } } - return REEFNET_SUCCESS; + return DEVICE_STATUS_SUCCESS; } + + +static const device_backend_t reefnet_sensusultra_device_backend = { + DEVICE_TYPE_REEFNET_SENSUSULTRA, + reefnet_sensusultra_device_handshake, /* handshake */ + NULL, /* version */ + NULL, /* read */ + NULL, /* write */ + reefnet_sensusultra_device_download, /* download */ + reefnet_sensusultra_device_foreach, /* foreach */ + reefnet_sensusultra_device_close /* close */ +}; diff --git a/src/reefnet_sensusultra.h b/src/reefnet_sensusultra.h index 882a8a6..28eaa5c 100644 --- a/src/reefnet_sensusultra.h +++ b/src/reefnet_sensusultra.h @@ -5,7 +5,7 @@ extern "C" { #endif /* __cplusplus */ -typedef struct sensusultra sensusultra; +#include "device.h" #define REEFNET_SENSUSULTRA_PACKET_SIZE 512 #define REEFNET_SENSUSULTRA_MEMORY_USER_SIZE 16384 /* 32 PAGES */ @@ -14,29 +14,35 @@ typedef struct sensusultra sensusultra; #define REEFNET_SENSUSULTRA_HANDSHAKE_SIZE 24 #define REEFNET_SENSUSULTRA_SENSE_SIZE 6 -int reefnet_sensusultra_open (sensusultra **device, const char* name); +device_status_t +reefnet_sensusultra_device_open (device_t **device, const char* name); -int reefnet_sensusultra_close (sensusultra *device); +device_status_t +reefnet_sensusultra_device_set_maxretries (device_t *device, unsigned int maxretries); -int reefnet_sensusultra_set_maxretries (sensusultra *device, unsigned int maxretries); +device_status_t +reefnet_sensusultra_device_read_user (device_t *device, unsigned char *data, unsigned int size); -int reefnet_sensusultra_handshake (sensusultra *device, unsigned char *data, unsigned int size); +device_status_t +reefnet_sensusultra_device_write_user (device_t *device, const unsigned char *data, unsigned int size); -int reefnet_sensusultra_read_data (sensusultra *device, unsigned char *data, unsigned int size); -int reefnet_sensusultra_read_user (sensusultra *device, unsigned char *data, unsigned int size); +device_status_t +reefnet_sensusultra_device_write_interval (device_t *device, unsigned int value); -int reefnet_sensusultra_write_user (sensusultra *device, const unsigned char *data, unsigned int size); +device_status_t +reefnet_sensusultra_device_write_threshold (device_t *device, unsigned int value); -int reefnet_sensusultra_write_interval (sensusultra *device, unsigned int value); -int reefnet_sensusultra_write_threshold (sensusultra *device, unsigned int value); -int reefnet_sensusultra_write_endcount (sensusultra *device, unsigned int value); -int reefnet_sensusultra_write_averaging (sensusultra *device, unsigned int value); +device_status_t +reefnet_sensusultra_device_write_endcount (device_t *device, unsigned int value); -int reefnet_sensusultra_sense (sensusultra *device, unsigned char *data, unsigned int size); +device_status_t +reefnet_sensusultra_device_write_averaging (device_t *device, unsigned int value); -int reefnet_sensusultra_read_dives (sensusultra *device, dive_callback_t callback, void *userdata); +device_status_t +reefnet_sensusultra_device_sense (device_t *device, unsigned char *data, unsigned int size); -int reefnet_sensusultra_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata); +device_status_t +reefnet_sensusultra_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata); #ifdef __cplusplus }