Merge git://github.com/libdivecomputer/libdivecomputer into Subsurface-branch
Merge with upstream. * git://github.com/libdivecomputer/libdivecomputer: Simplify the conditional compilation Disable some Windows specific compiler warnings Use SDP to auto-detect the rfcomm port number Use the actual IrDA device names Use the correct data type for the temperature Disable O2 sensors with default calibration values Add support for the Seac Jack Check for memory allocation errors Erase the buffer before calling the vtable function Replace hardcoded size with the sizeof operator Use the correct model number for the Shearwater Nerd 2
This commit is contained in:
commit
fb0d0b269e
@ -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])
|
||||
|
||||
101
src/bluetooth.c
101
src/bluetooth.c
@ -30,6 +30,7 @@
|
||||
#ifdef _WIN32
|
||||
#ifdef HAVE_WS2BTH_H
|
||||
#define BLUETOOTH
|
||||
#include <initguid.h>
|
||||
#include <ws2bth.h>
|
||||
#endif
|
||||
#else
|
||||
@ -39,6 +40,8 @@
|
||||
#include <bluetooth/rfcomm.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
#include <bluetooth/sdp.h>
|
||||
#include <bluetooth/sdp_lib.h>
|
||||
#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));
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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.");
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
14
src/usbhid.c
14
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)
|
||||
{
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user