Switch to goto style error handling.

With the goto error handling, all cleanup code can be moved to a central
location and no longer needs to be duplicated multiple times.
This commit is contained in:
Jef Driesen 2015-10-12 19:46:00 +02:00
parent 0fb6f5a7fa
commit 18d4d5dcc0
37 changed files with 608 additions and 416 deletions

View File

@ -82,12 +82,17 @@ static const dc_device_vtable_t atomics_cobalt_device_vtable = {
dc_status_t dc_status_t
atomics_cobalt_device_open (dc_device_t **out, dc_context_t *context) atomics_cobalt_device_open (dc_device_t **out, dc_context_t *context)
{ {
#ifdef HAVE_LIBUSB
dc_status_t status = DC_STATUS_SUCCESS;
atomics_cobalt_device_t *device = NULL;
#endif
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
#ifdef HAVE_LIBUSB #ifdef HAVE_LIBUSB
// Allocate memory. // Allocate memory.
atomics_cobalt_device_t *device = (atomics_cobalt_device_t *) malloc (sizeof (atomics_cobalt_device_t)); device = (atomics_cobalt_device_t *) malloc (sizeof (atomics_cobalt_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -105,39 +110,41 @@ atomics_cobalt_device_open (dc_device_t **out, dc_context_t *context)
int rc = libusb_init (&device->context); int rc = libusb_init (&device->context);
if (rc < 0) { if (rc < 0) {
ERROR (context, "Failed to initialize usb support."); ERROR (context, "Failed to initialize usb support.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
device->handle = libusb_open_device_with_vid_pid (device->context, VID, PID); device->handle = libusb_open_device_with_vid_pid (device->context, VID, PID);
if (device->handle == NULL) { if (device->handle == NULL) {
ERROR (context, "Failed to open the usb device."); ERROR (context, "Failed to open the usb device.");
libusb_exit (device->context); status = DC_STATUS_IO;
free (device); goto error_usb_exit;
return DC_STATUS_IO;
} }
rc = libusb_claim_interface (device->handle, 0); rc = libusb_claim_interface (device->handle, 0);
if (rc < 0) { if (rc < 0) {
ERROR (context, "Failed to claim the usb interface."); ERROR (context, "Failed to claim the usb interface.");
libusb_close (device->handle); status = DC_STATUS_IO;
libusb_exit (device->context); goto error_usb_close;
free (device);
return DC_STATUS_IO;
} }
dc_status_t status = atomics_cobalt_device_version ((dc_device_t *) device, device->version, sizeof (device->version)); status = atomics_cobalt_device_version ((dc_device_t *) device, device->version, sizeof (device->version));
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to identify the dive computer."); ERROR (context, "Failed to identify the dive computer.");
libusb_close (device->handle); goto error_usb_close;
libusb_exit (device->context);
free (device);
return status;
} }
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_usb_close:
libusb_close (device->handle);
error_usb_exit:
libusb_exit (device->context);
error_free:
free (device);
return status;
#else #else
return DC_STATUS_UNSUPPORTED; return DC_STATUS_UNSUPPORTED;
#endif #endif

View File

@ -63,11 +63,14 @@ static const dc_device_vtable_t citizen_aqualand_device_vtable = {
dc_status_t dc_status_t
citizen_aqualand_device_open (dc_device_t **out, dc_context_t *context, const char *name) citizen_aqualand_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
citizen_aqualand_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
citizen_aqualand_device_t *device = (citizen_aqualand_device_t *) malloc (sizeof (citizen_aqualand_device_t)); device = (citizen_aqualand_device_t *) malloc (sizeof (citizen_aqualand_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -84,25 +87,23 @@ citizen_aqualand_device_open (dc_device_t **out, dc_context_t *context, const ch
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (4800 8N1). // Set the serial communication protocol (4800 8N1).
rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000ms). // Set the timeout for receiving data (1000ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -112,6 +113,12 @@ citizen_aqualand_device_open (dc_device_t **out, dc_context_t *context, const ch
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -236,11 +236,14 @@ cressi_edy_quit (cressi_edy_device_t *device)
dc_status_t dc_status_t
cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *name) cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
cressi_edy_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
cressi_edy_device_t *device = (cressi_edy_device_t *) malloc (sizeof (cressi_edy_device_t)); device = (cressi_edy_device_t *) malloc (sizeof (cressi_edy_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -259,34 +262,31 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (1200 8N1). // Set the serial communication protocol (1200 8N1).
rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the DTR and clear the RTS line. // Set the DTR and clear the RTS line.
if (serial_set_dtr (device->port, 1) == -1 || if (serial_set_dtr (device->port, 1) == -1 ||
serial_set_rts (device->port, 0) == -1) { serial_set_rts (device->port, 0) == -1) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -308,9 +308,8 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na
rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -320,6 +319,12 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -74,11 +74,14 @@ static const dc_device_vtable_t cressi_leonardo_device_vtable = {
dc_status_t dc_status_t
cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const char *name) cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
cressi_leonardo_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
cressi_leonardo_device_t *device = (cressi_leonardo_device_t *) malloc (sizeof (cressi_leonardo_device_t)); device = (cressi_leonardo_device_t *) malloc (sizeof (cressi_leonardo_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -95,34 +98,31 @@ cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const cha
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (115200 8N1). // Set the serial communication protocol (115200 8N1).
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Clear the DTR and set the RTS line. // Clear the DTR and set the RTS line.
if (serial_set_dtr (device->port, 0) == -1 || if (serial_set_dtr (device->port, 0) == -1 ||
serial_set_rts (device->port, 1) == -1) { serial_set_rts (device->port, 1) == -1) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
serial_sleep (device->port, 100); serial_sleep (device->port, 100);
@ -131,6 +131,12 @@ cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const cha
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }
static dc_status_t static dc_status_t

View File

@ -149,11 +149,14 @@ diverite_nitekq_handshake (diverite_nitekq_device_t *device)
dc_status_t dc_status_t
diverite_nitekq_device_open (dc_device_t **out, dc_context_t *context, const char *name) diverite_nitekq_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
diverite_nitekq_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
diverite_nitekq_device_t *device = (diverite_nitekq_device_t *) malloc (sizeof (diverite_nitekq_device_t)); device = (diverite_nitekq_device_t *) malloc (sizeof (diverite_nitekq_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -170,25 +173,23 @@ diverite_nitekq_device_open (dc_device_t **out, dc_context_t *context, const cha
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (9600 8N1). // Set the serial communication protocol (9600 8N1).
rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000ms). // Set the timeout for receiving data (1000ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -196,18 +197,21 @@ diverite_nitekq_device_open (dc_device_t **out, dc_context_t *context, const cha
serial_flush (device->port, SERIAL_QUEUE_BOTH); serial_flush (device->port, SERIAL_QUEUE_BOTH);
// Perform the handshaking. // Perform the handshaking.
dc_status_t status = diverite_nitekq_handshake (device); status = diverite_nitekq_handshake (device);
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to handshake."); ERROR (context, "Failed to handshake.");
serial_close (device->port); goto error_close;
free (device);
return status;
} }
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -110,11 +110,14 @@ divesystem_idive_device_open (dc_device_t **out, dc_context_t *context, const ch
dc_status_t dc_status_t
divesystem_idive_device_open2 (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) divesystem_idive_device_open2 (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
divesystem_idive_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
divesystem_idive_device_t *device = (divesystem_idive_device_t *) malloc (sizeof (divesystem_idive_device_t)); device = (divesystem_idive_device_t *) malloc (sizeof (divesystem_idive_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -132,25 +135,23 @@ divesystem_idive_device_open2 (dc_device_t **out, dc_context_t *context, const c
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (115200 8N1). // Set the serial communication protocol (115200 8N1).
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000ms). // Set the timeout for receiving data (1000ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -160,6 +161,12 @@ divesystem_idive_device_open2 (dc_device_t **out, dc_context_t *context, const c
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -202,11 +202,14 @@ hw_frog_transfer (hw_frog_device_t *device,
dc_status_t dc_status_t
hw_frog_device_open (dc_device_t **out, dc_context_t *context, const char *name) hw_frog_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
hw_frog_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
hw_frog_device_t *device = (hw_frog_device_t *) malloc (sizeof (hw_frog_device_t)); device = (hw_frog_device_t *) malloc (sizeof (hw_frog_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -223,25 +226,23 @@ hw_frog_device_open (dc_device_t **out, dc_context_t *context, const char *name)
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (115200 8N1). // Set the serial communication protocol (115200 8N1).
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000ms). // Set the timeout for receiving data (3000ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -249,17 +250,21 @@ hw_frog_device_open (dc_device_t **out, dc_context_t *context, const char *name)
serial_flush (device->port, SERIAL_QUEUE_BOTH); serial_flush (device->port, SERIAL_QUEUE_BOTH);
// Send the init command. // Send the init command.
dc_status_t status = hw_frog_transfer (device, NULL, INIT, NULL, 0, NULL, 0); status = hw_frog_transfer (device, NULL, INIT, NULL, 0, NULL, 0);
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to send the command."); ERROR (context, "Failed to send the command.");
serial_close (device->port); goto error_close;
free (device);
return status;
} }
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -125,11 +125,14 @@ hw_ostc_send (hw_ostc_device_t *device, unsigned char cmd, unsigned int echo)
dc_status_t dc_status_t
hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name) hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
hw_ostc_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
hw_ostc_device_t *device = (hw_ostc_device_t *) malloc (sizeof (hw_ostc_device_t)); device = (hw_ostc_device_t *) malloc (sizeof (hw_ostc_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -146,25 +149,23 @@ hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name)
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (115200 8N1). // Set the serial communication protocol (115200 8N1).
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data. // Set the timeout for receiving data.
if (serial_set_timeout (device->port, 4000) == -1) { if (serial_set_timeout (device->port, 4000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -174,6 +175,12 @@ hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name)
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -275,11 +275,14 @@ hw_ostc3_transfer (hw_ostc3_device_t *device,
dc_status_t dc_status_t
hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name) hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
hw_ostc3_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
hw_ostc3_device_t *device = (hw_ostc3_device_t *) malloc (sizeof (hw_ostc3_device_t)); device = (hw_ostc3_device_t *) malloc (sizeof (hw_ostc3_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -296,25 +299,23 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (115200 8N1). // Set the serial communication protocol (115200 8N1).
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000ms). // Set the timeout for receiving data (3000ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -326,6 +327,12 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -92,8 +92,7 @@ irda_socket_open (irda_t **out, dc_context_t *context)
WORD wVersionRequested = MAKEWORD (2, 2); WORD wVersionRequested = MAKEWORD (2, 2);
if (WSAStartup (wVersionRequested, &wsaData) != 0) { if (WSAStartup (wVersionRequested, &wsaData) != 0) {
SYSERROR (context, ERRNO); SYSERROR (context, ERRNO);
free (device); goto error_free;
return -1;
} }
// Confirm that the winsock dll supports version 2.2. // Confirm that the winsock dll supports version 2.2.
@ -102,9 +101,7 @@ irda_socket_open (irda_t **out, dc_context_t *context)
if (LOBYTE (wsaData.wVersion) != 2 || if (LOBYTE (wsaData.wVersion) != 2 ||
HIBYTE (wsaData.wVersion) != 2) { HIBYTE (wsaData.wVersion) != 2) {
ERROR (context, "Incorrect winsock version."); ERROR (context, "Incorrect winsock version.");
WSACleanup (); goto error_wsacleanup;
free (device);
return -1;
} }
#endif #endif
@ -116,16 +113,20 @@ irda_socket_open (irda_t **out, dc_context_t *context)
if (device->fd == -1) { if (device->fd == -1) {
#endif #endif
SYSERROR (context, ERRNO); SYSERROR (context, ERRNO);
#ifdef _WIN32 goto error_wsacleanup;
WSACleanup ();
#endif
free (device);
return -1;
} }
*out = device; *out = device;
return 0; return 0;
error_wsacleanup:
#ifdef _WIN32
WSACleanup ();
error_free:
#endif
free (device);
return -1;
} }

View File

@ -96,11 +96,14 @@ static const mares_darwin_layout_t mares_darwinair_layout = {
dc_status_t dc_status_t
mares_darwin_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) mares_darwin_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
mares_darwin_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
mares_darwin_device_t *device = (mares_darwin_device_t *) malloc (sizeof (mares_darwin_device_t)); device = (mares_darwin_device_t *) malloc (sizeof (mares_darwin_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -121,34 +124,31 @@ mares_darwin_device_open (dc_device_t **out, dc_context_t *context, const char *
int rc = serial_open (&device->base.port, context, name); int rc = serial_open (&device->base.port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (9600 8N1). // Set the serial communication protocol (9600 8N1).
rc = serial_configure (device->base.port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->base.port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->base.port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->base.port, 1000) == -1) { if (serial_set_timeout (device->base.port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->base.port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the DTR/RTS lines. // Set the DTR/RTS lines.
if (serial_set_dtr (device->base.port, 1) == -1 || if (serial_set_dtr (device->base.port, 1) == -1 ||
serial_set_rts (device->base.port, 1) == -1) { serial_set_rts (device->base.port, 1) == -1) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->base.port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -162,6 +162,12 @@ mares_darwin_device_open (dc_device_t **out, dc_context_t *context, const char *
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->base.port);
error_free:
free (device);
return status;
} }
static dc_status_t static dc_status_t

View File

@ -214,11 +214,14 @@ mares_iconhd_transfer (mares_iconhd_device_t *device,
dc_status_t dc_status_t
mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
mares_iconhd_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
mares_iconhd_device_t *device = (mares_iconhd_device_t *) malloc (sizeof (mares_iconhd_device_t)); device = (mares_iconhd_device_t *) malloc (sizeof (mares_iconhd_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -239,25 +242,23 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (115200 8E1). // Set the serial communication protocol (115200 8E1).
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_EVEN, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_EVEN, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the DTR/RTS lines. // Set the DTR/RTS lines.
@ -265,9 +266,8 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
serial_set_rts (device->port, 0) == -1) serial_set_rts (device->port, 0) == -1)
{ {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -275,12 +275,10 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
// Send the version command. // Send the version command.
unsigned char command[] = {0xC2, 0x67}; unsigned char command[] = {0xC2, 0x67};
dc_status_t status = mares_iconhd_transfer (device, command, sizeof (command), status = mares_iconhd_transfer (device, command, sizeof (command),
device->version, sizeof (device->version)); device->version, sizeof (device->version));
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
serial_close (device->port); goto error_close;
free (device);
return status;
} }
// Autodetect the model using the version packet. // Autodetect the model using the version packet.
@ -314,6 +312,12 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -90,11 +90,14 @@ static const mares_common_layout_t mares_nemo_apneist_layout = {
dc_status_t dc_status_t
mares_nemo_device_open (dc_device_t **out, dc_context_t *context, const char *name) mares_nemo_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
mares_nemo_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
mares_nemo_device_t *device = (mares_nemo_device_t *) malloc (sizeof (mares_nemo_device_t)); device = (mares_nemo_device_t *) malloc (sizeof (mares_nemo_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -111,34 +114,31 @@ mares_nemo_device_open (dc_device_t **out, dc_context_t *context, const char *na
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (9600 8N1). // Set the serial communication protocol (9600 8N1).
rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the DTR/RTS lines. // Set the DTR/RTS lines.
if (serial_set_dtr (device->port, 1) == -1 || if (serial_set_dtr (device->port, 1) == -1 ||
serial_set_rts (device->port, 1) == -1) { serial_set_rts (device->port, 1) == -1) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -147,6 +147,12 @@ mares_nemo_device_open (dc_device_t **out, dc_context_t *context, const char *na
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -88,11 +88,14 @@ static const mares_common_layout_t mares_nemowide_layout = {
dc_status_t dc_status_t
mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *name) mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
mares_puck_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
mares_puck_device_t *device = (mares_puck_device_t *) malloc (sizeof (mares_puck_device_t)); device = (mares_puck_device_t *) malloc (sizeof (mares_puck_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -109,34 +112,31 @@ mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *na
int rc = serial_open (&device->base.port, context, name); int rc = serial_open (&device->base.port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (38400 8N1). // Set the serial communication protocol (38400 8N1).
rc = serial_configure (device->base.port, 38400, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->base.port, 38400, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->base.port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->base.port, 1000) == -1) { if (serial_set_timeout (device->base.port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->base.port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Clear the DTR/RTS lines. // Clear the DTR/RTS lines.
if (serial_set_dtr (device->base.port, 0) == -1 || if (serial_set_dtr (device->base.port, 0) == -1 ||
serial_set_rts (device->base.port, 0) == -1) { serial_set_rts (device->base.port, 0) == -1) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->base.port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -144,11 +144,9 @@ mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *na
// Identify the model number. // Identify the model number.
unsigned char header[PACKETSIZE] = {0}; unsigned char header[PACKETSIZE] = {0};
dc_status_t status = mares_common_device_read ((dc_device_t *) device, 0, header, sizeof (header)); status = mares_common_device_read ((dc_device_t *) device, 0, header, sizeof (header));
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
serial_close (device->base.port); goto error_close;
free (device);
return status;
} }
// Override the base class values. // Override the base class values.
@ -171,6 +169,12 @@ mares_puck_device_open (dc_device_t **out, dc_context_t *context, const char *na
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->base.port);
error_free:
free (device);
return status;
} }

View File

@ -520,13 +520,15 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char
dc_status_t dc_status_t
oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
oceanic_atom2_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
oceanic_atom2_device_t *device = (oceanic_atom2_device_t *) malloc (sizeof (oceanic_atom2_device_t)); device = (oceanic_atom2_device_t *) malloc (sizeof (oceanic_atom2_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -546,8 +548,8 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Get the correct baudrate. // Get the correct baudrate.
@ -560,17 +562,15 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char
rc = serial_configure (device->port, baudrate, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, baudrate, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Give the interface 100 ms to settle and draw power up. // Give the interface 100 ms to settle and draw power up.
@ -586,11 +586,9 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char
// Switch the device from surface mode into download mode. Before sending // Switch the device from surface mode into download mode. Before sending
// this command, the device needs to be in PC mode (automatically activated // this command, the device needs to be in PC mode (automatically activated
// by connecting the device), or already in download mode. // by connecting the device), or already in download mode.
dc_status_t status = oceanic_atom2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); status = oceanic_atom2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version));
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
serial_close (device->port); goto error_close;
free (device);
return status;
} }
// Override the base class values. // Override the base class values.
@ -641,6 +639,12 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -221,11 +221,14 @@ oceanic_veo250_quit (oceanic_veo250_device_t *device)
dc_status_t dc_status_t
oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char *name) oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
oceanic_veo250_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
oceanic_veo250_device_t *device = (oceanic_veo250_device_t *) malloc (sizeof (oceanic_veo250_device_t)); device = (oceanic_veo250_device_t *) malloc (sizeof (oceanic_veo250_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -246,34 +249,31 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (9600 8N1). // Set the serial communication protocol (9600 8N1).
rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000 ms). // Set the timeout for receiving data (3000 ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the DTR and RTS lines. // Set the DTR and RTS lines.
if (serial_set_dtr (device->port, 1) == -1 || if (serial_set_dtr (device->port, 1) == -1 ||
serial_set_rts (device->port, 1) == -1) { serial_set_rts (device->port, 1) == -1) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Give the interface 100 ms to settle and draw power up. // Give the interface 100 ms to settle and draw power up.
@ -283,11 +283,9 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char
serial_flush (device->port, SERIAL_QUEUE_BOTH); serial_flush (device->port, SERIAL_QUEUE_BOTH);
// Initialize the data cable (PPS mode). // Initialize the data cable (PPS mode).
dc_status_t status = oceanic_veo250_init (device); status = oceanic_veo250_init (device);
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
serial_close (device->port); goto error_close;
free (device);
return status;
} }
// Delay the sending of the version command. // Delay the sending of the version command.
@ -298,14 +296,18 @@ oceanic_veo250_device_open (dc_device_t **out, dc_context_t *context, const char
// the user), or already in download mode. // the user), or already in download mode.
status = oceanic_veo250_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); status = oceanic_veo250_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version));
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
serial_close (device->port); goto error_close;
free (device);
return status;
} }
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -254,11 +254,14 @@ oceanic_vtpro_calibrate (oceanic_vtpro_device_t *device)
dc_status_t dc_status_t
oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char *name) oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
oceanic_vtpro_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
oceanic_vtpro_device_t *device = (oceanic_vtpro_device_t *) malloc (sizeof (oceanic_vtpro_device_t)); device = (oceanic_vtpro_device_t *) malloc (sizeof (oceanic_vtpro_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -277,34 +280,31 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (9600 8N1). // Set the serial communication protocol (9600 8N1).
rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000 ms). // Set the timeout for receiving data (3000 ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the DTR and RTS lines. // Set the DTR and RTS lines.
if (serial_set_dtr (device->port, 1) == -1 || if (serial_set_dtr (device->port, 1) == -1 ||
serial_set_rts (device->port, 1) == -1) { serial_set_rts (device->port, 1) == -1) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Give the interface 100 ms to settle and draw power up. // Give the interface 100 ms to settle and draw power up.
@ -314,11 +314,9 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char
serial_flush (device->port, SERIAL_QUEUE_BOTH); serial_flush (device->port, SERIAL_QUEUE_BOTH);
// Initialize the data cable (MOD mode). // Initialize the data cable (MOD mode).
dc_status_t status = oceanic_vtpro_init (device); status = oceanic_vtpro_init (device);
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
serial_close (device->port); goto error_close;
free (device);
return status;
} }
// Switch the device from surface mode into download mode. Before sending // Switch the device from surface mode into download mode. Before sending
@ -326,9 +324,7 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char
// the user), or already in download mode. // the user), or already in download mode.
status = oceanic_vtpro_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); status = oceanic_vtpro_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version));
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
serial_close (device->port); goto error_close;
free (device);
return status;
} }
// Calibrate the device. Although calibration is optional, it's highly // Calibrate the device. Although calibration is optional, it's highly
@ -336,9 +332,7 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char
// when processing the command itself is quite slow. // when processing the command itself is quite slow.
status = oceanic_vtpro_calibrate (device); status = oceanic_vtpro_calibrate (device);
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
serial_close (device->port); goto error_close;
free (device);
return status;
} }
// Override the base class values. // Override the base class values.
@ -351,6 +345,12 @@ oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -89,11 +89,14 @@ reefnet_sensus_cancel (reefnet_sensus_device_t *device)
dc_status_t dc_status_t
reefnet_sensus_device_open (dc_device_t **out, dc_context_t *context, const char *name) reefnet_sensus_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
reefnet_sensus_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
reefnet_sensus_device_t *device = (reefnet_sensus_device_t *) malloc (sizeof (reefnet_sensus_device_t)); device = (reefnet_sensus_device_t *) malloc (sizeof (reefnet_sensus_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -114,25 +117,23 @@ reefnet_sensus_device_open (dc_device_t **out, dc_context_t *context, const char
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (19200 8N1). // Set the serial communication protocol (19200 8N1).
rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000 ms). // Set the timeout for receiving data (3000 ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -141,6 +142,12 @@ reefnet_sensus_device_open (dc_device_t **out, dc_context_t *context, const char
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -68,11 +68,14 @@ static const dc_device_vtable_t reefnet_sensuspro_device_vtable = {
dc_status_t dc_status_t
reefnet_sensuspro_device_open (dc_device_t **out, dc_context_t *context, const char *name) reefnet_sensuspro_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
reefnet_sensuspro_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
reefnet_sensuspro_device_t *device = (reefnet_sensuspro_device_t *) malloc (sizeof (reefnet_sensuspro_device_t)); device = (reefnet_sensuspro_device_t *) malloc (sizeof (reefnet_sensuspro_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -92,25 +95,23 @@ reefnet_sensuspro_device_open (dc_device_t **out, dc_context_t *context, const c
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (19200 8N1). // Set the serial communication protocol (19200 8N1).
rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000ms). // Set the timeout for receiving data (3000ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -119,6 +120,12 @@ reefnet_sensuspro_device_open (dc_device_t **out, dc_context_t *context, const c
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -77,11 +77,14 @@ static const dc_device_vtable_t reefnet_sensusultra_device_vtable = {
dc_status_t dc_status_t
reefnet_sensusultra_device_open (dc_device_t **out, dc_context_t *context, const char *name) reefnet_sensusultra_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
reefnet_sensusultra_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t *) malloc (sizeof (reefnet_sensusultra_device_t)); device = (reefnet_sensusultra_device_t *) malloc (sizeof (reefnet_sensusultra_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -101,25 +104,23 @@ reefnet_sensusultra_device_open (dc_device_t **out, dc_context_t *context, const
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (115200 8N1). // Set the serial communication protocol (115200 8N1).
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000ms). // Set the timeout for receiving data (3000ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -128,6 +129,12 @@ reefnet_sensusultra_device_open (dc_device_t **out, dc_context_t *context, const
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -157,17 +157,14 @@ serial_open (serial_t **out, dc_context_t *context, const char* name)
device->fd = open (name, O_RDWR | O_NOCTTY | O_NONBLOCK); device->fd = open (name, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (device->fd == -1) { if (device->fd == -1) {
SYSERROR (context, errno); SYSERROR (context, errno);
free (device); goto error_free;
return -1; // Error during open call.
} }
#ifndef ENABLE_PTY #ifndef ENABLE_PTY
// Enable exclusive access mode. // Enable exclusive access mode.
if (ioctl (device->fd, TIOCEXCL, NULL) != 0) { if (ioctl (device->fd, TIOCEXCL, NULL) != 0) {
SYSERROR (context, errno); SYSERROR (context, errno);
close (device->fd); goto error_close;
free (device);
return -1;
} }
#endif #endif
@ -177,14 +174,18 @@ serial_open (serial_t **out, dc_context_t *context, const char* name)
// file descriptor represents a terminal device. // file descriptor represents a terminal device.
if (tcgetattr (device->fd, &device->tty) != 0) { if (tcgetattr (device->fd, &device->tty) != 0) {
SYSERROR (context, errno); SYSERROR (context, errno);
close (device->fd); goto error_close;
free (device);
return -1;
} }
*out = device; *out = device;
return 0; return 0;
error_close:
close (device->fd);
error_free:
free (device);
return -1;
} }
// //

View File

@ -150,8 +150,7 @@ serial_open (serial_t **out, dc_context_t *context, const char* name)
NULL); NULL);
if (device->hFile == INVALID_HANDLE_VALUE) { if (device->hFile == INVALID_HANDLE_VALUE) {
SYSERROR (context, GetLastError ()); SYSERROR (context, GetLastError ());
free (device); goto error_free;
return -1;
} }
// Retrieve the current communication settings and timeouts, // Retrieve the current communication settings and timeouts,
@ -161,14 +160,18 @@ serial_open (serial_t **out, dc_context_t *context, const char* name)
if (!GetCommState (device->hFile, &device->dcb) || if (!GetCommState (device->hFile, &device->dcb) ||
!GetCommTimeouts (device->hFile, &device->timeouts)) { !GetCommTimeouts (device->hFile, &device->timeouts)) {
SYSERROR (context, GetLastError ()); SYSERROR (context, GetLastError ());
CloseHandle (device->hFile); goto error_close;
free (device);
return -1;
} }
*out = device; *out = device;
return 0; return 0;
error_close:
CloseHandle (device->hFile);
error_free:
free (device);
return -1;
} }
// //

View File

@ -40,6 +40,8 @@
dc_status_t dc_status_t
shearwater_common_open (shearwater_common_device_t *device, dc_context_t *context, const char *name) 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. // Open the device.
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
@ -51,15 +53,15 @@ shearwater_common_open (shearwater_common_device_t *device, dc_context_t *contex
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_close;
} }
// Set the timeout for receiving data (3000ms). // Set the timeout for receiving data (3000ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_close;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -67,6 +69,10 @@ shearwater_common_open (shearwater_common_device_t *device, dc_context_t *contex
serial_flush (device->port, SERIAL_QUEUE_BOTH); serial_flush (device->port, SERIAL_QUEUE_BOTH);
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
return status;
} }

View File

@ -79,13 +79,14 @@ str2num (unsigned char data[], unsigned int size, unsigned int offset)
dc_status_t dc_status_t
shearwater_petrel_device_open (dc_device_t **out, dc_context_t *context, const char *name) shearwater_petrel_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t rc = DC_STATUS_SUCCESS; dc_status_t status = DC_STATUS_SUCCESS;
shearwater_petrel_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
shearwater_petrel_device_t *device = (shearwater_petrel_device_t *) malloc (sizeof (shearwater_petrel_device_t)); device = (shearwater_petrel_device_t *) malloc (sizeof (shearwater_petrel_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -98,15 +99,18 @@ shearwater_petrel_device_open (dc_device_t **out, dc_context_t *context, const c
memset (device->fingerprint, 0, sizeof (device->fingerprint)); memset (device->fingerprint, 0, sizeof (device->fingerprint));
// Open the device. // Open the device.
rc = shearwater_common_open (&device->base, context, name); status = shearwater_common_open (&device->base, context, name);
if (rc != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
free (device); goto error_free;
return rc;
} }
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_free:
free (device);
return status;
} }

View File

@ -65,13 +65,14 @@ static const dc_device_vtable_t shearwater_predator_device_vtable = {
dc_status_t dc_status_t
shearwater_predator_device_open (dc_device_t **out, dc_context_t *context, const char *name) shearwater_predator_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t rc = DC_STATUS_SUCCESS; dc_status_t status = DC_STATUS_SUCCESS;
shearwater_predator_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
shearwater_predator_device_t *device = (shearwater_predator_device_t *) malloc (sizeof (shearwater_predator_device_t)); device = (shearwater_predator_device_t *) malloc (sizeof (shearwater_predator_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -84,15 +85,18 @@ shearwater_predator_device_open (dc_device_t **out, dc_context_t *context, const
memset (device->fingerprint, 0, sizeof (device->fingerprint)); memset (device->fingerprint, 0, sizeof (device->fingerprint));
// Open the device. // Open the device.
rc = shearwater_common_open (&device->base, context, name); status = shearwater_common_open (&device->base, context, name);
if (rc != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
free (device); goto error_free;
return rc;
} }
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_free:
free (device);
return status;
} }

View File

@ -129,11 +129,14 @@ suunto_d9_device_autodetect (suunto_d9_device_t *device, unsigned int model)
dc_status_t dc_status_t
suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
suunto_d9_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
suunto_d9_device_t *device = (suunto_d9_device_t *) malloc (sizeof (suunto_d9_device_t)); device = (suunto_d9_device_t *) malloc (sizeof (suunto_d9_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -149,33 +152,30 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (9600 8N1). // Set the serial communication protocol (9600 8N1).
rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000 ms). // Set the timeout for receiving data (3000 ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the DTR line (power supply for the interface). // Set the DTR line (power supply for the interface).
if (serial_set_dtr (device->port, 1) == -1) { if (serial_set_dtr (device->port, 1) == -1) {
ERROR (context, "Failed to set the DTR line."); ERROR (context, "Failed to set the DTR line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Give the interface 100 ms to settle and draw power up. // Give the interface 100 ms to settle and draw power up.
@ -185,12 +185,10 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam
serial_flush (device->port, SERIAL_QUEUE_BOTH); serial_flush (device->port, SERIAL_QUEUE_BOTH);
// Try to autodetect the protocol variant. // Try to autodetect the protocol variant.
dc_status_t status = suunto_d9_device_autodetect (device, model); status = suunto_d9_device_autodetect (device, model);
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to identify the protocol variant."); ERROR (context, "Failed to identify the protocol variant.");
serial_close (device->port); goto error_close;
free (device);
return status;
} }
// Override the base class values. // Override the base class values.
@ -205,6 +203,12 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -71,11 +71,14 @@ static const suunto_common_layout_t suunto_eon_layout = {
dc_status_t dc_status_t
suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *name) suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
suunto_eon_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
suunto_eon_device_t *device = (suunto_eon_device_t *) malloc (sizeof (suunto_eon_device_t)); device = (suunto_eon_device_t *) malloc (sizeof (suunto_eon_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -91,38 +94,41 @@ suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *na
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (1200 8N2). // Set the serial communication protocol (1200 8N2).
rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000ms). // Set the timeout for receiving data (1000ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Clear the RTS line. // Clear the RTS line.
if (serial_set_rts (device->port, 0)) { if (serial_set_rts (device->port, 0)) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -556,6 +556,7 @@ static int initialize_eonsteel(suunto_eonsteel_device_t *eon)
dc_status_t dc_status_t
suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char *name, unsigned int model)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
suunto_eonsteel_device_t *eon; suunto_eonsteel_device_t *eon;
if (out == NULL) if (out == NULL)
@ -574,16 +575,15 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char
if (libusb_init(&eon->ctx)) { if (libusb_init(&eon->ctx)) {
ERROR(context, "libusb_init() failed"); ERROR(context, "libusb_init() failed");
free(eon); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
eon->handle = libusb_open_device_with_vid_pid(eon->ctx, 0x1493, 0x0030); eon->handle = libusb_open_device_with_vid_pid(eon->ctx, 0x1493, 0x0030);
if (!eon->handle) { if (!eon->handle) {
ERROR(context, "unable to open device"); ERROR(context, "unable to open device");
libusb_exit(eon->ctx); status = DC_STATUS_IO;
free(eon); goto error_usb_exit;
return DC_STATUS_IO;
} }
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102)
@ -594,15 +594,21 @@ suunto_eonsteel_device_open(dc_device_t **out, dc_context_t *context, const char
if (initialize_eonsteel(eon) < 0) { if (initialize_eonsteel(eon) < 0) {
ERROR(context, "unable to initialize device"); ERROR(context, "unable to initialize device");
libusb_close(eon->handle); status = DC_STATUS_IO;
libusb_exit(eon->ctx); goto error_usb_close;
free(eon);
return DC_STATUS_IO;
} }
*out = (dc_device_t *) eon; *out = (dc_device_t *) eon;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_usb_close:
libusb_close(eon->handle);
error_usb_exit:
libusb_exit(eon->ctx);
error_free:
free(eon);
return status;
} }
static int count_dir_entries(struct directory_entry *de) static int count_dir_entries(struct directory_entry *de)

View File

@ -65,11 +65,14 @@ static const dc_device_vtable_t suunto_solution_device_vtable = {
dc_status_t dc_status_t
suunto_solution_device_open (dc_device_t **out, dc_context_t *context, const char *name) suunto_solution_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
suunto_solution_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
suunto_solution_device_t *device = (suunto_solution_device_t *) malloc (sizeof (suunto_solution_device_t)); device = (suunto_solution_device_t *) malloc (sizeof (suunto_solution_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -85,38 +88,41 @@ suunto_solution_device_open (dc_device_t **out, dc_context_t *context, const cha
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (1200 8N2). // Set the serial communication protocol (1200 8N2).
rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000ms). // Set the timeout for receiving data (1000ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Clear the RTS line. // Clear the RTS line.
if (serial_set_rts (device->port, 0)) { if (serial_set_rts (device->port, 0)) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -91,11 +91,14 @@ static const suunto_common_layout_t suunto_spyder_layout = {
dc_status_t dc_status_t
suunto_vyper_device_open (dc_device_t **out, dc_context_t *context, const char *name) suunto_vyper_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
suunto_vyper_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
suunto_vyper_device_t *device = (suunto_vyper_device_t *) malloc (sizeof (suunto_vyper_device_t)); device = (suunto_vyper_device_t *) malloc (sizeof (suunto_vyper_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -111,33 +114,30 @@ suunto_vyper_device_open (dc_device_t **out, dc_context_t *context, const char *
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status= DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (2400 8O1). // Set the serial communication protocol (2400 8O1).
rc = serial_configure (device->port, 2400, 8, SERIAL_PARITY_ODD, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 2400, 8, SERIAL_PARITY_ODD, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the DTR line (power supply for the interface). // Set the DTR line (power supply for the interface).
if (serial_set_dtr (device->port, 1) == -1) { if (serial_set_dtr (device->port, 1) == -1) {
ERROR (context, "Failed to set the DTR line."); ERROR (context, "Failed to set the DTR line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Give the interface 100 ms to settle and draw power up. // Give the interface 100 ms to settle and draw power up.
@ -149,6 +149,12 @@ suunto_vyper_device_open (dc_device_t **out, dc_context_t *context, const char *
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -80,11 +80,14 @@ static const suunto_common2_layout_t suunto_helo2_layout = {
dc_status_t dc_status_t
suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char *name) suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
suunto_vyper2_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
suunto_vyper2_device_t *device = (suunto_vyper2_device_t *) malloc (sizeof (suunto_vyper2_device_t)); device = (suunto_vyper2_device_t *) malloc (sizeof (suunto_vyper2_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -100,33 +103,30 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (9600 8N1). // Set the serial communication protocol (9600 8N1).
rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000 ms). // Set the timeout for receiving data (3000 ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the DTR line (power supply for the interface). // Set the DTR line (power supply for the interface).
if (serial_set_dtr (device->port, 1) == -1) { if (serial_set_dtr (device->port, 1) == -1) {
ERROR (context, "Failed to set the DTR line."); ERROR (context, "Failed to set the DTR line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Give the interface 100 ms to settle and draw power up. // Give the interface 100 ms to settle and draw power up.
@ -139,12 +139,10 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char
serial_set_halfduplex (device->port, 1); serial_set_halfduplex (device->port, 1);
// Read the version info. // Read the version info.
dc_status_t status = suunto_common2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); status = suunto_common2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version));
if (status != DC_STATUS_SUCCESS) { if (status != DC_STATUS_SUCCESS) {
ERROR (context, "Failed to read the version info."); ERROR (context, "Failed to read the version info.");
serial_close (device->port); goto error_close;
free (device);
return status;
} }
// Override the base class values. // Override the base class values.
@ -157,6 +155,12 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -74,11 +74,14 @@ static const dc_device_vtable_t uwatec_aladin_device_vtable = {
dc_status_t dc_status_t
uwatec_aladin_device_open (dc_device_t **out, dc_context_t *context, const char *name) uwatec_aladin_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
uwatec_aladin_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
uwatec_aladin_device_t *device = (uwatec_aladin_device_t *) malloc (sizeof (uwatec_aladin_device_t)); device = (uwatec_aladin_device_t *) malloc (sizeof (uwatec_aladin_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -97,39 +100,42 @@ uwatec_aladin_device_open (dc_device_t **out, dc_context_t *context, const char
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (19200 8N1). // Set the serial communication protocol (19200 8N1).
rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 19200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (INFINITE). // Set the timeout for receiving data (INFINITE).
if (serial_set_timeout (device->port, -1) == -1) { if (serial_set_timeout (device->port, -1) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Clear the RTS line and set the DTR line. // Clear the RTS line and set the DTR line.
if (serial_set_dtr (device->port, 1) == -1 || if (serial_set_dtr (device->port, 1) == -1 ||
serial_set_rts (device->port, 0) == -1) { serial_set_rts (device->port, 0) == -1) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -70,11 +70,14 @@ static const dc_device_vtable_t uwatec_memomouse_device_vtable = {
dc_status_t dc_status_t
uwatec_memomouse_device_open (dc_device_t **out, dc_context_t *context, const char *name) uwatec_memomouse_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
uwatec_memomouse_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
uwatec_memomouse_device_t *device = (uwatec_memomouse_device_t *) malloc (sizeof (uwatec_memomouse_device_t)); device = (uwatec_memomouse_device_t *) malloc (sizeof (uwatec_memomouse_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -93,34 +96,31 @@ uwatec_memomouse_device_open (dc_device_t **out, dc_context_t *context, const ch
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (9600 8N1). // Set the serial communication protocol (9600 8N1).
rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Clear the RTS and DTR lines. // Clear the RTS and DTR lines.
if (serial_set_rts (device->port, 0) == -1 || if (serial_set_rts (device->port, 0) == -1 ||
serial_set_dtr (device->port, 0) == -1) { serial_set_dtr (device->port, 0) == -1) {
ERROR (context, "Failed to set the DTR/RTS line."); ERROR (context, "Failed to set the DTR/RTS line.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -129,6 +129,12 @@ uwatec_memomouse_device_open (dc_device_t **out, dc_context_t *context, const ch
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -186,11 +186,14 @@ uwatec_meridian_handshake (uwatec_meridian_device_t *device)
dc_status_t dc_status_t
uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const char *name) uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
uwatec_meridian_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
uwatec_meridian_device_t *device = (uwatec_meridian_device_t *) malloc (sizeof (uwatec_meridian_device_t)); device = (uwatec_meridian_device_t *) malloc (sizeof (uwatec_meridian_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -209,25 +212,23 @@ uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const cha
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (57600 8N1). // Set the serial communication protocol (57600 8N1).
rc = serial_configure (device->port, 57600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 57600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (3000ms). // Set the timeout for receiving data (3000ms).
if (serial_set_timeout (device->port, 3000) == -1) { if (serial_set_timeout (device->port, 3000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -239,6 +240,12 @@ uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const cha
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }

View File

@ -145,11 +145,14 @@ uwatec_smart_handshake (uwatec_smart_device_t *device)
dc_status_t dc_status_t
uwatec_smart_device_open (dc_device_t **out, dc_context_t *context) uwatec_smart_device_open (dc_device_t **out, dc_context_t *context)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
uwatec_smart_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
uwatec_smart_device_t *device = (uwatec_smart_device_t *) malloc (sizeof (uwatec_smart_device_t)); device = (uwatec_smart_device_t *) malloc (sizeof (uwatec_smart_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -169,33 +172,30 @@ uwatec_smart_device_open (dc_device_t **out, dc_context_t *context)
int rc = irda_socket_open (&device->socket, context); int rc = irda_socket_open (&device->socket, context);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the irda socket."); ERROR (context, "Failed to open the irda socket.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Discover the device. // Discover the device.
rc = irda_socket_discover (device->socket, uwatec_smart_discovery, device); rc = irda_socket_discover (device->socket, uwatec_smart_discovery, device);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to discover the device."); ERROR (context, "Failed to discover the device.");
irda_socket_close (device->socket); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
if (device->address == 0) { if (device->address == 0) {
ERROR (context, "No dive computer found."); ERROR (context, "No dive computer found.");
irda_socket_close (device->socket); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Connect the device. // Connect the device.
rc = irda_socket_connect_lsap (device->socket, device->address, 1); rc = irda_socket_connect_lsap (device->socket, device->address, 1);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to connect the device."); ERROR (context, "Failed to connect the device.");
irda_socket_close (device->socket); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Perform the handshaking. // Perform the handshaking.
@ -204,6 +204,12 @@ uwatec_smart_device_open (dc_device_t **out, dc_context_t *context)
*out = (dc_device_t*) device; *out = (dc_device_t*) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
irda_socket_close (device->socket);
error_free:
free (device);
return status;
} }

View File

@ -512,11 +512,14 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser)
dc_status_t dc_status_t
uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int devtime, dc_ticks_t systime) uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int devtime, dc_ticks_t systime)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
uwatec_smart_parser_t *parser = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
uwatec_smart_parser_t *parser = (uwatec_smart_parser_t *) malloc (sizeof (uwatec_smart_parser_t)); parser = (uwatec_smart_parser_t *) malloc (sizeof (uwatec_smart_parser_t));
if (parser == NULL) { if (parser == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -594,8 +597,8 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
parser->nevents[0] = C_ARRAY_SIZE (uwatec_smart_tec_events_0); parser->nevents[0] = C_ARRAY_SIZE (uwatec_smart_tec_events_0);
break; break;
default: default:
free (parser); status = DC_STATUS_INVALIDARGS;
return DC_STATUS_INVALIDARGS; goto error_free;
} }
parser->cached = 0; parser->cached = 0;
@ -616,6 +619,10 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
*out = (dc_parser_t*) parser; *out = (dc_parser_t*) parser;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_free:
free (parser);
return status;
} }

View File

@ -137,11 +137,14 @@ zeagle_n2ition3_init (zeagle_n2ition3_device_t *device)
dc_status_t dc_status_t
zeagle_n2ition3_device_open (dc_device_t **out, dc_context_t *context, const char *name) zeagle_n2ition3_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{ {
dc_status_t status = DC_STATUS_SUCCESS;
zeagle_n2ition3_device_t *device = NULL;
if (out == NULL) if (out == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
// Allocate memory. // Allocate memory.
zeagle_n2ition3_device_t *device = (zeagle_n2ition3_device_t *) malloc (sizeof (zeagle_n2ition3_device_t)); device = (zeagle_n2ition3_device_t *) malloc (sizeof (zeagle_n2ition3_device_t));
if (device == NULL) { if (device == NULL) {
ERROR (context, "Failed to allocate memory."); ERROR (context, "Failed to allocate memory.");
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
@ -158,25 +161,23 @@ zeagle_n2ition3_device_open (dc_device_t **out, dc_context_t *context, const cha
int rc = serial_open (&device->port, context, name); int rc = serial_open (&device->port, context, name);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to open the serial port."); ERROR (context, "Failed to open the serial port.");
free (device); status = DC_STATUS_IO;
return DC_STATUS_IO; goto error_free;
} }
// Set the serial communication protocol (4800 8N1). // Set the serial communication protocol (4800 8N1).
rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) { if (rc == -1) {
ERROR (context, "Failed to set the terminal attributes."); ERROR (context, "Failed to set the terminal attributes.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Set the timeout for receiving data (1000 ms). // Set the timeout for receiving data (1000 ms).
if (serial_set_timeout (device->port, 1000) == -1) { if (serial_set_timeout (device->port, 1000) == -1) {
ERROR (context, "Failed to set the timeout."); ERROR (context, "Failed to set the timeout.");
serial_close (device->port); status = DC_STATUS_IO;
free (device); goto error_close;
return DC_STATUS_IO;
} }
// Make sure everything is in a sane state. // Make sure everything is in a sane state.
@ -188,6 +189,12 @@ zeagle_n2ition3_device_open (dc_device_t **out, dc_context_t *context, const cha
*out = (dc_device_t *) device; *out = (dc_device_t *) device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
error_close:
serial_close (device->port);
error_free:
free (device);
return status;
} }