diff --git a/src/citizen_aqualand.c b/src/citizen_aqualand.c index 774a3e4..68cfc8c 100644 --- a/src/citizen_aqualand.c +++ b/src/citizen_aqualand.c @@ -33,14 +33,9 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &citizen_aqualand_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - typedef struct citizen_aqualand_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char fingerprint[8]; } citizen_aqualand_device_t; @@ -82,38 +77,36 @@ citizen_aqualand_device_open (dc_device_t **out, dc_context_t *context, const ch memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (4800 8N1). - rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 4800, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_sleep (device->port, 300); - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep (device->port, 300); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -125,10 +118,12 @@ citizen_aqualand_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; citizen_aqualand_device_t *device = (citizen_aqualand_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -154,6 +149,7 @@ citizen_aqualand_device_set_fingerprint (dc_device_t *abstract, const unsigned c static dc_status_t citizen_aqualand_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; citizen_aqualand_device_t *device = (citizen_aqualand_device_t *) abstract; // Erase the current contents of the buffer and @@ -163,49 +159,49 @@ citizen_aqualand_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) return DC_STATUS_NOMEMORY; } - serial_set_dtr (device->port, 1); + dc_serial_set_dtr (device->port, 1); // Send the init byte. const unsigned char init[] = {0x7F}; - int n = serial_write (device->port, init, sizeof (init)); - if (n != sizeof (init)) { + status = dc_serial_write (device->port, init, sizeof (init), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } - serial_sleep(device->port, 1200); + dc_serial_sleep(device->port, 1200); // Send the command. const unsigned char command[] = {0xFF}; - n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } while (1) { // Receive the response packet. unsigned char answer[32] = {0}; - n = serial_read (device->port, answer, sizeof (answer)); - if (n != sizeof (answer)) { + status = dc_serial_read (device->port, answer, sizeof (answer), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } dc_buffer_append(buffer, answer, sizeof (answer)); // Send the command. - n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } if (answer[sizeof(answer) - 1] == 0xFF) break; } - serial_set_dtr (device->port, 0); + dc_serial_set_dtr (device->port, 0); return DC_STATUS_SUCCESS; } diff --git a/src/cochran_commander.c b/src/cochran_commander.c index 02ec1cb..735120b 100644 --- a/src/cochran_commander.c +++ b/src/cochran_commander.c @@ -32,11 +32,6 @@ #define C_ARRAY_SIZE(array) (sizeof (array) / sizeof *(array)) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define COCHRAN_MODEL_COMMANDER_AIR_NITROX 0 #define COCHRAN_MODEL_EMC_14 1 #define COCHRAN_MODEL_EMC_16 2 @@ -92,7 +87,7 @@ typedef struct cochran_device_layout_t { typedef struct cochran_commander_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; const cochran_device_layout_t *layout; unsigned char id[67]; unsigned char fingerprint[6]; @@ -226,33 +221,36 @@ cochran_commander_get_model (cochran_commander_device_t *device) static dc_status_t cochran_commander_serial_setup (cochran_commander_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; + // Set the serial communication protocol (9600 8N2, no FC). - int rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 9600, 8, DC_PARITY_NONE, DC_STOPBITS_TWO, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (device->base.context, "Failed to set the terminal attributes."); - return DC_STATUS_IO; + return status; } // Set the timeout for receiving data (5000 ms). - if (serial_set_timeout (device->port, 5000) == -1) { + status = dc_serial_set_timeout (device->port, 5000); + if (status != DC_STATUS_SUCCESS) { ERROR (device->base.context, "Failed to set the timeout."); - return DC_STATUS_IO; + return status; } // Wake up DC and trigger heartbeat - serial_set_break(device->port, 1); - serial_sleep(device->port, 16); - serial_set_break(device->port, 0); + dc_serial_set_break(device->port, 1); + dc_serial_sleep(device->port, 16); + dc_serial_set_break(device->port, 0); // Clear old heartbeats - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Wait for heartbeat byte before send unsigned char answer = 0; - int n = serial_read(device->port, &answer, 1); - if (n != 1) { + status = dc_serial_read(device->port, &answer, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (device->base.context, "Failed to receive device heartbeat."); - return EXITCODE (n); + return status; } if (answer != 0xAA) { @@ -270,6 +268,7 @@ cochran_commander_packet (cochran_commander_device_t *device, dc_event_progress_ unsigned char answer[], unsigned int asize, int high_speed) { dc_device_t *abstract = (dc_device_t *) device; + dc_status_t status = DC_STATUS_SUCCESS; if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; @@ -279,24 +278,24 @@ cochran_commander_packet (cochran_commander_device_t *device, dc_event_progress_ // has no buffering. for (unsigned int i = 0; i < csize; i++) { // Give the DC time to read the character. - if (i) serial_sleep(device->port, 16); // 16 ms + if (i) dc_serial_sleep(device->port, 16); // 16 ms - unsigned int n = serial_write(device->port, command + i, 1); - if (n != 1) { + status = dc_serial_write(device->port, command + i, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } } if (high_speed) { // Give the DC time to process the command. - serial_sleep(device->port, 45); + dc_serial_sleep(device->port, 45); // Rates are odd, like 806400 for the EMC, 115200 for commander - int rc = serial_configure(device->port, device->layout->baudrate, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure(device->port, device->layout->baudrate, 8, DC_PARITY_NONE, DC_STOPBITS_TWO, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to set the high baud rate."); - return DC_STATUS_IO; + return status; } } @@ -308,17 +307,16 @@ cochran_commander_packet (cochran_commander_device_t *device, dc_event_progress_ if (len > 1024) len = 1024; - int n = serial_read (device->port, answer + nbytes, len); - if (n != len) { - ERROR (abstract->context, "Failed to receive data, expected %u," - "read %u.",len, n); - return EXITCODE (n); + status = dc_serial_read (device->port, answer + nbytes, len, NULL); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to receive data."); + return status; } - nbytes += n; + nbytes += len; if (progress) { - progress->current += n; + progress->current += len; device_event_emit (abstract, DC_EVENT_PROGRESS, progress); } } @@ -417,7 +415,7 @@ cochran_commander_read (cochran_commander_device_t *device, dc_event_progress_t return DC_STATUS_UNSUPPORTED; } - serial_sleep(device->port, 800); + dc_serial_sleep(device->port, 800); // set back to 9600 baud rc = cochran_commander_serial_setup(device); @@ -630,10 +628,9 @@ cochran_commander_device_open (dc_device_t **out, dc_context_t *context, const c cochran_commander_device_set_fingerprint((dc_device_t *) device, NULL, 0); // Open the device. - int rc = serial_open (&device->port, device->base.context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, device->base.context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (device->base.context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } @@ -674,7 +671,7 @@ cochran_commander_device_open (dc_device_t **out, dc_context_t *context, const c return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -685,10 +682,12 @@ cochran_commander_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; cochran_commander_device_t *device = (cochran_commander_device_t *) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/cressi_edy.c b/src/cressi_edy.c index cfd5f9e..0dbe456 100644 --- a/src/cressi_edy.c +++ b/src/cressi_edy.c @@ -34,11 +34,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &cressi_edy_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define MAXRETRIES 4 #define SZ_PACKET 0x80 @@ -60,7 +55,7 @@ typedef struct cressi_edy_layout_t { typedef struct cressi_edy_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; const cressi_edy_layout_t *layout; unsigned char fingerprint[SZ_PAGE / 2]; unsigned int model; @@ -122,6 +117,7 @@ iceil (unsigned int x, unsigned int n) static dc_status_t cressi_edy_packet (cressi_edy_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, int trailer) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; if (device_is_cancelled (abstract)) @@ -129,18 +125,18 @@ cressi_edy_packet (cressi_edy_device_t *device, const unsigned char command[], u for (unsigned int i = 0; i < csize; ++i) { // Send the command to the device. - int n = serial_write (device->port, command + i, 1); - if (n != 1) { + status = dc_serial_write (device->port, command + i, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the echo. unsigned char echo = 0; - n = serial_read (device->port, &echo, 1); - if (n != 1) { + status = dc_serial_read (device->port, &echo, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the echo."); - return EXITCODE (n); + return status; } // Verify the echo. @@ -152,10 +148,10 @@ cressi_edy_packet (cressi_edy_device_t *device, const unsigned char command[], u if (asize) { // Receive the answer of the device. - int n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the trailer of the packet. @@ -182,8 +178,8 @@ cressi_edy_transfer (cressi_edy_device_t *device, const unsigned char command[], return rc; // Delay the next attempt. - serial_sleep (device->port, 300); - serial_flush (device->port, SERIAL_QUEUE_INPUT); + dc_serial_sleep (device->port, 300); + dc_serial_purge (device->port, DC_DIRECTION_INPUT); } return DC_STATUS_SUCCESS; @@ -257,39 +253,43 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (1200 8N1). - rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 1200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Set the DTR and clear the RTS line. - if (serial_set_dtr (device->port, 1) == -1 || - serial_set_rts (device->port, 0) == -1) { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Set the DTR line. + status = dc_serial_set_dtr (device->port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the DTR line."); + goto error_close; + } + + // Clear the RTS line. + status = dc_serial_set_rts (device->port, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to clear the RTS line."); goto error_close; } // Make sure everything is in a sane state. - serial_sleep(device->port, 300); - serial_flush(device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep(device->port, 300); + dc_serial_purge(device->port, DC_DIRECTION_ALL); // Send the init commands. cressi_edy_init1 (device); @@ -303,23 +303,22 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na } // Set the serial communication protocol (4800 8N1). - rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 4800, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_sleep(device->port, 300); - serial_flush(device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep(device->port, 300); + dc_serial_purge(device->port, DC_DIRECTION_ALL); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -331,13 +330,15 @@ cressi_edy_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; cressi_edy_device_t *device = (cressi_edy_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Send the quit command. cressi_edy_quit (device); // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/cressi_leonardo.c b/src/cressi_leonardo.c index 40a6630..b99f999 100644 --- a/src/cressi_leonardo.c +++ b/src/cressi_leonardo.c @@ -34,11 +34,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &cressi_leonardo_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_MEMORY 32000 #define RB_LOGBOOK_BEGIN 0x0100 @@ -52,7 +47,7 @@ typedef struct cressi_leonardo_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char fingerprint[5]; } cressi_leonardo_device_t; @@ -93,45 +88,49 @@ cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const cha memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (115200 8N1). - rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Clear the DTR and set the RTS line. - if (serial_set_dtr (device->port, 0) == -1 || - serial_set_rts (device->port, 1) == -1) { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Clear the DTR line. + status = dc_serial_set_dtr (device->port, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to clear the DTR line."); goto error_close; } - serial_sleep (device->port, 100); - serial_flush (device->port, SERIAL_QUEUE_BOTH); + // Set the RTS line. + status = dc_serial_set_rts (device->port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the RTS line."); + goto error_close; + } + + dc_serial_sleep (device->port, 100); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -142,10 +141,12 @@ cressi_leonardo_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; cressi_leonardo_device_t *device = (cressi_leonardo_device_t *) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -170,6 +171,7 @@ cressi_leonardo_device_set_fingerprint (dc_device_t *abstract, const unsigned ch static dc_status_t cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; cressi_leonardo_device_t *device = (cressi_leonardo_device_t *) abstract; // Erase the current contents of the buffer and @@ -186,18 +188,18 @@ cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) // Send the command header to the dive computer. const unsigned char command[] = {0x7B, 0x31, 0x32, 0x33, 0x44, 0x42, 0x41, 0x7d}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the header packet. unsigned char header[7] = {0}; - n = serial_read (device->port, header, sizeof (header)); - if (n != sizeof (header)) { + status = dc_serial_read (device->port, header, sizeof (header), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the header packet. @@ -215,8 +217,9 @@ cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) unsigned int len = 1024; // Increase the packet size if more data is immediately available. - int available = serial_get_received (device->port); - if (available > len) + size_t available = 0; + status = dc_serial_get_available (device->port, &available); + if (status == DC_STATUS_SUCCESS && available > len) len = available; // Limit the packet size to the total size. @@ -224,10 +227,10 @@ cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) len = SZ_MEMORY - nbytes; // Read the packet. - n = serial_read (device->port, data + nbytes, len); - if (n != len) { + status = dc_serial_read (device->port, data + nbytes, len, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Update and emit a progress event. @@ -239,10 +242,10 @@ cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) // Receive the trailer packet. unsigned char trailer[4] = {0}; - n = serial_read (device->port, trailer, sizeof (trailer)); - if (n != sizeof (trailer)) { + status = dc_serial_read (device->port, trailer, sizeof (trailer), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Convert to a binary checksum. diff --git a/src/diverite_nitekq.c b/src/diverite_nitekq.c index a873424..30060cd 100644 --- a/src/diverite_nitekq.c +++ b/src/diverite_nitekq.c @@ -33,11 +33,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &diverite_nitekq_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define KEEPALIVE 0x3E // '<' #define BLOCK 0x42 // 'B' #define DISCONNECT 0x44 // 'D' @@ -57,7 +52,7 @@ typedef struct diverite_nitekq_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char version[32]; unsigned char fingerprint[SZ_LOGBOOK]; } diverite_nitekq_device_t; @@ -82,6 +77,7 @@ static const dc_device_vtable_t diverite_nitekq_device_vtable = { static dc_status_t diverite_nitekq_send (diverite_nitekq_device_t *device, unsigned char cmd) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; if (device_is_cancelled (abstract)) @@ -89,10 +85,10 @@ diverite_nitekq_send (diverite_nitekq_device_t *device, unsigned char cmd) // Send the command. unsigned char command[] = {cmd}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -102,21 +98,22 @@ diverite_nitekq_send (diverite_nitekq_device_t *device, unsigned char cmd) static dc_status_t diverite_nitekq_receive (diverite_nitekq_device_t *device, unsigned char data[], unsigned int size) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Read the answer. - int n = serial_read (device->port, data, size); - if (n != size) { + status = dc_serial_read (device->port, data, size, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Read the checksum. unsigned char checksum[2] = {0}; - n = serial_read (device->port, checksum, sizeof (checksum)); - if (n != sizeof (checksum)) { + status = dc_serial_read (device->port, checksum, sizeof (checksum), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the checksum."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -126,21 +123,22 @@ diverite_nitekq_receive (diverite_nitekq_device_t *device, unsigned char data[], static dc_status_t diverite_nitekq_handshake (diverite_nitekq_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command. unsigned char command[] = {HANDSHAKE}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Read the answer. - n = serial_read (device->port, device->version, sizeof (device->version)); - if (n != sizeof (device->version)) { + status = dc_serial_read (device->port, device->version, sizeof (device->version), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -168,31 +166,29 @@ diverite_nitekq_device_open (dc_device_t **out, dc_context_t *context, const cha memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (9600 8N1). - rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 9600, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_sleep (device->port, 100); - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep (device->port, 100); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Perform the handshaking. status = diverite_nitekq_handshake (device); @@ -206,7 +202,7 @@ diverite_nitekq_device_open (dc_device_t **out, dc_context_t *context, const cha return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -218,13 +214,15 @@ diverite_nitekq_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; diverite_nitekq_device_t *device = (diverite_nitekq_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Disconnect. diverite_nitekq_send (device, DISCONNECT); // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/divesystem_idive.c b/src/divesystem_idive.c index e48e47b..75a2dbe 100644 --- a/src/divesystem_idive.c +++ b/src/divesystem_idive.c @@ -32,11 +32,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &divesystem_idive_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define IX3M_EASY 0x22 #define IX3M_DEEP 0x23 #define IX3M_TEC 0x24 @@ -67,7 +62,7 @@ typedef struct divesystem_idive_commands_t { typedef struct divesystem_idive_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char fingerprint[4]; unsigned int model; } divesystem_idive_device_t; @@ -130,38 +125,36 @@ divesystem_idive_device_open2 (dc_device_t **out, dc_context_t *context, const c device->model = model; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (115200 8N1). - rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_sleep (device->port, 300); - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep (device->port, 300); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -173,10 +166,12 @@ divesystem_idive_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; divesystem_idive_device_t *device = (divesystem_idive_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -203,6 +198,7 @@ divesystem_idive_device_set_fingerprint (dc_device_t *abstract, const unsigned c static dc_status_t divesystem_idive_send (divesystem_idive_device_t *device, const unsigned char command[], unsigned int csize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; unsigned char packet[MAXPACKET + 4]; unsigned short crc = 0; @@ -222,10 +218,10 @@ divesystem_idive_send (divesystem_idive_device_t *device, const unsigned char co packet[csize + 3] = (crc ) & 0xFF; // Send the data packet. - int n = serial_write (device->port, packet, csize + 4); - if (n != csize + 4) { + status = dc_serial_write (device->port, packet, csize + 4, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -235,9 +231,9 @@ divesystem_idive_send (divesystem_idive_device_t *device, const unsigned char co static dc_status_t divesystem_idive_receive (divesystem_idive_device_t *device, unsigned char answer[], unsigned int *asize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; unsigned char packet[MAXPACKET + 4]; - int n = 0; if (asize == NULL || *asize < MAXPACKET) { ERROR (abstract->context, "Invalid arguments."); @@ -246,10 +242,10 @@ divesystem_idive_receive (divesystem_idive_device_t *device, unsigned char answe // Read the packet start byte. while (1) { - n = serial_read (device->port, packet + 0, 1); - if (n != 1) { + status = dc_serial_read (device->port, packet + 0, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the packet start byte."); - return EXITCODE (n); + return status; } if (packet[0] == START) @@ -257,10 +253,10 @@ divesystem_idive_receive (divesystem_idive_device_t *device, unsigned char answe } // Read the packet length. - n = serial_read (device->port, packet + 1, 1); - if (n != 1) { + status = dc_serial_read (device->port, packet + 1, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the packet length."); - return EXITCODE (n); + return status; } unsigned int len = packet[1]; @@ -270,10 +266,10 @@ divesystem_idive_receive (divesystem_idive_device_t *device, unsigned char answe } // Read the packet payload and checksum. - n = serial_read (device->port, packet + 2, len + 2); - if (n != len + 2) { + status = dc_serial_read (device->port, packet + 2, len + 2, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the packet payload and checksum."); - return EXITCODE (n); + return status; } // Verify the checksum. @@ -346,7 +342,7 @@ divesystem_idive_transfer (divesystem_idive_device_t *device, const unsigned cha return DC_STATUS_PROTOCOL; // Delay the next attempt. - serial_sleep(device->port, 100); + dc_serial_sleep(device->port, 100); } // Verify the length of the packet. diff --git a/src/hw_frog.c b/src/hw_frog.c index 511052c..0ba5342 100644 --- a/src/hw_frog.c +++ b/src/hw_frog.c @@ -33,11 +33,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &hw_frog_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_DISPLAY 15 #define SZ_CUSTOMTEXT 13 #define SZ_VERSION (SZ_CUSTOMTEXT + 4) @@ -61,7 +56,7 @@ typedef struct hw_frog_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char fingerprint[5]; } hw_frog_device_t; @@ -110,6 +105,7 @@ hw_frog_transfer (hw_frog_device_t *device, unsigned char output[], unsigned int osize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; if (device_is_cancelled (abstract)) @@ -117,19 +113,19 @@ hw_frog_transfer (hw_frog_device_t *device, // Send the command. unsigned char command[1] = {cmd}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } if (cmd != INIT && cmd != HEADER) { // Read the echo. unsigned char answer[1] = {0}; - n = serial_read (device->port, answer, sizeof (answer)); - if (n != sizeof (answer)) { + status = dc_serial_read (device->port, answer, sizeof (answer), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the echo."); - return EXITCODE (n); + return status; } // Verify the echo. @@ -141,10 +137,10 @@ hw_frog_transfer (hw_frog_device_t *device, if (input) { // Send the input data packet. - n = serial_write (device->port, input, isize); - if (n != isize) { + status = dc_serial_write (device->port, input, isize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the data packet."); - return EXITCODE (n); + return status; } } @@ -155,8 +151,9 @@ hw_frog_transfer (hw_frog_device_t *device, unsigned int len = 1024; // Increase the packet size if more data is immediately available. - int available = serial_get_received (device->port); - if (available > len) + size_t available = 0; + status = dc_serial_get_available (device->port, &available); + if (status == DC_STATUS_SUCCESS && available > len) len = available; // Limit the packet size to the total size. @@ -164,10 +161,10 @@ hw_frog_transfer (hw_frog_device_t *device, len = osize - nbytes; // Read the packet. - n = serial_read (device->port, output + nbytes, len); - if (n != len) { + status = dc_serial_read (device->port, output + nbytes, len, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Update and emit a progress event. @@ -183,10 +180,10 @@ hw_frog_transfer (hw_frog_device_t *device, if (cmd != EXIT) { // Read the ready byte. unsigned char answer[1] = {0}; - n = serial_read (device->port, answer, sizeof (answer)); - if (n != sizeof (answer)) { + status = dc_serial_read (device->port, answer, sizeof (answer), NULL); + if (status != sizeof (answer)) { ERROR (abstract->context, "Failed to receive the ready byte."); - return EXITCODE (n); + return status; } // Verify the ready byte. @@ -221,31 +218,29 @@ hw_frog_device_open (dc_device_t **out, dc_context_t *context, const char *name) memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (115200 8N1). - rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_sleep (device->port, 300); - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep (device->port, 300); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Send the init command. status = hw_frog_transfer (device, NULL, INIT, NULL, 0, NULL, 0); @@ -259,7 +254,7 @@ hw_frog_device_open (dc_device_t **out, dc_context_t *context, const char *name) return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -281,8 +276,9 @@ hw_frog_device_close (dc_device_t *abstract) } // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/hw_ostc.c b/src/hw_ostc.c index 6a6c3d7..1185e81 100644 --- a/src/hw_ostc.c +++ b/src/hw_ostc.c @@ -33,11 +33,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &hw_ostc_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define C_ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) #define MAXRETRIES 9 @@ -64,7 +59,7 @@ typedef struct hw_ostc_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char fingerprint[5]; } hw_ostc_device_t; @@ -93,23 +88,24 @@ static const dc_device_vtable_t hw_ostc_device_vtable = { static dc_status_t hw_ostc_send (hw_ostc_device_t *device, unsigned char cmd, unsigned int echo) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command. unsigned char command[1] = {cmd}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } if (echo) { // Read the echo. unsigned char answer[1] = {0}; - n = serial_read (device->port, answer, sizeof (answer)); - if (n != sizeof (answer)) { + status = dc_serial_read (device->port, answer, sizeof (answer), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the echo."); - return EXITCODE (n); + return status; } // Verify the echo. @@ -144,38 +140,36 @@ hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name) memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (115200 8N1). - rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data. - if (serial_set_timeout (device->port, 4000) == -1) { + status = dc_serial_set_timeout (device->port, 4000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_sleep (device->port, 100); - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep (device->port, 100); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -187,10 +181,12 @@ hw_ostc_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; hw_ostc_device_t *device = (hw_ostc_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -217,6 +213,7 @@ hw_ostc_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[ static dc_status_t hw_ostc_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; hw_ostc_device_t *device = (hw_ostc_device_t*) abstract; // Erase the current contents of the buffer. @@ -232,18 +229,18 @@ hw_ostc_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) // Send the command. unsigned char command[1] = {'a'}; - int rc = serial_write (device->port, command, sizeof (command)); - if (rc != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (rc); + return status; } // Read the header. unsigned char header[SZ_HEADER] = {0}; - int n = serial_read (device->port, header, sizeof (header)); - if (n != sizeof (header)) { + status = dc_serial_read (device->port, header, sizeof (header), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the header."); - return EXITCODE (n); + return status; } // Verify the header. @@ -285,8 +282,9 @@ hw_ostc_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) unsigned int len = 1024; // Increase the packet size if more data is immediately available. - int available = serial_get_received (device->port); - if (available > len) + size_t available = 0; + status = dc_serial_get_available (device->port, &available); + if (status == DC_STATUS_SUCCESS && available > len) len = available; // Limit the packet size to the total size. @@ -294,10 +292,10 @@ hw_ostc_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) len = size - nbytes; // Read the packet. - int n = serial_read (device->port, data + nbytes, len); - if (n != len) { + status = dc_serial_read (device->port, data + nbytes, len, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Update and emit a progress event. @@ -351,6 +349,7 @@ hw_ostc_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void dc_status_t hw_ostc_device_md2hash (dc_device_t *abstract, unsigned char data[], unsigned int size) { + dc_status_t status = DC_STATUS_SUCCESS; hw_ostc_device_t *device = (hw_ostc_device_t *) abstract; if (!ISINSTANCE (abstract)) @@ -367,10 +366,10 @@ hw_ostc_device_md2hash (dc_device_t *abstract, unsigned char data[], unsigned in return rc; // Read the answer. - int n = serial_read (device->port, data, SZ_MD2HASH); - if (n != SZ_MD2HASH) { + status = dc_serial_read (device->port, data, SZ_MD2HASH, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -380,6 +379,7 @@ hw_ostc_device_md2hash (dc_device_t *abstract, unsigned char data[], unsigned in dc_status_t hw_ostc_device_clock (dc_device_t *abstract, const dc_datetime_t *datetime) { + dc_status_t status = DC_STATUS_SUCCESS; hw_ostc_device_t *device = (hw_ostc_device_t *) abstract; if (!ISINSTANCE (abstract)) @@ -399,10 +399,10 @@ hw_ostc_device_clock (dc_device_t *abstract, const dc_datetime_t *datetime) unsigned char packet[6] = { datetime->hour, datetime->minute, datetime->second, datetime->month, datetime->day, datetime->year - 2000}; - int n = serial_write (device->port, packet, sizeof (packet)); - if (n != sizeof (packet)) { + status = dc_serial_write (device->port, packet, sizeof (packet), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the data packet."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -412,6 +412,7 @@ hw_ostc_device_clock (dc_device_t *abstract, const dc_datetime_t *datetime) dc_status_t hw_ostc_device_eeprom_read (dc_device_t *abstract, unsigned int bank, unsigned char data[], unsigned int size) { + dc_status_t status = DC_STATUS_SUCCESS; hw_ostc_device_t *device = (hw_ostc_device_t *) abstract; if (!ISINSTANCE (abstract)) @@ -434,10 +435,10 @@ hw_ostc_device_eeprom_read (dc_device_t *abstract, unsigned int bank, unsigned c return rc; // Read the answer. - int n = serial_read (device->port, data, SZ_EEPROM); - if (n != SZ_EEPROM) { + status = dc_serial_read (device->port, data, SZ_EEPROM, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -499,6 +500,7 @@ hw_ostc_device_reset (dc_device_t *abstract) dc_status_t hw_ostc_device_screenshot (dc_device_t *abstract, dc_buffer_t *buffer, hw_ostc_format_t format) { + dc_status_t status = DC_STATUS_SUCCESS; hw_ostc_device_t *device = (hw_ostc_device_t *) abstract; if (!ISINSTANCE (abstract)) @@ -554,13 +556,13 @@ hw_ostc_device_screenshot (dc_device_t *abstract, dc_buffer_t *buffer, hw_ostc_f unsigned int npixels = 0; while (npixels < WIDTH * HEIGHT) { unsigned char raw[3] = {0}; - int n = serial_read (device->port, raw, 1); - if (n != 1) { + status = dc_serial_read (device->port, raw, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the packet."); - return EXITCODE (n); + return status; } - unsigned int nbytes = n; + unsigned int nbytes = 1; unsigned int count = raw[0]; if ((count & 0x80) == 0x00) { // Black pixel. @@ -572,13 +574,13 @@ hw_ostc_device_screenshot (dc_device_t *abstract, dc_buffer_t *buffer, hw_ostc_f count &= 0x3F; } else { // Color pixel. - n = serial_read (device->port, raw + 1, 2); - if (n != 2) { + status = dc_serial_read (device->port, raw + 1, 2, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the packet."); - return EXITCODE (n); + return status; } - nbytes += n; + nbytes += 2; count &= 0x3F; } count++; @@ -767,22 +769,23 @@ hw_ostc_firmware_readfile (hw_ostc_firmware_t *firmware, dc_context_t *context, static dc_status_t hw_ostc_firmware_setup_internal (hw_ostc_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command. unsigned char command[1] = {0xC1}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Read the response. unsigned char answer[2] = {0}; - n = serial_read (device->port, answer, sizeof (answer)); - if (n != sizeof (answer)) { + status = dc_serial_read (device->port, answer, sizeof (answer), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the response."); - return EXITCODE (n); + return status; } // Verify the response. @@ -818,21 +821,22 @@ hw_ostc_firmware_setup (hw_ostc_device_t *device, unsigned int maxretries) static dc_status_t hw_ostc_firmware_write_internal (hw_ostc_device_t *device, unsigned char *data, unsigned int size) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the packet. - int n = serial_write (device->port, data, size); - if (n != size) { + status = dc_serial_write (device->port, data, size, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the packet."); - return EXITCODE (n); + return status; } // Read the response. unsigned char answer[1] = {0}; - n = serial_read (device->port, answer, sizeof (answer)); - if (n != sizeof (answer)) { + status = dc_serial_read (device->port, answer, sizeof (answer), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the response."); - return EXITCODE (n); + return status; } // Verify the response. @@ -901,16 +905,17 @@ hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename) // bootloader needs to be send repeatedly, until the response packet is // received. Thus the time between each two attempts is directly controlled // by the timeout value. - serial_set_timeout (device->port, 300); + dc_serial_set_timeout (device->port, 300); // Setup the bootloader. const unsigned int baudrates[] = {19200, 115200}; for (unsigned int i = 0; i < C_ARRAY_SIZE(baudrates); ++i) { // Adjust the baudrate. - if (serial_configure (device->port, baudrates[i], 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE) == -1) { + rc = dc_serial_configure (device->port, baudrates[i], 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (rc != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to set the terminal attributes."); free (firmware); - return DC_STATUS_IO; + return rc; } // Try to setup the bootloader. @@ -926,7 +931,7 @@ hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename) } // Increase the timeout again. - serial_set_timeout (device->port, 1000); + dc_serial_set_timeout (device->port, 1000); // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index a4276eb..0ed1874 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -38,11 +38,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &hw_ostc3_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_DISPLAY 16 #define SZ_CUSTOMTEXT 60 #define SZ_VERSION (SZ_CUSTOMTEXT + 4) @@ -98,7 +93,7 @@ typedef enum hw_ostc3_state_t { typedef struct hw_ostc3_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned int hardware; unsigned char fingerprint[5]; hw_ostc3_state_t state; @@ -188,6 +183,7 @@ hw_ostc3_transfer (hw_ostc3_device_t *device, unsigned int delay) { dc_device_t *abstract = (dc_device_t *) device; + dc_status_t status = DC_STATUS_SUCCESS; if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; @@ -197,18 +193,18 @@ hw_ostc3_transfer (hw_ostc3_device_t *device, // Send the command. unsigned char command[1] = {cmd}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Read the echo. unsigned char echo[1] = {0}; - n = serial_read (device->port, echo, sizeof (echo)); - if (n != sizeof (echo)) { + status = dc_serial_read (device->port, echo, sizeof (echo), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the echo."); - return EXITCODE (n); + return status; } // Verify the echo. @@ -234,10 +230,10 @@ hw_ostc3_transfer (hw_ostc3_device_t *device, len = isize - nbytes; // Write the packet. - n = serial_write (device->port, input + nbytes, len); - if (n != len) { + status = dc_serial_write (device->port, input + nbytes, len, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the data packet."); - return EXITCODE (n); + return status; } // Update and emit a progress event. @@ -257,8 +253,9 @@ hw_ostc3_transfer (hw_ostc3_device_t *device, unsigned int len = 1024; // Increase the packet size if more data is immediately available. - int available = serial_get_received (device->port); - if (available > len) + size_t available = 0; + status = dc_serial_get_available (device->port, &available); + if (status == DC_STATUS_SUCCESS && available > len) len = available; // Limit the packet size to the total size. @@ -266,10 +263,10 @@ hw_ostc3_transfer (hw_ostc3_device_t *device, len = osize - nbytes; // Read the packet. - n = serial_read (device->port, output + nbytes, len); - if (n != len) { + status = dc_serial_read (device->port, output + nbytes, len, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Update and emit a progress event. @@ -285,20 +282,22 @@ hw_ostc3_transfer (hw_ostc3_device_t *device, if (delay) { unsigned int count = delay / 100; for (unsigned int i = 0; i < count; ++i) { - if (serial_get_received (device->port) > 0) + size_t available = 0; + status = dc_serial_get_available (device->port, &available); + if (status == DC_STATUS_SUCCESS && available > 0) break; - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); } } if (cmd != EXIT) { // Read the ready byte. unsigned char answer[1] = {0}; - n = serial_read (device->port, answer, sizeof (answer)); - if (n != sizeof (answer)) { + status = dc_serial_read (device->port, answer, sizeof (answer), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the ready byte."); - return EXITCODE (n); + return status; } // Verify the ready byte. @@ -334,31 +333,29 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (115200 8N1). - rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_sleep (device->port, 300); - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep (device->port, 300); + dc_serial_purge (device->port, DC_DIRECTION_ALL); device->state = OPEN; @@ -367,7 +364,7 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -396,28 +393,28 @@ hw_ostc3_device_init_download (hw_ostc3_device_t *device) static dc_status_t hw_ostc3_device_init_service (hw_ostc3_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; dc_context_t *context = (abstract ? abstract->context : NULL); unsigned char command[] = {0xAA, 0xAB, 0xCD, 0xEF}; unsigned char output[5]; - int n = 0; // We cant use hw_ostc3_transfer here, due to the different echos - n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Give the device some time to enter service mode - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); // Read the response - n = serial_read (device->port, output, sizeof (output)); - if (n != sizeof (output)) { + status = dc_serial_read (device->port, output, sizeof (output), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to receive the echo."); - return EXITCODE (n); + return status; } // Verify the response to service mode @@ -500,8 +497,9 @@ hw_ostc3_device_close (dc_device_t *abstract) } // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/irda.c b/src/irda.c index 57b5076..2d3a1fb 100644 --- a/src/irda.c +++ b/src/irda.c @@ -39,16 +39,19 @@ #endif #include "irda.h" +#include "common-private.h" #include "context-private.h" #include "array.h" #ifdef _WIN32 +typedef int s_ssize_t; #define S_ERRNO WSAGetLastError () #define S_EAGAIN WSAEWOULDBLOCK #define S_INVALID INVALID_SOCKET #define S_IOCTL ioctlsocket #define S_CLOSE closesocket #else +typedef ssize_t s_ssize_t; #define S_ERRNO errno #define S_EAGAIN EAGAIN #define S_INVALID -1 @@ -60,32 +63,34 @@ #define snprintf _snprintf #endif -struct irda_t { +struct dc_irda_t { dc_context_t *context; #ifdef _WIN32 SOCKET fd; #else int fd; #endif - long timeout; + int timeout; }; - -int -irda_socket_open (irda_t **out, dc_context_t *context) +dc_status_t +dc_irda_open (dc_irda_t **out, dc_context_t *context) { + dc_status_t status = DC_STATUS_SUCCESS; + dc_irda_t *device = NULL; + if (out == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; // Allocate memory. - irda_t *device = (irda_t *) malloc (sizeof (irda_t)); + device = (dc_irda_t *) malloc (sizeof (dc_irda_t)); if (device == NULL) { #ifdef _WIN32 SYSERROR (context, ERROR_OUTOFMEMORY); #else SYSERROR (context, ENOMEM); #endif - return -1; // ENOMEM (Not enough space) + return DC_STATUS_NOMEMORY; } // Library context. @@ -101,6 +106,7 @@ irda_socket_open (irda_t **out, dc_context_t *context) int rc = WSAStartup (wVersionRequested, &wsaData); if (rc != 0) { SYSERROR (context, rc); + status = DC_STATUS_UNSUPPORTED; goto error_free; } @@ -110,6 +116,7 @@ irda_socket_open (irda_t **out, dc_context_t *context) if (LOBYTE (wsaData.wVersion) != 2 || HIBYTE (wsaData.wVersion) != 2) { ERROR (context, "Incorrect winsock version."); + status = DC_STATUS_UNSUPPORTED; goto error_wsacleanup; } #endif @@ -118,12 +125,13 @@ irda_socket_open (irda_t **out, dc_context_t *context) device->fd = socket (AF_IRDA, SOCK_STREAM, 0); if (device->fd == S_INVALID) { SYSERROR (context, S_ERRNO); + status = DC_STATUS_IO; goto error_wsacleanup; } *out = device; - return 0; + return DC_STATUS_SUCCESS; error_wsacleanup: #ifdef _WIN32 @@ -131,17 +139,16 @@ error_wsacleanup: error_free: #endif free (device); - return -1; + return status; } - -int -irda_socket_close (irda_t *device) +dc_status_t +dc_irda_close (dc_irda_t *device) { - int errcode = 0; + dc_status_t status = DC_STATUS_SUCCESS; if (device == NULL) - return -1; + return DC_STATUS_SUCCESS; // Terminate all send and receive operations. shutdown (device->fd, 0); @@ -149,35 +156,34 @@ irda_socket_close (irda_t *device) // Close the socket. if (S_CLOSE (device->fd) != 0) { SYSERROR (device->context, S_ERRNO); - errcode = -1; + dc_status_set_error(&status, DC_STATUS_IO); } #ifdef _WIN32 // Terminate the winsock dll. if (WSACleanup () != 0) { SYSERROR (device->context, S_ERRNO); - errcode = -1; + dc_status_set_error(&status, DC_STATUS_IO); } #endif // Free memory. free (device); - return errcode; + return status; } - -int -irda_socket_set_timeout (irda_t *device, long timeout) +dc_status_t +dc_irda_set_timeout (dc_irda_t *device, int timeout) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; - INFO (device->context, "Timeout: value=%li", timeout); + INFO (device->context, "Timeout: value=%i", timeout); device->timeout = timeout; - return 0; + return DC_STATUS_SUCCESS; } @@ -192,11 +198,11 @@ irda_socket_set_timeout (irda_t *device, long timeout) sizeof (struct irda_device_info) * (DISCOVER_MAX_DEVICES - 1) #endif -int -irda_socket_discover (irda_t *device, irda_callback_t callback, void *userdata) +dc_status_t +dc_irda_discover (dc_irda_t *device, dc_irda_callback_t callback, void *userdata) { if (device == NULL) - return -1; + return DC_STATUS_INVALIDARGS; unsigned char data[DISCOVER_BUFSIZE] = {0}; #ifdef _WIN32 @@ -223,13 +229,13 @@ irda_socket_discover (irda_t *device, irda_callback_t callback, void *userdata) if (rc != 0) { if (S_ERRNO != S_EAGAIN) { SYSERROR (device->context, S_ERRNO); - return -1; // Error during getsockopt call. + return DC_STATUS_IO; } } // Abort if the maximum number of retries is reached. if (nretries++ >= DISCOVER_MAX_RETRIES) - return 0; + return DC_STATUS_SUCCESS; // Restore the size parameter in case it was // modified by the previous getsockopt call. @@ -266,15 +272,14 @@ irda_socket_discover (irda_t *device, irda_callback_t callback, void *userdata) } } - return 0; + return DC_STATUS_SUCCESS; } - -int -irda_socket_connect_name (irda_t *device, unsigned int address, const char *name) +dc_status_t +dc_irda_connect_name (dc_irda_t *device, unsigned int address, const char *name) { if (device == NULL) - return -1; + return DC_STATUS_INVALIDARGS; INFO (device->context, "Connect: address=%08x, name=%s", address, name ? name : ""); @@ -301,17 +306,17 @@ irda_socket_connect_name (irda_t *device, unsigned int address, const char *name if (connect (device->fd, (struct sockaddr *) &peer, sizeof (peer)) != 0) { SYSERROR (device->context, S_ERRNO); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } -int -irda_socket_connect_lsap (irda_t *device, unsigned int address, unsigned int lsap) +dc_status_t +dc_irda_connect_lsap (dc_irda_t *device, unsigned int address, unsigned int lsap) { if (device == NULL) - return -1; + return DC_STATUS_INVALIDARGS; INFO (device->context, "Connect: address=%08x, lsap=%u", address, lsap); @@ -333,18 +338,17 @@ irda_socket_connect_lsap (irda_t *device, unsigned int address, unsigned int lsa if (connect (device->fd, (struct sockaddr *) &peer, sizeof (peer)) != 0) { SYSERROR (device->context, S_ERRNO); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } - -int -irda_socket_available (irda_t *device) +dc_status_t +dc_irda_get_available (dc_irda_t *device, size_t *value) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; #ifdef _WIN32 unsigned long bytes = 0; @@ -354,18 +358,25 @@ irda_socket_available (irda_t *device) if (S_IOCTL (device->fd, FIONREAD, &bytes) != 0) { SYSERROR (device->context, S_ERRNO); - return -1; + return DC_STATUS_IO; } - return bytes; + if (value) + *value = bytes; + + return DC_STATUS_SUCCESS; } - -int -irda_socket_read (irda_t *device, void *data, unsigned int size) +dc_status_t +dc_irda_read (dc_irda_t *device, void *data, size_t size, size_t *actual) { - if (device == NULL) - return -1; // EINVAL (Invalid argument) + dc_status_t status = DC_STATUS_SUCCESS; + size_t nbytes = 0; + + if (device == NULL) { + status = DC_STATUS_INVALIDARGS; + goto out; + } struct timeval tv; if (device->timeout >= 0) { @@ -377,20 +388,21 @@ irda_socket_read (irda_t *device, void *data, unsigned int size) FD_ZERO (&fds); FD_SET (device->fd, &fds); - unsigned int nbytes = 0; while (nbytes < size) { int rc = select (device->fd + 1, &fds, NULL, NULL, (device->timeout >= 0 ? &tv : NULL)); if (rc < 0) { SYSERROR (device->context, S_ERRNO); - return -1; // Error during select call. + status = DC_STATUS_IO; + goto out; } else if (rc == 0) { break; // Timeout. } - int n = recv (device->fd, (char*) data + nbytes, size - nbytes, 0); + s_ssize_t n = recv (device->fd, (char*) data + nbytes, size - nbytes, 0); if (n < 0) { SYSERROR (device->context, S_ERRNO); - return -1; // Error during recv call. + status = DC_STATUS_IO; + goto out; } else if (n == 0) { break; // EOF reached. } @@ -398,30 +410,50 @@ irda_socket_read (irda_t *device, void *data, unsigned int size) nbytes += n; } + if (nbytes != size) { + status = DC_STATUS_TIMEOUT; + } + +out: HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Read", (unsigned char *) data, nbytes); - return nbytes; + if (actual) + *actual = nbytes; + + return status; } - -int -irda_socket_write (irda_t *device, const void *data, unsigned int size) +dc_status_t +dc_irda_write (dc_irda_t *device, const void *data, size_t size, size_t *actual) { - if (device == NULL) - return -1; // EINVAL (Invalid argument) + dc_status_t status = DC_STATUS_SUCCESS; + size_t nbytes = 0; + + if (device == NULL) { + status = DC_STATUS_INVALIDARGS; + goto out; + } - unsigned int nbytes = 0; while (nbytes < size) { - int n = send (device->fd, (char*) data + nbytes, size - nbytes, 0); + s_ssize_t n = send (device->fd, (char*) data + nbytes, size - nbytes, 0); if (n < 0) { SYSERROR (device->context, S_ERRNO); - return -1; // Error during send call. + status = DC_STATUS_IO; + goto out; } nbytes += n; } + if (nbytes != size) { + status = DC_STATUS_TIMEOUT; + } + +out: HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (unsigned char *) data, nbytes); - return nbytes; + if (actual) + *actual = nbytes; + + return status; } diff --git a/src/irda.h b/src/irda.h index d83037a..84d2f4d 100644 --- a/src/irda.h +++ b/src/irda.h @@ -19,37 +19,161 @@ * MA 02110-1301 USA */ -#ifndef IRDA_H -#define IRDA_H +#ifndef DC_IRDA_H +#define DC_IRDA_H +#include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -typedef struct irda_t irda_t; +/** + * Opaque object representing an IrDA connection. + */ +typedef struct dc_irda_t dc_irda_t; -typedef void (*irda_callback_t) (unsigned int address, const char *name, unsigned int charset, unsigned int hints, void *userdata); +/** + * IrDA enumeration callback. + * + * @param[in] address The IrDA device address. + * @param[in] name The IrDA device name. + * @param[in] charset The IrDA device character set. + * @param[in] hints The IrDA device hints. + * @param[in] userdata The user data pointer. + */ +typedef void (*dc_irda_callback_t) (unsigned int address, const char *name, unsigned int charset, unsigned int hints, void *userdata); -int irda_socket_open (irda_t **device, dc_context_t *context); +/** + * Open an IrDA connection. + * + * @param[out] irda A location to store the IrDA connection. + * @param[in] context A valid context object. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_irda_open (dc_irda_t **irda, dc_context_t *context); -int irda_socket_close (irda_t *device); +/** + * Close the IrDA connection and free all resources. + * + * @param[in] irda A valid IrDA connection. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_irda_close (dc_irda_t *irda); -int irda_socket_set_timeout (irda_t *device, long timeout); +/** + * Set the read timeout. + * + * There are three distinct modes available: + * + * 1. Blocking (timeout < 0): + * + * The read operation is blocked until all the requested bytes have + * been received. If the requested number of bytes does not arrive, + * the operation will block forever. + * + * 2. Non-blocking (timeout == 0): + * + * The read operation returns immediately with the bytes that have + * already been received, even if no bytes have been received. + * + * 3. Timeout (timeout > 0): + * + * The read operation is blocked until all the requested bytes have + * been received. If the requested number of bytes does not arrive + * within the specified amount of time, the operation will return + * with the bytes that have already been received. + * + * @param[in] irda A valid IrDA connection. + * @param[in] timeout The timeout in milliseconds. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_irda_set_timeout (dc_irda_t *irda, int timeout); -int irda_socket_discover (irda_t *device, irda_callback_t callback, void *userdata); +/** + * Enumerate the IrDA devices. + * + * @param[in] irda A valid IrDA connection. + * @param[in] callback The callback function to call. + * @param[in] userdata User data to pass to the callback function. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_irda_discover (dc_irda_t *irda, dc_irda_callback_t callback, void *userdata); -int irda_socket_connect_name (irda_t *device, unsigned int address, const char *name); -int irda_socket_connect_lsap (irda_t *device, unsigned int address, unsigned int lsap); +/** + * Connect to an IrDA device. + * + * @param[in] irda A valid IrDA connection. + * @param[in] address The IrDA device address. + * @param[in] name The IrDA service name. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_irda_connect_name (dc_irda_t *irda, unsigned int address, const char *name); -int irda_socket_available (irda_t *device); +/** + * Connect to an IrDA device. + * + * @param[in] irda A valid IrDA connection. + * @param[in] address The IrDA device address. + * @param[in] lsap The IrDA LSAP number. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_irda_connect_lsap (dc_irda_t *irda, unsigned int address, unsigned int lsap); -int irda_socket_read (irda_t *device, void *data, unsigned int size); +/** + * Query the number of available bytes in the input buffer. + * + * @param[in] irda A valid IrDA connection. + * @param[out] value A location to store the number of bytes in the + * input buffer. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_irda_get_available (dc_irda_t *irda, size_t *value); -int irda_socket_write (irda_t *device, const void *data, unsigned int size); +/** + * Read data from the IrDA connection. + * + * @param[in] irda A valid IrDA connection. + * @param[out] data The memory buffer to read the data into. + * @param[in] size The number of bytes to read. + * @param[out] actual An (optional) location to store the actual + * number of bytes transferred. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_irda_read (dc_irda_t *irda, void *data, size_t size, size_t *actual); + +/** + * Write data to the IrDA connection. + * + * @param[in] irda A valid IrDA connection. + * @param[in] data The memory buffer to write the data from. + * @param[in] size The number of bytes to write. + * @param[out] actual An (optional) location to store the actual + * number of bytes transferred. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_irda_write (dc_irda_t *irda, const void *data, size_t size, size_t *actual); #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* IRDA_H */ +#endif /* DC_IRDA_H */ diff --git a/src/irda_dummy.c b/src/irda_dummy.c index 504aee8..7579324 100644 --- a/src/irda_dummy.c +++ b/src/irda_dummy.c @@ -23,65 +23,56 @@ #include "irda.h" - -int -irda_socket_open (irda_t **out, dc_context_t *context) +dc_status_t +dc_irda_open (dc_irda_t **out, dc_context_t *context) { - return -1; + return DC_STATUS_UNSUPPORTED; } - -int -irda_socket_close (irda_t *device) +dc_status_t +dc_irda_close (dc_irda_t *device) { - return -1; + return DC_STATUS_UNSUPPORTED; } - -int -irda_socket_set_timeout (irda_t *device, long timeout) +dc_status_t +dc_irda_set_timeout (dc_irda_t *device, int timeout) { - return -1; + return DC_STATUS_UNSUPPORTED; } - -int -irda_socket_discover (irda_t *device, irda_callback_t callback, void *userdata) +dc_status_t +dc_irda_discover (dc_irda_t *device, dc_irda_callback_t callback, void *userdata) { - return -1; + return DC_STATUS_UNSUPPORTED; } - -int -irda_socket_connect_name (irda_t *device, unsigned int address, const char *name) +dc_status_t +dc_irda_connect_name (dc_irda_t *device, unsigned int address, const char *name) { - return -1; + return DC_STATUS_UNSUPPORTED; } - -int -irda_socket_connect_lsap (irda_t *device, unsigned int address, unsigned int lsap) +dc_status_t +dc_irda_connect_lsap (dc_irda_t *device, unsigned int address, unsigned int lsap) { - return -1; + return DC_STATUS_UNSUPPORTED; } - -int -irda_socket_available (irda_t *device) +dc_status_t +dc_irda_get_available (dc_irda_t *device, size_t *value) { - return -1; + return DC_STATUS_UNSUPPORTED; } - -int -irda_socket_read (irda_t *device, void *data, unsigned int size) +dc_status_t +dc_irda_read (dc_irda_t *device, void *data, size_t size, size_t *actual) { - return -1; + return DC_STATUS_UNSUPPORTED; } - -int -irda_socket_write (irda_t *device, const void *data, unsigned int size) +dc_status_t +dc_irda_write (dc_irda_t *device, const void *data, size_t size, size_t *actual) { - return -1; + return DC_STATUS_UNSUPPORTED; } diff --git a/src/mares_common.c b/src/mares_common.c index 6f0c3dd..b157dc2 100644 --- a/src/mares_common.c +++ b/src/mares_common.c @@ -28,11 +28,6 @@ #include "checksum.h" #include "array.h" -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define MAXRETRIES 4 #define FP_OFFSET 8 @@ -86,29 +81,30 @@ mares_common_make_ascii (const unsigned char raw[], unsigned int rsize, unsigned static dc_status_t mares_common_packet (mares_common_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; if (device->delay) { - serial_sleep (device->port, device->delay); + dc_serial_sleep (device->port, device->delay); } // Send the command to the device. - int n = serial_write (device->port, command, csize); - if (n != csize) { + status = dc_serial_write (device->port, command, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } if (device->echo) { // Receive the echo of the command. unsigned char echo[PACKETSIZE] = {0}; - n = serial_read (device->port, echo, csize); - if (n != csize) { + status = dc_serial_read (device->port, echo, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the echo."); - return EXITCODE (n); + return status; } // Verify the echo. @@ -118,10 +114,10 @@ mares_common_packet (mares_common_device_t *device, const unsigned char command[ } // Receive the answer of the device. - n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the header and trailer of the packet. @@ -159,8 +155,8 @@ mares_common_transfer (mares_common_device_t *device, const unsigned char comman return rc; // Discard any garbage bytes. - serial_sleep (device->port, 100); - serial_flush (device->port, SERIAL_QUEUE_INPUT); + dc_serial_sleep (device->port, 100); + dc_serial_purge (device->port, DC_DIRECTION_INPUT); } return rc; diff --git a/src/mares_common.h b/src/mares_common.h index 33228c5..4652d06 100644 --- a/src/mares_common.h +++ b/src/mares_common.h @@ -41,7 +41,7 @@ typedef struct mares_common_layout_t { typedef struct mares_common_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned int echo; unsigned int delay; } mares_common_device_t; diff --git a/src/mares_darwin.c b/src/mares_darwin.c index f8a39d9..3f06a4a 100644 --- a/src/mares_darwin.c +++ b/src/mares_darwin.c @@ -122,39 +122,43 @@ mares_darwin_device_open (dc_device_t **out, dc_context_t *context, const char * device->layout = &mares_darwin_layout; // Open the device. - int rc = serial_open (&device->base.port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->base.port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (9600 8N1). - rc = serial_configure (device->base.port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->base.port, 9600, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->base.port, 1000) == -1) { + status = dc_serial_set_timeout (device->base.port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Set the DTR/RTS lines. - if (serial_set_dtr (device->base.port, 1) == -1 || - serial_set_rts (device->base.port, 1) == -1) { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Set the DTR line. + status = dc_serial_set_dtr (device->base.port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the DTR line."); + goto error_close; + } + + // Set the RTS line. + status = dc_serial_set_rts (device->base.port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the RTS line."); goto error_close; } // Make sure everything is in a sane state. - serial_sleep (device->base.port, 100); - serial_flush (device->base.port, SERIAL_QUEUE_BOTH); + dc_serial_sleep (device->base.port, 100); + dc_serial_purge (device->base.port, DC_DIRECTION_ALL); // Override the base class values. device->base.echo = 1; @@ -165,7 +169,7 @@ mares_darwin_device_open (dc_device_t **out, dc_context_t *context, const char * return DC_STATUS_SUCCESS; error_close: - serial_close (device->base.port); + dc_serial_close (device->base.port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -176,10 +180,12 @@ mares_darwin_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; mares_darwin_device_t *device = (mares_darwin_device_t *) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->base.port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->base.port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index 79dda55..9c33307 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -34,11 +34,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &mares_iconhd_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define MATRIX 0x0F #define SMART 0x000010 #define SMARTAPNEA 0x010010 @@ -69,7 +64,7 @@ typedef struct mares_iconhd_model_t { typedef struct mares_iconhd_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; const mares_iconhd_layout_t *layout; unsigned char fingerprint[10]; unsigned char version[140]; @@ -150,6 +145,7 @@ mares_iconhd_transfer (mares_iconhd_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; assert (csize >= 2); @@ -158,18 +154,18 @@ mares_iconhd_transfer (mares_iconhd_device_t *device, return DC_STATUS_CANCELLED; // Send the command header to the dive computer. - int n = serial_write (device->port, command, 2); - if (n != 2) { + status = dc_serial_write (device->port, command, 2, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the header byte. unsigned char header[1] = {0}; - n = serial_read (device->port, header, sizeof (header)); - if (n != sizeof (header)) { + status = dc_serial_read (device->port, header, sizeof (header), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the header byte. @@ -180,26 +176,26 @@ mares_iconhd_transfer (mares_iconhd_device_t *device, // Send the command payload to the dive computer. if (csize > 2) { - n = serial_write (device->port, command + 2, csize - 2); - if (n != csize - 2) { + status = dc_serial_write (device->port, command + 2, csize - 2, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } } // Read the packet. - n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Receive the trailer byte. unsigned char trailer[1] = {0}; - n = serial_read (device->port, trailer, sizeof (trailer)); - if (n != sizeof (trailer)) { + status = dc_serial_read (device->port, trailer, sizeof (trailer), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the trailer byte. @@ -237,39 +233,42 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * device->packetsize = 0; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (115200 8E1). - rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_EVEN, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 115200, 8, DC_PARITY_EVEN, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Set the DTR/RTS lines. - if (serial_set_dtr (device->port, 0) == -1 || - serial_set_rts (device->port, 0) == -1) - { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Clear the DTR line. + status = dc_serial_set_dtr (device->port, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to clear the DTR line."); + goto error_close; + } + + // Clear the RTS line. + status = dc_serial_set_rts (device->port, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to clear the RTS line."); goto error_close; } // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Send the version command. unsigned char command[] = {0xC2, 0x67}; @@ -312,7 +311,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -324,10 +323,12 @@ mares_iconhd_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; mares_iconhd_device_t *device = (mares_iconhd_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/mares_nemo.c b/src/mares_nemo.c index 7f71dbf..16824ae 100644 --- a/src/mares_nemo.c +++ b/src/mares_nemo.c @@ -33,11 +33,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &mares_nemo_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #ifdef PACKETSIZE #undef PACKETSIZE /* Override the common value. */ #endif @@ -51,7 +46,7 @@ typedef struct mares_nemo_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char fingerprint[5]; } mares_nemo_device_t; @@ -109,45 +104,49 @@ mares_nemo_device_open (dc_device_t **out, dc_context_t *context, const char *na memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (9600 8N1). - rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 9600, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Set the DTR/RTS lines. - if (serial_set_dtr (device->port, 1) == -1 || - serial_set_rts (device->port, 1) == -1) { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Set the DTR line. + status = dc_serial_set_dtr (device->port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the DTR line."); + goto error_close; + } + + // Set the RTS line. + status = dc_serial_set_rts (device->port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the RTS line."); goto error_close; } // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -159,10 +158,12 @@ mares_nemo_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; mares_nemo_device_t *device = (mares_nemo_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -189,6 +190,7 @@ mares_nemo_device_set_fingerprint (dc_device_t *abstract, const unsigned char da static dc_status_t mares_nemo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; mares_nemo_device_t *device = (mares_nemo_device_t *) abstract; // Erase the current contents of the buffer and @@ -204,21 +206,22 @@ mares_nemo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); // Wait until some data arrives. - while (serial_get_received (device->port) == 0) { + size_t available = 0; + while (dc_serial_get_available (device->port, &available) == DC_STATUS_SUCCESS && available == 0) { if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; device_event_emit (abstract, DC_EVENT_WAITING, NULL); - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); } // Receive the header of the package. unsigned char header = 0x00; for (unsigned int i = 0; i < 20;) { - int n = serial_read (device->port, &header, 1); - if (n != 1) { + status = dc_serial_read (device->port, &header, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the header."); - return EXITCODE (n); + return status; } if (header == 0xEE) { i++; // Continue. @@ -235,10 +238,10 @@ mares_nemo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) while (nbytes < MEMORYSIZE) { // Read the packet. unsigned char packet[(PACKETSIZE + 1) * 2] = {0}; - int n = serial_read (device->port, packet, sizeof (packet)); - if (n != sizeof (packet)) { + status = dc_serial_read (device->port, packet, sizeof (packet), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the checksums of the packet. diff --git a/src/mares_puck.c b/src/mares_puck.c index 67666df..853ad03 100644 --- a/src/mares_puck.c +++ b/src/mares_puck.c @@ -110,38 +110,42 @@ mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *na memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->base.port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->base.port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (38400 8N1). - rc = serial_configure (device->base.port, 38400, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->base.port, 38400, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->base.port, 1000) == -1) { + status = dc_serial_set_timeout (device->base.port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Clear the DTR/RTS lines. - if (serial_set_dtr (device->base.port, 0) == -1 || - serial_set_rts (device->base.port, 0) == -1) { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Clear the DTR line. + status = dc_serial_set_dtr (device->base.port, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to clear the DTR line."); + goto error_close; + } + + // Clear the RTS line. + status = dc_serial_set_rts (device->base.port, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to clear the RTS line."); goto error_close; } // Make sure everything is in a sane state. - serial_flush (device->base.port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->base.port, DC_DIRECTION_ALL); // Identify the model number. unsigned char header[PACKETSIZE] = {0}; @@ -172,7 +176,7 @@ mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *na return DC_STATUS_SUCCESS; error_close: - serial_close (device->base.port); + dc_serial_close (device->base.port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -184,10 +188,12 @@ mares_puck_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; mares_puck_device_t *device = (mares_puck_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->base.port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->base.port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index bc93387..0ebf670 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -40,11 +40,6 @@ #define MAXDELAY 16 #define INVALID 0xFFFFFFFF -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define CMD_INIT 0xA8 #define CMD_VERSION 0x84 #define CMD_READ1 0xB1 @@ -59,7 +54,7 @@ typedef struct oceanic_atom2_device_t { oceanic_common_device_t base; - serial_t *port; + dc_serial_t *port; unsigned int delay; unsigned int bigpage; unsigned char cache[256]; @@ -422,20 +417,21 @@ static const oceanic_common_layout_t aqualung_i450t_layout = { static dc_status_t oceanic_atom2_packet (oceanic_atom2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int crc_size) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; if (device->delay) { - serial_sleep (device->port, device->delay); + dc_serial_sleep (device->port, device->delay); } // Send the command to the dive computer. - int n = serial_write (device->port, command, csize); - if (n != csize) { + status = dc_serial_write (device->port, command, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Get the correct ACK byte. @@ -446,10 +442,10 @@ oceanic_atom2_packet (oceanic_atom2_device_t *device, const unsigned char comman // Receive the response (ACK/NAK) of the dive computer. unsigned char response = 0; - n = serial_read (device->port, &response, 1); - if (n != 1) { + status = dc_serial_read (device->port, &response, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the response of the dive computer. @@ -460,10 +456,10 @@ oceanic_atom2_packet (oceanic_atom2_device_t *device, const unsigned char comman if (asize) { // Receive the answer of the dive computer. - int n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the checksum of the answer. @@ -509,8 +505,8 @@ oceanic_atom2_transfer (oceanic_atom2_device_t *device, const unsigned char comm device->delay++; // Delay the next attempt. - serial_sleep (device->port, 100); - serial_flush (device->port, SERIAL_QUEUE_INPUT); + dc_serial_sleep (device->port, 100); + dc_serial_purge (device->port, DC_DIRECTION_INPUT); } return DC_STATUS_SUCCESS; @@ -564,10 +560,9 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char memset(device->cache, 0, sizeof(device->cache)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } @@ -578,29 +573,28 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char } // Set the serial communication protocol (38400 8N1). - rc = serial_configure (device->port, baudrate, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, baudrate, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Give the interface 100 ms to settle and draw power up. - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); // Set the DTR/RTS lines. - serial_set_dtr(device->port, 1); - serial_set_rts(device->port, 1); + dc_serial_set_dtr(device->port, 1); + dc_serial_set_rts(device->port, 1); // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Switch the device from surface mode into download mode. Before sending // this command, the device needs to be in PC mode (automatically activated @@ -662,7 +656,7 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -674,13 +668,15 @@ oceanic_atom2_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; oceanic_atom2_device_t *device = (oceanic_atom2_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Send the quit command. oceanic_atom2_quit (device); // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/oceanic_veo250.c b/src/oceanic_veo250.c index 653d51e..93373a7 100644 --- a/src/oceanic_veo250.c +++ b/src/oceanic_veo250.c @@ -36,17 +36,12 @@ #define MAXRETRIES 2 #define MULTIPAGE 4 -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define ACK 0x5A #define NAK 0xA5 typedef struct oceanic_veo250_device_t { oceanic_common_device_t base; - serial_t *port; + dc_serial_t *port; unsigned int last; } oceanic_veo250_device_t; @@ -91,27 +86,28 @@ static const oceanic_common_layout_t oceanic_veo250_layout = { static dc_status_t oceanic_veo250_send (oceanic_veo250_device_t *device, const unsigned char command[], unsigned int csize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; // Discard garbage bytes. - serial_flush (device->port, SERIAL_QUEUE_INPUT); + dc_serial_purge (device->port, DC_DIRECTION_INPUT); // Send the command to the dive computer. - int n = serial_write (device->port, command, csize); - if (n != csize) { + status = dc_serial_write (device->port, command, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the response (ACK/NAK) of the dive computer. unsigned char response = NAK; - n = serial_read (device->port, &response, 1); - if (n != 1) { + status = dc_serial_read (device->port, &response, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the response of the dive computer. @@ -127,6 +123,7 @@ oceanic_veo250_send (oceanic_veo250_device_t *device, const unsigned char comman static dc_status_t oceanic_veo250_transfer (oceanic_veo250_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command to the device. If the device responds with an @@ -146,14 +143,14 @@ oceanic_veo250_transfer (oceanic_veo250_device_t *device, const unsigned char co return rc; // Delay the next attempt. - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); } // Receive the answer of the dive computer. - int n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the last byte of the answer. @@ -169,24 +166,26 @@ oceanic_veo250_transfer (oceanic_veo250_device_t *device, const unsigned char co static dc_status_t oceanic_veo250_init (oceanic_veo250_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command to the dive computer. unsigned char command[2] = {0x55, 0x00}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the answer of the dive computer. + size_t n = 0; unsigned char answer[13] = {0}; - n = serial_read (device->port, answer, sizeof (answer)); - if (n != sizeof (answer)) { + status = dc_serial_read (device->port, answer, sizeof (answer), &n); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); if (n == 0) return DC_STATUS_SUCCESS; - return EXITCODE (n); + return status; } // Verify the answer. @@ -205,14 +204,15 @@ oceanic_veo250_init (oceanic_veo250_device_t *device) static dc_status_t oceanic_veo250_quit (oceanic_veo250_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command to the dive computer. unsigned char command[2] = {0x98, 0x00}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -247,41 +247,45 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char device->last = 0; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (9600 8N1). - rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 9600, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000 ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Set the DTR and RTS lines. - if (serial_set_dtr (device->port, 1) == -1 || - serial_set_rts (device->port, 1) == -1) { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Set the DTR line. + status = dc_serial_set_dtr (device->port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the DTR line."); + goto error_close; + } + + // Set the RTS line. + status = dc_serial_set_rts (device->port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the RTS line."); goto error_close; } // Give the interface 100 ms to settle and draw power up. - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Initialize the data cable (PPS mode). status = oceanic_veo250_init (device); @@ -290,7 +294,7 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char } // Delay the sending of the version command. - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); // Switch the device from surface mode into download mode. Before sending // this command, the device needs to be in PC mode (manually activated by @@ -305,7 +309,7 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -317,13 +321,15 @@ oceanic_veo250_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; oceanic_veo250_device_t *device = (oceanic_veo250_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Switch the device back to surface mode. oceanic_veo250_quit (device); // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/oceanic_vtpro.c b/src/oceanic_vtpro.c index 040f23f..fdd993e 100644 --- a/src/oceanic_vtpro.c +++ b/src/oceanic_vtpro.c @@ -36,18 +36,13 @@ #define MAXRETRIES 2 #define MULTIPAGE 4 -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define ACK 0x5A #define NAK 0xA5 #define END 0x51 typedef struct oceanic_vtpro_device_t { oceanic_common_device_t base; - serial_t *port; + dc_serial_t *port; } 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); @@ -107,24 +102,25 @@ static const oceanic_common_layout_t oceanic_wisdom_layout = { static dc_status_t oceanic_vtpro_send (oceanic_vtpro_device_t *device, const unsigned char command[], unsigned int csize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; // Send the command to the dive computer. - int n = serial_write (device->port, command, csize); - if (n != csize) { + status = dc_serial_write (device->port, command, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the response (ACK/NAK) of the dive computer. unsigned char response = NAK; - n = serial_read (device->port, &response, 1); - if (n != 1) { + status = dc_serial_read (device->port, &response, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the response of the dive computer. @@ -140,6 +136,7 @@ oceanic_vtpro_send (oceanic_vtpro_device_t *device, const unsigned char command[ static dc_status_t oceanic_vtpro_transfer (oceanic_vtpro_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command to the device. If the device responds with an @@ -160,10 +157,10 @@ oceanic_vtpro_transfer (oceanic_vtpro_device_t *device, const unsigned char comm } // Receive the answer of the dive computer. - int n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -173,22 +170,23 @@ oceanic_vtpro_transfer (oceanic_vtpro_device_t *device, const unsigned char comm static dc_status_t oceanic_vtpro_init (oceanic_vtpro_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command to the dive computer. unsigned char command[2] = {0xAA, 0x00}; - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the answer of the dive computer. unsigned char answer[13] = {0}; - n = serial_read (device->port, answer, sizeof (answer)); - if (n != sizeof (answer)) { + status = dc_serial_read (device->port, answer, sizeof (answer), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the answer. @@ -236,9 +234,9 @@ oceanic_vtpro_calibrate (oceanic_vtpro_device_t *device) // device needs approximately 6 seconds to respond. unsigned char answer[2] = {0}; unsigned char command[2] = {0x18, 0x00}; - serial_set_timeout (device->port, 9000); + dc_serial_set_timeout (device->port, 9000); dc_status_t rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, sizeof (answer)); - serial_set_timeout (device->port, 3000); + dc_serial_set_timeout (device->port, 3000); if (rc != DC_STATUS_SUCCESS) return rc; @@ -278,41 +276,45 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char device->port = NULL; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (9600 8N1). - rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 9600, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000 ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Set the DTR and RTS lines. - if (serial_set_dtr (device->port, 1) == -1 || - serial_set_rts (device->port, 1) == -1) { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Set the DTR line. + status = dc_serial_set_dtr (device->port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the DTR line."); + goto error_close; + } + + // Set the RTS line. + status = dc_serial_set_rts (device->port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the RTS line."); goto error_close; } // Give the interface 100 ms to settle and draw power up. - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Initialize the data cable (MOD mode). status = oceanic_vtpro_init (device); @@ -348,7 +350,7 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -360,13 +362,15 @@ oceanic_vtpro_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; oceanic_vtpro_device_t *device = (oceanic_vtpro_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Switch the device back to surface mode. oceanic_vtpro_quit (device); // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; diff --git a/src/reefnet_sensus.c b/src/reefnet_sensus.c index 0660155..51e9a7f 100644 --- a/src/reefnet_sensus.c +++ b/src/reefnet_sensus.c @@ -32,17 +32,12 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &reefnet_sensus_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_MEMORY 32768 #define SZ_HANDSHAKE 10 typedef struct reefnet_sensus_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char handshake[SZ_HANDSHAKE]; unsigned int waiting; unsigned int timestamp; @@ -70,14 +65,15 @@ static const dc_device_vtable_t reefnet_sensus_device_vtable = { static dc_status_t reefnet_sensus_cancel (reefnet_sensus_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command to the device. unsigned char command = 0x00; - int n = serial_write (device->port, &command, 1); - if (n != 1) { + status = dc_serial_write (device->port, &command, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // The device leaves the waiting state. @@ -112,37 +108,35 @@ reefnet_sensus_device_open (dc_device_t **out, dc_context_t *context, const char memset (device->handshake, 0, sizeof (device->handshake)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (19200 8N1). - rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 19200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000 ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -154,15 +148,18 @@ reefnet_sensus_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; reefnet_sensus_device_t *device = (reefnet_sensus_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Safely close the connection if the last handshake was // successful, but no data transfer was ever initiated. if (device->waiting) reefnet_sensus_cancel (device); + // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -208,22 +205,23 @@ reefnet_sensus_device_set_fingerprint (dc_device_t *abstract, const unsigned cha static dc_status_t reefnet_sensus_handshake (reefnet_sensus_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Send the command to the device. unsigned char command = 0x0A; - int n = serial_write (device->port, &command, 1); - if (n != 1) { + status = dc_serial_write (device->port, &command, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the answer from the device. unsigned char handshake[SZ_HANDSHAKE + 2] = {0}; - n = serial_read (device->port, handshake, sizeof (handshake)); - if (n != sizeof (handshake)) { + status = dc_serial_read (device->port, handshake, sizeof (handshake), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the handshake."); - return EXITCODE (n); + return status; } // Verify the header of the packet. @@ -264,7 +262,7 @@ reefnet_sensus_handshake (reefnet_sensus_device_t *device) // Wait at least 10 ms to ensures the data line is // clear before transmission from the host begins. - serial_sleep (device->port, 10); + dc_serial_sleep (device->port, 10); return DC_STATUS_SUCCESS; } @@ -273,6 +271,7 @@ reefnet_sensus_handshake (reefnet_sensus_device_t *device) static dc_status_t reefnet_sensus_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; reefnet_sensus_device_t *device = (reefnet_sensus_device_t*) abstract; // Erase the current contents of the buffer and @@ -294,10 +293,10 @@ reefnet_sensus_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) // Send the command to the device. unsigned char command = 0x40; - int n = serial_write (device->port, &command, 1); - if (n != 1) { + status = dc_serial_write (device->port, &command, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // The device leaves the waiting state. @@ -311,10 +310,10 @@ reefnet_sensus_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) if (len > 128) len = 128; - n = serial_read (device->port, answer + nbytes, len); - if (n != len) { + status = dc_serial_read (device->port, answer + nbytes, len, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Update and emit a progress event. diff --git a/src/reefnet_sensuspro.c b/src/reefnet_sensuspro.c index 8e17f1e..b9c08db 100644 --- a/src/reefnet_sensuspro.c +++ b/src/reefnet_sensuspro.c @@ -32,17 +32,12 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &reefnet_sensuspro_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_MEMORY 56320 #define SZ_HANDSHAKE 10 typedef struct reefnet_sensuspro_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char handshake[SZ_HANDSHAKE]; unsigned int timestamp; unsigned int devtime; @@ -90,37 +85,35 @@ reefnet_sensuspro_device_open (dc_device_t **out, dc_context_t *context, const c memset (device->handshake, 0, sizeof (device->handshake)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (19200 8N1). - rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 19200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -132,10 +125,12 @@ reefnet_sensuspro_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; reefnet_sensuspro_device_t *device = (reefnet_sensuspro_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -181,21 +176,22 @@ reefnet_sensuspro_device_set_fingerprint (dc_device_t *abstract, const unsigned static dc_status_t reefnet_sensuspro_handshake (reefnet_sensuspro_device_t *device) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Assert a break condition. - serial_set_break (device->port, 1); + dc_serial_set_break (device->port, 1); // Receive the handshake from the dive computer. unsigned char handshake[SZ_HANDSHAKE + 2] = {0}; - int rc = serial_read (device->port, handshake, sizeof (handshake)); - if (rc != sizeof (handshake)) { + status = dc_serial_read (device->port, handshake, sizeof (handshake), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the handshake."); - return EXITCODE (rc); + return status; } // Clear the break condition again. - serial_set_break (device->port, 0); + dc_serial_set_break (device->port, 0); // Verify the checksum of the handshake packet. unsigned short crc = array_uint16_le (handshake + SZ_HANDSHAKE); @@ -231,7 +227,7 @@ reefnet_sensuspro_handshake (reefnet_sensuspro_device_t *device) vendor.size = sizeof (device->handshake); device_event_emit (abstract, DC_EVENT_VENDOR, &vendor); - serial_sleep (device->port, 10); + dc_serial_sleep (device->port, 10); return DC_STATUS_SUCCESS; } @@ -240,6 +236,7 @@ reefnet_sensuspro_handshake (reefnet_sensuspro_device_t *device) static dc_status_t reefnet_sensuspro_send (reefnet_sensuspro_device_t *device, unsigned char command) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Wake-up the device. @@ -248,10 +245,10 @@ reefnet_sensuspro_send (reefnet_sensuspro_device_t *device, unsigned char comman return rc; // Send the instruction code to the device. - int n = serial_write (device->port, &command, 1); - if (n != 1) { + status = dc_serial_write (device->port, &command, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -261,6 +258,7 @@ reefnet_sensuspro_send (reefnet_sensuspro_device_t *device, unsigned char comman static dc_status_t reefnet_sensuspro_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; reefnet_sensuspro_device_t *device = (reefnet_sensuspro_device_t*) abstract; // Erase the current contents of the buffer and @@ -287,10 +285,10 @@ reefnet_sensuspro_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) if (len > 256) len = 256; - int n = serial_read (device->port, answer + nbytes, len); - if (n != len) { + status = dc_serial_read (device->port, answer + nbytes, len, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Update and emit a progress event. @@ -338,6 +336,7 @@ reefnet_sensuspro_device_foreach (dc_device_t *abstract, dc_dive_callback_t call dc_status_t reefnet_sensuspro_device_write_interval (dc_device_t *abstract, unsigned char interval) { + dc_status_t status = DC_STATUS_SUCCESS; reefnet_sensuspro_device_t *device = (reefnet_sensuspro_device_t*) abstract; if (!ISINSTANCE (abstract)) @@ -351,12 +350,12 @@ reefnet_sensuspro_device_write_interval (dc_device_t *abstract, unsigned char in if (rc != DC_STATUS_SUCCESS) return rc; - serial_sleep (device->port, 10); + dc_serial_sleep (device->port, 10); - int n = serial_write (device->port, &interval, 1); - if (n != 1) { + status = dc_serial_write (device->port, &interval, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the data packet."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; diff --git a/src/reefnet_sensusultra.c b/src/reefnet_sensusultra.c index db070e6..ead2388 100644 --- a/src/reefnet_sensusultra.c +++ b/src/reefnet_sensusultra.c @@ -33,11 +33,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &reefnet_sensusultra_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_PACKET 512 #define SZ_MEMORY 2080768 #define SZ_USER 16384 @@ -51,7 +46,7 @@ typedef struct reefnet_sensusultra_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char handshake[SZ_HANDSHAKE]; unsigned int timestamp; unsigned int devtime; @@ -99,37 +94,35 @@ reefnet_sensusultra_device_open (dc_device_t **out, dc_context_t *context, const memset (device->handshake, 0, sizeof (device->handshake)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (115200 8N1). - rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -141,10 +134,12 @@ reefnet_sensusultra_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -190,14 +185,15 @@ reefnet_sensusultra_device_set_fingerprint (dc_device_t *abstract, const unsigne static dc_status_t reefnet_sensusultra_send_uchar (reefnet_sensusultra_device_t *device, unsigned char value) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Wait for the prompt byte. unsigned char prompt = 0; - int rc = serial_read (device->port, &prompt, 1); - if (rc != 1) { + status = dc_serial_read (device->port, &prompt, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the prompt byte"); - return EXITCODE (rc); + return status; } // Verify the prompt byte. @@ -207,10 +203,10 @@ reefnet_sensusultra_send_uchar (reefnet_sensusultra_device_t *device, unsigned c } // Send the value to the device. - rc = serial_write (device->port, &value, 1); - if (rc != 1) { + status = dc_serial_write (device->port, &value, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the value."); - return EXITCODE (rc); + return status; } return DC_STATUS_SUCCESS; @@ -239,18 +235,19 @@ reefnet_sensusultra_send_ushort (reefnet_sensusultra_device_t *device, unsigned static dc_status_t reefnet_sensusultra_packet (reefnet_sensusultra_device_t *device, unsigned char *data, unsigned int size, unsigned int header) { - assert (size >= header + 2); - + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; + assert (size >= header + 2); + if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; // Receive the data packet. - int rc = serial_read (device->port, data, size); - if (rc != size) { + status = dc_serial_read (device->port, data, size, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the packet."); - return EXITCODE (rc); + return status; } // Verify the checksum of the packet. @@ -349,7 +346,7 @@ static dc_status_t reefnet_sensusultra_send (reefnet_sensusultra_device_t *device, unsigned short command) { // Flush the input and output buffers. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Wake-up the device and send the instruction code. unsigned int nretries = 0; @@ -369,8 +366,8 @@ reefnet_sensusultra_send (reefnet_sensusultra_device_t *device, unsigned short c // not accidentally buffered by the host and (mis)interpreted as part // of the next packet. - serial_sleep (device->port, 250); - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep (device->port, 250); + dc_serial_purge (device->port, DC_DIRECTION_ALL); } return DC_STATUS_SUCCESS; diff --git a/src/serial.h b/src/serial.h index 5a9d8ea..ac94ec8 100644 --- a/src/serial.h +++ b/src/serial.h @@ -19,101 +19,303 @@ * MA 02110-1301 USA */ -#ifndef SERIAL_H -#define SERIAL_H +#ifndef DC_SERIAL_H +#define DC_SERIAL_H +#include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -typedef struct serial_t serial_t; +/** + * Opaque object representing a serial connection. + */ +typedef struct dc_serial_t dc_serial_t; -typedef enum serial_parity_t { - SERIAL_PARITY_NONE, - SERIAL_PARITY_EVEN, - SERIAL_PARITY_ODD -} serial_parity_t; +/** + * The parity checking scheme. + */ +typedef enum dc_parity_t { + DC_PARITY_NONE, /**< No parity */ + DC_PARITY_ODD, /**< Odd parity */ + DC_PARITY_EVEN, /**< Even parity */ + DC_PARITY_MARK, /**< Mark parity (always 1) */ + DC_PARITY_SPACE /**< Space parity (alwasy 0) */ +} dc_parity_t; -typedef enum serial_flowcontrol_t { - SERIAL_FLOWCONTROL_NONE, - SERIAL_FLOWCONTROL_HARDWARE, - SERIAL_FLOWCONTROL_SOFTWARE -} serial_flowcontrol_t; +/** + * The number of stop bits. + */ +typedef enum dc_stopbits_t { + DC_STOPBITS_ONE, /**< 1 stop bit */ + DC_STOPBITS_ONEPOINTFIVE, /**< 1.5 stop bits*/ + DC_STOPBITS_TWO /**< 2 stop bits */ +} dc_stopbits_t; -typedef enum serial_queue_t { - SERIAL_QUEUE_INPUT = 0x01, - SERIAL_QUEUE_OUTPUT = 0x02, - SERIAL_QUEUE_BOTH = SERIAL_QUEUE_INPUT | SERIAL_QUEUE_OUTPUT -} serial_queue_t; +/** + * The flow control. + */ +typedef enum dc_flowcontrol_t { + DC_FLOWCONTROL_NONE, /**< No flow control */ + DC_FLOWCONTROL_HARDWARE, /**< Hardware (RTS/CTS) flow control */ + DC_FLOWCONTROL_SOFTWARE /**< Software (XON/XOFF) flow control */ +} dc_flowcontrol_t; -typedef enum serial_line_t { - SERIAL_LINE_DCD, // Data carrier detect - SERIAL_LINE_CTS, // Clear to send - SERIAL_LINE_DSR, // Data set ready - SERIAL_LINE_RNG, // Ring indicator -} serial_line_t; +/** + * The direction of the data transmission. + */ +typedef enum dc_direction_t { + DC_DIRECTION_INPUT = 0x01, /**< Input direction */ + DC_DIRECTION_OUTPUT = 0x02, /**< Output direction */ + DC_DIRECTION_ALL = DC_DIRECTION_INPUT | DC_DIRECTION_OUTPUT /**< All directions */ +} dc_direction_t; -typedef void (*serial_callback_t) (const char *name, void *userdata); +/** + * The serial line signals. + */ +typedef enum dc_line_t { + DC_LINE_DCD = 0x01, /**< Data carrier detect */ + DC_LINE_CTS = 0x02, /**< Clear to send */ + DC_LINE_DSR = 0x04, /**< Data set ready */ + DC_LINE_RNG = 0x08, /**< Ring indicator */ +} dc_line_t; -int serial_enumerate (serial_callback_t callback, void *userdata); +/** + * Serial enumeration callback. + * + * @param[in] name The name of the device node. + * @param[in] userdata The user data pointer. + */ +typedef void (*dc_serial_callback_t) (const char *name, void *userdata); -int serial_open (serial_t **device, dc_context_t *context, const char* name); +/** + * Enumerate the serial ports. + * + * @param[in] callback The callback function to call. + * @param[in] userdata User data to pass to the callback function. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_enumerate (dc_serial_callback_t callback, void *userdata); -int serial_close (serial_t *device); +/** + * Open a serial connection. + * + * @param[out] serial A location to store the serial connection. + * @param[in] context A valid context object. + * @param[in] name The name of the device node. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_open (dc_serial_t **serial, dc_context_t *context, const char *name); -int serial_configure (serial_t *device, int baudrate, int databits, int parity, int stopbits, int flowcontrol); +/** + * Close the serial connection and free all resources. + * + * @param[in] serial A valid serial connection. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_close (dc_serial_t *serial); -// -// Available read modes: -// -// * Blocking (timeout < 0): -// -// The read function is blocked until all the requested bytes have -// been received. If the requested number of bytes does not arrive, -// the function will block forever. -// -// * Non-blocking (timeout == 0): -// -// The read function returns immediately with the bytes that have already -// been received, even if no bytes have been received. -// -// * Timeout (timeout > 0): -// -// The read function is blocked until all the requested bytes have -// been received. If the requested number of bytes does not arrive -// within the specified amount of time, the function will return -// with the bytes that have already been received. -// +/** + * Configure the serial line settings of the connection. + * + * @param[in] serial A valid serial connection. + * @param[in] baudrate The baud rate setting. + * @param[in] databits The number of data bits. + * @param[in] parity The parity setting. + * @param[in] stopbits The number of stop bits. + * @param[in] flowcontrol The flow control setting. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_configure (dc_serial_t *serial, unsigned int baudrate, unsigned int databits, dc_parity_t parity, dc_stopbits_t stopbits, dc_flowcontrol_t flowcontrol); -int serial_set_timeout (serial_t *device, long timeout /* milliseconds */); +/** + * Set the read timeout. + * + * There are three distinct modes available: + * + * 1. Blocking (timeout < 0): + * + * The read operation is blocked until all the requested bytes have + * been received. If the requested number of bytes does not arrive, + * the operation will block forever. + * + * 2. Non-blocking (timeout == 0): + * + * The read operation returns immediately with the bytes that have + * already been received, even if no bytes have been received. + * + * 3. Timeout (timeout > 0): + * + * The read operation is blocked until all the requested bytes have + * been received. If the requested number of bytes does not arrive + * within the specified amount of time, the operation will return + * with the bytes that have already been received. + * + * @param[in] serial A valid serial connection. + * @param[in] timeout The timeout in milliseconds. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_set_timeout (dc_serial_t *serial, int timeout); -int serial_set_queue_size (serial_t *device, unsigned int input, unsigned int output); +/** + * Set the state of the half duplex emulation. + * + * @param[in] serial A valid serial connection. + * @param[in] value The half duplex state. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_set_halfduplex (dc_serial_t *serial, unsigned int value); -int serial_set_halfduplex (serial_t *device, int value); +/** + * Set the receive latency. + * + * The effect of this setting is highly platform and driver specific. On + * Windows it does nothing at all, on Linux it controls the low latency + * flag (e.g. only zero vs non-zero latency), and on Mac OS X it sets + * the receive latency as requested. + * + * @param[in] serial A valid serial connection. + * @param[in] value The latency in milliseconds. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_set_latency (dc_serial_t *serial, unsigned int value); -int serial_set_latency (serial_t *device, unsigned int milliseconds); +/** + * Read data from the serial connection. + * + * @param[in] serial A valid serial connection. + * @param[out] data The memory buffer to read the data into. + * @param[in] size The number of bytes to read. + * @param[out] actual An (optional) location to store the actual + * number of bytes transferred. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_read (dc_serial_t *serial, void *data, size_t size, size_t *actual); -int serial_read (serial_t *device, void* data, unsigned int size); -int serial_write (serial_t *device, const void* data, unsigned int size); +/** + * Write data to the serial connection. + * + * @param[in] serial A valid serial connection. + * @param[in] data The memory buffer to write the data from. + * @param[in] size The number of bytes to write. + * @param[out] actual An (optional) location to store the actual + * number of bytes transferred. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_write (dc_serial_t *serial, const void *data, size_t size, size_t *actual); -int serial_flush (serial_t *device, int queue); +/** + * Flush the internal output buffer and wait until the data has been + * transmitted. + * + * @param[in] serial A valid serial connection. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_flush (dc_serial_t *serial); -int serial_send_break (serial_t *device); +/** + * Discards all data from the internal buffers. + * + * @param[in] serial A valid serial connection. + * @param[in] direction The direction of the buffer(s). + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_purge (dc_serial_t *serial, dc_direction_t direction); -int serial_set_break (serial_t *device, int level); -int serial_set_dtr (serial_t *device, int level); -int serial_set_rts (serial_t *device, int level); +/** + * Set the state of the break condition. + * + * @param[in] serial A valid serial connection. + * @param[in] value The break condition state. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_set_break (dc_serial_t *serial, unsigned int value); -int serial_get_received (serial_t *device); -int serial_get_transmitted (serial_t *device); +/** + * Set the state of the DTR line. + * + * @param[in] serial A valid serial connection. + * @param[in] value The DTR line state. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_set_dtr (dc_serial_t *serial, unsigned int value); -int serial_get_line (serial_t *device, int line); +/** + * Set the state of the RTS line. + * + * @param[in] serial A valid serial connection. + * @param[in] value The RTS line state. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_set_rts (dc_serial_t *serial, unsigned int value); -int serial_sleep (serial_t *device, unsigned long timeout /* milliseconds */); +/** + * Query the number of available bytes in the input buffer. + * + * @param[in] serial A valid serial connection. + * @param[out] value A location to store the number of bytes in the + * input buffer. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_get_available (dc_serial_t *serial, size_t *value); + +/** + * Query the state of the line signals. + * + * @param[in] serial A valid serial connection. + * @param[out] value A location to store the bitmap with the state of + * the line signals. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_get_lines (dc_serial_t *serial, unsigned int *value); + +/** + * Suspend execution of the current thread for the specified amount of + * time. + * + * @param[in] serial A valid serial connection. + * @param[in] milliseconds The number of milliseconds to sleep. + * @returns #DC_STATUS_SUCCESS on success, or another #dc_status_t code + * on failure. + */ +dc_status_t +dc_serial_sleep (dc_serial_t *serial, unsigned int milliseconds); #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* SERIAL_H */ +#endif /* DC_SERIAL_H */ diff --git a/src/serial_posix.c b/src/serial_posix.c index b67ddb7..c33882a 100644 --- a/src/serial_posix.c +++ b/src/serial_posix.c @@ -54,16 +54,17 @@ #endif #include "serial.h" +#include "common-private.h" #include "context-private.h" -struct serial_t { +struct dc_serial_t { /* Library context. */ dc_context_t *context; /* * The file descriptor corresponding to the serial port. */ int fd; - long timeout; + int timeout; /* * Serial port settings are saved into this variable immediately * after the port is opened. These settings are restored when the @@ -77,8 +78,8 @@ struct serial_t { }; -int -serial_enumerate (serial_callback_t callback, void *userdata) +dc_status_t +dc_serial_enumerate (dc_serial_callback_t callback, void *userdata) { DIR *dp = NULL; struct dirent *ep = NULL; @@ -97,7 +98,7 @@ serial_enumerate (serial_callback_t callback, void *userdata) dp = opendir (dirname); if (dp == NULL) { - return -1; + return DC_STATUS_IO; } while ((ep = readdir (dp)) != NULL) { @@ -107,7 +108,7 @@ serial_enumerate (serial_callback_t callback, void *userdata) int n = snprintf (filename, sizeof (filename), "%s/%s", dirname, ep->d_name); if (n >= sizeof (filename)) { closedir (dp); - return -1; + return DC_STATUS_NOMEMORY; } callback (filename, userdata); @@ -118,27 +119,24 @@ serial_enumerate (serial_callback_t callback, void *userdata) closedir (dp); - return 0; + return DC_STATUS_SUCCESS; } - -// -// Open the serial port. -// - -int -serial_open (serial_t **out, dc_context_t *context, const char* name) +dc_status_t +dc_serial_open (dc_serial_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + if (out == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; INFO (context, "Open: name=%s", name ? name : ""); // Allocate memory. - serial_t *device = (serial_t *) malloc (sizeof (serial_t)); + dc_serial_t *device = (dc_serial_t *) malloc (sizeof (dc_serial_t)); if (device == NULL) { SYSERROR (context, ENOMEM); - return -1; // ENOMEM (Not enough space) + return DC_STATUS_NOMEMORY; } // Library context. @@ -157,6 +155,7 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) device->fd = open (name, O_RDWR | O_NOCTTY | O_NONBLOCK); if (device->fd == -1) { SYSERROR (context, errno); + status = DC_STATUS_IO; goto error_free; } @@ -164,6 +163,7 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) // Enable exclusive access mode. if (ioctl (device->fd, TIOCEXCL, NULL) != 0) { SYSERROR (context, errno); + status = DC_STATUS_IO; goto error_close; } #endif @@ -174,36 +174,33 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) // file descriptor represents a terminal device. if (tcgetattr (device->fd, &device->tty) != 0) { SYSERROR (context, errno); + status = DC_STATUS_IO; goto error_close; } *out = device; - return 0; + return DC_STATUS_SUCCESS; error_close: close (device->fd); error_free: free (device); - return -1; + return status; } -// -// Close the serial port. -// - -int -serial_close (serial_t *device) +dc_status_t +dc_serial_close (dc_serial_t *device) { - int errcode = 0; + dc_status_t status = DC_STATUS_SUCCESS; if (device == NULL) - return 0; + return DC_STATUS_SUCCESS; // Restore the initial terminal attributes. if (tcsetattr (device->fd, TCSANOW, &device->tty) != 0) { SYSERROR (device->context, errno); - errcode = -1; + dc_status_set_error(&status, DC_STATUS_IO); } #ifndef ENABLE_PTY @@ -214,24 +211,20 @@ serial_close (serial_t *device) // Close the device. if (close (device->fd) != 0) { SYSERROR (device->context, errno); - errcode = -1; + dc_status_set_error(&status, DC_STATUS_IO); } // Free memory. free (device); - return errcode; + return status; } -// -// Configure the serial port (baudrate, databits, parity, stopbits and flowcontrol). -// - -int -serial_configure (serial_t *device, int baudrate, int databits, int parity, int stopbits, int flowcontrol) +dc_status_t +dc_serial_configure (dc_serial_t *device, unsigned int baudrate, unsigned int databits, dc_parity_t parity, dc_stopbits_t stopbits, dc_flowcontrol_t flowcontrol) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; INFO (device->context, "Configure: baudrate=%i, databits=%i, parity=%i, stopbits=%i, flowcontrol=%i", baudrate, databits, parity, stopbits, flowcontrol); @@ -241,7 +234,7 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int memset (&tty, 0, sizeof (tty)); if (tcgetattr (device->fd, &tty) != 0) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } // Setup raw input/output mode without echo. @@ -337,7 +330,7 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int if (cfsetispeed (&tty, baud) != 0 || cfsetospeed (&tty, baud) != 0) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } // Set the character size. @@ -356,70 +349,70 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int tty.c_cflag |= CS8; break; default: - return -1; + return DC_STATUS_INVALIDARGS; } // Set the parity type. tty.c_cflag &= ~(PARENB | PARODD); tty.c_iflag &= ~(IGNPAR | PARMRK | INPCK); switch (parity) { - case SERIAL_PARITY_NONE: // No parity + case DC_PARITY_NONE: tty.c_iflag |= IGNPAR; break; - case SERIAL_PARITY_EVEN: // Even parity + case DC_PARITY_EVEN: tty.c_cflag |= PARENB; tty.c_iflag |= INPCK; break; - case SERIAL_PARITY_ODD: // Odd parity + case DC_PARITY_ODD: tty.c_cflag |= (PARENB | PARODD); tty.c_iflag |= INPCK; break; default: - return -1; + return DC_STATUS_INVALIDARGS; } // Set the number of stop bits. switch (stopbits) { - case 1: // One stopbit + case DC_STOPBITS_ONE: tty.c_cflag &= ~CSTOPB; break; - case 2: // Two stopbits + case DC_STOPBITS_TWO: tty.c_cflag |= CSTOPB; break; default: - return -1; + return DC_STATUS_INVALIDARGS; } // Set the flow control. switch (flowcontrol) { - case SERIAL_FLOWCONTROL_NONE: // No flow control. + case DC_FLOWCONTROL_NONE: #ifdef CRTSCTS tty.c_cflag &= ~CRTSCTS; #endif tty.c_iflag &= ~(IXON | IXOFF | IXANY); break; - case SERIAL_FLOWCONTROL_HARDWARE: // Hardware (RTS/CTS) flow control. + case DC_FLOWCONTROL_HARDWARE: #ifdef CRTSCTS tty.c_cflag |= CRTSCTS; tty.c_iflag &= ~(IXON | IXOFF | IXANY); break; #else - return -1; // Hardware flow control is unsupported. + return DC_STATUS_UNSUPPORTED; #endif - case SERIAL_FLOWCONTROL_SOFTWARE: // Software (XON/XOFF) flow control. + case DC_FLOWCONTROL_SOFTWARE: #ifdef CRTSCTS tty.c_cflag &= ~CRTSCTS; #endif tty.c_iflag |= (IXON | IXOFF); break; default: - return -1; + return DC_STATUS_INVALIDARGS; } // Apply the new settings. if (tcsetattr (device->fd, TCSANOW, &tty) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } // Configure a custom baudrate if necessary. @@ -429,7 +422,7 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int struct serial_struct ss; if (ioctl (device->fd, TIOCGSERIAL, &ss) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } // Set the custom divisor. @@ -440,81 +433,62 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int // Apply the new settings. if (ioctl (device->fd, TIOCSSERIAL, &ss) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } #elif defined(IOSSIOSPEED) speed_t speed = baudrate; if (ioctl (device->fd, IOSSIOSPEED, &speed) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } #else // Custom baudrates are not supported. - return -1; + return DC_STATUS_UNSUPPORTED; #endif } device->baudrate = baudrate; device->nbits = 1 + databits + stopbits + (parity ? 1 : 0); - return 0; + return DC_STATUS_SUCCESS; } -// -// Configure the serial port (timeouts). -// - -int -serial_set_timeout (serial_t *device, long timeout) +dc_status_t +dc_serial_set_timeout (dc_serial_t *device, int timeout) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; - INFO (device->context, "Timeout: value=%li", timeout); + INFO (device->context, "Timeout: value=%i", timeout); device->timeout = timeout; - return 0; + return DC_STATUS_SUCCESS; } - -// -// Configure the serial port (recommended size of the input/output buffers). -// - -int -serial_set_queue_size (serial_t *device, unsigned int input, unsigned int output) +dc_status_t +dc_serial_set_halfduplex (dc_serial_t *device, unsigned int value) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) - - return 0; -} - - -int -serial_set_halfduplex (serial_t *device, int value) -{ - if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; device->halfduplex = value; - return 0; + return DC_STATUS_SUCCESS; } -int -serial_set_latency (serial_t *device, unsigned int milliseconds) +dc_status_t +dc_serial_set_latency (dc_serial_t *device, unsigned int milliseconds) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; #if defined(TIOCGSERIAL) && defined(TIOCSSERIAL) && !defined(__ANDROID__) // Get the current settings. struct serial_struct ss; if (ioctl (device->fd, TIOCGSERIAL, &ss) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } // Set or clear the low latency flag. @@ -527,7 +501,7 @@ serial_set_latency (serial_t *device, unsigned int milliseconds) // Apply the new settings. if (ioctl (device->fd, TIOCSSERIAL, &ss) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } #elif defined(IOSSDATALAT) // Set the receive latency in microseconds. Serial drivers use this @@ -536,27 +510,31 @@ serial_set_latency (serial_t *device, unsigned int milliseconds) unsigned long usec = (milliseconds == 0 ? 1 : milliseconds * 1000); if (ioctl (device->fd, IOSSDATALAT, &usec) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } #endif - return 0; + return DC_STATUS_SUCCESS; } -int -serial_read (serial_t *device, void *data, unsigned int size) +dc_status_t +dc_serial_read (dc_serial_t *device, void *data, size_t size, size_t *actual) { - if (device == NULL) - return -1; // EINVAL (Invalid argument) + dc_status_t status = DC_STATUS_SUCCESS; + size_t nbytes = 0; + + if (device == NULL) { + status = DC_STATUS_INVALIDARGS; + goto out; + } // The total timeout. - long timeout = device->timeout; + int timeout = device->timeout; // The absolute target time. struct timeval tve; int init = 1; - unsigned int nbytes = 0; while (nbytes < size) { fd_set fds; FD_ZERO (&fds); @@ -567,7 +545,8 @@ serial_read (serial_t *device, void *data, unsigned int size) struct timeval now; if (gettimeofday (&now, NULL) != 0) { SYSERROR (device->context, errno); - return -1; + status = DC_STATUS_IO; + goto out; } if (init) { @@ -593,17 +572,19 @@ serial_read (serial_t *device, void *data, unsigned int size) if (errno == EINTR) continue; // Retry. SYSERROR (device->context, errno); - return -1; // Error during select call. + status = DC_STATUS_IO; + goto out; } else if (rc == 0) { break; // Timeout. } - int n = read (device->fd, (char *) data + nbytes, size - nbytes); + ssize_t n = read (device->fd, (char *) data + nbytes, size - nbytes); if (n < 0) { if (errno == EINTR || errno == EAGAIN) continue; // Retry. SYSERROR (device->context, errno); - return -1; // Error during read call. + status = DC_STATUS_IO; + goto out; } else if (n == 0) { break; // EOF. } @@ -611,28 +592,40 @@ serial_read (serial_t *device, void *data, unsigned int size) nbytes += n; } + if (nbytes != size) { + status = DC_STATUS_TIMEOUT; + } + +out: HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Read", (unsigned char *) data, nbytes); - return nbytes; + if (actual) + *actual = nbytes; + + return status; } - -int -serial_write (serial_t *device, const void *data, unsigned int size) +dc_status_t +dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *actual) { - if (device == NULL) - return -1; // EINVAL (Invalid argument) + dc_status_t status = DC_STATUS_SUCCESS; + size_t nbytes = 0; + + if (device == NULL) { + status = DC_STATUS_INVALIDARGS; + goto out; + } struct timeval tve, tvb; if (device->halfduplex) { // Get the current time. if (gettimeofday (&tvb, NULL) != 0) { SYSERROR (device->context, errno); - return -1; + status = DC_STATUS_IO; + goto out; } } - unsigned int nbytes = 0; while (nbytes < size) { fd_set fds; FD_ZERO (&fds); @@ -643,17 +636,19 @@ serial_write (serial_t *device, const void *data, unsigned int size) if (errno == EINTR) continue; // Retry. SYSERROR (device->context, errno); - return -1; // Error during select call. + status = DC_STATUS_IO; + goto out; } else if (rc == 0) { break; // Timeout. } - int n = write (device->fd, (char *) data + nbytes, size - nbytes); + ssize_t n = write (device->fd, (const char *) data + nbytes, size - nbytes); if (n < 0) { if (errno == EINTR || errno == EAGAIN) continue; // Retry. SYSERROR (device->context, errno); - return -1; // Error during write call. + status = DC_STATUS_IO; + goto out; } else if (n == 0) { break; // EOF. } @@ -670,7 +665,8 @@ serial_write (serial_t *device, const void *data, unsigned int size) #endif if (errno != EINTR ) { SYSERROR (device->context, errno); - return -1; + status = DC_STATUS_IO; + goto out; } } @@ -678,7 +674,8 @@ serial_write (serial_t *device, const void *data, unsigned int size) // Get the current time. if (gettimeofday (&tve, NULL) != 0) { SYSERROR (device->context, errno); - return -1; + status = DC_STATUS_IO; + goto out; } // Calculate the elapsed time (microseconds). @@ -697,69 +694,67 @@ serial_write (serial_t *device, const void *data, unsigned int size) // The remaining time is rounded up to the nearest millisecond to // match the Windows implementation. The higher resolution is // pointless anyway, since we already added a fudge factor above. - serial_sleep (device, (remaining + 999) / 1000); + dc_serial_sleep (device, (remaining + 999) / 1000); } } +out: HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (unsigned char *) data, nbytes); - return nbytes; + if (actual) + *actual = nbytes; + + return status; } - -int -serial_flush (serial_t *device, int queue) +dc_status_t +dc_serial_purge (dc_serial_t *device, dc_direction_t direction) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; - INFO (device->context, "Flush: queue=%u, input=%i, output=%i", queue, - serial_get_received (device), - serial_get_transmitted (device)); + INFO (device->context, "Purge: direction=%u", direction); int flags = 0; - switch (queue) { - case SERIAL_QUEUE_INPUT: + switch (direction) { + case DC_DIRECTION_INPUT: flags = TCIFLUSH; break; - case SERIAL_QUEUE_OUTPUT: + case DC_DIRECTION_OUTPUT: flags = TCOFLUSH; break; - default: + case DC_DIRECTION_ALL: flags = TCIOFLUSH; break; + default: + return DC_STATUS_INVALIDARGS; } if (tcflush (device->fd, flags) != 0) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } - -int -serial_send_break (serial_t *device) +dc_status_t +dc_serial_flush (dc_serial_t *device) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; - if (tcsendbreak (device->fd, 0) != 0) { - SYSERROR (device->context, errno); - return -1; - } - - return 0; + INFO (device->context, "Flush: none"); + + return DC_STATUS_SUCCESS; } - -int -serial_set_break (serial_t *device, int level) +dc_status_t +dc_serial_set_break (dc_serial_t *device, unsigned int level) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; INFO (device->context, "Break: value=%i", level); @@ -767,18 +762,17 @@ serial_set_break (serial_t *device, int level) if (ioctl (device->fd, action, NULL) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } - -int -serial_set_dtr (serial_t *device, int level) +dc_status_t +dc_serial_set_dtr (dc_serial_t *device, unsigned int level) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; INFO (device->context, "DTR: value=%i", level); @@ -787,18 +781,17 @@ serial_set_dtr (serial_t *device, int level) int value = TIOCM_DTR; if (ioctl (device->fd, action, &value) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } - -int -serial_set_rts (serial_t *device, int level) +dc_status_t +dc_serial_set_rts (dc_serial_t *device, unsigned int level) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; INFO (device->context, "RTS: value=%i", level); @@ -807,81 +800,66 @@ serial_set_rts (serial_t *device, int level) int value = TIOCM_RTS; if (ioctl (device->fd, action, &value) != 0 && NOPTY) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } - -int -serial_get_received (serial_t *device) +dc_status_t +dc_serial_get_available (dc_serial_t *device, size_t *value) { if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; int bytes = 0; if (ioctl (device->fd, TIOCINQ, &bytes) != 0) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } - return bytes; + if (value) + *value = bytes; + + return DC_STATUS_SUCCESS; } - -int -serial_get_transmitted (serial_t *device) +dc_status_t +dc_serial_get_lines (dc_serial_t *device, unsigned int *value) { + unsigned int lines = 0; + if (device == NULL) - return -1; // EINVAL (Invalid argument) - - int bytes = 0; - if (ioctl (device->fd, TIOCOUTQ, &bytes) != 0) { - SYSERROR (device->context, errno); - return -1; - } - - return bytes; -} - - -int -serial_get_line (serial_t *device, int line) -{ - if (device == NULL) - return -1; // EINVAL (Invalid argument) + return DC_STATUS_INVALIDARGS; int status = 0; if (ioctl (device->fd, TIOCMGET, &status) != 0) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } - switch (line) { - case SERIAL_LINE_DCD: - return (status & TIOCM_CAR) == TIOCM_CAR; - case SERIAL_LINE_CTS: - return (status & TIOCM_CTS) == TIOCM_CTS; - case SERIAL_LINE_DSR: - return (status & TIOCM_DSR) == TIOCM_DSR; - case SERIAL_LINE_RNG: - return (status & TIOCM_RNG) == TIOCM_RNG; - default: - return -1; - } + if (status & TIOCM_CAR) + lines |= DC_LINE_DCD; + if (status & TIOCM_CTS) + lines |= DC_LINE_CTS; + if (status & TIOCM_DSR) + lines |= DC_LINE_DSR; + if (status & TIOCM_RNG) + lines |= DC_LINE_RNG; - return 0; + if (value) + *value = lines; + + return DC_STATUS_SUCCESS; } - -int -serial_sleep (serial_t *device, unsigned long timeout) +dc_status_t +dc_serial_sleep (dc_serial_t *device, unsigned int timeout) { if (device == NULL) - return -1; + return DC_STATUS_INVALIDARGS; - INFO (device->context, "Sleep: value=%lu", timeout); + INFO (device->context, "Sleep: value=%u", timeout); struct timespec ts; ts.tv_sec = (timeout / 1000); @@ -890,9 +868,9 @@ serial_sleep (serial_t *device, unsigned long timeout) while (nanosleep (&ts, &ts) != 0) { if (errno != EINTR ) { SYSERROR (device->context, errno); - return -1; + return DC_STATUS_IO; } } - return 0; + return DC_STATUS_SUCCESS; } diff --git a/src/serial_win32.c b/src/serial_win32.c index 56c3866..a7dd039 100644 --- a/src/serial_win32.c +++ b/src/serial_win32.c @@ -25,9 +25,10 @@ #include #include "serial.h" +#include "common-private.h" #include "context-private.h" -struct serial_t { +struct dc_serial_t { /* Library context. */ dc_context_t *context; /* @@ -47,17 +48,17 @@ struct serial_t { unsigned int nbits; }; -int -serial_enumerate (serial_callback_t callback, void *userdata) +dc_status_t +dc_serial_enumerate (dc_serial_callback_t callback, void *userdata) { // Open the registry key. HKEY hKey; LONG rc = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey); if (rc != ERROR_SUCCESS) { if (rc == ERROR_FILE_NOT_FOUND) - return 0; + return DC_STATUS_SUCCESS; else - return -1; + return DC_STATUS_IO; } // Get the number of values. @@ -65,7 +66,7 @@ serial_enumerate (serial_callback_t callback, void *userdata) rc = RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL); if (rc != ERROR_SUCCESS) { RegCloseKey(hKey); - return -1; + return DC_STATUS_IO; } for (DWORD i = 0; i < count; ++i) { @@ -77,7 +78,7 @@ serial_enumerate (serial_callback_t callback, void *userdata) rc = RegEnumValueA (hKey, i, name, &name_len, NULL, &type, (LPBYTE) data, &data_len); if (rc != ERROR_SUCCESS) { RegCloseKey(hKey); - return -1; + return DC_STATUS_IO; } // Ignore non-string values. @@ -87,7 +88,7 @@ serial_enumerate (serial_callback_t callback, void *userdata) // Prevent a possible buffer overflow. if (data_len >= sizeof (data)) { RegCloseKey(hKey); - return -1; + return DC_STATUS_NOMEMORY; } // Null terminate the string. @@ -98,18 +99,16 @@ serial_enumerate (serial_callback_t callback, void *userdata) RegCloseKey(hKey); - return 0; + return DC_STATUS_SUCCESS; } -// -// Open the serial port. -// - -int -serial_open (serial_t **out, dc_context_t *context, const char* name) +dc_status_t +dc_serial_open (dc_serial_t **out, dc_context_t *context, const char *name) { + dc_status_t status = DC_STATUS_SUCCESS; + if (out == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; INFO (context, "Open: name=%s", name ? name : ""); @@ -119,7 +118,7 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) if (name && strncmp (name, buffer, 4) != 0) { size_t length = strlen (name) + 1; if (length + 4 > sizeof (buffer)) - return -1; + return DC_STATUS_NOMEMORY; memcpy (buffer + 4, name, length); devname = buffer; } else { @@ -127,10 +126,10 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) } // Allocate memory. - serial_t *device = (serial_t *) malloc (sizeof (serial_t)); + dc_serial_t *device = (dc_serial_t *) malloc (sizeof (dc_serial_t)); if (device == NULL) { SYSERROR (context, ERROR_OUTOFMEMORY); - return -1; // ERROR_OUTOFMEMORY (Not enough storage is available to complete this operation) + return DC_STATUS_NOMEMORY; } // Library context. @@ -150,6 +149,7 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) NULL); if (device->hFile == INVALID_HANDLE_VALUE) { SYSERROR (context, GetLastError ()); + status = DC_STATUS_IO; goto error_free; } @@ -160,60 +160,53 @@ serial_open (serial_t **out, dc_context_t *context, const char* name) if (!GetCommState (device->hFile, &device->dcb) || !GetCommTimeouts (device->hFile, &device->timeouts)) { SYSERROR (context, GetLastError ()); + status = DC_STATUS_IO; goto error_close; } *out = device; - return 0; + return DC_STATUS_SUCCESS; error_close: CloseHandle (device->hFile); error_free: free (device); - return -1; + return status; } -// -// Close the serial port. -// - -int -serial_close (serial_t *device) +dc_status_t +dc_serial_close (dc_serial_t *device) { - int errcode = 0; + dc_status_t status = DC_STATUS_SUCCESS; if (device == NULL) - return 0; + return DC_STATUS_SUCCESS; // Restore the initial communication settings and timeouts. if (!SetCommState (device->hFile, &device->dcb) || !SetCommTimeouts (device->hFile, &device->timeouts)) { SYSERROR (device->context, GetLastError ()); - errcode = -1; + dc_status_set_error(&status, DC_STATUS_IO); } // Close the device. if (!CloseHandle (device->hFile)) { SYSERROR (device->context, GetLastError ()); - errcode = -1; + dc_status_set_error(&status, DC_STATUS_IO); } // Free memory. free (device); - return errcode; + return status; } -// -// Configure the serial port (baudrate, databits, parity, stopbits and flowcontrol). -// - -int -serial_configure (serial_t *device, int baudrate, int databits, int parity, int stopbits, int flowcontrol) +dc_status_t +dc_serial_configure (dc_serial_t *device, unsigned int baudrate, unsigned int databits, dc_parity_t parity, dc_stopbits_t stopbits, dc_flowcontrol_t flowcontrol) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; INFO (device->context, "Configure: baudrate=%i, databits=%i, parity=%i, stopbits=%i, flowcontrol=%i", baudrate, databits, parity, stopbits, flowcontrol); @@ -222,7 +215,7 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int DCB dcb; if (!GetCommState (device->hFile, &dcb)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } dcb.fBinary = TRUE; // Enable Binary Transmission @@ -235,40 +228,41 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int if (databits >= 5 && databits <= 8) dcb.ByteSize = databits; else - return -1; + return DC_STATUS_INVALIDARGS; // Parity checking. switch (parity) { - case SERIAL_PARITY_NONE: // No parity + case DC_PARITY_NONE: dcb.Parity = NOPARITY; dcb.fParity = FALSE; break; - case SERIAL_PARITY_EVEN: // Even parity + case DC_PARITY_EVEN: dcb.Parity = EVENPARITY; dcb.fParity = TRUE; break; - case SERIAL_PARITY_ODD: // Odd parity + case DC_PARITY_ODD: dcb.Parity = ODDPARITY; dcb.fParity = TRUE; break; default: - return -1; + return DC_STATUS_INVALIDARGS; } + // Stopbits. switch (stopbits) { - case 1: // One stopbit + case DC_STOPBITS_ONE: dcb.StopBits = ONESTOPBIT; break; - case 2: // Two stopbits + case DC_STOPBITS_TWO: dcb.StopBits = TWOSTOPBITS; break; default: - return -1; + return DC_STATUS_INVALIDARGS; } // Flow control. switch (flowcontrol) { - case SERIAL_FLOWCONTROL_NONE: // No flow control. + case DC_FLOWCONTROL_NONE: dcb.fInX = FALSE; dcb.fOutX = FALSE; dcb.fOutxCtsFlow = FALSE; @@ -276,7 +270,7 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fRtsControl = RTS_CONTROL_ENABLE; break; - case SERIAL_FLOWCONTROL_HARDWARE: // Hardware (RTS/CTS) flow control. + case DC_FLOWCONTROL_HARDWARE: dcb.fInX = FALSE; dcb.fOutX = FALSE; dcb.fOutxCtsFlow = TRUE; @@ -284,7 +278,7 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; break; - case SERIAL_FLOWCONTROL_SOFTWARE: // Software (XON/XOFF) flow control. + case DC_FLOWCONTROL_SOFTWARE: dcb.fInX = TRUE; dcb.fOutX = TRUE; dcb.fOutxCtsFlow = FALSE; @@ -293,38 +287,34 @@ serial_configure (serial_t *device, int baudrate, int databits, int parity, int dcb.fRtsControl = RTS_CONTROL_ENABLE; break; default: - return -1; + return DC_STATUS_INVALIDARGS; } // Apply the new settings. if (!SetCommState (device->hFile, &dcb)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } device->baudrate = baudrate; device->nbits = 1 + databits + stopbits + (parity ? 1 : 0); - return 0; + return DC_STATUS_SUCCESS; } -// -// Configure the serial port (timeouts). -// - -int -serial_set_timeout (serial_t *device, long timeout) +dc_status_t +dc_serial_set_timeout (dc_serial_t *device, int timeout) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; - INFO (device->context, "Timeout: value=%li", timeout); + INFO (device->context, "Timeout: value=%i", timeout); // Retrieve the current timeouts. COMMTIMEOUTS timeouts; if (!GetCommTimeouts (device->hFile, &timeouts)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } // Update the settings. @@ -354,75 +344,72 @@ serial_set_timeout (serial_t *device, long timeout) // Activate the new timeouts. if (!SetCommTimeouts (device->hFile, &timeouts)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } -// -// Configure the serial port (recommended size of the input/output buffers). -// - -int -serial_set_queue_size (serial_t *device, unsigned int input, unsigned int output) +dc_status_t +dc_serial_set_halfduplex (dc_serial_t *device, unsigned int value) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) - - if (!SetupComm (device->hFile, input, output)) { - SYSERROR (device->context, GetLastError ()); - return -1; - } - - return 0; -} - - -int -serial_set_halfduplex (serial_t *device, int value) -{ - if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; device->halfduplex = value; - return 0; + return DC_STATUS_SUCCESS; } - -int -serial_set_latency (serial_t *device, unsigned int milliseconds) +dc_status_t +dc_serial_set_latency (dc_serial_t *device, unsigned int value) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; - return 0; + return DC_STATUS_SUCCESS; } -int -serial_read (serial_t *device, void* data, unsigned int size) +dc_status_t +dc_serial_read (dc_serial_t *device, void *data, size_t size, size_t *actual) { - if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) - + dc_status_t status = DC_STATUS_SUCCESS; DWORD dwRead = 0; - if (!ReadFile (device->hFile, data, size, &dwRead, NULL)) { - SYSERROR (device->context, GetLastError ()); - return -1; + + if (device == NULL) { + status = DC_STATUS_INVALIDARGS; + goto out; } + if (!ReadFile (device->hFile, data, size, &dwRead, NULL)) { + SYSERROR (device->context, GetLastError ()); + status = DC_STATUS_IO; + goto out; + } + + if (dwRead != size) { + status = DC_STATUS_TIMEOUT; + } + +out: HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Read", (unsigned char *) data, dwRead); - return dwRead; + if (actual) + *actual = dwRead; + + return status; } - -int -serial_write (serial_t *device, const void* data, unsigned int size) +dc_status_t +dc_serial_write (dc_serial_t *device, const void *data, size_t size, size_t *actual) { - if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + dc_status_t status = DC_STATUS_SUCCESS; + DWORD dwWritten = 0; + + if (device == NULL) { + status = DC_STATUS_INVALIDARGS; + goto out; + } LARGE_INTEGER begin, end, freq; if (device->halfduplex) { @@ -430,21 +417,23 @@ serial_write (serial_t *device, const void* data, unsigned int size) if (!QueryPerformanceFrequency(&freq) || !QueryPerformanceCounter(&begin)) { SYSERROR (device->context, GetLastError ()); - return -1; + status = DC_STATUS_IO; + goto out; } } - DWORD dwWritten = 0; if (!WriteFile (device->hFile, data, size, &dwWritten, NULL)) { SYSERROR (device->context, GetLastError ()); - return -1; + status = DC_STATUS_IO; + goto out; } if (device->halfduplex) { // Get the current time. if (!QueryPerformanceCounter(&end)) { SYSERROR (device->context, GetLastError ()); - return -1; + status = DC_STATUS_IO; + goto out; } // Calculate the elapsed time (microseconds). @@ -461,99 +450,99 @@ serial_write (serial_t *device, const void* data, unsigned int size) // The remaining time is rounded up to the nearest millisecond // because the Windows Sleep() function doesn't have a higher // resolution. - serial_sleep (device, (remaining + 999) / 1000); + dc_serial_sleep (device, (remaining + 999) / 1000); } } + if (dwWritten != size) { + status = DC_STATUS_TIMEOUT; + } + +out: HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (unsigned char *) data, dwWritten); - return dwWritten; + if (actual) + *actual = dwWritten; + + return status; } - -int -serial_flush (serial_t *device, int queue) +dc_status_t +dc_serial_purge (dc_serial_t *device, dc_direction_t direction) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; - INFO (device->context, "Flush: queue=%u, input=%i, output=%i", queue, - serial_get_received (device), - serial_get_transmitted (device)); + INFO (device->context, "Purge: direction=%u", direction); DWORD flags = 0; - switch (queue) { - case SERIAL_QUEUE_INPUT: + switch (direction) { + case DC_DIRECTION_INPUT: flags = PURGE_RXABORT | PURGE_RXCLEAR; break; - case SERIAL_QUEUE_OUTPUT: + case DC_DIRECTION_OUTPUT: flags = PURGE_TXABORT | PURGE_TXCLEAR; break; - default: + case DC_DIRECTION_ALL: flags = PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR; break; + default: + return DC_STATUS_INVALIDARGS; } if (!PurgeComm (device->hFile, flags)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } - -int -serial_send_break (serial_t *device) +dc_status_t +dc_serial_flush (dc_serial_t *device) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; - if (!SetCommBreak (device->hFile)) { + INFO (device->context, "Flush: none"); + + if (!FlushFileBuffers (device->hFile)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } - Sleep (250); - - if (!ClearCommBreak (device->hFile)) { - SYSERROR (device->context, GetLastError ()); - return -1; - } - - return 0; + return DC_STATUS_SUCCESS; } - -int -serial_set_break (serial_t *device, int level) +dc_status_t +dc_serial_set_break (dc_serial_t *device, unsigned int level) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; INFO (device->context, "Break: value=%i", level); if (level) { if (!SetCommBreak (device->hFile)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } } else { if (!ClearCommBreak (device->hFile)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } } - return 0; + return DC_STATUS_SUCCESS; } -int -serial_set_dtr (serial_t *device, int level) +dc_status_t +dc_serial_set_dtr (dc_serial_t *device, unsigned int level) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; INFO (device->context, "DTR: value=%i", level); @@ -561,18 +550,17 @@ serial_set_dtr (serial_t *device, int level) if (!EscapeCommFunction (device->hFile, status)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } - -int -serial_set_rts (serial_t *device, int level) +dc_status_t +dc_serial_set_rts (dc_serial_t *device, unsigned int level) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; INFO (device->context, "RTS: value=%i", level); @@ -580,85 +568,69 @@ serial_set_rts (serial_t *device, int level) if (!EscapeCommFunction (device->hFile, status)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } - return 0; + return DC_STATUS_SUCCESS; } - -int -serial_get_received (serial_t *device) +dc_status_t +dc_serial_get_available (dc_serial_t *device, size_t *value) { if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; COMSTAT stats; if (!ClearCommError (device->hFile, NULL, &stats)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } - return stats.cbInQue; + if (value) + *value = stats.cbInQue; + + return DC_STATUS_SUCCESS; } - -int -serial_get_transmitted (serial_t *device) +dc_status_t +dc_serial_get_lines (dc_serial_t *device, unsigned int *value) { + unsigned int lines = 0; + if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) - - COMSTAT stats; - - if (!ClearCommError (device->hFile, NULL, &stats)) { - SYSERROR (device->context, GetLastError ()); - return -1; - } - - return stats.cbOutQue; -} - - -int -serial_get_line (serial_t *device, int line) -{ - if (device == NULL) - return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect) + return DC_STATUS_INVALIDARGS; DWORD stats = 0; if (!GetCommModemStatus (device->hFile, &stats)) { SYSERROR (device->context, GetLastError ()); - return -1; + return DC_STATUS_IO; } - switch (line) { - case SERIAL_LINE_DCD: - return (stats & MS_RLSD_ON) == MS_RLSD_ON; - case SERIAL_LINE_CTS: - return (stats & MS_CTS_ON) == MS_CTS_ON; - case SERIAL_LINE_DSR: - return (stats & MS_DSR_ON) == MS_DSR_ON; - case SERIAL_LINE_RNG: - return (stats & MS_RING_ON) == MS_RING_ON; - default: - return -1; - } + if (stats & MS_RLSD_ON) + lines |= DC_LINE_DCD; + if (stats & MS_CTS_ON) + lines |= DC_LINE_CTS; + if (stats & MS_DSR_ON) + lines |= DC_LINE_DSR; + if (stats & MS_RING_ON) + lines |= DC_LINE_RNG; - return 0; + if (value) + *value = lines; + + return DC_STATUS_SUCCESS; } - -int -serial_sleep (serial_t *device, unsigned long timeout) +dc_status_t +dc_serial_sleep (dc_serial_t *device, unsigned int timeout) { if (device == NULL) - return -1; + return DC_STATUS_INVALIDARGS; - INFO (device->context, "Sleep: value=%lu", timeout); + INFO (device->context, "Sleep: value=%u", timeout); Sleep (timeout); - return 0; + return DC_STATUS_SUCCESS; } diff --git a/src/shearwater_common.c b/src/shearwater_common.c index ac53a7e..c6dafbb 100644 --- a/src/shearwater_common.c +++ b/src/shearwater_common.c @@ -35,43 +35,40 @@ #define ESC_END 0xDC #define ESC_ESC 0xDD -#define EXITCODE(n) ((n) < 0 ? DC_STATUS_IO : DC_STATUS_TIMEOUT) - dc_status_t shearwater_common_open (shearwater_common_device_t *device, dc_context_t *context, const char *name) { dc_status_t status = DC_STATUS_SUCCESS; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - return DC_STATUS_IO; + return status; } // Set the serial communication protocol (115200 8N1). - rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 115200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_sleep (device->port, 300); - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_sleep (device->port, 300); + dc_serial_purge (device->port, DC_DIRECTION_ALL); return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); return status; } @@ -80,11 +77,7 @@ dc_status_t shearwater_common_close (shearwater_common_device_t *device) { // Close the device. - if (serial_close (device->port) == -1) { - return DC_STATUS_IO; - } - - return DC_STATUS_SUCCESS; + return dc_serial_close (device->port); } @@ -150,7 +143,7 @@ shearwater_common_decompress_xor (unsigned char *data, unsigned int size) static dc_status_t shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned char data[], unsigned int size) { - int n = 0; + dc_status_t status = DC_STATUS_SUCCESS; const unsigned char end[] = {END}; const unsigned char esc_end[] = {ESC, ESC_END}; const unsigned char esc_esc[] = {ESC, ESC_ESC}; @@ -160,9 +153,9 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned #if 0 // Send an initial END character to flush out any data that may have // accumulated in the receiver due to line noise. - n = serial_write (device->port, end, sizeof (end)); - if (n != sizeof (end)) { - return EXITCODE(n); + status = dc_serial_write (device->port, end, sizeof (end), NULL); + if (status != DC_STATUS_SUCCESS) { + return status; } #endif @@ -189,9 +182,9 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned // Flush the buffer if necessary. if (nbytes + len + sizeof(end) > sizeof(buffer)) { - n = serial_write (device->port, buffer, nbytes); - if (n != nbytes) { - return EXITCODE(n); + status = dc_serial_write (device->port, buffer, nbytes, NULL); + if (status != DC_STATUS_SUCCESS) { + return status; } nbytes = 0; @@ -207,9 +200,9 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned nbytes += sizeof(end); // Flush the buffer. - n = serial_write (device->port, buffer, nbytes); - if (n != nbytes) { - return EXITCODE(n); + status = dc_serial_write (device->port, buffer, nbytes, NULL); + if (status != DC_STATUS_SUCCESS) { + return status; } return DC_STATUS_SUCCESS; @@ -219,6 +212,7 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned static dc_status_t shearwater_common_slip_read (shearwater_common_device_t *device, unsigned char data[], unsigned int size, unsigned int *actual) { + dc_status_t status = DC_STATUS_SUCCESS; unsigned int received = 0; // Read bytes until a complete packet has been received. If the @@ -227,12 +221,11 @@ shearwater_common_slip_read (shearwater_common_device_t *device, unsigned char d // than the supplied buffer size. while (1) { unsigned char c = 0; - int n = 0; // Get a single character to process. - n = serial_read (device->port, &c, 1); - if (n != 1) { - return EXITCODE(n); + status = dc_serial_read (device->port, &c, 1, NULL); + if (status != DC_STATUS_SUCCESS) { + return status; } switch (c) { @@ -249,9 +242,9 @@ shearwater_common_slip_read (shearwater_common_device_t *device, unsigned char d case ESC: // If it's an ESC character, get another character and then // figure out what to store in the packet based on that. - n = serial_read (device->port, &c, 1); - if (n != 1) { - return EXITCODE(n); + status = dc_serial_read (device->port, &c, 1, NULL); + if (status != DC_STATUS_SUCCESS) { + return status; } // If it's not one of the two escaped characters, then we diff --git a/src/shearwater_common.h b/src/shearwater_common.h index a07de14..b93f973 100644 --- a/src/shearwater_common.h +++ b/src/shearwater_common.h @@ -34,7 +34,7 @@ extern "C" { typedef struct shearwater_common_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; } shearwater_common_device_t; dc_status_t diff --git a/src/suunto_d9.c b/src/suunto_d9.c index dcacd99..00de2ee 100644 --- a/src/suunto_d9.c +++ b/src/suunto_d9.c @@ -33,11 +33,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), (const dc_device_vtable_t *) &suunto_d9_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define C_ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) #define D4i 0x19 @@ -49,7 +44,7 @@ typedef struct suunto_d9_device_t { suunto_common2_device_t base; - serial_t *port; + dc_serial_t *port; } suunto_d9_device_t; static dc_status_t suunto_d9_device_packet (dc_device_t *abstract, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size); @@ -114,10 +109,10 @@ suunto_d9_device_autodetect (suunto_d9_device_t *device, unsigned int model) unsigned int idx = (hint + i) % C_ARRAY_SIZE(baudrates); // Adjust the baudrate. - int rc = serial_configure (device->port, baudrates[idx], 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, baudrates[idx], 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to set the terminal attributes."); - return DC_STATUS_IO; + return status; } // Try reading the version info. @@ -153,40 +148,38 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam device->port = NULL; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (9600 8N1). - rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 9600, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000 ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Set the DTR line (power supply for the interface). - if (serial_set_dtr (device->port, 1) == -1) { + status = dc_serial_set_dtr (device->port, 1); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the DTR line."); - status = DC_STATUS_IO; goto error_close; } // Give the interface 100 ms to settle and draw power up. - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Try to autodetect the protocol variant. status = suunto_d9_device_autodetect (device, model); @@ -210,7 +203,7 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -222,10 +215,12 @@ suunto_d9_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; suunto_d9_device_t *device = (suunto_d9_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -235,28 +230,29 @@ suunto_d9_device_close (dc_device_t *abstract) static dc_status_t suunto_d9_device_packet (dc_device_t *abstract, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size) { + dc_status_t status = DC_STATUS_SUCCESS; suunto_d9_device_t *device = (suunto_d9_device_t *) abstract; if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; // Clear RTS to send the command. - serial_set_rts (device->port, 0); + dc_serial_set_rts (device->port, 0); // Send the command to the dive computer. - int n = serial_write (device->port, command, csize); - if (n != csize) { + status = dc_serial_write (device->port, command, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the echo. unsigned char echo[128] = {0}; assert (sizeof (echo) >= csize); - n = serial_read (device->port, echo, csize); - if (n != csize) { + status = dc_serial_read (device->port, echo, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the echo."); - return EXITCODE (n); + return status; } // Verify the echo. @@ -266,13 +262,13 @@ suunto_d9_device_packet (dc_device_t *abstract, const unsigned char command[], u } // Set RTS to receive the reply. - serial_set_rts (device->port, 1); + dc_serial_set_rts (device->port, 1); // Receive the answer of the dive computer. - n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the header of the package. diff --git a/src/suunto_eon.c b/src/suunto_eon.c index 6e8375c..f7cab8f 100644 --- a/src/suunto_eon.c +++ b/src/suunto_eon.c @@ -33,16 +33,11 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &suunto_eon_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_MEMORY 0x900 typedef struct suunto_eon_device_t { suunto_common_device_t base; - serial_t *port; + dc_serial_t *port; } suunto_eon_device_t; static dc_status_t suunto_eon_device_dump (dc_device_t *abstract, dc_buffer_t *buffer); @@ -92,32 +87,30 @@ suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *na device->port = NULL; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (1200 8N2). - rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 1200, 8, DC_PARITY_NONE, DC_STOPBITS_TWO, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Clear the RTS line. - if (serial_set_rts (device->port, 0)) { + status = dc_serial_set_rts (device->port, 0); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; goto error_close; } @@ -126,7 +119,7 @@ suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *na return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -138,10 +131,12 @@ suunto_eon_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; suunto_eon_device_t *device = (suunto_eon_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -151,6 +146,7 @@ suunto_eon_device_close (dc_device_t *abstract) static dc_status_t suunto_eon_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; suunto_eon_device_t *device = (suunto_eon_device_t*) abstract; // Erase the current contents of the buffer and @@ -167,10 +163,10 @@ suunto_eon_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) // Send the command. unsigned char command[1] = {'P'}; - int rc = serial_write (device->port, command, sizeof (command)); - if (rc != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (rc); + return status; } // Receive the answer. @@ -181,8 +177,9 @@ suunto_eon_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) unsigned int len = 64; // Increase the packet size if more data is immediately available. - int available = serial_get_received (device->port); - if (available > len) + size_t available = 0; + status = dc_serial_get_available (device->port, &available); + if (status == DC_STATUS_SUCCESS && available > len) len = available; // Limit the packet size to the total size. @@ -190,10 +187,10 @@ suunto_eon_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) len = sizeof(answer) - nbytes; // Read the packet. - int n = serial_read (device->port, answer + nbytes, len); - if (n != len) { + status = dc_serial_read (device->port, answer + nbytes, len, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Update and emit a progress event. @@ -254,6 +251,7 @@ suunto_eon_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v dc_status_t suunto_eon_device_write_name (dc_device_t *abstract, unsigned char data[], unsigned int size) { + dc_status_t status = DC_STATUS_SUCCESS; suunto_eon_device_t *device = (suunto_eon_device_t*) abstract; if (!ISINSTANCE (abstract)) @@ -265,10 +263,10 @@ suunto_eon_device_write_name (dc_device_t *abstract, unsigned char data[], unsig // Send the command. unsigned char command[21] = {'N'}; memcpy (command + 1, data, size); - int rc = serial_write (device->port, command, sizeof (command)); - if (rc != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (rc); + return status; } return DC_STATUS_SUCCESS; @@ -278,6 +276,7 @@ suunto_eon_device_write_name (dc_device_t *abstract, unsigned char data[], unsig dc_status_t suunto_eon_device_write_interval (dc_device_t *abstract, unsigned char interval) { + dc_status_t status = DC_STATUS_SUCCESS; suunto_eon_device_t *device = (suunto_eon_device_t*) abstract; if (!ISINSTANCE (abstract)) @@ -285,10 +284,10 @@ suunto_eon_device_write_interval (dc_device_t *abstract, unsigned char interval) // Send the command. unsigned char command[2] = {'T', interval}; - int rc = serial_write (device->port, command, sizeof (command)); - if (rc != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (rc); + return status; } return DC_STATUS_SUCCESS; diff --git a/src/suunto_solution.c b/src/suunto_solution.c index d151352..9a8149e 100644 --- a/src/suunto_solution.c +++ b/src/suunto_solution.c @@ -32,11 +32,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &suunto_solution_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_MEMORY 256 #define RB_PROFILE_BEGIN 0x020 @@ -44,7 +39,7 @@ typedef struct suunto_solution_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; } suunto_solution_device_t; static dc_status_t suunto_solution_device_dump (dc_device_t *abstract, dc_buffer_t *buffer); @@ -83,32 +78,30 @@ suunto_solution_device_open (dc_device_t **out, dc_context_t *context, const cha device->port = NULL; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (1200 8N2). - rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 1200, 8, DC_PARITY_NONE, DC_STOPBITS_TWO, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Clear the RTS line. - if (serial_set_rts (device->port, 0)) { + status = dc_serial_set_rts (device->port, 0); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; goto error_close; } @@ -117,7 +110,7 @@ suunto_solution_device_open (dc_device_t **out, dc_context_t *context, const cha return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -129,10 +122,12 @@ suunto_solution_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; suunto_solution_device_t *device = (suunto_solution_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -142,6 +137,7 @@ suunto_solution_device_close (dc_device_t *abstract) static dc_status_t suunto_solution_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; suunto_solution_device_t *device = (suunto_solution_device_t*) abstract; // Erase the current contents of the buffer and @@ -158,20 +154,20 @@ suunto_solution_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) progress.maximum = SZ_MEMORY - 1 + 2; device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); - int n = 0; unsigned char command[3] = {0}; unsigned char answer[3] = {0}; // Assert DTR - serial_set_dtr (device->port, 1); + dc_serial_set_dtr (device->port, 1); // Send: 0xFF command[0] = 0xFF; - serial_write (device->port, command, 1); + dc_serial_write (device->port, command, 1, NULL); // Receive: 0x3F - n = serial_read (device->port, answer, 1); - if (n != 1) return EXITCODE (n); + status = dc_serial_read (device->port, answer, 1, NULL); + if (status != DC_STATUS_SUCCESS) + return status; if (answer[0] != 0x3F) WARNING (abstract->context, "Unexpected answer byte."); @@ -179,7 +175,7 @@ suunto_solution_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) command[0] = 0x4D; command[1] = 0x01; command[2] = 0x01; - serial_write (device->port, command, 3); + dc_serial_write (device->port, command, 3, NULL); // Update and emit a progress event. progress.current += 1; @@ -188,24 +184,26 @@ suunto_solution_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) data[0] = 0x00; for (unsigned int i = 1; i < SZ_MEMORY; ++i) { // Receive: 0x01, i, data[i] - n = serial_read (device->port, answer, 3); - if (n != 3) return EXITCODE (n); + status = dc_serial_read (device->port, answer, 3, NULL); + if (status != DC_STATUS_SUCCESS) + return status; if (answer[0] != 0x01 || answer[1] != i) WARNING (abstract->context, "Unexpected answer byte."); // Send: i command[0] = i; - serial_write (device->port, command, 1); + dc_serial_write (device->port, command, 1, NULL); // Receive: data[i] - n = serial_read (device->port, data + i, 1); - if (n != 1) return EXITCODE (n); + status = dc_serial_read (device->port, data + i, 1, NULL); + if (status != DC_STATUS_SUCCESS) + return status; if (data[i] != answer[2]) WARNING (abstract->context, "Unexpected answer byte."); // Send: 0x0D command[0] = 0x0D; - serial_write (device->port, command, 1); + dc_serial_write (device->port, command, 1, NULL); // Update and emit a progress event. progress.current += 1; @@ -213,28 +211,31 @@ suunto_solution_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) } // Receive: 0x02, 0x00, 0x80 - n = serial_read (device->port, answer, 3); - if (n != 3) return EXITCODE (n); + status = dc_serial_read (device->port, answer, 3, NULL); + if (status != DC_STATUS_SUCCESS) + return status; if (answer[0] != 0x02 || answer[1] != 0x00 || answer[2] != 0x80) WARNING (abstract->context, "Unexpected answer byte."); // Send: 0x80 command[0] = 0x80; - serial_write (device->port, command, 1); + dc_serial_write (device->port, command, 1, NULL); // Receive: 0x80 - n = serial_read (device->port, answer, 1); - if (n != 1) return EXITCODE (n); + status = dc_serial_read (device->port, answer, 1, NULL); + if (status != DC_STATUS_SUCCESS) + return status; if (answer[0] != 0x80) WARNING (abstract->context, "Unexpected answer byte."); // Send: 0x20 command[0] = 0x20; - serial_write (device->port, command, 1); + dc_serial_write (device->port, command, 1, NULL); // Receive: 0x3F - n = serial_read (device->port, answer, 1); - if (n != 1) return EXITCODE (n); + status = dc_serial_read (device->port, answer, 1, NULL); + if (status != DC_STATUS_SUCCESS) + return status; if (answer[0] != 0x3F) WARNING (abstract->context, "Unexpected answer byte."); diff --git a/src/suunto_vyper.c b/src/suunto_vyper.c index 8ec502f..2d9f3a9 100644 --- a/src/suunto_vyper.c +++ b/src/suunto_vyper.c @@ -34,11 +34,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &suunto_vyper_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) @@ -52,7 +47,7 @@ typedef struct suunto_vyper_device_t { suunto_common_device_t base; - serial_t *port; + dc_serial_t *port; } suunto_vyper_device_t; static dc_status_t suunto_vyper_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size); @@ -112,47 +107,45 @@ suunto_vyper_device_open (dc_device_t **out, dc_context_t *context, const char * device->port = NULL; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status= DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (2400 8O1). - rc = serial_configure (device->port, 2400, 8, SERIAL_PARITY_ODD, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 2400, 8, DC_PARITY_ODD, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Set the DTR line (power supply for the interface). - if (serial_set_dtr (device->port, 1) == -1) { + status = dc_serial_set_dtr (device->port, 1); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the DTR line."); - status = DC_STATUS_IO; goto error_close; } // Give the interface 100 ms to settle and draw power up. - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -164,10 +157,12 @@ suunto_vyper_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; suunto_vyper_device_t *device = (suunto_vyper_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -177,18 +172,19 @@ suunto_vyper_device_close (dc_device_t *abstract) static dc_status_t suunto_vyper_send (suunto_vyper_device_t *device, const unsigned char command[], unsigned int csize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; - serial_sleep (device->port, 500); + dc_serial_sleep (device->port, 500); // Set RTS to send the command. - serial_set_rts (device->port, 1); + dc_serial_set_rts (device->port, 1); // Send the command to the dive computer. - int n = serial_write (device->port, command, csize); - if (n != csize) { + status = dc_serial_write (device->port, command, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // If the interface sends an echo back (which is the case for many clone @@ -202,11 +198,11 @@ suunto_vyper_send (suunto_vyper_device_t *device, const unsigned char command[], // receive the reply before RTS is cleared. We have to wait some time // before clearing RTS (around 30ms). But if we wait too long (> 500ms), // the reply disappears again. - serial_sleep (device->port, 200); - serial_flush (device->port, SERIAL_QUEUE_INPUT); + dc_serial_sleep (device->port, 200); + dc_serial_purge (device->port, DC_DIRECTION_INPUT); // Clear RTS to receive the reply. - serial_set_rts (device->port, 0); + dc_serial_set_rts (device->port, 0); return DC_STATUS_SUCCESS; } @@ -215,10 +211,11 @@ suunto_vyper_send (suunto_vyper_device_t *device, const unsigned char command[], static dc_status_t suunto_vyper_transfer (suunto_vyper_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size) { - assert (asize >= size + 2); - + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; + assert (asize >= size + 2); + if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; @@ -230,10 +227,10 @@ suunto_vyper_transfer (suunto_vyper_device_t *device, const unsigned char comman } // Receive the answer of the dive computer. - int n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the header of the package. @@ -329,6 +326,7 @@ suunto_vyper_device_write (dc_device_t *abstract, unsigned int address, const un static dc_status_t suunto_vyper_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init, dc_event_progress_t *progress) { + dc_status_t status = DC_STATUS_SUCCESS; suunto_vyper_device_t *device = (suunto_vyper_device_t*) abstract; if (device_is_cancelled (abstract)) @@ -352,9 +350,10 @@ suunto_vyper_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init, dc unsigned int nbytes = 0; for (unsigned int npackages = 0;; ++npackages) { // Receive the header of the package. + size_t n = 0; unsigned char answer[SZ_PACKET + 3] = {0}; - int n = serial_read (device->port, answer, 2); - if (n != 2) { + status = dc_serial_read (device->port, answer, 2, &n); + if (status != DC_STATUS_SUCCESS) { // If no data is received because a timeout occured, we assume // the last package was already received and the transmission // can be finished. Unfortunately this is not 100% reliable, @@ -366,7 +365,7 @@ suunto_vyper_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init, dc if (n == 0 && npackages != 0) break; ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the header of the package. @@ -378,10 +377,10 @@ suunto_vyper_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init, dc // Receive the remaining part of the package. unsigned char len = answer[1]; - n = serial_read (device->port, answer + 2, len + 1); - if (n != len + 1) { + status = dc_serial_read (device->port, answer + 2, len + 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the checksum of the package. diff --git a/src/suunto_vyper2.c b/src/suunto_vyper2.c index a0b07a4..7a0f26b 100644 --- a/src/suunto_vyper2.c +++ b/src/suunto_vyper2.c @@ -32,16 +32,11 @@ #define ISINSTANCE(device) dc_device_isinstance((device), (const dc_device_vtable_t *) &suunto_vyper2_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define HELO2 0x15 typedef struct suunto_vyper2_device_t { suunto_common2_device_t base; - serial_t *port; + dc_serial_t *port; } suunto_vyper2_device_t; static dc_status_t suunto_vyper2_device_packet (dc_device_t *abstract, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size); @@ -101,43 +96,41 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char device->port = NULL; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (9600 8N1). - rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 9600, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000 ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Set the DTR line (power supply for the interface). - if (serial_set_dtr (device->port, 1) == -1) { + status = dc_serial_set_dtr (device->port, 1); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the DTR line."); - status = DC_STATUS_IO; goto error_close; } // Give the interface 100 ms to settle and draw power up. - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Enable half-duplex emulation. - serial_set_halfduplex (device->port, 1); + dc_serial_set_halfduplex (device->port, 1); // Read the version info. status = suunto_common2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); @@ -158,7 +151,7 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -170,10 +163,12 @@ suunto_vyper2_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; suunto_vyper2_device_t *device = (suunto_vyper2_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -183,31 +178,32 @@ suunto_vyper2_device_close (dc_device_t *abstract) static dc_status_t suunto_vyper2_device_packet (dc_device_t *abstract, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int size) { + dc_status_t status = DC_STATUS_SUCCESS; suunto_vyper2_device_t *device = (suunto_vyper2_device_t *) abstract; if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; - serial_sleep (device->port, 600); + dc_serial_sleep (device->port, 600); // Set RTS to send the command. - serial_set_rts (device->port, 1); + dc_serial_set_rts (device->port, 1); // Send the command to the dive computer. - int n = serial_write (device->port, command, csize); - if (n != csize) { + status = dc_serial_write (device->port, command, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Clear RTS to receive the reply. - serial_set_rts (device->port, 0); + dc_serial_set_rts (device->port, 0); // Receive the answer of the dive computer. - n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the header of the package. diff --git a/src/uwatec_aladin.c b/src/uwatec_aladin.c index 47c0ee2..91b87a9 100644 --- a/src/uwatec_aladin.c +++ b/src/uwatec_aladin.c @@ -33,11 +33,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &uwatec_aladin_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_MEMORY 2048 #define RB_PROFILE_BEGIN 0x000 @@ -49,7 +44,7 @@ typedef struct uwatec_aladin_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned int timestamp; unsigned int devtime; dc_ticks_t systime; @@ -95,33 +90,37 @@ uwatec_aladin_device_open (dc_device_t **out, dc_context_t *context, const char device->devtime = 0; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (19200 8N1). - rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 19200, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (INFINITE). - if (serial_set_timeout (device->port, -1) == -1) { + status = dc_serial_set_timeout (device->port, -1); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Clear the RTS line and set the DTR line. - if (serial_set_dtr (device->port, 1) == -1 || - serial_set_rts (device->port, 0) == -1) { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Set the DTR line. + status = dc_serial_set_dtr (device->port, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the DTR line."); + goto error_close; + } + + // Clear the RTS line. + status = dc_serial_set_rts (device->port, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to clear the RTS line."); goto error_close; } @@ -130,7 +129,7 @@ uwatec_aladin_device_open (dc_device_t **out, dc_context_t *context, const char return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -142,10 +141,12 @@ uwatec_aladin_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; uwatec_aladin_device_t *device = (uwatec_aladin_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -172,6 +173,7 @@ uwatec_aladin_device_set_fingerprint (dc_device_t *abstract, const unsigned char static dc_status_t uwatec_aladin_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; uwatec_aladin_device_t *device = (uwatec_aladin_device_t*) abstract; // Erase the current contents of the buffer and @@ -193,10 +195,10 @@ uwatec_aladin_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; - int rc = serial_read (device->port, answer + i, 1); - if (rc != 1) { + status = dc_serial_read (device->port, answer + i, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (rc); + return status; } if (answer[i] == (i < 3 ? 0x55 : 0x00)) { i++; // Continue. @@ -214,10 +216,10 @@ uwatec_aladin_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); // Receive the remaining part of the package. - int rc = serial_read (device->port, answer + 4, sizeof (answer) - 4); - if (rc != sizeof (answer) - 4) { + status = dc_serial_read (device->port, answer + 4, sizeof (answer) - 4, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Unexpected EOF in answer."); - return EXITCODE (rc); + return status; } // Update and emit a progress event. diff --git a/src/uwatec_memomouse.c b/src/uwatec_memomouse.c index ba1153a..92e3044 100644 --- a/src/uwatec_memomouse.c +++ b/src/uwatec_memomouse.c @@ -33,11 +33,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &uwatec_memomouse_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define PACKETSIZE 126 #define ACK 0x60 @@ -45,7 +40,7 @@ typedef struct uwatec_memomouse_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned int timestamp; unsigned int devtime; dc_ticks_t systime; @@ -91,45 +86,49 @@ uwatec_memomouse_device_open (dc_device_t **out, dc_context_t *context, const ch device->devtime = 0; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (9600 8N1). - rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 9600, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } - // Clear the RTS and DTR lines. - if (serial_set_rts (device->port, 0) == -1 || - serial_set_dtr (device->port, 0) == -1) { - ERROR (context, "Failed to set the DTR/RTS line."); - status = DC_STATUS_IO; + // Clear the DTR line. + status = dc_serial_set_dtr (device->port, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to clear the DTR line."); + goto error_close; + } + + // Clear the RTS line. + status = dc_serial_set_rts (device->port, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to clear the RTS line."); goto error_close; } // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -141,10 +140,12 @@ uwatec_memomouse_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; uwatec_memomouse_device_t *device = (uwatec_memomouse_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -171,15 +172,16 @@ uwatec_memomouse_device_set_fingerprint (dc_device_t *abstract, const unsigned c static dc_status_t uwatec_memomouse_read_packet (uwatec_memomouse_device_t *device, unsigned char data[], unsigned int size, unsigned int *result) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; assert (result != NULL); // Receive the header of the package. - int rc = serial_read (device->port, data, 1); - if (rc != 1) { + status = dc_serial_read (device->port, data, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (rc); + return status; } // Reverse the bits. @@ -193,10 +195,10 @@ uwatec_memomouse_read_packet (uwatec_memomouse_device_t *device, unsigned char d } // Receive the remaining part of the package. - rc = serial_read (device->port, data + 1, len + 1); - if (rc != len + 1) { + status = dc_serial_read (device->port, data + 1, len + 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (rc); + return status; } // Reverse the bits. @@ -219,6 +221,7 @@ uwatec_memomouse_read_packet (uwatec_memomouse_device_t *device, unsigned char d static dc_status_t uwatec_memomouse_read_packet_outer (uwatec_memomouse_device_t *device, unsigned char data[], unsigned int size, unsigned int *result) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; dc_status_t rc = DC_STATUS_SUCCESS; @@ -229,14 +232,14 @@ uwatec_memomouse_read_packet_outer (uwatec_memomouse_device_t *device, unsigned return rc; // Flush the input buffer. - serial_flush (device->port, SERIAL_QUEUE_INPUT); + dc_serial_purge (device->port, DC_DIRECTION_INPUT); // Reject the packet. unsigned char value = NAK; - int n = serial_write (device->port, &value, 1); - if (n != 1) { + status = dc_serial_write (device->port, &value, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to reject the packet."); - return EXITCODE (n); + return status; } } @@ -247,6 +250,7 @@ uwatec_memomouse_read_packet_outer (uwatec_memomouse_device_t *device, unsigned static dc_status_t uwatec_memomouse_read_packet_inner (uwatec_memomouse_device_t *device, dc_buffer_t *buffer, dc_event_progress_t *progress) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; // Erase the current contents of the buffer. @@ -271,10 +275,10 @@ uwatec_memomouse_read_packet_inner (uwatec_memomouse_device_t *device, dc_buffer // Accept the packet. unsigned char value = ACK; - int n = serial_write (device->port, &value, 1); - if (n != 1) { + status = dc_serial_write (device->port, &value, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to accept the packet."); - return EXITCODE (n); + return status; } if (nbytes == 0) { @@ -329,29 +333,31 @@ uwatec_memomouse_read_packet_inner (uwatec_memomouse_device_t *device, dc_buffer static dc_status_t uwatec_memomouse_dump_internal (uwatec_memomouse_device_t *device, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; + size_t available = 0; // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; device_event_emit (&device->base, DC_EVENT_PROGRESS, &progress); // Waiting for greeting message. - while (serial_get_received (device->port) == 0) { + while (dc_serial_get_available (device->port, &available) == DC_STATUS_SUCCESS && available == 0) { if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; // Flush the input buffer. - serial_flush (device->port, SERIAL_QUEUE_INPUT); + dc_serial_purge (device->port, DC_DIRECTION_INPUT); // Reject the packet. unsigned char value = NAK; - int n = serial_write (device->port, &value, 1); - if (n != 1) { + status = dc_serial_write (device->port, &value, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to reject the packet."); - return EXITCODE (n); + return status; } - serial_sleep (device->port, 300); + dc_serial_sleep (device->port, 300); } // Read the ID string. @@ -374,27 +380,27 @@ uwatec_memomouse_dump_internal (uwatec_memomouse_device_t *device, dc_buffer_t * // Wait a small amount of time before sending the command. // Without this delay, the transfer will fail most of the time. - serial_sleep (device->port, 50); + dc_serial_sleep (device->port, 50); // Keep send the command to the device, // until the ACK answer is received. unsigned char answer = NAK; while (answer == NAK) { // Flush the input buffer. - serial_flush (device->port, SERIAL_QUEUE_INPUT); + dc_serial_purge (device->port, DC_DIRECTION_INPUT); // Send the command to the device. - int n = serial_write (device->port, command, sizeof (command)); - if (n != sizeof (command)) { + status = dc_serial_write (device->port, command, sizeof (command), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Wait for the answer (ACK). - n = serial_read (device->port, &answer, 1); - if (n != 1) { + status = dc_serial_read (device->port, &answer, 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } } @@ -405,12 +411,12 @@ uwatec_memomouse_dump_internal (uwatec_memomouse_device_t *device, dc_buffer_t * } // Wait for the data packet. - while (serial_get_received (device->port) == 0) { + while (dc_serial_get_available (device->port, &available) == DC_STATUS_SUCCESS && available == 0) { if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; device_event_emit (&device->base, DC_EVENT_WAITING, NULL); - serial_sleep (device->port, 100); + dc_serial_sleep (device->port, 100); } // Fetch the current system time. @@ -438,7 +444,9 @@ uwatec_memomouse_dump_internal (uwatec_memomouse_device_t *device, dc_buffer_t * static dc_status_t uwatec_memomouse_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; uwatec_memomouse_device_t *device = (uwatec_memomouse_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Erase the current contents of the buffer. if (!dc_buffer_clear (buffer)) { @@ -448,24 +456,26 @@ uwatec_memomouse_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) // Give the interface some time to notice the DTR // line change from a previous transfer (if any). - serial_sleep (device->port, 500); + dc_serial_sleep (device->port, 500); // Set the DTR line. - if (serial_set_dtr (device->port, 1) == -1) { + rc = dc_serial_set_dtr (device->port, 1); + if (rc != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to set the RTS line."); - return DC_STATUS_IO; + return rc; } // Start the transfer. - dc_status_t rc = uwatec_memomouse_dump_internal (device, buffer); + status = uwatec_memomouse_dump_internal (device, buffer); // Clear the DTR line again. - if (serial_set_dtr (device->port, 0) == -1) { + rc = dc_serial_set_dtr (device->port, 0); + if (rc != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to set the RTS line."); - return DC_STATUS_IO; + return rc; } - return rc; + return status; } diff --git a/src/uwatec_meridian.c b/src/uwatec_meridian.c index e8de867..3e08f94 100644 --- a/src/uwatec_meridian.c +++ b/src/uwatec_meridian.c @@ -33,17 +33,12 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &uwatec_meridian_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define ACK 0x11 #define NAK 0x66 typedef struct uwatec_meridian_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned int timestamp; unsigned int devtime; dc_ticks_t systime; @@ -69,6 +64,7 @@ static const dc_device_vtable_t uwatec_meridian_device_vtable = { static dc_status_t uwatec_meridian_transfer (uwatec_meridian_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; assert (csize > 0 && csize <= 255); @@ -85,18 +81,18 @@ uwatec_meridian_transfer (uwatec_meridian_device_t *device, const unsigned char packet[11 + csize] = checksum_xor_uint8 (packet + 7, csize + 4, 0x00); // Send the packet. - int n = serial_write (device->port, packet, csize + 12); - if (n != csize + 12) { + status = dc_serial_write (device->port, packet, csize + 12, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Read the echo. unsigned char echo[sizeof(packet)]; - n = serial_read (device->port, echo, csize + 12); - if (n != csize + 12) { + status = dc_serial_read (device->port, echo, csize + 12, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the echo."); - return EXITCODE (n); + return status; } // Verify the echo. @@ -107,10 +103,10 @@ uwatec_meridian_transfer (uwatec_meridian_device_t *device, const unsigned char // Read the header. unsigned char header[6]; - n = serial_read (device->port, header, sizeof (header)); - if (n != sizeof (header)) { + status = dc_serial_read (device->port, header, sizeof (header), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the header."); - return EXITCODE (n); + return status; } // Verify the header. @@ -120,18 +116,18 @@ uwatec_meridian_transfer (uwatec_meridian_device_t *device, const unsigned char } // Read the packet. - n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the packet."); - return EXITCODE (n); + return status; } // Read the checksum. unsigned char csum = 0x00; - n = serial_read (device->port, &csum, sizeof (csum)); - if (n != sizeof (csum)) { + status = dc_serial_read (device->port, &csum, sizeof (csum), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the checksum."); - return EXITCODE (n); + return status; } // Verify the checksum. @@ -207,30 +203,28 @@ uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const cha device->devtime = 0; // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (57600 8N1). - rc = serial_configure (device->port, 57600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 57600, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (3000ms). - if (serial_set_timeout (device->port, 3000) == -1) { + status = dc_serial_set_timeout (device->port, 3000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Perform the handshaking. uwatec_meridian_handshake (device); @@ -240,7 +234,7 @@ uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const cha return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -252,10 +246,12 @@ uwatec_meridian_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; uwatec_meridian_device_t *device = (uwatec_meridian_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -282,6 +278,7 @@ uwatec_meridian_device_set_fingerprint (dc_device_t *abstract, const unsigned ch static dc_status_t uwatec_meridian_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + dc_status_t status = DC_STATUS_SUCCESS; uwatec_meridian_device_t *device = (uwatec_meridian_device_t*) abstract; dc_status_t rc = DC_STATUS_SUCCESS; @@ -395,10 +392,10 @@ uwatec_meridian_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) // Read the header. unsigned char header[5]; - int n = serial_read (device->port, header, sizeof (header)); - if (n != sizeof (header)) { + status = dc_serial_read (device->port, header, sizeof (header), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the header."); - return EXITCODE (n); + return status; } // Get the packet size. @@ -409,18 +406,18 @@ uwatec_meridian_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) } // Read the packet data. - n = serial_read (device->port, data + nbytes, packetsize - 1); - if (n != packetsize - 1) { + status = dc_serial_read (device->port, data + nbytes, packetsize - 1, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the packet."); - return EXITCODE (n); + return status; } // Read the checksum. unsigned char csum = 0x00; - n = serial_read (device->port, &csum, sizeof (csum)); - if (n != sizeof (csum)) { + status = dc_serial_read (device->port, &csum, sizeof (csum), NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the checksum."); - return EXITCODE (n); + return status; } // Verify the checksum. diff --git a/src/uwatec_smart.c b/src/uwatec_smart.c index 065943f..3c55f07 100644 --- a/src/uwatec_smart.c +++ b/src/uwatec_smart.c @@ -31,14 +31,9 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &uwatec_smart_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - typedef struct uwatec_smart_device_t { dc_device_t base; - irda_t *socket; + dc_irda_t *socket; unsigned int address; unsigned int timestamp; unsigned int devtime; @@ -88,18 +83,19 @@ uwatec_smart_discovery (unsigned int address, const char *name, unsigned int cha static dc_status_t uwatec_smart_transfer (uwatec_smart_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; - int n = irda_socket_write (device->socket, command, csize); - if (n != csize) { + status = dc_irda_write (device->socket, command, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } - n = irda_socket_read (device->socket, answer, asize); - if (n != asize) { + status = dc_irda_read (device->socket, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } return DC_STATUS_SUCCESS; @@ -167,18 +163,16 @@ uwatec_smart_device_open (dc_device_t **out, dc_context_t *context) device->devtime = 0; // Open the irda socket. - int rc = irda_socket_open (&device->socket, context); - if (rc == -1) { + status = dc_irda_open (&device->socket, context); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the irda socket."); - status = DC_STATUS_IO; goto error_free; } // Discover the device. - rc = irda_socket_discover (device->socket, uwatec_smart_discovery, device); - if (rc == -1) { + status = dc_irda_discover (device->socket, uwatec_smart_discovery, device); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to discover the device."); - status = DC_STATUS_IO; goto error_close; } @@ -189,10 +183,9 @@ uwatec_smart_device_open (dc_device_t **out, dc_context_t *context) } // Connect the device. - rc = irda_socket_connect_lsap (device->socket, device->address, 1); - if (rc == -1) { + status = dc_irda_connect_lsap (device->socket, device->address, 1); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to connect the device."); - status = DC_STATUS_IO; goto error_close; } @@ -204,7 +197,7 @@ uwatec_smart_device_open (dc_device_t **out, dc_context_t *context) return DC_STATUS_SUCCESS; error_close: - irda_socket_close (device->socket); + dc_irda_close (device->socket); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -216,10 +209,12 @@ uwatec_smart_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; uwatec_smart_device_t *device = (uwatec_smart_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (irda_socket_close (device->socket) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_irda_close (device->socket); + if (status != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status; @@ -360,25 +355,26 @@ uwatec_smart_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) unsigned int len = 32; // Increase the packet size if more data is immediately available. - int available = irda_socket_available (device->socket); - if (available > len) + size_t available = 0; + rc = dc_irda_get_available (device->socket, &available); + if (rc == DC_STATUS_SUCCESS && available > len) len = available; // Limit the packet size to the total size. if (nbytes + len > length) len = length - nbytes; - int n = irda_socket_read (device->socket, data + nbytes, len); - if (n != len) { + rc = dc_irda_read (device->socket, data + nbytes, len, NULL); + if (rc != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return rc; } // Update and emit a progress event. - progress.current += n; + progress.current += len; device_event_emit (&device->base, DC_EVENT_PROGRESS, &progress); - nbytes += n; + nbytes += len; } return DC_STATUS_SUCCESS; diff --git a/src/zeagle_n2ition3.c b/src/zeagle_n2ition3.c index ae76696..516dd57 100644 --- a/src/zeagle_n2ition3.c +++ b/src/zeagle_n2ition3.c @@ -34,11 +34,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &zeagle_n2ition3_device_vtable) -#define EXITCODE(rc) \ -( \ - rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \ -) - #define SZ_MEMORY 0x8000 #define SZ_PACKET 64 @@ -51,7 +46,7 @@ typedef struct zeagle_n2ition3_device_t { dc_device_t base; - serial_t *port; + dc_serial_t *port; unsigned char fingerprint[16]; } zeagle_n2ition3_device_t; @@ -76,6 +71,7 @@ static const dc_device_vtable_t zeagle_n2ition3_device_vtable = { static dc_status_t zeagle_n2ition3_packet (zeagle_n2ition3_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize) { + dc_status_t status = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; assert (asize >= csize + 5); @@ -84,17 +80,17 @@ zeagle_n2ition3_packet (zeagle_n2ition3_device_t *device, const unsigned char co return DC_STATUS_CANCELLED; // Send the command to the device. - int n = serial_write (device->port, command, csize); - if (n != csize) { + status = dc_serial_write (device->port, command, csize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + return status; } // Receive the answer of the device. - n = serial_read (device->port, answer, asize); - if (n != asize) { + status = dc_serial_read (device->port, answer, asize, NULL); + if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); + return status; } // Verify the echo. @@ -156,30 +152,28 @@ zeagle_n2ition3_device_open (dc_device_t **out, dc_context_t *context, const cha memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. - int rc = serial_open (&device->port, context, name); - if (rc == -1) { + status = dc_serial_open (&device->port, context, name); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); - status = DC_STATUS_IO; goto error_free; } // Set the serial communication protocol (4800 8N1). - rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + status = dc_serial_configure (device->port, 4800, 8, DC_PARITY_NONE, DC_STOPBITS_ONE, DC_FLOWCONTROL_NONE); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the terminal attributes."); - status = DC_STATUS_IO; goto error_close; } // Set the timeout for receiving data (1000 ms). - if (serial_set_timeout (device->port, 1000) == -1) { + status = dc_serial_set_timeout (device->port, 1000); + if (status != DC_STATUS_SUCCESS) { ERROR (context, "Failed to set the timeout."); - status = DC_STATUS_IO; goto error_close; } // Make sure everything is in a sane state. - serial_flush (device->port, SERIAL_QUEUE_BOTH); + dc_serial_purge (device->port, DC_DIRECTION_ALL); // Send the init commands. zeagle_n2ition3_init (device); @@ -189,7 +183,7 @@ zeagle_n2ition3_device_open (dc_device_t **out, dc_context_t *context, const cha return DC_STATUS_SUCCESS; error_close: - serial_close (device->port); + dc_serial_close (device->port); error_free: dc_device_deallocate ((dc_device_t *) device); return status; @@ -201,10 +195,12 @@ zeagle_n2ition3_device_close (dc_device_t *abstract) { dc_status_t status = DC_STATUS_SUCCESS; zeagle_n2ition3_device_t *device = (zeagle_n2ition3_device_t*) abstract; + dc_status_t rc = DC_STATUS_SUCCESS; // Close the device. - if (serial_close (device->port) == -1) { - dc_status_set_error(&status, DC_STATUS_IO); + rc = dc_serial_close (device->port); + if (rc != DC_STATUS_SUCCESS) { + dc_status_set_error(&status, rc); } return status;