diff --git a/configure.ac b/configure.ac index 1f7bca9..cf0a56d 100644 --- a/configure.ac +++ b/configure.ac @@ -195,6 +195,11 @@ AX_APPEND_COMPILE_FLAGS([ \ -Wno-unused-parameter \ ]) +# Windows specific compiler options. +AS_IF([test "$os_win32" = "yes"], [ + AX_APPEND_COMPILE_FLAGS([-Wno-pedantic-ms-format]) +]) + # Versioning. AC_SUBST([DC_VERSION],[dc_version]) AC_SUBST([DC_VERSION_MAJOR],[dc_version_major]) diff --git a/src/bluetooth.c b/src/bluetooth.c index b139892..1c3211e 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -30,6 +30,7 @@ #ifdef _WIN32 #ifdef HAVE_WS2BTH_H #define BLUETOOTH +#include #include #endif #else @@ -39,6 +40,8 @@ #include #include #include +#include +#include #endif #endif @@ -105,6 +108,89 @@ dc_address_set (bdaddr_t *ba, dc_bluetooth_address_t address) shift += 8; } } + +static dc_status_t +dc_bluetooth_sdp (uint8_t *port, dc_context_t *context, const bdaddr_t *ba) +{ + dc_status_t status = DC_STATUS_SUCCESS; + sdp_session_t *session = NULL; + sdp_list_t *search = NULL, *attrid = NULL; + sdp_list_t *records = NULL; + uint8_t channel = 0; + + // Connect to the SDP server on the remote device. + session = sdp_connect (BDADDR_ANY, ba, SDP_RETRY_IF_BUSY); + if (session == NULL) { + s_errcode_t errcode = S_ERRNO; + SYSERROR (context, errcode); + status = dc_socket_syserror(errcode); + goto error; + } + + // Specify the UUID of the serial port service with all attributes. + uuid_t uuid = {0}; + uint32_t range = 0x0000FFFF; + sdp_uuid16_create (&uuid, SERIAL_PORT_SVCLASS_ID); + search = sdp_list_append (NULL, &uuid); + attrid = sdp_list_append (NULL, &range); + if (search == NULL || attrid == NULL) { + s_errcode_t errcode = S_ERRNO; + SYSERROR (context, errcode); + status = dc_socket_syserror(errcode); + goto error; + } + + // Get a list of the service records with their attributes. + if (sdp_service_search_attr_req (session, search, SDP_ATTR_REQ_RANGE, attrid, &records) != 0) { + s_errcode_t errcode = S_ERRNO; + SYSERROR (context, errcode); + status = dc_socket_syserror(errcode); + goto error; + } + + // Go through each of the service records. + for (sdp_list_t *r = records; r; r = r->next ) { + sdp_record_t *record = (sdp_record_t *) r->data; + + // Get a list of the protocol sequences. + sdp_list_t *protos = NULL; + if (sdp_get_access_protos (record, &protos) != 0 ) { + s_errcode_t errcode = S_ERRNO; + SYSERROR (context, errcode); + status = dc_socket_syserror(errcode); + goto error; + } + + // Get the rfcomm port number. + int ch = sdp_get_proto_port (protos, RFCOMM_UUID); + + sdp_list_foreach (protos, (sdp_list_func_t) sdp_list_free, NULL); + sdp_list_free (protos, NULL); + + if (ch > 0) { + channel = ch; + break; + } + } + + if (channel == 0) { + ERROR (context, "No serial port service found!"); + status = DC_STATUS_IO; + goto error; + } + + INFO (context, "SDP: channel=%u", channel); + + *port = channel; + +error: + sdp_list_free (records, (sdp_free_func_t) sdp_record_free); + sdp_list_free (attrid, NULL); + sdp_list_free (search, NULL); + sdp_close (session); + + return status; +} #endif #endif @@ -298,12 +384,23 @@ dc_bluetooth_connect (dc_iostream_t *abstract, dc_bluetooth_address_t address, u sa.addressFamily = AF_BTH; sa.btAddr = address; sa.port = port; - memset(&sa.serviceClassId, 0, sizeof(sa.serviceClassId)); + if (port == 0) { + sa.serviceClassId = SerialPortServiceClass_UUID; + } else { + memset(&sa.serviceClassId, 0, sizeof(sa.serviceClassId)); + } #else struct sockaddr_rc sa; sa.rc_family = AF_BLUETOOTH; - sa.rc_channel = port; dc_address_set (&sa.rc_bdaddr, address); + if (port == 0) { + dc_status_t rc = dc_bluetooth_sdp (&sa.rc_channel, abstract->context, &sa.rc_bdaddr); + if (rc != DC_STATUS_SUCCESS) { + return rc; + } + } else { + sa.rc_channel = port; + } #endif return dc_socket_connect (&device->base, (struct sockaddr *) &sa, sizeof (sa)); diff --git a/src/citizen_aqualand.c b/src/citizen_aqualand.c index 4d1817c..99e60e6 100644 --- a/src/citizen_aqualand.c +++ b/src/citizen_aqualand.c @@ -152,13 +152,6 @@ citizen_aqualand_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t status = DC_STATUS_SUCCESS; citizen_aqualand_device_t *device = (citizen_aqualand_device_t *) abstract; - // Erase the current contents of the buffer and - // pre-allocate the required amount of memory. - if (!dc_buffer_clear (buffer)) { - ERROR (abstract->context, "Insufficient buffer space available."); - return DC_STATUS_NOMEMORY; - } - status = dc_iostream_set_dtr (device->iostream, 1); if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to set the DTR line."); @@ -192,7 +185,10 @@ citizen_aqualand_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) return status; } - dc_buffer_append(buffer, answer, sizeof (answer)); + if (!dc_buffer_append(buffer, answer, sizeof (answer))) { + ERROR (abstract->context, "Insufficient buffer space available."); + return status; + } // Send the command. status = dc_iostream_write (device->iostream, command, sizeof (command), NULL); diff --git a/src/cochran_commander.c b/src/cochran_commander.c index e21ec7e..bbf92c7 100644 --- a/src/cochran_commander.c +++ b/src/cochran_commander.c @@ -842,12 +842,6 @@ cochran_commander_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) unsigned int config_size = sizeof(config); unsigned int size = device->layout->rb_profile_end - device->layout->rb_logbook_begin; - // Make sure buffer is good. - if (!dc_buffer_clear(buffer)) { - ERROR (abstract->context, "Uninitialized buffer."); - return DC_STATUS_INVALIDARGS; - } - // Reserve space if (!dc_buffer_resize(buffer, size)) { ERROR(abstract->context, "Insufficient buffer space available."); diff --git a/src/cochran_commander_parser.c b/src/cochran_commander_parser.c index 12e8b42..e8ba76f 100644 --- a/src/cochran_commander_parser.c +++ b/src/cochran_commander_parser.c @@ -474,19 +474,19 @@ cochran_commander_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, if (value) { switch (type) { case DC_FIELD_TEMPERATURE_SURFACE: - *((unsigned int*) value) = (data[layout->start_temp] - 32.0) / 1.8; + *((double *) value) = (data[layout->start_temp] - 32.0) / 1.8; break; case DC_FIELD_TEMPERATURE_MINIMUM: if (data[layout->min_temp] == 0xFF) return DC_STATUS_UNSUPPORTED; - *((unsigned int*) value) = (data[layout->min_temp] / 2.0 + 20 - 32) / 1.8; + *((double *) value) = (data[layout->min_temp] / 2.0 + 20 - 32) / 1.8; break; case DC_FIELD_TEMPERATURE_MAXIMUM: if (layout->max_temp == UNSUPPORTED) return DC_STATUS_UNSUPPORTED; if (data[layout->max_temp] == 0xFF) return DC_STATUS_UNSUPPORTED; - *((unsigned int*) value) = (data[layout->max_temp] / 2.0 + 20 - 32) / 1.8; + *((double *) value) = (data[layout->max_temp] / 2.0 + 20 - 32) / 1.8; break; case DC_FIELD_DIVETIME: minutes = array_uint16_le(data + layout->divetime); diff --git a/src/cressi_edy.c b/src/cressi_edy.c index 80e4fac..327b4aa 100644 --- a/src/cressi_edy.c +++ b/src/cressi_edy.c @@ -389,9 +389,8 @@ cressi_edy_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { cressi_edy_device_t *device = (cressi_edy_device_t *) abstract; - // Erase the current contents of the buffer and - // allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_resize (buffer, device->layout->memsize)) { + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, device->layout->memsize)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/cressi_leonardo.c b/src/cressi_leonardo.c index 4021288..e9d142b 100644 --- a/src/cressi_leonardo.c +++ b/src/cressi_leonardo.c @@ -320,9 +320,8 @@ cressi_leonardo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t status = DC_STATUS_SUCCESS; cressi_leonardo_device_t *device = (cressi_leonardo_device_t *) abstract; - // Erase the current contents of the buffer and - // pre-allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_resize (buffer, SZ_MEMORY)) { + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/descriptor.c b/src/descriptor.c index acfa624..c549f7a 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -293,9 +293,9 @@ static const dc_descriptor_t g_descriptors[] = { {"Shearwater", "Petrel", DC_FAMILY_SHEARWATER_PETREL, 3}, // BT // BLE {"Shearwater", "Petrel 2", DC_FAMILY_SHEARWATER_PETREL, 3}, // BT // BLE {"Shearwater", "Nerd", DC_FAMILY_SHEARWATER_PETREL, 4}, // BT - {"Shearwater", "Nerd 2", DC_FAMILY_SHEARWATER_PETREL, 4}, // BLE {"Shearwater", "Perdix", DC_FAMILY_SHEARWATER_PETREL, 5}, // BT // BLE {"Shearwater", "Perdix AI", DC_FAMILY_SHEARWATER_PETREL, 6}, // BLE + {"Shearwater", "Nerd 2", DC_FAMILY_SHEARWATER_PETREL, 7}, // BLE /* Dive Rite NiTek Q */ {"Dive Rite", "NiTek Q", DC_FAMILY_DIVERITE_NITEKQ, 0}, /* Citizen Hyper Aqualand */ @@ -322,6 +322,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Ratio", "iDive Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x42}, {"Ratio", "iDive Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x44}, {"Ratio", "iDive Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x45}, + {"Seac", "Jack", DC_FAMILY_DIVESYSTEM_IDIVE, 0x1000}, /* Cochran Commander */ {"Cochran", "Commander TM", DC_FAMILY_COCHRAN_COMMANDER, 0}, // FTDI {"Cochran", "Commander I", DC_FAMILY_COCHRAN_COMMANDER, 1}, // FTDI diff --git a/src/device.c b/src/device.c index 49f845a..3998cb7 100644 --- a/src/device.c +++ b/src/device.c @@ -316,6 +316,11 @@ dc_device_dump (dc_device_t *device, dc_buffer_t *buffer) if (device->vtable->dump == NULL) return DC_STATUS_UNSUPPORTED; + if (buffer == NULL) + return DC_STATUS_INVALIDARGS; + + dc_buffer_clear (buffer); + return device->vtable->dump (device, buffer); } diff --git a/src/diverite_nitekq.c b/src/diverite_nitekq.c index 8524b56..6fc38b5 100644 --- a/src/diverite_nitekq.c +++ b/src/diverite_nitekq.c @@ -258,8 +258,8 @@ diverite_nitekq_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t rc = DC_STATUS_SUCCESS; unsigned char packet[256] = {0}; - // Erase the current contents of the buffer. - if (!dc_buffer_clear (buffer) || !dc_buffer_reserve (buffer, SZ_PACKET + SZ_MEMORY)) { + // Pre-allocate the required amount of memory. + if (!dc_buffer_reserve (buffer, SZ_PACKET + SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/divesystem_idive.c b/src/divesystem_idive.c index c3d21bd..f2976b1 100644 --- a/src/divesystem_idive.c +++ b/src/divesystem_idive.c @@ -493,7 +493,12 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb dc_buffer_clear(buffer); dc_buffer_reserve(buffer, commands->header.size + commands->sample.size * nsamples); - dc_buffer_append(buffer, packet, commands->header.size); + + if (!dc_buffer_append(buffer, packet, commands->header.size)) { + ERROR (abstract->context, "Insufficient buffer space available."); + dc_buffer_free(buffer); + return rc; + } for (unsigned int j = 0; j < nsamples; j += commands->nsamples) { unsigned int idx = j + 1; @@ -518,7 +523,11 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb progress.current = i * NSTEPS + STEP(j + n + 1, nsamples + 1); device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); - dc_buffer_append(buffer, packet, commands->sample.size * n); + if (!dc_buffer_append(buffer, packet, commands->sample.size * n)) { + ERROR (abstract->context, "Insufficient buffer space available."); + dc_buffer_free(buffer); + return rc; + } } unsigned char *data = dc_buffer_get_data(buffer); diff --git a/src/hw_ostc.c b/src/hw_ostc.c index 8967393..c47af16 100644 --- a/src/hw_ostc.c +++ b/src/hw_ostc.c @@ -219,12 +219,6 @@ hw_ostc_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t status = DC_STATUS_SUCCESS; hw_ostc_device_t *device = (hw_ostc_device_t*) abstract; - // Erase the current contents of the buffer. - if (!dc_buffer_clear (buffer)) { - ERROR (abstract->context, "Insufficient buffer space available."); - return DC_STATUS_NOMEMORY; - } - // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; progress.maximum = SZ_HEADER + SZ_FW_NEW; @@ -593,7 +587,10 @@ hw_ostc_device_screenshot (dc_device_t *abstract, dc_buffer_t *buffer, hw_ostc_f if (format == HW_OSTC_FORMAT_RAW) { // Append the raw data to the output buffer. - dc_buffer_append (buffer, raw, nbytes); + if (!dc_buffer_append (buffer, raw, nbytes)) { + ERROR (abstract->context, "Insufficient buffer space available."); + return DC_STATUS_NOMEMORY; + } } else { // Store the decompressed data in the output buffer. for (unsigned int i = 0; i < count; ++i) { diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index e240342..5dec754 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -1150,7 +1150,11 @@ hw_ostc3_firmware_readfile4 (dc_buffer_t *buffer, dc_context_t *context, const c size_t n = 0; unsigned char block[1024] = {0}; while ((n = fread (block, 1, sizeof (block), fp)) > 0) { - dc_buffer_append (buffer, block, n); + if (!dc_buffer_append (buffer, block, n)) { + ERROR (context, "Insufficient buffer space available."); + fclose (fp); + return DC_STATUS_NOMEMORY; + } } // Close the file. @@ -1555,12 +1559,6 @@ hw_ostc3_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract; - // Erase the current contents of the buffer. - if (!dc_buffer_clear (buffer)) { - ERROR (abstract->context, "Insufficient buffer space available."); - return DC_STATUS_NOMEMORY; - } - // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; progress.maximum = SZ_MEMORY; diff --git a/src/irda.c b/src/irda.c index 972c125..b38a502 100644 --- a/src/irda.c +++ b/src/irda.c @@ -263,13 +263,13 @@ dc_irda_connect_lsap (dc_iostream_t *abstract, unsigned int address, unsigned in peer.irdaDeviceID[1] = (address >> 8) & 0xFF; peer.irdaDeviceID[2] = (address >> 16) & 0xFF; peer.irdaDeviceID[3] = (address >> 24) & 0xFF; - snprintf (peer.irdaServiceName, 25, "LSAP-SEL%u", lsap); + snprintf (peer.irdaServiceName, sizeof(peer.irdaServiceName), "LSAP-SEL%u", lsap); #else struct sockaddr_irda peer; peer.sir_family = AF_IRDA; peer.sir_addr = address; peer.sir_lsap_sel = lsap; - memset (peer.sir_name, 0x00, 25); + 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 e4d118f..0d5152d 100644 --- a/src/mares_darwin.c +++ b/src/mares_darwin.c @@ -219,9 +219,8 @@ mares_darwin_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) assert (device->layout != NULL); - // Erase the current contents of the buffer and - // allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_resize (buffer, device->layout->memsize)) { + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, device->layout->memsize)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index bccc570..c9352e2 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -403,9 +403,8 @@ mares_iconhd_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { mares_iconhd_device_t *device = (mares_iconhd_device_t *) abstract; - // Erase the current contents of the buffer and - // pre-allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_resize (buffer, device->layout->memsize)) { + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, device->layout->memsize)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/mares_nemo.c b/src/mares_nemo.c index d6d4e01..a83b459 100644 --- a/src/mares_nemo.c +++ b/src/mares_nemo.c @@ -193,9 +193,8 @@ mares_nemo_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t status = DC_STATUS_SUCCESS; mares_nemo_device_t *device = (mares_nemo_device_t *) abstract; - // Erase the current contents of the buffer and - // pre-allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_reserve (buffer, MEMORYSIZE)) { + // Pre-allocate the required amount of memory. + if (!dc_buffer_reserve (buffer, MEMORYSIZE)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/mares_puck.c b/src/mares_puck.c index 5006b43..6d921f0 100644 --- a/src/mares_puck.c +++ b/src/mares_puck.c @@ -224,9 +224,8 @@ mares_puck_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) assert (device->layout != NULL); - // Erase the current contents of the buffer and - // allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_resize (buffer, device->layout->memsize)) { + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, device->layout->memsize)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/oceanic_common.c b/src/oceanic_common.c index 43bc06d..1ab491d 100644 --- a/src/oceanic_common.c +++ b/src/oceanic_common.c @@ -156,9 +156,8 @@ oceanic_common_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) assert (device != NULL); assert (device->layout != NULL); - // Erase the current contents of the buffer and - // allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_resize (buffer, device->layout->memsize)) { + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, device->layout->memsize)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/reefnet_sensus.c b/src/reefnet_sensus.c index 0fc6e52..b8d0820 100644 --- a/src/reefnet_sensus.c +++ b/src/reefnet_sensus.c @@ -279,9 +279,8 @@ reefnet_sensus_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t status = DC_STATUS_SUCCESS; reefnet_sensus_device_t *device = (reefnet_sensus_device_t*) abstract; - // Erase the current contents of the buffer and - // pre-allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_reserve (buffer, SZ_MEMORY)) { + // Pre-allocate the required amount of memory. + if (!dc_buffer_reserve (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/reefnet_sensuspro.c b/src/reefnet_sensuspro.c index 5af9181..0001f1c 100644 --- a/src/reefnet_sensuspro.c +++ b/src/reefnet_sensuspro.c @@ -271,9 +271,8 @@ reefnet_sensuspro_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t status = DC_STATUS_SUCCESS; reefnet_sensuspro_device_t *device = (reefnet_sensuspro_device_t*) abstract; - // Erase the current contents of the buffer and - // pre-allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_reserve (buffer, SZ_MEMORY)) { + // Pre-allocate the required amount of memory. + if (!dc_buffer_reserve (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/reefnet_sensusultra.c b/src/reefnet_sensusultra.c index a6aef5a..9ac95a2 100644 --- a/src/reefnet_sensusultra.c +++ b/src/reefnet_sensusultra.c @@ -379,9 +379,8 @@ reefnet_sensusultra_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { reefnet_sensusultra_device_t *device = (reefnet_sensusultra_device_t*) abstract; - // Erase the current contents of the buffer and - // pre-allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_reserve (buffer, SZ_MEMORY)) { + // Pre-allocate the required amount of memory. + if (!dc_buffer_reserve (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/scubapro_g2.c b/src/scubapro_g2.c index c6c533f..c33d902 100644 --- a/src/scubapro_g2.c +++ b/src/scubapro_g2.c @@ -307,12 +307,6 @@ scubapro_g2_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) scubapro_g2_device_t *device = (scubapro_g2_device_t*) abstract; dc_status_t rc = DC_STATUS_SUCCESS; - // Erase the current contents of the buffer. - if (!dc_buffer_clear (buffer)) { - ERROR (abstract->context, "Insufficient buffer space available."); - return DC_STATUS_NOMEMORY; - } - // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; device_event_emit (&device->base, DC_EVENT_PROGRESS, &progress); diff --git a/src/shearwater_common.h b/src/shearwater_common.h index 4e3a561..3075f99 100644 --- a/src/shearwater_common.h +++ b/src/shearwater_common.h @@ -38,6 +38,7 @@ extern "C" { #define NERD 4 #define PERDIX 5 #define PERDIXAI 6 +#define NERD2 7 #define NSTEPS 10000 #define STEP(i,n) ((NSTEPS * (i) + (n) / 2) / (n)) diff --git a/src/shearwater_petrel.c b/src/shearwater_petrel.c index 5f38aaa..28624c3 100644 --- a/src/shearwater_petrel.c +++ b/src/shearwater_petrel.c @@ -224,9 +224,11 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call break; case 0x0606: case 0x0A0A: // Nerd 1 - case 0x0E0D: // Nerd 2 model = NERD; break; + case 0x0E0D: // Nerd 2 + model = NERD2; + break; case 0x0404: case 0x0909: // Petrel 1 case 0x0B0B: // Petrel 1 (newer hardware) diff --git a/src/shearwater_predator.c b/src/shearwater_predator.c index a47d414..6326785 100644 --- a/src/shearwater_predator.c +++ b/src/shearwater_predator.c @@ -127,8 +127,8 @@ shearwater_predator_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { shearwater_common_device_t *device = (shearwater_common_device_t *) abstract; - // Erase the current contents of the buffer. - if (!dc_buffer_clear (buffer) || !dc_buffer_reserve (buffer, SZ_MEMORY)) { + // Pre-allocate the required amount of memory. + if (!dc_buffer_reserve (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index 16b458a..96b443f 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -71,6 +71,7 @@ struct shearwater_predator_parser_t { unsigned int ngasmixes; unsigned int oxygen[NGASMIXES]; unsigned int helium[NGASMIXES]; + unsigned int calibrated; double calibration[3]; unsigned int serial; dc_divemode_t mode; @@ -159,6 +160,10 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig parser->oxygen[i] = 0; parser->helium[i] = 0; } + parser->calibrated = 0; + for (unsigned int i = 0; i < 3; ++i) { + parser->calibration[i] = 0.0; + } parser->mode = DC_DIVEMODE_OC; *out = (dc_parser_t *) parser; @@ -182,6 +187,10 @@ shearwater_predator_parser_set_data (dc_parser_t *abstract, const unsigned char parser->oxygen[i] = 0; parser->helium[i] = 0; } + parser->calibrated = 0; + for (unsigned int i = 0; i < 3; ++i) { + parser->calibration[i] = 0.0; + } parser->mode = DC_DIVEMODE_OC; return DC_STATUS_SUCCESS; @@ -449,17 +458,34 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) } // Cache sensor calibration for later use - parser->calibration[0] = array_uint16_be(data + 87) / 100000.0; - parser->calibration[1] = array_uint16_be(data + 89) / 100000.0; - parser->calibration[2] = array_uint16_be(data + 91) / 100000.0; - // The Predator expects the mV output of the cells to be within 30mV - // to 70mV in 100% O2 at 1 atmosphere. - // If the calibration value is scaled with a factor 2.2, then the - // sensors lines up and matches the average. - if (parser->model == PREDATOR) { - for (size_t i = 0; i < 3; ++i) { + unsigned int nsensors = 0, ndefaults = 0; + for (size_t i = 0; i < 3; ++i) { + unsigned int calibration = array_uint16_be(data + 87 + i * 2); + parser->calibration[i] = calibration / 100000.0; + if (parser->model == PREDATOR) { + // The Predator expects the mV output of the cells to be + // within 30mV to 70mV in 100% O2 at 1 atmosphere. If the + // calibration value is scaled with a factor 2.2, then the + // sensors lines up and matches the average. parser->calibration[i] *= 2.2; } + if (data[86] & (1 << i)) { + if (calibration == 2100) { + ndefaults++; + } + nsensors++; + } + } + if (nsensors == ndefaults) { + // If all (calibrated) sensors still have their factory default + // calibration values (2100), they are probably not calibrated + // properly. To avoid returning incorrect ppO2 values to the + // application, they are manually disabled (e.g. marked as + // uncalibrated). + WARNING (abstract->context, "Disabled all O2 sensors due to a default calibration value."); + parser->calibrated = 0; + } else { + parser->calibrated = data[86]; } // Cache the data for later use. @@ -630,13 +656,13 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal if (callback) callback (DC_SAMPLE_PPO2, sample, userdata); #else sample.ppo2 = data[offset + 12] * parser->calibration[0]; - if (callback && (data[86] & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata); + if (callback && (parser->calibrated & 0x01)) callback (DC_SAMPLE_PPO2, sample, userdata); sample.ppo2 = data[offset + 14] * parser->calibration[1]; - if (callback && (data[86] & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata); + if (callback && (parser->calibrated & 0x02)) callback (DC_SAMPLE_PPO2, sample, userdata); sample.ppo2 = data[offset + 15] * parser->calibration[2]; - if (callback && (data[86] & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata); + if (callback && (parser->calibrated & 0x04)) callback (DC_SAMPLE_PPO2, sample, userdata); #endif } diff --git a/src/suunto_eon.c b/src/suunto_eon.c index f41fae6..8b9138c 100644 --- a/src/suunto_eon.c +++ b/src/suunto_eon.c @@ -149,9 +149,8 @@ suunto_eon_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t status = DC_STATUS_SUCCESS; suunto_eon_device_t *device = (suunto_eon_device_t*) abstract; - // Erase the current contents of the buffer and - // pre-allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_reserve (buffer, SZ_MEMORY)) { + // Pre-allocate the required amount of memory. + if (!dc_buffer_reserve (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index 609608d..f9ded4d 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -94,6 +94,15 @@ static const dc_device_vtable_t suunto_eonsteel_device_vtable = { static const char dive_directory[] = "0:/dives"; +static void file_list_free (struct directory_entry *de) +{ + while (de) { + struct directory_entry *next = de->next; + free (de); + de = next; + } +} + static struct directory_entry *alloc_dirent(int type, int len, const char *name) { struct directory_entry *res; @@ -593,7 +602,10 @@ static int read_file(suunto_eonsteel_device_t *eon, const char *filename, dc_buf if (got > size) got = size; - dc_buffer_append(buf, result+8, got); + if (!dc_buffer_append (buf, result + 8, got)) { + ERROR (eon->base.context, "Insufficient buffer space available."); + return -1; + } offset += got; size -= got; } @@ -833,7 +845,12 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac return DC_STATUS_SUCCESS; } - file = dc_buffer_new(0); + file = dc_buffer_new (16384); + if (file == NULL) { + ERROR (abstract->context, "Insufficient buffer space available."); + file_list_free (de); + return DC_STATUS_NOMEMORY; + } progress.maximum = count_dir_entries(de); progress.current = 0; device_event_emit(abstract, DC_EVENT_PROGRESS, &progress); diff --git a/src/suunto_solution.c b/src/suunto_solution.c index ffa8262..9480252 100644 --- a/src/suunto_solution.c +++ b/src/suunto_solution.c @@ -143,9 +143,8 @@ suunto_solution_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t status = DC_STATUS_SUCCESS; suunto_solution_device_t *device = (suunto_solution_device_t*) abstract; - // Erase the current contents of the buffer and - // allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_resize (buffer, SZ_MEMORY)) { + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/suunto_vyper.c b/src/suunto_vyper.c index 89be1fc..276e633 100644 --- a/src/suunto_vyper.c +++ b/src/suunto_vyper.c @@ -454,9 +454,8 @@ suunto_vyper_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init, dc static dc_status_t suunto_vyper_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { - // Erase the current contents of the buffer and - // allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_resize (buffer, SZ_MEMORY)) { + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/usbhid.c b/src/usbhid.c index f3eb4bc..468c1ab 100644 --- a/src/usbhid.c +++ b/src/usbhid.c @@ -107,6 +107,12 @@ static const dc_iostream_vtable_t dc_usbhid_vtable = { dc_usbhid_close, /* close */ }; +static dc_mutex_t g_usbhid_mutex = DC_MUTEX_INIT; +static size_t g_usbhid_refcount = 0; +#ifdef USE_LIBUSB +static libusb_context *g_usbhid_ctx = NULL; +#endif + #if defined(USE_LIBUSB) static dc_status_t syserror(int errcode) @@ -129,7 +135,6 @@ syserror(int errcode) } } #endif -#endif static dc_status_t usbhid_packet_close(dc_custom_io_t *io) @@ -206,13 +211,6 @@ dc_usbhid_custom_io (dc_context_t *context, unsigned int vid, unsigned int pid) return DC_STATUS_SUCCESS; } -#ifdef USBHID -static dc_mutex_t g_usbhid_mutex = DC_MUTEX_INIT; -static size_t g_usbhid_refcount = 0; -#ifdef USE_LIBUSB -static libusb_context *g_usbhid_ctx = NULL; -#endif - static void dc_mutex_lock (dc_mutex_t *mutex) { diff --git a/src/uwatec_aladin.c b/src/uwatec_aladin.c index dc697c2..0f1a49a 100644 --- a/src/uwatec_aladin.c +++ b/src/uwatec_aladin.c @@ -178,9 +178,8 @@ uwatec_aladin_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) dc_status_t status = DC_STATUS_SUCCESS; uwatec_aladin_device_t *device = (uwatec_aladin_device_t*) abstract; - // Erase the current contents of the buffer and - // pre-allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_reserve (buffer, SZ_MEMORY)) { + // Pre-allocate the required amount of memory. + if (!dc_buffer_reserve (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } diff --git a/src/uwatec_memomouse.c b/src/uwatec_memomouse.c index 90466a0..ca3a747 100644 --- a/src/uwatec_memomouse.c +++ b/src/uwatec_memomouse.c @@ -450,12 +450,6 @@ uwatec_memomouse_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) uwatec_memomouse_device_t *device = (uwatec_memomouse_device_t*) abstract; dc_status_t rc = DC_STATUS_SUCCESS; - // Erase the current contents of the buffer. - if (!dc_buffer_clear (buffer)) { - ERROR (abstract->context, "Insufficient buffer space available."); - return DC_STATUS_NOMEMORY; - } - // Give the interface some time to notice the DTR // line change from a previous transfer (if any). dc_iostream_sleep (device->iostream, 500); diff --git a/src/uwatec_meridian.c b/src/uwatec_meridian.c index 5844c29..17f1b62 100644 --- a/src/uwatec_meridian.c +++ b/src/uwatec_meridian.c @@ -288,12 +288,6 @@ uwatec_meridian_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) uwatec_meridian_device_t *device = (uwatec_meridian_device_t*) abstract; dc_status_t rc = DC_STATUS_SUCCESS; - // Erase the current contents of the buffer. - if (!dc_buffer_clear (buffer)) { - ERROR (abstract->context, "Insufficient buffer space available."); - return DC_STATUS_NOMEMORY; - } - // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; device_event_emit (&device->base, DC_EVENT_PROGRESS, &progress); diff --git a/src/uwatec_smart.c b/src/uwatec_smart.c index d30bee6..4581881 100644 --- a/src/uwatec_smart.c +++ b/src/uwatec_smart.c @@ -27,9 +27,12 @@ #include "device-private.h" #include "irda.h" #include "array.h" +#include "platform.h" #define ISINSTANCE(device) dc_device_isinstance((device), &uwatec_smart_device_vtable) +#define C_ARRAY_SIZE(array) (sizeof (array) / sizeof *(array)) + typedef struct uwatec_smart_device_t { dc_device_t base; dc_iostream_t *iostream; @@ -62,22 +65,25 @@ uwatec_smart_extract_dives (dc_device_t *device, const unsigned char data[], uns static void uwatec_smart_discovery (unsigned int address, const char *name, unsigned int charset, unsigned int hints, void *userdata) { + static const char *names[] = { + "Aladin Smart Com", + "Aladin Smart Pro", + "Aladin Smart Tec", + "Aladin Smart Z", + "Uwatec Aladin", + "UWATEC Galileo", + "UWATEC Galileo Sol", + }; + uwatec_smart_device_t *device = (uwatec_smart_device_t*) userdata; - if (device == NULL) + if (device == NULL || name == NULL) return; - if (strncmp (name, "UWATEC Galileo Sol", 18) == 0 || - strncmp (name, "Uwatec Smart", 12) == 0 || - strstr (name, "Uwatec") != NULL || - strstr (name, "UWATEC") != NULL || - strstr (name, "Aladin") != NULL || - strstr (name, "ALADIN") != NULL || - strstr (name, "Smart") != NULL || - strstr (name, "SMART") != NULL || - strstr (name, "Galileo") != NULL || - strstr (name, "GALILEO") != NULL) - { - device->address = address; + for (size_t i = 0; i < C_ARRAY_SIZE(names); ++i) { + if (strcasecmp(name, names[i]) == 0) { + device->address = address; + return; + } } } @@ -243,12 +249,6 @@ uwatec_smart_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) uwatec_smart_device_t *device = (uwatec_smart_device_t*) abstract; dc_status_t rc = DC_STATUS_SUCCESS; - // Erase the current contents of the buffer. - if (!dc_buffer_clear (buffer)) { - ERROR (abstract->context, "Insufficient buffer space available."); - return DC_STATUS_NOMEMORY; - } - // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; device_event_emit (&device->base, DC_EVENT_PROGRESS, &progress); diff --git a/src/zeagle_n2ition3.c b/src/zeagle_n2ition3.c index 01b9d5e..58f81ba 100644 --- a/src/zeagle_n2ition3.c +++ b/src/zeagle_n2ition3.c @@ -263,9 +263,8 @@ zeagle_n2ition3_device_read (dc_device_t *abstract, unsigned int address, unsign static dc_status_t zeagle_n2ition3_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { - // Erase the current contents of the buffer and - // allocate the required amount of memory. - if (!dc_buffer_clear (buffer) || !dc_buffer_resize (buffer, SZ_MEMORY)) { + // Allocate the required amount of memory. + if (!dc_buffer_resize (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; }