diff --git a/src/citizen_aqualand.c b/src/citizen_aqualand.c index 3af5d52..4d1817c 100644 --- a/src/citizen_aqualand.c +++ b/src/citizen_aqualand.c @@ -159,7 +159,11 @@ citizen_aqualand_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) return DC_STATUS_NOMEMORY; } - dc_iostream_set_dtr (device->iostream, 1); + status = dc_iostream_set_dtr (device->iostream, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to set the DTR line."); + return status; + } // Send the init byte. const unsigned char init[] = {0x7F}; @@ -201,7 +205,11 @@ citizen_aqualand_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) break; } - dc_iostream_set_dtr (device->iostream, 0); + status = dc_iostream_set_dtr (device->iostream, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to clear the DTR line."); + return status; + } return DC_STATUS_SUCCESS; } diff --git a/src/divesystem_idive.c b/src/divesystem_idive.c index 46ecb34..c3d21bd 100644 --- a/src/divesystem_idive.c +++ b/src/divesystem_idive.c @@ -477,6 +477,7 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb WARNING(abstract->context, "Skipped unreadable dive!"); continue; } else { + dc_buffer_free(buffer); return rc; } } @@ -500,8 +501,10 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb (idx ) & 0xFF, (idx >> 8) & 0xFF}; rc = divesystem_idive_transfer (device, cmd_sample, sizeof(cmd_sample), packet, commands->sample.size * commands->nsamples, &errcode); - if (rc != DC_STATUS_SUCCESS) + if (rc != DC_STATUS_SUCCESS) { + dc_buffer_free(buffer); return rc; + } // If the number of samples is not an exact multiple of the // number of samples per packet, then the last packet diff --git a/src/hw_ostc.c b/src/hw_ostc.c index 36d6080..8967393 100644 --- a/src/hw_ostc.c +++ b/src/hw_ostc.c @@ -905,7 +905,12 @@ hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename) // bootloader needs to be send repeatedly, until the response packet is // received. Thus the time between each two attempts is directly controlled // by the timeout value. - dc_iostream_set_timeout (device->iostream, 300); + rc = dc_iostream_set_timeout (device->iostream, 300); + if (rc != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the timeout."); + free (firmware); + return rc; + } // Setup the bootloader. const unsigned int baudrates[] = {19200, 115200}; @@ -931,7 +936,12 @@ hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename) } // Increase the timeout again. - dc_iostream_set_timeout (device->iostream, 1000); + rc = dc_iostream_set_timeout (device->iostream, 1000); + if (rc != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the timeout."); + free (firmware); + return rc; + } // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; diff --git a/src/irda.c b/src/irda.c index 149808a..972c125 100644 --- a/src/irda.c +++ b/src/irda.c @@ -221,18 +221,22 @@ dc_irda_connect_name (dc_iostream_t *abstract, unsigned int address, const char peer.irdaDeviceID[1] = (address >> 8) & 0xFF; peer.irdaDeviceID[2] = (address >> 16) & 0xFF; peer.irdaDeviceID[3] = (address >> 24) & 0xFF; - if (name) - strncpy (peer.irdaServiceName, name, 25); - else - memset (peer.irdaServiceName, 0x00, 25); + if (name) { + strncpy (peer.irdaServiceName, name, sizeof(peer.irdaServiceName) - 1); + peer.irdaServiceName[sizeof(peer.irdaServiceName) - 1] = '\0'; + } else { + memset (peer.irdaServiceName, 0x00, sizeof(peer.irdaServiceName)); + } #else struct sockaddr_irda peer; peer.sir_family = AF_IRDA; peer.sir_addr = address; - if (name) - strncpy (peer.sir_name, name, 25); - else - memset (peer.sir_name, 0x00, 25); + if (name) { + strncpy (peer.sir_name, name, sizeof(peer.sir_name) - 1); + peer.sir_name[sizeof(peer.sir_name) - 1] = '\0'; + } else { + memset (peer.sir_name, 0x00, sizeof(peer.sir_name)); + } #endif return dc_socket_connect (&device->base, (struct sockaddr *) &peer, sizeof (peer)); diff --git a/src/mares_darwin.c b/src/mares_darwin.c index 4f87f6f..e4d118f 100644 --- a/src/mares_darwin.c +++ b/src/mares_darwin.c @@ -331,7 +331,7 @@ mares_darwin_extract_dives (dc_device_t *abstract, const unsigned char data[], u current -= length; } - if (device && memcmp (buffer, device->fingerprint, sizeof (device->fingerprint)) == 0) { + if (memcmp (buffer, device->fingerprint, sizeof (device->fingerprint)) == 0) { free (buffer); return DC_STATUS_SUCCESS; } diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index 9a9a351..bccc570 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -620,7 +620,7 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, break; unsigned char *fp = buffer + offset + length - headersize + fingerprint; - if (device && memcmp (fp, device->fingerprint, sizeof (device->fingerprint)) == 0) { + if (memcmp (fp, device->fingerprint, sizeof (device->fingerprint)) == 0) { break; } diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 77c8e9d..77b946a 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -630,8 +630,16 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char dc_iostream_sleep (device->iostream, 100); // Set the DTR/RTS lines. - dc_iostream_set_dtr(device->iostream, 1); - dc_iostream_set_rts(device->iostream, 1); + status = dc_iostream_set_dtr(device->iostream, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the DTR line."); + return status; + } + status = dc_iostream_set_rts(device->iostream, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set the DTR line."); + return status; + } // Make sure everything is in a sane state. dc_iostream_purge (device->iostream, DC_DIRECTION_ALL); diff --git a/src/oceanic_vtpro.c b/src/oceanic_vtpro.c index e1ba31c..8635b73 100644 --- a/src/oceanic_vtpro.c +++ b/src/oceanic_vtpro.c @@ -269,9 +269,13 @@ oceanic_vtpro_calibrate (oceanic_vtpro_device_t *device) // device needs approximately 6 seconds to respond. unsigned char answer[2] = {0}; unsigned char command[2] = {0x18, 0x00}; - dc_iostream_set_timeout (device->iostream, 9000); - dc_status_t rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, sizeof (answer)); - dc_iostream_set_timeout (device->iostream, 3000); + dc_status_t rc = dc_iostream_set_timeout (device->iostream, 9000); + if (rc != DC_STATUS_SUCCESS) + return rc; + rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, sizeof (answer)); + if (rc != DC_STATUS_SUCCESS) + return rc; + rc = dc_iostream_set_timeout (device->iostream, 3000); if (rc != DC_STATUS_SUCCESS) return rc; diff --git a/src/reefnet_sensuspro.c b/src/reefnet_sensuspro.c index e50cb44..5af9181 100644 --- a/src/reefnet_sensuspro.c +++ b/src/reefnet_sensuspro.c @@ -182,7 +182,11 @@ reefnet_sensuspro_handshake (reefnet_sensuspro_device_t *device) dc_device_t *abstract = (dc_device_t *) device; // Assert a break condition. - dc_iostream_set_break (device->iostream, 1); + status = dc_iostream_set_break (device->iostream, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to set break."); + return status; + } // Receive the handshake from the dive computer. unsigned char handshake[SZ_HANDSHAKE + 2] = {0}; @@ -193,7 +197,11 @@ reefnet_sensuspro_handshake (reefnet_sensuspro_device_t *device) } // Clear the break condition again. - dc_iostream_set_break (device->iostream, 0); + status = dc_iostream_set_break (device->iostream, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to clear break."); + return status; + } // Verify the checksum of the handshake packet. unsigned short crc = array_uint16_le (handshake + SZ_HANDSHAKE); diff --git a/src/reefnet_sensusultra.c b/src/reefnet_sensusultra.c index fd3d399..a6aef5a 100644 --- a/src/reefnet_sensusultra.c +++ b/src/reefnet_sensusultra.c @@ -716,6 +716,7 @@ reefnet_sensusultra_device_foreach (dc_device_t *abstract, dc_dive_callback_t ca // Prepend the packet to the buffer. if (!dc_buffer_prepend (buffer, packet + 2, SZ_PACKET)) { + dc_buffer_free (buffer); ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/serial_posix.c b/src/serial_posix.c index 1698df8..9a9373e 100644 --- a/src/serial_posix.c +++ b/src/serial_posix.c @@ -262,7 +262,11 @@ dc_serial_close (dc_iostream_t *abstract) #ifndef ENABLE_PTY // Disable exclusive access mode. - ioctl (device->fd, TIOCNXCL, NULL); + if (ioctl (device->fd, TIOCNXCL, NULL)) { + int errcode = errno; + SYSERROR (abstract->context, errcode); + dc_status_set_error(&status, syserror (errcode)); + } #endif // Close the device. diff --git a/src/suunto_d9.c b/src/suunto_d9.c index 2c92a49..8c2834c 100644 --- a/src/suunto_d9.c +++ b/src/suunto_d9.c @@ -240,7 +240,11 @@ suunto_d9_device_packet (dc_device_t *abstract, const unsigned char command[], u return DC_STATUS_CANCELLED; // Clear RTS to send the command. - dc_iostream_set_rts (device->iostream, 0); + status = dc_iostream_set_rts (device->iostream, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to clear RTS."); + return status; + } // Send the command to the dive computer. status = dc_iostream_write (device->iostream, command, csize, NULL); @@ -265,7 +269,11 @@ suunto_d9_device_packet (dc_device_t *abstract, const unsigned char command[], u } // Set RTS to receive the reply. - dc_iostream_set_rts (device->iostream, 1); + status = dc_iostream_set_rts (device->iostream, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to set RTS."); + return status; + } // Receive the answer of the dive computer. status = dc_iostream_read (device->iostream, answer, asize, NULL); diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index cbf1b75..609608d 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -671,6 +671,7 @@ static int get_file_list(suunto_eonsteel_device_t *eon, struct directory_entry * sizeof(result), result); if (rc < 0) { ERROR(eon->base.context, "cmd DIR_LOOKUP failed"); + return -1; } HEXDUMP(eon->base.context, DC_LOGLEVEL_DEBUG, "DIR_LOOKUP", result, rc); diff --git a/src/suunto_eonsteel_parser.c b/src/suunto_eonsteel_parser.c index 429e862..ffdd172 100644 --- a/src/suunto_eonsteel_parser.c +++ b/src/suunto_eonsteel_parser.c @@ -217,7 +217,7 @@ static int fill_in_group_details(suunto_eonsteel_parser_t *eon, struct type_desc long index; index = strtol(grp, &end, 10); - if (index < 0 || index > MAXTYPE || end == grp) { + if (index < 0 || index >= MAXTYPE || end == grp) { ERROR(eon->base.context, "Group type descriptor '%s' does not parse", desc->desc); break; } @@ -344,7 +344,7 @@ static int record_type(suunto_eonsteel_parser_t *eon, unsigned short type, const } } while ((name = next) != NULL); - if (type > MAXTYPE) { + if (type >= MAXTYPE) { ERROR(eon->base.context, "Type out of range (%04x: '%s' '%s' '%s')", type, desc.desc ? desc.desc : "", @@ -413,7 +413,7 @@ static int traverse_entry(suunto_eonsteel_parser_t *eon, const unsigned char *p, end += 4; } - if (type > MAXTYPE || !eon->type_desc[type].desc) { + if (type >= MAXTYPE || !eon->type_desc[type].desc) { HEXDUMP(eon->base.context, DC_LOGLEVEL_DEBUG, "last", last, 16); HEXDUMP(eon->base.context, DC_LOGLEVEL_DEBUG, "this", begin, 16); } else { @@ -776,10 +776,12 @@ static void sample_setpoint_type(const struct type_desc *desc, struct sample_dat sample.ppo2 = info->eon->cache.customsetpoint; else { DEBUG(info->eon->base.context, "sample_setpoint_type(%u) unknown type '%s'", value, type); + free((void *)type); return; } if (info->callback) info->callback(DC_SAMPLE_SETPOINT, sample, info->userdata); + free((void *)type); } // uint32 @@ -1125,6 +1127,7 @@ static int add_gas_type(suunto_eonsteel_parser_t *eon, const struct type_desc *d eon->cache.initialized |= 1 << DC_FIELD_GASMIX_COUNT; eon->cache.initialized |= 1 << DC_FIELD_TANK_COUNT; + free((void *)name); return 0; } diff --git a/src/suunto_solution.c b/src/suunto_solution.c index 2e9e14e..ffa8262 100644 --- a/src/suunto_solution.c +++ b/src/suunto_solution.c @@ -161,7 +161,11 @@ suunto_solution_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) unsigned char answer[3] = {0}; // Assert DTR - dc_iostream_set_dtr (device->iostream, 1); + status = dc_iostream_set_dtr(device->iostream, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to set the DTR line."); + return status; + } // Send: 0xFF command[0] = 0xFF; diff --git a/src/suunto_vyper.c b/src/suunto_vyper.c index ba5ad20..89be1fc 100644 --- a/src/suunto_vyper.c +++ b/src/suunto_vyper.c @@ -178,7 +178,11 @@ suunto_vyper_send (suunto_vyper_device_t *device, const unsigned char command[], dc_iostream_sleep (device->iostream, 500); // Set RTS to send the command. - dc_iostream_set_rts (device->iostream, 1); + status = dc_iostream_set_rts (device->iostream, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to set RTS."); + return status; + } // Send the command to the dive computer. status = dc_iostream_write (device->iostream, command, csize, NULL); @@ -202,7 +206,11 @@ suunto_vyper_send (suunto_vyper_device_t *device, const unsigned char command[], dc_iostream_purge (device->iostream, DC_DIRECTION_INPUT); // Clear RTS to receive the reply. - dc_iostream_set_rts (device->iostream, 0); + status = dc_iostream_set_rts (device->iostream, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to clear RTS."); + return status; + } return DC_STATUS_SUCCESS; } diff --git a/src/suunto_vyper2.c b/src/suunto_vyper2.c index 6ddd3d7..2591878 100644 --- a/src/suunto_vyper2.c +++ b/src/suunto_vyper2.c @@ -127,10 +127,18 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char dc_iostream_sleep (device->iostream, 100); // Make sure everything is in a sane state. - dc_iostream_purge (device->iostream, DC_DIRECTION_ALL); + status = dc_iostream_purge (device->iostream, DC_DIRECTION_ALL); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to reset IO state."); + goto error_close; + } // Enable half-duplex emulation. - dc_iostream_set_halfduplex (device->iostream, 1); + status = dc_iostream_set_halfduplex (device->iostream, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (context, "Failed to set half duplex."); + goto error_close; + } // Read the version info. status = suunto_common2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); @@ -187,7 +195,11 @@ suunto_vyper2_device_packet (dc_device_t *abstract, const unsigned char command[ dc_iostream_sleep (device->iostream, 600); // Set RTS to send the command. - dc_iostream_set_rts (device->iostream, 1); + status = dc_iostream_set_rts (device->iostream, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to set the RTS line."); + return status; + } // Send the command to the dive computer. status = dc_iostream_write (device->iostream, command, csize, NULL); @@ -197,7 +209,11 @@ suunto_vyper2_device_packet (dc_device_t *abstract, const unsigned char command[ } // Clear RTS to receive the reply. - dc_iostream_set_rts (device->iostream, 0); + status = dc_iostream_set_rts (device->iostream, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to set the RTS line."); + return status; + } // Receive the answer of the dive computer. status = dc_iostream_read (device->iostream, answer, asize, NULL); diff --git a/src/uwatec_smart.c b/src/uwatec_smart.c index bb67131..d30bee6 100644 --- a/src/uwatec_smart.c +++ b/src/uwatec_smart.c @@ -213,17 +213,10 @@ error_free: static dc_status_t uwatec_smart_device_close (dc_device_t *abstract) { - dc_status_t status = DC_STATUS_SUCCESS; uwatec_smart_device_t *device = (uwatec_smart_device_t*) abstract; - dc_status_t rc = DC_STATUS_SUCCESS; - // Close the device. - rc = dc_iostream_close (device->iostream); - if (status != DC_STATUS_SUCCESS) { - dc_status_set_error(&status, rc); - } - - return status; + // Close the device and pass up the return code. + return dc_iostream_close (device->iostream); } diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index a70acb7..bd715b0 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -886,15 +886,15 @@ uwatec_smart_fixsignbit (unsigned int x, unsigned int n) return 0; unsigned int signbit = (1 << (n - 1)); - unsigned int mask = (0xFFFFFFFF << n); + unsigned int mask = (signbit - 1); // When turning a two's-complement number with a certain number // of bits into one with more bits, the sign bit must be repeated // in all the extra bits. if ((x & signbit) == signbit) - return x | mask; + return x | ~mask; else - return x & ~mask; + return x & mask; }