import: turn C-string in device_data_t into std::strings

It was never clear what was a pointer to a static string from
libdivecomputer and what was allocated.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-02 21:26:22 +02:00
parent 0c45c5279b
commit b20a091e5c
11 changed files with 99 additions and 105 deletions

View file

@ -68,16 +68,14 @@ static QString writeGasDetails(gas g)
bool ConfigureDiveComputer::saveXMLBackup(const QString &fileName, const DeviceDetails &details, device_data_t *data) bool ConfigureDiveComputer::saveXMLBackup(const QString &fileName, const DeviceDetails &details, device_data_t *data)
{ {
QString xml = ""; QString xml = "";
QString vendor = data->vendor;
QString product = data->product;
QXmlStreamWriter writer(&xml); QXmlStreamWriter writer(&xml);
writer.setAutoFormatting(true); writer.setAutoFormatting(true);
writer.writeStartDocument(); writer.writeStartDocument();
writer.writeStartElement("DiveComputerSettingsBackup"); writer.writeStartElement("DiveComputerSettingsBackup");
writer.writeStartElement("DiveComputer"); writer.writeStartElement("DiveComputer");
writer.writeTextElement("Vendor", vendor); writer.writeTextElement("Vendor", QString::fromStdString(data->vendor));
writer.writeTextElement("Product", product); writer.writeTextElement("Product", QString::fromStdString(data->product));
writer.writeEndElement(); writer.writeEndElement();
writer.writeStartElement("Settings"); writer.writeStartElement("Settings");
writer.writeTextElement("CustomText", details.customText); writer.writeTextElement("CustomText", details.customText);

View file

@ -111,10 +111,12 @@ static int dtrak_prepare_data(int model, device_data_t &dev_data)
while (model != g_models[i].model_num && g_models[i].model_num != 0xEE) while (model != g_models[i].model_num && g_models[i].model_num != 0xEE)
i++; i++;
dev_data.model = copy_string(g_models[i].name); dev_data.model = g_models[i].name;
dev_data.vendor = (const char *)malloc(strlen(g_models[i].name) + 1); dev_data.vendor = (const char *)malloc(strlen(g_models[i].name) + 1);
sscanf(g_models[i].name, "%[A-Za-z] ", (char *)dev_data.vendor); dev_data.vendor.clear();
dev_data.product = copy_string(strchr(g_models[i].name, ' ') + 1); for (const char *s = g_models[i].name; isalpha(*s); ++s)
dev_data.vendor += *s;
dev_data.product = strchr(g_models[i].name, ' ') + 1;
d = get_descriptor(g_models[i].type, g_models[i].libdc_num); d = get_descriptor(g_models[i].type, g_models[i].libdc_num);
if (d) if (d)
@ -520,7 +522,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
libdc_model = dtrak_prepare_data(tmp_1byte, devdata); libdc_model = dtrak_prepare_data(tmp_1byte, devdata);
if (!libdc_model) if (!libdc_model)
report_error(translate("gettextFromC", "[Warning] Manual dive # %d\n"), dt_dive->number); report_error(translate("gettextFromC", "[Warning] Manual dive # %d\n"), dt_dive->number);
dt_dive->dc.model = copy_string(devdata.model); dt_dive->dc.model = copy_string(devdata.model.c_str());
/* /*
* Air usage, unknown use. Probably allows or deny manually entering gas * Air usage, unknown use. Probably allows or deny manually entering gas

View file

@ -81,7 +81,7 @@ void DownloadThread::run()
auto internalData = m_data->internalData(); auto internalData = m_data->internalData();
internalData->descriptor = descriptorLookup[m_data->vendor().toLower() + m_data->product().toLower()]; internalData->descriptor = descriptorLookup[m_data->vendor().toLower() + m_data->product().toLower()];
internalData->log = &log; internalData->log = &log;
internalData->btname = strdup(m_data->devBluetoothName().toUtf8()); internalData->btname = m_data->devBluetoothName().toStdString();
if (!internalData->descriptor) { if (!internalData->descriptor) {
report_info("No download possible when DC type is unknown"); report_info("No download possible when DC type is unknown");
return; return;
@ -103,7 +103,7 @@ void DownloadThread::run()
std::string errorText; std::string errorText;
import_thread_cancelled = false; import_thread_cancelled = false;
error.clear(); error.clear();
if (!strcmp(internalData->vendor, "Uemis")) if (internalData->vendor == "Uemis")
errorText = do_uemis_import(internalData); errorText = do_uemis_import(internalData);
else else
errorText = do_libdivecomputer_import(internalData); errorText = do_libdivecomputer_import(internalData);
@ -116,9 +116,9 @@ void DownloadThread::run()
error = tr("No new dives downloaded from dive computer").toStdString(); error = tr("No new dives downloaded from dive computer").toStdString();
report_info("Finishing download thread: %d dives downloaded", log.dives->nr); report_info("Finishing download thread: %d dives downloaded", log.dives->nr);
} }
qPrefDiveComputer::set_vendor(internalData->vendor); qPrefDiveComputer::set_vendor(internalData->vendor.c_str());
qPrefDiveComputer::set_product(internalData->product); qPrefDiveComputer::set_product(internalData->product.c_str());
qPrefDiveComputer::set_device(internalData->devname); qPrefDiveComputer::set_device(internalData->devname.c_str());
qPrefDiveComputer::set_device_name(m_data->devBluetoothName()); qPrefDiveComputer::set_device_name(m_data->devBluetoothName());
updateRememberedDCs(); updateRememberedDCs();
@ -246,17 +246,17 @@ DCDeviceData *DownloadThread::data()
QString DCDeviceData::vendor() const QString DCDeviceData::vendor() const
{ {
return data.vendor; return QString::fromStdString(data.vendor);
} }
QString DCDeviceData::product() const QString DCDeviceData::product() const
{ {
return data.product; return QString::fromStdString(data.product);
} }
QString DCDeviceData::devName() const QString DCDeviceData::devName() const
{ {
return data.devname; return QString::fromStdString(data.devname);
} }
QString DCDeviceData::devBluetoothName() const QString DCDeviceData::devBluetoothName() const

View file

@ -40,6 +40,7 @@
#include "core/qthelper.h" #include "core/qthelper.h"
#include "core/file.h" #include "core/file.h"
#include <array> #include <array>
#include <charconv>
std::string dumpfile_name; std::string dumpfile_name;
std::string logfile_name; std::string logfile_name;
@ -226,7 +227,7 @@ static dc_status_t parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_
cyl.type.workingpressure.mbar = lrint(tank.workpressure * 1000); cyl.type.workingpressure.mbar = lrint(tank.workpressure * 1000);
if (tank.type & DC_TANKVOLUME_IMPERIAL) { if (tank.type & DC_TANKVOLUME_IMPERIAL) {
if (same_string(devdata->model, "Suunto EON Steel")) { if (devdata->model == "Suunto EON Steel") {
/* Suunto EON Steele gets this wrong. Badly. /* Suunto EON Steele gets this wrong. Badly.
* but on the plus side it only supports a few imperial sizes, * but on the plus side it only supports a few imperial sizes,
* so let's try and guess at least the most common ones. * so let's try and guess at least the most common ones.
@ -279,7 +280,7 @@ static dc_status_t parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_
if (!nearly_0(tank.endpressure)) { if (!nearly_0(tank.endpressure)) {
cyl.start.mbar = lrint(tank.beginpressure * 1000); cyl.start.mbar = lrint(tank.beginpressure * 1000);
cyl.end.mbar = lrint(tank.endpressure * 1000); cyl.end.mbar = lrint(tank.endpressure * 1000);
} else if (same_string(devdata->vendor, "Uwatec")) { } else if (devdata->vendor == "Uwatec") {
cyl.start.mbar = lrint(tank.beginpressure * 1000 + 30000); cyl.start.mbar = lrint(tank.beginpressure * 1000 + 30000);
cyl.end.mbar = 30000; cyl.end.mbar = 30000;
} }
@ -577,22 +578,6 @@ static int find_dive(struct divecomputer *match)
return 0; return 0;
} }
/*
* Like g_strdup_printf(), but without the stupid g_malloc/g_free confusion.
* And we limit the string to some arbitrary size.
*/
static char *str_printf(const char *fmt, ...)
{
va_list args;
char buf[1024];
va_start(args, fmt);
vsnprintf(buf, sizeof(buf) - 1, fmt, args);
va_end(args);
buf[sizeof(buf) - 1] = 0;
return strdup(buf);
}
/* /*
* The dive ID for libdivecomputer dives is the first word of the * The dive ID for libdivecomputer dives is the first word of the
* SHA1 of the fingerprint, if it exists. * SHA1 of the fingerprint, if it exists.
@ -827,14 +812,14 @@ static int dive_cb(const unsigned char *data, unsigned int size,
rc = dc_parser_new(&parser, devdata->device, data, size); rc = dc_parser_new(&parser, devdata->device, data, size);
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
download_error(translate("gettextFromC", "Unable to create parser for %s %s: %d"), devdata->vendor, devdata->product, errmsg(rc)); download_error(translate("gettextFromC", "Unable to create parser for %s %s: %d"), devdata->vendor.c_str(), devdata->product.c_str(), errmsg(rc));
return true; return true;
} }
dive = alloc_dive(); dive = alloc_dive();
// Fill in basic fields // Fill in basic fields
dive->dc.model = strdup(devdata->model); dive->dc.model = strdup(devdata->model.c_str());
dive->dc.diveid = calculate_diveid(fingerprint, fsize); dive->dc.diveid = calculate_diveid(fingerprint, fsize);
// Parse the dive's header data // Parse the dive's header data
@ -939,7 +924,7 @@ static std::string fingerprint_file(device_data_t *devdata)
uint32_t model, serial; uint32_t model, serial;
// Model hash and libdivecomputer 32-bit 'serial number' for the file name // Model hash and libdivecomputer 32-bit 'serial number' for the file name
model = calculate_string_hash(devdata->model); model = calculate_string_hash(devdata->model.c_str());
serial = devdata->devinfo.serial; serial = devdata->devinfo.serial;
return format_string_std("%s/fingerprints/%04x.%u", return format_string_std("%s/fingerprints/%04x.%u",
@ -1038,7 +1023,7 @@ static void lookup_fingerprint(dc_device_t *device, device_data_t *devdata)
return; return;
/* first try our in memory data - raw_data is owned by the table, the dc_device_set_fingerprint function copies the data */ /* first try our in memory data - raw_data is owned by the table, the dc_device_set_fingerprint function copies the data */
int fsize = get_fingerprint_data(&fingerprint_table, calculate_string_hash(devdata->model), devdata->devinfo.serial, &raw_data); int fsize = get_fingerprint_data(&fingerprint_table, calculate_string_hash(devdata->model.c_str()), devdata->devinfo.serial, &raw_data);
if (fsize) { if (fsize) {
if (verbose) if (verbose)
dev_info(devdata, "... found fingerprint in dive table"); dev_info(devdata, "... found fingerprint in dive table");
@ -1094,14 +1079,14 @@ static void event_cb(dc_device_t *device, dc_event_type_t event, const void *dat
devdata->descriptor = better_descriptor; devdata->descriptor = better_descriptor;
devdata->product = dc_descriptor_get_product(better_descriptor); devdata->product = dc_descriptor_get_product(better_descriptor);
devdata->vendor = dc_descriptor_get_vendor(better_descriptor); devdata->vendor = dc_descriptor_get_vendor(better_descriptor);
devdata->model = str_printf("%s %s", devdata->vendor, devdata->product); devdata->model = devdata->vendor + " " + devdata->product;
} else { } else {
report_info("EVENT_DEVINFO gave us a different detected product (model %d instead of %d), but that one is unknown.", report_info("EVENT_DEVINFO gave us a different detected product (model %d instead of %d), but that one is unknown.",
devinfo->model, dc_descriptor_get_model(devdata->descriptor)); devinfo->model, dc_descriptor_get_model(devdata->descriptor));
} }
} }
dev_info(devdata, translate("gettextFromC", "model=%s firmware=%u serial=%u"), dev_info(devdata, translate("gettextFromC", "model=%s firmware=%u serial=%u"),
devdata->product, devinfo->firmware, devinfo->serial); devdata->product.c_str(), devinfo->firmware, devinfo->serial);
if (devdata->libdc_logfile) { if (devdata->libdc_logfile) {
fprintf(devdata->libdc_logfile, "Event: model=%u (0x%08x), firmware=%u (0x%08x), serial=%u (0x%08x)\n", fprintf(devdata->libdc_logfile, "Event: model=%u (0x%08x), firmware=%u (0x%08x), serial=%u (0x%08x)\n",
devinfo->model, devinfo->model, devinfo->model, devinfo->model,
@ -1146,7 +1131,7 @@ static std::string do_device_import(device_data_t *data)
dc_status_t rc; dc_status_t rc;
dc_device_t *device = data->device; dc_device_t *device = data->device;
data->model = str_printf("%s %s", data->vendor, data->product); data->model = data->vendor + " " + data->product;
// Register the event handler. // Register the event handler.
int events = DC_EVENT_WAITING | DC_EVENT_PROGRESS | DC_EVENT_DEVINFO | DC_EVENT_CLOCK | DC_EVENT_VENDOR; int events = DC_EVENT_WAITING | DC_EVENT_PROGRESS | DC_EVENT_DEVINFO | DC_EVENT_CLOCK | DC_EVENT_VENDOR;
@ -1260,7 +1245,7 @@ unsigned int get_supported_transports(device_data_t *data)
*/ */
if (data->bluetooth_mode) { if (data->bluetooth_mode) {
supported &= (DC_TRANSPORT_BLUETOOTH | DC_TRANSPORT_BLE); supported &= (DC_TRANSPORT_BLUETOOTH | DC_TRANSPORT_BLE);
if (!strncmp(data->devname, "LE:", 3)) if (starts_with(data->devname, "LE:"))
supported &= DC_TRANSPORT_BLE; supported &= DC_TRANSPORT_BLE;
} else { } else {
supported &= ~(DC_TRANSPORT_BLUETOOTH | DC_TRANSPORT_BLE); supported &= ~(DC_TRANSPORT_BLUETOOTH | DC_TRANSPORT_BLE);
@ -1334,7 +1319,7 @@ static dc_status_t irda_device_open(dc_iostream_t **iostream, dc_context_t *cont
// If that fails, use the device name. This will // If that fails, use the device name. This will
// use address 0 if it's not a number. // use address 0 if it's not a number.
if (!address) if (!address)
address = strtoul(data->devname, NULL, 0); std::from_chars(data->devname.c_str(), data->devname.c_str() + data->devname.size(), address);
dev_info(data, "Opening IRDA address %u", address); dev_info(data, "Opening IRDA address %u", address);
return dc_irda_open(&data->iostream, context, address, 1); return dc_irda_open(&data->iostream, context, address, 1);
@ -1383,10 +1368,10 @@ dc_status_t divecomputer_device_open(device_data_t *data)
#ifdef BT_SUPPORT #ifdef BT_SUPPORT
if (transports & DC_TRANSPORT_BLUETOOTH) { if (transports & DC_TRANSPORT_BLUETOOTH) {
dev_info(data, "Opening rfcomm stream %s", data->devname); dev_info(data, "Opening rfcomm stream %s", data->devname.c_str());
#if defined(__ANDROID__) || defined(__APPLE__) #if defined(__ANDROID__) || defined(__APPLE__)
// we don't have BT on iOS in the first place, so this is for Android and macOS // we don't have BT on iOS in the first place, so this is for Android and macOS
rc = rfcomm_stream_open(&data->iostream, context, data->devname); rc = rfcomm_stream_open(&data->iostream, context, data->devname.c_str());
#else #else
rc = bluetooth_device_open(context, data); rc = bluetooth_device_open(context, data);
#endif #endif
@ -1397,8 +1382,8 @@ dc_status_t divecomputer_device_open(device_data_t *data)
#ifdef BLE_SUPPORT #ifdef BLE_SUPPORT
if (transports & DC_TRANSPORT_BLE) { if (transports & DC_TRANSPORT_BLE) {
dev_info(data, "Connecting to BLE device %s", data->devname); dev_info(data, "Connecting to BLE device %s", data->devname.c_str());
rc = ble_packet_open(&data->iostream, context, data->devname, data); rc = ble_packet_open(&data->iostream, context, data->devname.c_str(), data);
if (rc == DC_STATUS_SUCCESS) if (rc == DC_STATUS_SUCCESS)
return rc; return rc;
} }
@ -1419,16 +1404,16 @@ dc_status_t divecomputer_device_open(device_data_t *data)
} }
if (transports & DC_TRANSPORT_SERIAL) { if (transports & DC_TRANSPORT_SERIAL) {
dev_info(data, "Opening serial device %s", data->devname); dev_info(data, "Opening serial device %s", data->devname.c_str());
#ifdef SERIAL_FTDI #ifdef SERIAL_FTDI
if (!strcasecmp(data->devname, "ftdi")) if (!strcasecmp(data->devname.c_str(), "ftdi"))
return ftdi_open(&data->iostream, context); return ftdi_open(&data->iostream, context);
#endif #endif
#ifdef __ANDROID__ #ifdef __ANDROID__
if (data->androidUsbDeviceDescriptor) if (data->androidUsbDeviceDescriptor)
return serial_usb_android_open(&data->iostream, context, data->androidUsbDeviceDescriptor); return serial_usb_android_open(&data->iostream, context, data->androidUsbDeviceDescriptor);
#endif #endif
rc = dc_serial_open(&data->iostream, context, data->devname); rc = dc_serial_open(&data->iostream, context, data->devname.c_str());
if (rc == DC_STATUS_SUCCESS) if (rc == DC_STATUS_SUCCESS)
return rc; return rc;
@ -1442,8 +1427,8 @@ dc_status_t divecomputer_device_open(device_data_t *data)
} }
if (transports & DC_TRANSPORT_USBSTORAGE) { if (transports & DC_TRANSPORT_USBSTORAGE) {
dev_info(data, "Opening USB storage at %s", data->devname); dev_info(data, "Opening USB storage at %s", data->devname.c_str());
rc = dc_usb_storage_open(&data->iostream, context, data->devname); rc = dc_usb_storage_open(&data->iostream, context, data->devname.c_str());
if (rc == DC_STATUS_SUCCESS) if (rc == DC_STATUS_SUCCESS)
return rc; return rc;
} }
@ -1499,7 +1484,7 @@ std::string do_libdivecomputer_import(device_data_t *data)
rc = dc_device_open(&data->device, data->context, data->descriptor, data->iostream); rc = dc_device_open(&data->device, data->context, data->descriptor, data->iostream);
if (rc != DC_STATUS_SUCCESS) { if (rc != DC_STATUS_SUCCESS) {
INFO("dc_device_open error value of %d", rc); INFO("dc_device_open error value of %d", rc);
if (subsurface_access(data->devname, R_OK | W_OK) != 0) if (subsurface_access(data->devname.c_str(), R_OK | W_OK) != 0)
#if defined(SUBSURFACE_MOBILE) #if defined(SUBSURFACE_MOBILE)
err = translate("gettextFromC", "Error opening the device %s %s (%s).\nIn most cases, in order to debug this issue, it is useful to send the developers the log files. You can copy them to the clipboard in the About dialog."); err = translate("gettextFromC", "Error opening the device %s %s (%s).\nIn most cases, in order to debug this issue, it is useful to send the developers the log files. You can copy them to the clipboard in the About dialog.");
#else #else
@ -1560,7 +1545,7 @@ std::string do_libdivecomputer_import(device_data_t *data)
*/ */
save_fingerprint(data); save_fingerprint(data);
if (data->fingerprint && data->fdiveid) if (data->fingerprint && data->fdiveid)
create_fingerprint_node(&fingerprint_table, calculate_string_hash(data->model), data->devinfo.serial, create_fingerprint_node(&fingerprint_table, calculate_string_hash(data->model.c_str()), data->devinfo.serial,
data->fingerprint, data->fsize, data->fdeviceid, data->fdiveid); data->fingerprint, data->fsize, data->fdeviceid, data->fdiveid);
free(data->fingerprint); free(data->fingerprint);
data->fingerprint = NULL; data->fingerprint = NULL;

View file

@ -21,10 +21,9 @@
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
#include <string>
extern "C" { extern "C" {
#else
#include <stdbool.h>
#endif
struct dive; struct dive;
struct divelog; struct divelog;
@ -32,8 +31,8 @@ struct devices;
typedef struct { typedef struct {
dc_descriptor_t *descriptor = nullptr; dc_descriptor_t *descriptor = nullptr;
const char *vendor = nullptr, *product = nullptr, *devname = nullptr; std::string vendor, product, devname;
const char *model = nullptr, *btname = nullptr; std::string model, btname;
unsigned char *fingerprint = nullptr; unsigned char *fingerprint = nullptr;
unsigned int fsize = 0, fdeviceid = 0, fdiveid = 0; unsigned int fsize = 0, fdeviceid = 0, fdiveid = 0;
struct dc_event_devinfo_t devinfo = { }; struct dc_event_devinfo_t devinfo = { };
@ -71,13 +70,10 @@ dc_status_t divecomputer_device_open(device_data_t *data);
unsigned int get_supported_transports(device_data_t *data); unsigned int get_supported_transports(device_data_t *data);
#ifdef __cplusplus
}
#include <string>
extern std::string logfile_name; extern std::string logfile_name;
extern std::string dumpfile_name; extern std::string dumpfile_name;
}
#endif #endif
#endif // LIBDIVECOMPUTER_H #endif // LIBDIVECOMPUTER_H

View file

@ -153,7 +153,7 @@ extern "C" void ostctools_import(const char *file, struct divelog *log)
report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number); report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number);
return; return;
} }
std::string tmp = format_string_std("%s %s (Imported from OSTCTools)", devdata.vendor, devdata.model); std::string tmp = devdata.vendor + " " + devdata.model + " (Imported from OSTCTools)";
ostcdive->dc.model = copy_string(tmp.c_str()); ostcdive->dc.model = copy_string(tmp.c_str());
// Parse the dive data // Parse the dive data

View file

@ -25,10 +25,6 @@
#define DEBUG_THRESHOLD 50 #define DEBUG_THRESHOLD 50
static int debugCounter; static int debugCounter;
#define IS_HW(_d) same_string((_d)->vendor, "Heinrichs Weikamp")
#define IS_SHEARWATER(_d) same_string((_d)->vendor, "Shearwater")
#define IS_GARMIN(_d) same_string((_d)->vendor, "Garmin")
#define MAXIMAL_HW_CREDIT 254 #define MAXIMAL_HW_CREDIT 254
#define MINIMAL_HW_CREDIT 32 #define MINIMAL_HW_CREDIT 32
@ -72,11 +68,26 @@ void BLEObject::serviceStateChanged(QLowEnergyService::ServiceState newState)
report_info("%s %d", to_str(service->serviceUuid()).c_str(), static_cast<int>(newState)); report_info("%s %d", to_str(service->serviceUuid()).c_str(), static_cast<int>(newState));
} }
static bool is_hw(const device_data_t &d)
{
return d.vendor == "Heinrichs Weikamp";
}
static bool is_shearwater(const device_data_t &d)
{
return d.vendor == "Shearwater";
}
static bool is_garmin(const device_data_t &d)
{
return d.vendor == "Garmin";
}
void BLEObject::characteristcStateChanged(const QLowEnergyCharacteristic &c, const QByteArray &value) void BLEObject::characteristcStateChanged(const QLowEnergyCharacteristic &c, const QByteArray &value)
{ {
if (verbose > 2 || debugCounter < DEBUG_THRESHOLD) if (verbose > 2 || debugCounter < DEBUG_THRESHOLD)
report_info("%s packet RECV %s", current_time().c_str(), qPrintable(value.toHex())); report_info("%s packet RECV %s", current_time().c_str(), qPrintable(value.toHex()));
if (IS_HW(device)) { if (is_hw(device)) {
if (c.uuid() == telit[TELIT_DATA_TX] || c.uuid() == ublox[UBLOX_DATA_TX]) { if (c.uuid() == telit[TELIT_DATA_TX] || c.uuid() == ublox[UBLOX_DATA_TX]) {
hw_credit--; hw_credit--;
receivedPackets.append(value); receivedPackets.append(value);
@ -92,7 +103,7 @@ void BLEObject::characteristcStateChanged(const QLowEnergyCharacteristic &c, con
void BLEObject::characteristicWritten(const QLowEnergyCharacteristic &c, const QByteArray &value) void BLEObject::characteristicWritten(const QLowEnergyCharacteristic &c, const QByteArray &value)
{ {
if (IS_HW(device)) { if (is_hw(device)) {
if (c.uuid() == telit[TELIT_CREDITS_RX] || c.uuid() == ublox[UBLOX_CREDITS_RX]) { if (c.uuid() == telit[TELIT_CREDITS_RX] || c.uuid() == ublox[UBLOX_CREDITS_RX]) {
bool ok; bool ok;
hw_credit += value.toHex().toInt(&ok, 16); hw_credit += value.toHex().toInt(&ok, 16);
@ -246,13 +257,13 @@ void BLEObject::addService(const QBluetoothUuid &newService)
} }
} }
BLEObject::BLEObject(QLowEnergyController *c, device_data_t *d) BLEObject::BLEObject(QLowEnergyController *c, device_data_t &d) :
controller(c),
isCharacteristicWritten(false),
device(d),
timeout(BLE_TIMEOUT)
{ {
controller = c;
device = d;
debugCounter = 0; debugCounter = 0;
isCharacteristicWritten = false;
timeout = BLE_TIMEOUT;
} }
BLEObject::~BLEObject() BLEObject::~BLEObject()
@ -549,9 +560,9 @@ dc_status_t BLEObject::setupHwTerminalIo(const QList<QLowEnergyCharacteristic> &
// Bluez is broken, and doesn't have a sane way to query // Bluez is broken, and doesn't have a sane way to query
// whether to use a random address or not. So we have to // whether to use a random address or not. So we have to
// fake it. // fake it.
static int use_random_address(device_data_t *user_device) static int use_random_address(const device_data_t &user_device)
{ {
return IS_SHEARWATER(user_device) || IS_GARMIN(user_device); return is_shearwater(user_device) || is_garmin(user_device);
} }
#endif #endif
@ -587,7 +598,7 @@ dc_status_t qt_ble_open(void **io, dc_context_t *, const char *devaddr, device_d
report_info("qt_ble_open(%s)", devaddr); report_info("qt_ble_open(%s)", devaddr);
#if !defined(Q_OS_WIN) #if !defined(Q_OS_WIN)
if (use_random_address(user_device)) if (use_random_address(*user_device))
controller->setRemoteAddressType(QLowEnergyController::RandomAddress); controller->setRemoteAddressType(QLowEnergyController::RandomAddress);
#endif #endif
@ -616,7 +627,7 @@ dc_status_t qt_ble_open(void **io, dc_context_t *, const char *devaddr, device_d
// We need to discover services etc here! // We need to discover services etc here!
// Note that ble takes ownership of controller and henceforth deleting ble will // Note that ble takes ownership of controller and henceforth deleting ble will
// take care of deleting controller. // take care of deleting controller.
BLEObject *ble = new BLEObject(controller, user_device); BLEObject *ble = new BLEObject(controller, *user_device);
// we used to call our addService function the moment a service was discovered, but that // we used to call our addService function the moment a service was discovered, but that
// could cause us to try to discover the details of a characteristic while we were still serching // could cause us to try to discover the details of a characteristic while we were still serching
// for services, which can cause a failure in the Qt BLE stack. // for services, which can cause a failure in the Qt BLE stack.
@ -657,7 +668,7 @@ dc_status_t qt_ble_open(void **io, dc_context_t *, const char *devaddr, device_d
/* Enable notifications */ /* Enable notifications */
QList<QLowEnergyCharacteristic> list = ble->preferredService()->characteristics(); QList<QLowEnergyCharacteristic> list = ble->preferredService()->characteristics();
if (IS_HW(user_device)) { if (is_hw(*user_device)) {
dc_status_t r = ble->setupHwTerminalIo(list); dc_status_t r = ble->setupHwTerminalIo(list);
if (r != DC_STATUS_SUCCESS) { if (r != DC_STATUS_SUCCESS) {
delete ble; delete ble;
@ -747,6 +758,14 @@ dc_status_t qt_ble_poll(void *io, int timeout)
return ble->poll(timeout); return ble->poll(timeout);
} }
dc_status_t BLEObject::get_name(char *data, size_t size)
{
if (device.btname.empty())
return DC_STATUS_UNSUPPORTED;
strncpy(data, device.btname.c_str(), size);
return DC_STATUS_SUCCESS;
}
dc_status_t qt_ble_ioctl(void *io, unsigned int request, void *data, size_t size) dc_status_t qt_ble_ioctl(void *io, unsigned int request, void *data, size_t size)
{ {
BLEObject *ble = (BLEObject *) io; BLEObject *ble = (BLEObject *) io;

View file

@ -23,17 +23,12 @@ class BLEObject : public QObject
Q_OBJECT Q_OBJECT
public: public:
BLEObject(QLowEnergyController *c, device_data_t *); BLEObject(QLowEnergyController *c, device_data_t &);
~BLEObject(); ~BLEObject();
inline void set_timeout(int value) { timeout = value; } inline void set_timeout(int value) { timeout = value; }
dc_status_t write(const void* data, size_t size, size_t *actual); dc_status_t write(const void* data, size_t size, size_t *actual);
dc_status_t read(void* data, size_t size, size_t *actual); dc_status_t read(void* data, size_t size, size_t *actual);
inline dc_status_t get_name(char *res, size_t size) dc_status_t get_name(char *res, size_t size);
{
if (!device->btname) return DC_STATUS_UNSUPPORTED;
strncpy(res, device->btname, size);
return DC_STATUS_SUCCESS;
}
dc_status_t poll(int timeout); dc_status_t poll(int timeout);
inline QLowEnergyService *preferredService() { return preferred; } inline QLowEnergyService *preferredService() { return preferred; }
@ -51,11 +46,11 @@ public slots:
private: private:
QVector<QLowEnergyService *> services; QVector<QLowEnergyService *> services;
QLowEnergyController *controller = nullptr; QLowEnergyController *controller;
QLowEnergyService *preferred = nullptr; QLowEnergyService *preferred = nullptr;
QList<QByteArray> receivedPackets; QList<QByteArray> receivedPackets;
bool isCharacteristicWritten; bool isCharacteristicWritten;
device_data_t *device; device_data_t &device;
unsigned int hw_credit = 0; unsigned int hw_credit = 0;
unsigned int desc_written = 0; unsigned int desc_written = 0;
int timeout; int timeout;

View file

@ -474,7 +474,7 @@ static std::string build_ans_path(const std::string &path, int filenumber)
} }
/* send a request to the dive computer and collect the answer */ /* send a request to the dive computer and collect the answer */
static std::string uemis_get_answer(const char *path, const std::string &request, int n_param_in, static std::string uemis_get_answer(const std::string &path, const std::string &request, int n_param_in,
int n_param_out, std::string &error_text) int n_param_out, std::string &error_text)
{ {
int i = 0; int i = 0;
@ -535,7 +535,7 @@ static std::string uemis_get_answer(const char *path, const std::string &request
if (import_thread_cancelled) if (import_thread_cancelled)
return std::string(); return std::string();
progress_bar_fraction = filenr / (double)uemis_max_files; progress_bar_fraction = filenr / (double)uemis_max_files;
std::string ans_path = build_ans_path(std::string(path), filenr - 1); std::string ans_path = build_ans_path(path, filenr - 1);
ans_file = subsurface_open(ans_path.c_str(), O_RDONLY, 0666); ans_file = subsurface_open(ans_path.c_str(), O_RDONLY, 0666);
if (ans_file < 0) { if (ans_file < 0) {
error_text = "can't open Uemis response file"; error_text = "can't open Uemis response file";
@ -1073,7 +1073,7 @@ static void do_delete_dives(struct dive_table *td, int idx)
td->dives[x]->hidden_by_filter = true; td->dives[x]->hidden_by_filter = true;
} }
static bool load_uemis_divespot(const char *mountpath, int divespot_id) static bool load_uemis_divespot(const std::string &mountpath, int divespot_id)
{ {
param_buff[2] = std::to_string(divespot_id); param_buff[2] = std::to_string(divespot_id);
#if UEMIS_DEBUG & 2 #if UEMIS_DEBUG & 2
@ -1090,7 +1090,7 @@ static bool load_uemis_divespot(const char *mountpath, int divespot_id)
return false; return false;
} }
static void get_uemis_divespot(device_data_t *devdata, const char *mountpath, int divespot_id, struct dive *dive) static void get_uemis_divespot(device_data_t *devdata, const std::string &mountpath, int divespot_id, struct dive *dive)
{ {
struct dive_site *nds = dive->dive_site; struct dive_site *nds = dive->dive_site;
@ -1128,7 +1128,7 @@ static void get_uemis_divespot(device_data_t *devdata, const char *mountpath, in
} }
} }
static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status, device_data_t *data, const char *mountpath, const char deviceidnr) static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status, device_data_t *data, const std::string &mountpath, const char deviceidnr)
{ {
struct dive *dive = data->log->dives->dives[idx]; struct dive *dive = data->log->dives->dives[idx];
char log_file_no_to_find[20]; char log_file_no_to_find[20];
@ -1228,7 +1228,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
std::string do_uemis_import(device_data_t *data) std::string do_uemis_import(device_data_t *data)
{ {
const char *mountpath = data->devname; const std::string &mountpath = data->devname;
short force_download = data->force_download; short force_download = data->force_download;
int newmax = -1; int newmax = -1;
int first, start, end = -2; int first, start, end = -2;

View file

@ -311,7 +311,7 @@ void OstcFirmwareCheck::checkLatest(QWidget *_parent, device_data_t *data, const
QStringList fwParts = latestFirmwareAvailable.split("."); QStringList fwParts = latestFirmwareAvailable.split(".");
int latestFirmwareAvailableNumber; int latestFirmwareAvailableNumber;
if (strcmp(data->product, "OSTC 4") == 0) { if (data->product == "OSTC 4") {
unsigned char X, Y, Z, beta; unsigned char X, Y, Z, beta;
X = (firmwareOnDevice & 0xF800) >> 11; X = (firmwareOnDevice & 0xF800) >> 11;
Y = (firmwareOnDevice & 0x07C0) >> 6; Y = (firmwareOnDevice & 0x07C0) >> 6;
@ -1532,10 +1532,10 @@ void ConfigureDiveComputerDialog::dc_open()
ui.progressBar->setFormat(tr("Connected to device")); ui.progressBar->setFormat(tr("Connected to device"));
qPrefDiveComputer::set_device(device_data.devname); qPrefDiveComputer::set_device(device_data.devname.c_str());
qPrefDiveComputer::set_device_name(device_data.btname); qPrefDiveComputer::set_device_name(device_data.btname.c_str());
qPrefDiveComputer::set_vendor(device_data.vendor); qPrefDiveComputer::set_vendor(device_data.vendor.c_str());
qPrefDiveComputer::set_product(device_data.product); qPrefDiveComputer::set_product(device_data.product.c_str());
} }
void ConfigureDiveComputerDialog::dc_close() void ConfigureDiveComputerDialog::dc_close()

View file

@ -824,7 +824,7 @@ static dc_status_t prepare_data(int data_model, const char *serial, dc_family_t
dev_data.device = NULL; dev_data.device = NULL;
dev_data.context = NULL; dev_data.context = NULL;
if (!data_model) { if (!data_model) {
dev_data.model = copy_string(manual_dc_name); dev_data.model = manual_dc_name;
dev_data.descriptor = NULL; dev_data.descriptor = NULL;
return DC_STATUS_NODEVICE; return DC_STATUS_NODEVICE;
} }
@ -832,11 +832,11 @@ static dc_status_t prepare_data(int data_model, const char *serial, dc_family_t
if (dev_data.descriptor) { if (dev_data.descriptor) {
dev_data.vendor = dc_descriptor_get_vendor(dev_data.descriptor); dev_data.vendor = dc_descriptor_get_vendor(dev_data.descriptor);
dev_data.product = dc_descriptor_get_product(dev_data.descriptor); dev_data.product = dc_descriptor_get_product(dev_data.descriptor);
concat(&dev_data.model, "", format_string_std("%s %s", dev_data.vendor, dev_data.product)); dev_data.model += dev_data.vendor + " " + dev_data.product;
dev_data.devinfo.serial = (uint32_t) lrint(strtod(serial, NULL)); dev_data.devinfo.serial = (uint32_t) lrint(strtod(serial, NULL));
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
} else { } else {
dev_data.model = copy_string("unsupported dive computer"); dev_data.model = "unsupported dive computer";
dev_data.devinfo.serial = (uint32_t) lrint(strtod(serial, NULL)); dev_data.devinfo.serial = (uint32_t) lrint(strtod(serial, NULL));
return DC_STATUS_UNSUPPORTED; return DC_STATUS_UNSUPPORTED;
} }
@ -844,7 +844,6 @@ static dc_status_t prepare_data(int data_model, const char *serial, dc_family_t
static void device_data_free(device_data_t &dev_data) static void device_data_free(device_data_t &dev_data)
{ {
free((void *) dev_data.model);
dc_descriptor_free(dev_data.descriptor); dc_descriptor_free(dev_data.descriptor);
} }
@ -952,7 +951,7 @@ extern "C" void smartrak_import(const char *file, struct divelog *log)
dc_fam = DC_FAMILY_UWATEC_ALADIN; dc_fam = DC_FAMILY_UWATEC_ALADIN;
} }
rc = prepare_data(dc_model, (char *)col[coln(DCNUMBER)]->bind_ptr, dc_fam, devdata); rc = prepare_data(dc_model, (char *)col[coln(DCNUMBER)]->bind_ptr, dc_fam, devdata);
smtkdive->dc.model = copy_string(devdata.model); smtkdive->dc.model = copy_string(devdata.model.c_str());
if (rc == DC_STATUS_SUCCESS && mdb_table.get_len(coln(PROFILE))) { if (rc == DC_STATUS_SUCCESS && mdb_table.get_len(coln(PROFILE))) {
prf_buffer = static_cast<unsigned char *>(mdb_ole_read_full(mdb, col[coln(PROFILE)], &prf_length)); prf_buffer = static_cast<unsigned char *>(mdb_ole_read_full(mdb, col[coln(PROFILE)], &prf_length));
if (prf_length > 0) { if (prf_length > 0) {