From ceeee5b2fa154fcbe849dda8e214d9b066a68d5a Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 30 Jan 2010 21:27:43 +0000 Subject: [PATCH] Removed the handshake and version functions. The handshake function is now called internally (even if it doesn't seem to be required at all), and the version function can be called through the public api. The format of the version data is changed too. --- examples/uwatec_smart_test.c | 12 +- src/libdivecomputer.symbols | 4 +- src/uwatec_smart.c | 284 +++++++++++++---------------------- src/uwatec_smart.h | 6 - 4 files changed, 108 insertions(+), 198 deletions(-) diff --git a/examples/uwatec_smart_test.c b/examples/uwatec_smart_test.c index e763156..b0a5e70 100644 --- a/examples/uwatec_smart_test.c +++ b/examples/uwatec_smart_test.c @@ -38,17 +38,9 @@ test_dump_memory (const char* filename) return rc; } - message ("uwatec_smart_device_handshake\n"); - rc = uwatec_smart_device_handshake (device); - if (rc != DEVICE_STATUS_SUCCESS) { - WARNING ("Handshake failed."); - device_close (device); - return rc; - } - - message ("uwatec_smart_device_version\n"); + message ("device_version\n"); unsigned char version[UWATEC_SMART_VERSION_SIZE] = {0}; - rc = uwatec_smart_device_version (device, version, sizeof (version)); + rc = device_version (device, version, sizeof (version)); if (rc != DEVICE_STATUS_SUCCESS) { WARNING ("Cannot identify computer."); device_close (device); diff --git a/src/libdivecomputer.symbols b/src/libdivecomputer.symbols index 9d033e1..43b3eb1 100644 --- a/src/libdivecomputer.symbols +++ b/src/libdivecomputer.symbols @@ -100,9 +100,7 @@ hw_ostc_device_open #endif #ifdef IRDA -uwatec_smart_device_handshake -uwatec_smart_device_open +uwatec_smart_device_open uwatec_smart_device_set_timestamp -uwatec_smart_device_version uwatec_smart_extract_dives #endif diff --git a/src/uwatec_smart.c b/src/uwatec_smart.c index a449e2b..137f56a 100644 --- a/src/uwatec_smart.c +++ b/src/uwatec_smart.c @@ -22,7 +22,6 @@ #include // malloc, free #include // strncmp, strstr #include // time, strftime -#include // assert #include "device-private.h" #include "uwatec_smart.h" @@ -45,6 +44,7 @@ typedef struct uwatec_smart_device_t { } uwatec_smart_device_t; static device_status_t uwatec_smart_device_set_fingerprint (device_t *device, const unsigned char data[], unsigned int size); +static device_status_t uwatec_smart_device_version (device_t *abstract, unsigned char data[], unsigned int size); static device_status_t uwatec_smart_device_dump (device_t *abstract, dc_buffer_t *buffer); static device_status_t uwatec_smart_device_foreach (device_t *abstract, dive_callback_t callback, void *userdata); static device_status_t uwatec_smart_device_close (device_t *abstract); @@ -52,7 +52,7 @@ static device_status_t uwatec_smart_device_close (device_t *abstract); static const device_backend_t uwatec_smart_device_backend = { DEVICE_TYPE_UWATEC_SMART, uwatec_smart_device_set_fingerprint, /* set_fingerprint */ - NULL, /* version */ + uwatec_smart_device_version, /* version */ NULL, /* read */ NULL, /* write */ uwatec_smart_device_dump, /* dump */ @@ -73,8 +73,6 @@ device_is_uwatec_smart (device_t *abstract) static void uwatec_smart_discovery (unsigned int address, const char *name, unsigned int charset, unsigned int hints, void *userdata) { - message ("device: address=%08x, name=%s, charset=%02x, hints=%04x\n", address, name, charset, hints); - uwatec_smart_device_t *device = (uwatec_smart_device_t*) userdata; if (device == NULL) return; @@ -88,13 +86,67 @@ uwatec_smart_discovery (unsigned int address, const char *name, unsigned int cha strstr (name, "Smart") != NULL || strstr (name, "SMART") != NULL || strstr (name, "Galileo") != NULL || - strstr (name, "GALILEO") != NULL) { - message ("Found an Uwatec dive computer.\n"); + strstr (name, "GALILEO") != NULL) + { device->address = address; } } +static device_status_t +uwatec_smart_transfer (uwatec_smart_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize) +{ + int n = irda_socket_write (device->socket, command, csize); + if (n != csize) { + WARNING ("Failed to send the command."); + return EXITCODE (n); + } + + n = irda_socket_read (device->socket, answer, asize); + if (n != asize) { + WARNING ("Failed to receive the answer."); + return EXITCODE (n); + } + + return DEVICE_STATUS_SUCCESS; +} + + +static device_status_t +uwatec_smart_handshake (uwatec_smart_device_t *device) +{ + // Command template. + unsigned char answer[1] = {0}; + unsigned char command[5] = {0x00, 0x10, 0x27, 0, 0}; + + // Handshake (stage 1). + command[0] = 0x1B; + device_status_t rc = uwatec_smart_transfer (device, command, 1, answer, 1); + if (rc != DEVICE_STATUS_SUCCESS) + return rc; + + // Verify the answer. + if (answer[0] != 0x01) { + WARNING ("Unexpected answer byte(s)."); + return DEVICE_STATUS_PROTOCOL; + } + + // Handshake (stage 2). + command[0] = 0x1C; + rc = uwatec_smart_transfer (device, command, 5, answer, 1); + if (rc != DEVICE_STATUS_SUCCESS) + return rc; + + // Verify the answer. + if (answer[0] != 0x01) { + WARNING ("Unexpected answer byte(s)."); + return DEVICE_STATUS_PROTOCOL; + } + + return DEVICE_STATUS_SUCCESS; +} + + device_status_t uwatec_smart_device_open (device_t **out) { @@ -157,6 +209,9 @@ uwatec_smart_device_open (device_t **out) return DEVICE_STATUS_IO; } + // Perform the handshaking. + uwatec_smart_handshake (device); + *out = (device_t*) device; return DEVICE_STATUS_SUCCESS; @@ -222,129 +277,34 @@ uwatec_smart_device_set_fingerprint (device_t *abstract, const unsigned char dat static device_status_t -uwatec_smart_transfer (uwatec_smart_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize) -{ - int rc = irda_socket_write (device->socket, command, csize); - if (rc != csize) { - WARNING ("Failed to send the command."); - return EXITCODE (rc); - } - - rc = irda_socket_read (device->socket, answer, asize); - if (rc != asize) { - WARNING ("Failed to receive the answer."); - return EXITCODE (rc); - } - - return DEVICE_STATUS_SUCCESS; -} - - -device_status_t -uwatec_smart_device_handshake (device_t *abstract) -{ - uwatec_smart_device_t *device = (uwatec_smart_device_t*) abstract; - - if (! device_is_uwatec_smart (abstract)) - return DEVICE_STATUS_TYPE_MISMATCH; - - unsigned char command[5] = {0}; - unsigned char answer[1] = {0}; - - // Handshake (stage 1). - - command[0] = 0x1B; - - device_status_t rc = uwatec_smart_transfer (device, command, 1, answer, 1); - if (rc != DEVICE_STATUS_SUCCESS) - return rc; - - message ("handshake: header=%02x\n", answer[0]); - - if (answer[0] != 0x01) { - WARNING ("Unexpected answer byte(s)."); - return DEVICE_STATUS_PROTOCOL; - } - - // Handshake (stage 2). - - command[0] = 0x1C; - command[1] = 0x10; - command[2] = 0x27; - command[3] = 0; - command[4] = 0; - - rc = uwatec_smart_transfer (device, command, 5, answer, 1); - if (rc != DEVICE_STATUS_SUCCESS) - return rc; - - message ("handshake: header=%02x\n", answer[0]); - - if (answer[0] != 0x01) { - WARNING ("Unexpected answer byte(s)."); - return DEVICE_STATUS_PROTOCOL; - } - - return DEVICE_STATUS_SUCCESS; -} - - -device_status_t uwatec_smart_device_version (device_t *abstract, unsigned char data[], unsigned int size) { - uwatec_smart_device_t *device = (uwatec_smart_device_t*) abstract; - - if (! device_is_uwatec_smart (abstract)) - return DEVICE_STATUS_TYPE_MISMATCH; - - unsigned char command[1] = {0}; - unsigned char answer[UWATEC_SMART_VERSION_SIZE] = {0}; - - // Dive Computer Time. - - command[0] = 0x1A; - - device_status_t rc = uwatec_smart_transfer (device, command, 1, answer + 0, 4); - if (rc != DEVICE_STATUS_SUCCESS) - return rc; - - time_t device_time = array_uint32_le (answer); - message ("handshake: timestamp=0x%08x\n", device_time); - - // PC Time and Time Correction. - - time_t now = time (NULL); - char datetime[21] = {0}; - strftime (datetime, sizeof (datetime), "%Y-%m-%dT%H:%M:%SZ", gmtime (&now)); - message ("handshake: now=%lu (%s)\n", (unsigned long)now, datetime); - - // Serial Number - - command[0] = 0x14; - - rc = uwatec_smart_transfer (device, command, 1, answer + 4, 4); - if (rc != DEVICE_STATUS_SUCCESS) - return rc; - - unsigned int serial = array_uint32_le (answer + 4); - message ("handshake: serial=0x%08x\n", serial); - - // Dive Computer Model. - - command[0] = 0x10; - - rc = uwatec_smart_transfer (device, command, 1, answer + 8, 1); - if (rc != DEVICE_STATUS_SUCCESS) - return rc; - - message ("handshake: model=0x%02x\n", answer[8]); + uwatec_smart_device_t *device = (uwatec_smart_device_t *) abstract; if (size < UWATEC_SMART_VERSION_SIZE) { WARNING ("Insufficient buffer space available."); return DEVICE_STATUS_MEMORY; } - memcpy (data, answer, UWATEC_SMART_VERSION_SIZE); + unsigned char command[1] = {0}; + + // Model Number. + command[0] = 0x10; + device_status_t rc = uwatec_smart_transfer (device, command, 1, data + 0, 1); + if (rc != DEVICE_STATUS_SUCCESS) + return rc; + + // Serial Number. + command[0] = 0x14; + rc = uwatec_smart_transfer (device, command, 1, data + 1, 4); + if (rc != DEVICE_STATUS_SUCCESS) + return rc; + + // Current Timestamp. + command[0] = 0x1A; + rc = uwatec_smart_transfer (device, command, 1, data + 5, 4); + if (rc != DEVICE_STATUS_SUCCESS) + return rc; return DEVICE_STATUS_SUCCESS; } @@ -368,42 +328,15 @@ uwatec_smart_device_dump (device_t *abstract, dc_buffer_t *buffer) device_progress_t progress = DEVICE_PROGRESS_INITIALIZER; device_event_emit (&device->base, DEVICE_EVENT_PROGRESS, &progress); - unsigned char command[9] = {0}; - unsigned char answer[4] = {0}; - - // Model Number. - - command[0] = 0x10; - device_status_t rc = uwatec_smart_transfer (device, command, 1, answer, 1); + // Read the version and clock data. + unsigned char version[UWATEC_SMART_VERSION_SIZE] = {0}; + device_status_t rc = uwatec_smart_device_version (abstract, version, sizeof (version)); if (rc != DEVICE_STATUS_SUCCESS) return rc; - unsigned int model = answer[0]; - message ("handshake: model=0x%02x\n", model); - - // Serial Number. - - command[0] = 0x14; - rc = uwatec_smart_transfer (device, command, 1, answer, 4); - if (rc != DEVICE_STATUS_SUCCESS) - return rc; - - unsigned int serial = array_uint32_le (answer); - message ("handshake: serial=0x%08x\n", serial); - - // Current Timestamp. - - command[0] = 0x1A; - rc = uwatec_smart_transfer (device, command, 1, answer, 4); - if (rc != DEVICE_STATUS_SUCCESS) - return rc; - - unsigned int timestamp = array_uint32_le (answer); - message ("handshake: timestamp=0x%08x\n", timestamp); - // Store the clock calibration values. device->systime = time (NULL); - device->devtime = timestamp; + device->devtime = array_uint32_le (version + 5); // Update and emit a progress event. progress.current += 9; @@ -411,29 +344,30 @@ uwatec_smart_device_dump (device_t *abstract, dc_buffer_t *buffer) // Emit a device info event. device_devinfo_t devinfo; - devinfo.model = model; + devinfo.model = version[0]; devinfo.firmware = 0; - devinfo.serial = serial; + devinfo.serial = array_uint32_le (version + 1); device_event_emit (&device->base, DEVICE_EVENT_DEVINFO, &devinfo); + // Command template. + unsigned char answer[4] = {0}; + unsigned char command[9] = {0x00, + (device->timestamp ) & 0xFF, + (device->timestamp >> 8 ) & 0xFF, + (device->timestamp >> 16) & 0xFF, + (device->timestamp >> 24) & 0xFF, + 0x10, + 0x27, + 0, + 0}; + // Data Length. - command[0] = 0xC6; - command[1] = (device->timestamp ) & 0xFF; - command[2] = (device->timestamp >> 8 ) & 0xFF; - command[3] = (device->timestamp >> 16) & 0xFF; - command[4] = (device->timestamp >> 24) & 0xFF; - command[5] = 0x10; - command[6] = 0x27; - command[7] = 0; - command[8] = 0; - - rc = uwatec_smart_transfer (device, command, 9, answer, 4); + rc = uwatec_smart_transfer (device, command, sizeof (command), answer, sizeof (answer)); if (rc != DEVICE_STATUS_SUCCESS) return rc; unsigned int length = array_uint32_le (answer); - message ("handshake: length=%u\n", length); // Update and emit a progress event. progress.maximum = 4 + 9 + (length ? length + 4 : 0); @@ -452,29 +386,21 @@ uwatec_smart_device_dump (device_t *abstract, dc_buffer_t *buffer) unsigned char *data = dc_buffer_get_data (buffer); // Data. - command[0] = 0xC4; - command[1] = (device->timestamp ) & 0xFF; - command[2] = (device->timestamp >> 8 ) & 0xFF; - command[3] = (device->timestamp >> 16) & 0xFF; - command[4] = (device->timestamp >> 24) & 0xFF; - command[5] = 0x10; - command[6] = 0x27; - command[7] = 0; - command[8] = 0; - - rc = uwatec_smart_transfer (device, command, 9, answer, 4); + rc = uwatec_smart_transfer (device, command, sizeof (command), answer, sizeof (answer)); if (rc != DEVICE_STATUS_SUCCESS) return rc; unsigned int total = array_uint32_le (answer); - message ("handshake: total=%u\n", total); // Update and emit a progress event. progress.current += 4; device_event_emit (&device->base, DEVICE_EVENT_PROGRESS, &progress); - assert (total == length + 4); + if (total != length + 4) { + WARNING ("Received an unexpected size."); + return DEVICE_STATUS_PROTOCOL; + } unsigned int nbytes = 0; while (nbytes < length) { diff --git a/src/uwatec_smart.h b/src/uwatec_smart.h index 427ff54..66e5718 100644 --- a/src/uwatec_smart.h +++ b/src/uwatec_smart.h @@ -37,12 +37,6 @@ uwatec_smart_device_open (device_t **device); device_status_t uwatec_smart_device_set_timestamp (device_t *device, unsigned int timestamp); -device_status_t -uwatec_smart_device_handshake (device_t *device); - -device_status_t -uwatec_smart_device_version (device_t *device, unsigned char data[], unsigned int size); - device_status_t uwatec_smart_extract_dives (device_t *device, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);