diff options
-rw-r--r-- | core/btdiscovery.cpp | 4 | ||||
-rw-r--r-- | core/configuredivecomputer.cpp | 16 | ||||
-rw-r--r-- | core/libdivecomputer.c | 25 | ||||
-rw-r--r-- | core/libdivecomputer.h | 14 | ||||
-rw-r--r-- | core/qt-ble.cpp | 37 | ||||
-rw-r--r-- | core/qt-ble.h | 8 | ||||
-rw-r--r-- | core/qtserialbluetooth.cpp | 310 | ||||
-rw-r--r-- | core/serial_ftdi.c | 123 | ||||
-rw-r--r-- | desktop-widgets/downloadfromdivecomputer.cpp | 6 |
9 files changed, 169 insertions, 374 deletions
diff --git a/core/btdiscovery.cpp b/core/btdiscovery.cpp index 254088ec1..5fa6a7c80 100644 --- a/core/btdiscovery.cpp +++ b/core/btdiscovery.cpp @@ -127,9 +127,7 @@ BTDiscovery *BTDiscovery::instance() } #if defined(BT_SUPPORT) -#if defined(SSRF_CUSTOM_IO) extern void addBtUuid(QBluetoothUuid uuid); -#endif extern QHash<QString, QStringList> productList; extern QStringList vendorList; @@ -151,7 +149,6 @@ QString markBLEAddress(const QBluetoothDeviceInfo *device) void BTDiscovery::btDeviceDiscovered(const QBluetoothDeviceInfo &device) { -#if defined(SSRF_CUSTOM_IO) btPairedDevice this_d; this_d.address = markBLEAddress(&device); this_d.name = device.name(); @@ -173,7 +170,6 @@ void BTDiscovery::btDeviceDiscovered(const QBluetoothDeviceInfo &device) #endif btDeviceDiscoveredMain(this_d); -#endif } void BTDiscovery::btDeviceDiscoveredMain(const btPairedDevice &device) diff --git a/core/configuredivecomputer.cpp b/core/configuredivecomputer.cpp index b59f1916b..6fef1eb21 100644 --- a/core/configuredivecomputer.cpp +++ b/core/configuredivecomputer.cpp @@ -635,24 +635,16 @@ QString ConfigureDiveComputer::dc_open(device_data_t *data) fprintf(data->libdc_logfile, "built with libdivecomputer v%s\n", dc_version(NULL)); } -#if defined(SSRF_CUSTOM_IO) if (data->bluetooth_mode) { -#if defined(BT_SUPPORT) && defined(SSRF_CUSTOM_IO) - rc = dc_context_set_custom_io(data->context, get_qt_serial_ops(), data); -#endif -#ifdef SERIAL_FTDI - } else if (!strcmp(data->devname, "ftdi")) { - rc = dc_context_set_custom_io(data->context, &serial_ftdi_ops, data); +#if defined(BT_SUPPORT) + rc = ble_packet_open(&data->iostream, data->context, data->devname, data); #endif } if (rc != DC_STATUS_SUCCESS) { report_error(errmsg(rc)); } else { -#else - { -#endif - rc = dc_device_open(&data->device, data->context, data->descriptor, data->devname); + rc = dc_device_open(&data->device, data->context, data->descriptor, data->iostream); } if (rc != DC_STATUS_SUCCESS) { @@ -672,6 +664,8 @@ void ConfigureDiveComputer::dc_close(device_data_t *data) if (data->context) dc_context_free(data->context); data->context = NULL; + dc_iostream_close(data->iostream); + data->iostream = NULL; if (data->libdc_logfile) fclose(data->libdc_logfile); diff --git a/core/libdivecomputer.c b/core/libdivecomputer.c index a666ca667..ed5158c69 100644 --- a/core/libdivecomputer.c +++ b/core/libdivecomputer.c @@ -18,11 +18,6 @@ #include "libdivecomputer.h" #include "core/version.h" -#if !defined(SSRF_LIBDC_VERSION) || SSRF_LIBDC_VERSION < 2 -#pragma message "Subsurface requires a reasonably current version of the Subsurface-branch" -#pragma message "of libdivecomputer (at least version 2 of our API)." -#pragma message "Please get it from http://github.com/Subsurface-divelog/libdc Subsurface-branch" -#endif // // If we have an old libdivecomputer, it doesn't // have the new DC_TANKINFO bits, but just volume @@ -1076,6 +1071,7 @@ const char *do_libdivecomputer_import(device_data_t *data) first_temp_is_air = 0; data->device = NULL; data->context = NULL; + data->iostream = NULL; if (data->libdc_log && logfile_name) fp = subsurface_fopen(logfile_name, "w"); @@ -1095,27 +1091,16 @@ const char *do_libdivecomputer_import(device_data_t *data) err = translate("gettextFromC", "Unable to open %s %s (%s)"); -#if defined(SSRF_CUSTOM_IO) if (data->bluetooth_mode) { -#if defined(BT_SUPPORT) && defined(SSRF_CUSTOM_IO) - rc = dc_context_set_custom_io(data->context, get_qt_serial_ops(), data); -#endif -#ifdef SERIAL_FTDI - } else if (!strcmp(data->devname, "ftdi")) { - rc = dc_context_set_custom_io(data->context, &serial_ftdi_ops, data); - INFO(0, "setting up ftdi ops"); -#else - INFO(0, "FTDI disabled"); +#if defined(BT_SUPPORT) + rc = ble_packet_open(&data->iostream, data->context, data->devname, data); #endif } if (rc != DC_STATUS_SUCCESS) { report_error(errmsg(rc)); } else { -#else - { -#endif - rc = dc_device_open(&data->device, data->context, data->descriptor, data->devname); + rc = dc_device_open(&data->device, data->context, data->descriptor, data->iostream); INFO(0, "dc_deveice_open error value of %d", rc); if (rc != DC_STATUS_SUCCESS && subsurface_access(data->devname, R_OK | W_OK) != 0) err = translate("gettextFromC", "Error opening the device %s %s (%s).\nIn most cases, in order to debug this issue, a libdivecomputer logfile will be useful.\nYou can create this logfile by selecting the corresponding checkbox in the download dialog."); @@ -1126,6 +1111,8 @@ const char *do_libdivecomputer_import(device_data_t *data) /* TODO: Show the logfile to the user on error. */ dc_device_close(data->device); data->device = NULL; + dc_iostream_close(data->iostream); + data->iostream = NULL; if (!downloadTable.nr) dev_info(data, translate("gettextFromC", "No new dives downloaded from dive computer")); } diff --git a/core/libdivecomputer.h b/core/libdivecomputer.h index 3986b629e..3da7fdc7b 100644 --- a/core/libdivecomputer.h +++ b/core/libdivecomputer.h @@ -11,9 +11,6 @@ #include <libdivecomputer/version.h> #include <libdivecomputer/device.h> #include <libdivecomputer/parser.h> -#ifdef SSRF_CUSTOM_IO -#include <libdivecomputer/custom_io.h> -#endif #include "dive.h" @@ -32,6 +29,7 @@ typedef struct dc_user_device_t uint32_t deviceid, diveid; dc_device_t *device; dc_context_t *context; + dc_iostream_t *iostream; struct dive_trip *trip; int preexisting; bool force_download; @@ -57,13 +55,9 @@ extern double progress_bar_fraction; extern char *logfile_name; extern char *dumpfile_name; -#if SSRF_CUSTOM_IO -// WTF. this symbol never shows up at link time -//extern dc_custom_io_t qt_serial_ops; -// Thats why I've worked around it with a stupid helper returning it. -dc_custom_io_t* get_qt_serial_ops(); -extern dc_custom_io_t serial_ftdi_ops; -#endif +dc_status_t ble_packet_open(dc_iostream_t **iostream, dc_context_t *context, const char* devaddr, void *userdata); +dc_status_t rfcomm_stream_open(dc_iostream_t **iostream, dc_context_t *context, const char* devaddr); +dc_status_t ftdi_open(dc_iostream_t **iostream, dc_context_t *context); #ifdef __cplusplus } diff --git a/core/qt-ble.cpp b/core/qt-ble.cpp index 8a29bedf3..d54b145ba 100644 --- a/core/qt-ble.cpp +++ b/core/qt-ble.cpp @@ -18,10 +18,6 @@ #include "core/qt-ble.h" #include "core/btdiscovery.h" -#if defined(SSRF_CUSTOM_IO) - -#include <libdivecomputer/custom_io.h> - #define BLE_TIMEOUT 12000 // 12 seconds seems like a very long time to wait #define DEBUG_THRESHOLD 50 static int debugCounter; @@ -152,6 +148,8 @@ dc_status_t BLEObject::write(const void *data, size_t size, size_t *actual) { Q_UNUSED(actual) // that seems like it might cause problems + if (actual) *actual = 0; + if (!receivedPackets.isEmpty()) { qDebug() << ".. write HIT with still incoming packets in queue"; } @@ -170,10 +168,8 @@ dc_status_t BLEObject::write(const void *data, size_t size, size_t *actual) QLowEnergyService::WriteWithoutResponse : QLowEnergyService::WriteWithResponse; - if (IS_SHEARWATER(device)) - bytes.prepend("\1\0", 2); - preferredService()->writeCharacteristic(c, bytes, mode); + if (actual) *actual = size; return DC_STATUS_SUCCESS; } @@ -199,9 +195,6 @@ dc_status_t BLEObject::read(void *data, size_t size, size_t *actual) QByteArray packet = receivedPackets.takeFirst(); - if (IS_SHEARWATER(device)) - packet.remove(0,2); - if ((size_t)packet.size() > size) return DC_STATUS_NOMEMORY; @@ -278,7 +271,7 @@ dc_status_t BLEObject::setupHwTerminalIo(QList<QLowEnergyCharacteristic> allC) return setHwCredit(MAXIMAL_HW_CREDIT); } -dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *devaddr) +dc_status_t qt_ble_open(void **io, dc_context_t *context, const char *devaddr, dc_user_device_t *user_device) { Q_UNUSED(context) debugCounter = 0; @@ -310,7 +303,7 @@ dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *d #endif qDebug() << "qt_ble_open(" << devaddr << ")"; - if (IS_SHEARWATER(io->user_device)) + if (IS_SHEARWATER(user_device)) controller->setRemoteAddressType(QLowEnergyController::RandomAddress); // Try to connect to the device @@ -342,7 +335,7 @@ dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *d // We need to discover services etc here! // Note that ble takes ownership of controller and henceforth deleting ble will // take care of deleting controller. - BLEObject *ble = new BLEObject(controller, io->user_device); + BLEObject *ble = new BLEObject(controller, user_device); ble->connect(controller, SIGNAL(serviceDiscovered(QBluetoothUuid)), SLOT(addService(QBluetoothUuid))); qDebug() << " .. discovering services"; @@ -386,7 +379,7 @@ dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *d if (!list.isEmpty()) { const QLowEnergyCharacteristic &c = list.constLast(); - if (IS_HW(io->user_device)) { + if (IS_HW(user_device)) { dc_status_t r = ble->setupHwTerminalIo(list); if (r != DC_STATUS_SUCCESS) { delete ble; @@ -422,15 +415,14 @@ dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *d } // Fill in info - io->userdata = (void *)ble; + *io = (void *)ble; return DC_STATUS_SUCCESS; } -dc_status_t qt_ble_close(dc_custom_io_t *io) +dc_status_t qt_ble_close(void *io) { - BLEObject *ble = (BLEObject *) io->userdata; + BLEObject *ble = (BLEObject *) io; - io->userdata = NULL; delete ble; return DC_STATUS_SUCCESS; @@ -443,19 +435,18 @@ static void checkThreshold() } } -dc_status_t qt_ble_read(dc_custom_io_t *io, void* data, size_t size, size_t *actual) +dc_status_t qt_ble_read(void *io, void* data, size_t size, size_t *actual) { checkThreshold(); - BLEObject *ble = (BLEObject *) io->userdata; + BLEObject *ble = (BLEObject *) io; return ble->read(data, size, actual); } -dc_status_t qt_ble_write(dc_custom_io_t *io, const void* data, size_t size, size_t *actual) +dc_status_t qt_ble_write(void *io, const void* data, size_t size, size_t *actual) { checkThreshold(); - BLEObject *ble = (BLEObject *) io->userdata; + BLEObject *ble = (BLEObject *) io; return ble->write(data, size, actual); } } /* extern "C" */ -#endif diff --git a/core/qt-ble.h b/core/qt-ble.h index f366afe89..5b3991bef 100644 --- a/core/qt-ble.h +++ b/core/qt-ble.h @@ -54,10 +54,10 @@ private: extern "C" { -dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *name); -dc_status_t qt_ble_read(dc_custom_io_t *io, void* data, size_t size, size_t *actual); -dc_status_t qt_ble_write(dc_custom_io_t *io, const void* data, size_t size, size_t *actual); -dc_status_t qt_ble_close(dc_custom_io_t *io); +dc_status_t qt_ble_open(void **io, dc_context_t *context, const char *devaddr, dc_user_device_t *user_device); +dc_status_t qt_ble_read(void *io, void* data, size_t size, size_t *actual); +dc_status_t qt_ble_write(void *io, const void* data, size_t size, size_t *actual); +dc_status_t qt_ble_close(void *io); } #endif diff --git a/core/qtserialbluetooth.cpp b/core/qtserialbluetooth.cpp index cb2cb5935..be6dfd3be 100644 --- a/core/qtserialbluetooth.cpp +++ b/core/qtserialbluetooth.cpp @@ -9,8 +9,7 @@ #include <libdivecomputer/version.h> #include <libdivecomputer/context.h> - -#if defined(SSRF_CUSTOM_IO) +#include <libdivecomputer/custom.h> #if defined(Q_OS_WIN) #include <winsock2.h> @@ -18,8 +17,6 @@ #include <ws2bth.h> #endif -#include <libdivecomputer/custom_io.h> - #ifdef BLE_SUPPORT # include "qt-ble.h" #endif @@ -46,195 +43,8 @@ typedef struct qt_serial_t { #ifdef BLE_SUPPORT -static dc_status_t ble_serial_open(dc_custom_io_t *io, dc_context_t *, const char* devaddr); -static dc_status_t ble_serial_close(dc_custom_io_t *io); -static dc_status_t ble_serial_read(dc_custom_io_t *io, void* data, size_t size, size_t *actual); -static dc_status_t ble_serial_write(dc_custom_io_t *io, const void* data, size_t size, size_t *actual); -static dc_status_t ble_serial_purge(dc_custom_io_t *io, dc_direction_t queue); -static dc_status_t ble_serial_get_available(dc_custom_io_t *io, size_t *available); -static dc_status_t ble_serial_set_timeout(dc_custom_io_t *io, long timeout); - -static dc_custom_io_t ble_serial_ops = { - .userdata = NULL, - .user_device = NULL, - - .serial_open = ble_serial_open, - .serial_close = ble_serial_close, - .serial_read = ble_serial_read, - .serial_write = ble_serial_write, - .serial_purge = ble_serial_purge, - .serial_get_available = ble_serial_get_available, - .serial_set_timeout = ble_serial_set_timeout, -// These doesn't make sense over bluetooth -// NULL means NOP - .serial_configure = NULL, - .serial_set_dtr = NULL, - .serial_set_rts = NULL, - .serial_set_break = NULL, - - .packet_size = 20, - .packet_open = qt_ble_open, - .packet_close = qt_ble_close, - .packet_read = qt_ble_read, - .packet_write = qt_ble_write, -}; - - -static dc_status_t ble_serial_open(dc_custom_io_t *io, dc_context_t *context, const char* devaddr) -{ - dc_context_set_custom_io(context, &ble_serial_ops, io->user_device); - return qt_ble_open(&ble_serial_ops, context, devaddr); -} - -#define BT_BLE_BUFSIZE 4096 -static struct { - unsigned int out_bytes, in_bytes, in_pos; - unsigned char in[BT_BLE_BUFSIZE]; - unsigned char out[BT_BLE_BUFSIZE]; -} buffer; - -static dc_status_t ble_serial_flush_write(void) -{ - int bytes = buffer.out_bytes; - - if (!bytes) - return DC_STATUS_SUCCESS; - buffer.out_bytes = 0; - return ble_serial_ops.packet_write(&ble_serial_ops, buffer.out, bytes, NULL); -} - -static dc_status_t ble_serial_flush_read(void) -{ - buffer.in_bytes = buffer.in_pos = 0; - return DC_STATUS_SUCCESS; -} - -static dc_status_t ble_serial_close(dc_custom_io_t *io) -{ - ble_serial_flush_write(); - io->userdata = NULL; - return qt_ble_close(&ble_serial_ops); -} - -static dc_status_t ble_serial_read(dc_custom_io_t *io, void* data, size_t size, size_t *actual) -{ - Q_UNUSED(io) - size_t len; - size_t received = 0; - - if (buffer.in_pos >= buffer.in_bytes) { - ble_serial_flush_write(); - } - - /* There is still unused/unread data in the input steam. - * So preseve it at the start of a new read. - */ - if (buffer.in_pos > 0) { - len = buffer.in_bytes - buffer.in_pos; - memcpy(buffer.in, buffer.in + buffer.in_pos, len); - buffer.in_pos = 0; - buffer.in_bytes = len; - } - - /* Read a long as requested in the size parameter */ - while ((buffer.in_bytes - buffer.in_pos) < size) { - dc_status_t rc; - - rc = ble_serial_ops.packet_read(&ble_serial_ops, buffer.in + buffer.in_bytes, - sizeof(buffer.in) - buffer.in_bytes, &received); - if (rc != DC_STATUS_SUCCESS) - return rc; - if (!received) - return DC_STATUS_IO; - - buffer.in_bytes += received; - } - - len = buffer.in_bytes - buffer.in_pos; - if (len > size) - len = size; - - memcpy(data, buffer.in + buffer.in_pos, len); - buffer.in_pos += len; - if (actual) - *actual = len; - return DC_STATUS_SUCCESS; -} - -static dc_status_t ble_serial_write(dc_custom_io_t *io, const void* data, size_t size, size_t *actual) -{ - Q_UNUSED(io) - dc_status_t rc = DC_STATUS_SUCCESS; - size_t transferred = 0; - - ble_serial_flush_read(); - - /* - * Most writes to a connected DC are small, typically some command bytes to get - * DC in download mode, or to set some parameter. All this just worked over BLE, - * however, sending a full firmware update (on an OSTC device) failed, as the - * underlying BLE interface can only handle small 20 byte BLE packets at once. - * - * So, send max ble->packet_size chuncks at once. - */ - while (size) { - size_t len = sizeof(buffer.out) - transferred; - - if ((int)len > io->packet_size) - len = io->packet_size; - if (len > size) - len = size; - memcpy(buffer.out + buffer.out_bytes, data, len); - buffer.out_bytes += len; - - if ((int)buffer.out_bytes <= io->packet_size || buffer.out_bytes == size) { - rc = ble_serial_flush_write(); - if (rc != DC_STATUS_SUCCESS) - break; - } - transferred += len; - data = (const void *) (len + (const char *)data); - size -= len; - } - if (actual) - *actual = transferred; - return DC_STATUS_SUCCESS; -} - -static dc_status_t ble_serial_purge(dc_custom_io_t *io, dc_direction_t queue) -{ - Q_UNUSED(io) - Q_UNUSED(queue) - /* Do we care? */ - return DC_STATUS_SUCCESS; -} - -static dc_status_t ble_serial_get_available(dc_custom_io_t *io, size_t *available) +static dc_status_t qt_serial_open(qt_serial_t **io, dc_context_t *context, const char* devaddr) { - Q_UNUSED(io) - *available = buffer.in_bytes - buffer.in_pos; - return DC_STATUS_SUCCESS; -} - -static dc_status_t ble_serial_set_timeout(dc_custom_io_t *io, long timeout) -{ - Q_UNUSED(io) - Q_UNUSED(timeout) - /* Do we care? */ - return DC_STATUS_SUCCESS; -} - -#endif - - - -static dc_status_t qt_serial_open(dc_custom_io_t *io, dc_context_t *context, const char* devaddr) -{ -#ifdef BLE_SUPPORT - if (!strncmp(devaddr, "LE:", 3)) - return ble_serial_open(io, context, devaddr); -#endif - // Allocate memory. qt_serial_t *serial_port = (qt_serial_t *) malloc (sizeof (qt_serial_t)); if (serial_port == NULL) { @@ -377,14 +187,15 @@ static dc_status_t qt_serial_open(dc_custom_io_t *io, dc_context_t *context, con } } #endif - io->userdata = serial_port; + + *io = serial_port; return DC_STATUS_SUCCESS; } -static dc_status_t qt_serial_close(dc_custom_io_t *io) +static dc_status_t qt_serial_close(void *io) { - qt_serial_t *device = (qt_serial_t*) io->userdata; + qt_serial_t *device = (qt_serial_t*) io; if (device == NULL) return DC_STATUS_SUCCESS; @@ -405,14 +216,12 @@ static dc_status_t qt_serial_close(dc_custom_io_t *io) free(device); #endif - io->userdata = NULL; - return DC_STATUS_SUCCESS; } -static dc_status_t qt_serial_read(dc_custom_io_t *io, void* data, size_t size, size_t *actual) +static dc_status_t qt_serial_read(void *io, void* data, size_t size, size_t *actual) { - qt_serial_t *device = (qt_serial_t*) io->userdata; + qt_serial_t *device = (qt_serial_t*) io; #if defined(Q_OS_WIN) if (device == NULL) @@ -471,9 +280,9 @@ static dc_status_t qt_serial_read(dc_custom_io_t *io, void* data, size_t size, s return DC_STATUS_SUCCESS; } -static dc_status_t qt_serial_write(dc_custom_io_t *io, const void* data, size_t size, size_t *actual) +static dc_status_t qt_serial_write(void *io, const void* data, size_t size, size_t *actual) { - qt_serial_t *device = (qt_serial_t*) io->userdata; + qt_serial_t *device = (qt_serial_t*) io; #if defined(Q_OS_WIN) if (device == NULL) @@ -520,9 +329,9 @@ static dc_status_t qt_serial_write(dc_custom_io_t *io, const void* data, size_t return DC_STATUS_SUCCESS; } -static dc_status_t qt_serial_purge(dc_custom_io_t *io, dc_direction_t queue) +static dc_status_t qt_serial_purge(void *io, dc_direction_t queue) { - qt_serial_t *device = (qt_serial_t*) io->userdata; + qt_serial_t *device = (qt_serial_t*) io; (void)queue; if (device == NULL) @@ -536,9 +345,9 @@ static dc_status_t qt_serial_purge(dc_custom_io_t *io, dc_direction_t queue) return DC_STATUS_SUCCESS; } -static dc_status_t qt_serial_get_available(dc_custom_io_t *io, size_t *available) +static dc_status_t qt_serial_get_available(void *io, size_t *available) { - qt_serial_t *device = (qt_serial_t*) io->userdata; + qt_serial_t *device = (qt_serial_t*) io; #if defined(Q_OS_WIN) if (device == NULL) @@ -577,9 +386,9 @@ static int qt_serial_get_transmitted(qt_serial_t *device) #endif } -static dc_status_t qt_serial_set_timeout(dc_custom_io_t *io, long timeout) +static dc_status_t qt_serial_set_timeout(void *io, int timeout) { - qt_serial_t *device = (qt_serial_t*) io->userdata; + qt_serial_t *device = (qt_serial_t*) io; if (device == NULL) return DC_STATUS_INVALIDARGS; @@ -589,35 +398,68 @@ static dc_status_t qt_serial_set_timeout(dc_custom_io_t *io, long timeout) return DC_STATUS_SUCCESS; } -dc_custom_io_t qt_serial_ops = { - .userdata = NULL, - .user_device = NULL, - .serial_open = qt_serial_open, - .serial_close = qt_serial_close, - .serial_read = qt_serial_read, - .serial_write = qt_serial_write, - .serial_purge = qt_serial_purge, - .serial_get_available = qt_serial_get_available, - .serial_set_timeout = qt_serial_set_timeout, -// These doesn't make sense over bluetooth -// NULL means NOP - .serial_configure = NULL, - .serial_set_dtr = NULL, - .serial_set_rts = NULL, - .serial_set_break = NULL, - -#ifdef BLE_SUPPORT - .packet_size = 20, - .packet_open = qt_ble_open, - .packet_close = qt_ble_close, - .packet_read = qt_ble_read, - .packet_write = qt_ble_write, #endif -}; -dc_custom_io_t* get_qt_serial_ops() { - return (dc_custom_io_t*) &qt_serial_ops; +dc_status_t +ble_packet_open(dc_iostream_t **iostream, dc_context_t *context, const char* devaddr, void *userdata) +{ + dc_status_t rc = DC_STATUS_SUCCESS; + void *io = NULL; + + static const dc_custom_cbs_t callbacks = { + NULL, /* set_timeout */ + NULL, /* set_latency */ + NULL, /* set_break */ + NULL, /* set_dtr */ + NULL, /* set_rts */ + NULL, /* get_lines */ + NULL, /* get_received */ + NULL, /* configure */ + qt_ble_read, /* read */ + qt_ble_write, /* write */ + NULL, /* flush */ + NULL, /* purge */ + NULL, /* sleep */ + qt_ble_close, /* close */ + }; + + rc = qt_ble_open(&io, context, devaddr, (dc_user_device_t *) userdata); + if (rc != DC_STATUS_SUCCESS) { + return rc; + } + + return dc_custom_open (iostream, context, DC_TRANSPORT_BLE, &callbacks, io); +} + +dc_status_t +rfcomm_stream_open(dc_iostream_t **iostream, dc_context_t *context, const char* devaddr) +{ + dc_status_t rc = DC_STATUS_SUCCESS; + qt_serial_t *io = NULL; + + static const dc_custom_cbs_t callbacks = { + qt_serial_set_timeout, /* set_timeout */ + NULL, /* set_latency */ + NULL, /* set_break */ + NULL, /* set_dtr */ + NULL, /* set_rts */ + NULL, /* get_lines */ + qt_serial_get_available, /* get_received */ + NULL, /* configure */ + qt_serial_read, /* read */ + qt_serial_write, /* write */ + NULL, /* flush */ + qt_serial_purge, /* purge */ + NULL, /* sleep */ + qt_serial_close, /* close */ + }; + + rc = qt_serial_open(&io, context, devaddr); + if (rc != DC_STATUS_SUCCESS) { + return rc; + } + + return dc_custom_open (iostream, context, DC_TRANSPORT_BLUETOOTH, &callbacks, io); } } -#endif diff --git a/core/serial_ftdi.c b/core/serial_ftdi.c index 166bf0894..6d99672f2 100644 --- a/core/serial_ftdi.c +++ b/core/serial_ftdi.c @@ -44,8 +44,8 @@ #define SYSERROR(context, errcode) ; #include "libdivecomputer.h" -#include <libdivecomputer/custom_io.h> #include <libdivecomputer/context.h> +#include <libdivecomputer/custom.h> #define VID 0x0403 // Vendor ID of FTDI @@ -73,9 +73,9 @@ typedef struct ftdi_serial_t { unsigned int parity; } ftdi_serial_t; -static dc_status_t serial_ftdi_get_received (dc_custom_io_t *io, size_t *value) +static dc_status_t serial_ftdi_get_received (void *io, size_t *value) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; @@ -147,7 +147,7 @@ static int serial_ftdi_open_device (struct ftdi_context *ftdi_ctx) // // Open the serial port. // Initialise ftdi_context and use it to open the device -static dc_status_t serial_ftdi_open (dc_custom_io_t *io, dc_context_t *context, const char* name) +static dc_status_t serial_ftdi_open (void **io, dc_context_t *context) { INFO(0, "serial_ftdi_open called"); // Allocate memory. @@ -207,7 +207,7 @@ static dc_status_t serial_ftdi_open (dc_custom_io_t *io, dc_context_t *context, device->ftdi_ctx = ftdi_ctx; - io->userdata = device; + *io = device; return DC_STATUS_SUCCESS; } @@ -215,9 +215,9 @@ static dc_status_t serial_ftdi_open (dc_custom_io_t *io, dc_context_t *context, // // Close the serial port. // -static dc_status_t serial_ftdi_close (dc_custom_io_t *io) +static dc_status_t serial_ftdi_close (void *io) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_SUCCESS; @@ -237,17 +237,15 @@ static dc_status_t serial_ftdi_close (dc_custom_io_t *io) // Free memory. free (device); - io->userdata = NULL; - return DC_STATUS_SUCCESS; } // // Configure the serial port (baudrate, databits, parity, stopbits and flowcontrol). // -static dc_status_t serial_ftdi_configure (dc_custom_io_t *io, unsigned int baudrate, unsigned int databits, dc_parity_t parity, dc_stopbits_t stopbits, dc_flowcontrol_t flowcontrol) +static dc_status_t serial_ftdi_configure (void *io, unsigned int baudrate, unsigned int databits, dc_parity_t parity, dc_stopbits_t stopbits, dc_flowcontrol_t flowcontrol) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; @@ -348,23 +346,23 @@ static dc_status_t serial_ftdi_configure (dc_custom_io_t *io, unsigned int baudr // // Configure the serial port (timeouts). // -static dc_status_t serial_ftdi_set_timeout (dc_custom_io_t *io, long timeout) +static dc_status_t serial_ftdi_set_timeout (void *io, int timeout) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; - INFO (device->context, "Timeout: value=%li", timeout); + INFO (device->context, "Timeout: value=%i", timeout); device->timeout = timeout; return DC_STATUS_SUCCESS; } -static dc_status_t serial_ftdi_read (dc_custom_io_t *io, void *data, size_t size, size_t *actual) +static dc_status_t serial_ftdi_read (void *io, void *data, size_t size, size_t *actual) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; @@ -380,7 +378,7 @@ static dc_status_t serial_ftdi_read (dc_custom_io_t *io, void *data, size_t size int slept = 0; unsigned int nbytes = 0; while (nbytes < size) { - int n = ftdi_read_data (device->ftdi_ctx, (char *) data + nbytes, size - nbytes); + int n = ftdi_read_data (device->ftdi_ctx, (unsigned char *) data + nbytes, size - nbytes); if (n < 0) { if (n == LIBUSB_ERROR_INTERRUPTED) continue; //Retry. @@ -406,19 +404,17 @@ static dc_status_t serial_ftdi_read (dc_custom_io_t *io, void *data, size_t size return DC_STATUS_SUCCESS; } -static dc_status_t serial_ftdi_write (dc_custom_io_t *io, const void *data, size_t size, size_t *actual) +static dc_status_t serial_ftdi_write (void *io, const void *data, size_t size, size_t *actual) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; - struct timeval tve, tvb; - unsigned int nbytes = 0; while (nbytes < size) { - int n = ftdi_write_data (device->ftdi_ctx, (char *) data + nbytes, size - nbytes); + int n = ftdi_write_data (device->ftdi_ctx, (unsigned char *) data + nbytes, size - nbytes); if (n < 0) { if (n == LIBUSB_ERROR_INTERRUPTED) continue; // Retry. @@ -439,9 +435,9 @@ static dc_status_t serial_ftdi_write (dc_custom_io_t *io, const void *data, size return DC_STATUS_SUCCESS; } -static dc_status_t serial_ftdi_flush (dc_custom_io_t *io, dc_direction_t queue) +static dc_status_t serial_ftdi_purge (void *io, dc_direction_t queue) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; @@ -476,26 +472,9 @@ static dc_status_t serial_ftdi_flush (dc_custom_io_t *io, dc_direction_t queue) return DC_STATUS_SUCCESS; } -static dc_status_t serial_ftdi_send_break (dc_custom_io_t *io) +static dc_status_t serial_ftdi_set_break (void *io, unsigned int level) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; - - if (device == NULL) - return DC_STATUS_INVALIDARGS; - - INFO (device->context, "Break : One time period."); - - // no direct functions for sending break signals in libftdi. - // there is a suggestion to lower the baudrate and sending NUL - // and resetting the baudrate up again. But it has flaws. - // Not implementing it before researching more. - - return DC_STATUS_UNSUPPORTED; -} - -static dc_status_t serial_ftdi_set_break (dc_custom_io_t *io, unsigned int level) -{ - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; @@ -510,16 +489,16 @@ static dc_status_t serial_ftdi_set_break (dc_custom_io_t *io, unsigned int level return DC_STATUS_UNSUPPORTED; } -static dc_status_t serial_ftdi_set_dtr (dc_custom_io_t *io, int level) +static dc_status_t serial_ftdi_set_dtr (void *io, unsigned int value) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; - INFO (device->context, "DTR: value=%i", level); + INFO (device->context, "DTR: value=%u", value); - if (ftdi_setdtr(device->ftdi_ctx, level)) { + if (ftdi_setdtr(device->ftdi_ctx, value)) { ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx)); return DC_STATUS_IO; } @@ -527,14 +506,14 @@ static dc_status_t serial_ftdi_set_dtr (dc_custom_io_t *io, int level) return DC_STATUS_SUCCESS; } -static dc_status_t serial_ftdi_set_rts (dc_custom_io_t *io, int level) +static dc_status_t serial_ftdi_set_rts (void *io, unsigned int level) { - ftdi_serial_t *device = (ftdi_serial_t*) io->userdata; + ftdi_serial_t *device = io; if (device == NULL) return DC_STATUS_INVALIDARGS; - INFO (device->context, "RTS: value=%i", level); + INFO (device->context, "RTS: value=%u", level); if (ftdi_setrts(device->ftdi_ctx, level)) { ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx)); @@ -544,19 +523,31 @@ static dc_status_t serial_ftdi_set_rts (dc_custom_io_t *io, int level) return DC_STATUS_SUCCESS; } -dc_custom_io_t serial_ftdi_ops = { - .userdata = NULL, - .serial_open = serial_ftdi_open, - .serial_close = serial_ftdi_close, - .serial_read = serial_ftdi_read, - .serial_write = serial_ftdi_write, - .serial_purge = serial_ftdi_flush, - .serial_get_available = serial_ftdi_get_received, - .serial_set_timeout = serial_ftdi_set_timeout, - .serial_configure = serial_ftdi_configure, - .serial_set_dtr = serial_ftdi_set_dtr, - .serial_set_rts = serial_ftdi_set_rts, -// Can't be done in ftdi? -// only used in vyper2 - .serial_set_break = serial_ftdi_set_break, -}; +dc_status_t ftdi_open(dc_iostream_t **iostream, dc_context_t *context) +{ + dc_status_t rc = DC_STATUS_SUCCESS; + void *io = NULL; + + static const dc_custom_cbs_t callbacks = { + serial_ftdi_set_timeout, /* set_timeout */ + NULL, /* set_latency */ + serial_ftdi_set_break, /* set_break */ + serial_ftdi_set_dtr, /* set_dtr */ + serial_ftdi_set_rts, /* set_rts */ + NULL, /* get_lines */ + serial_ftdi_get_received, /* get_received */ + serial_ftdi_configure, /* configure */ + serial_ftdi_read, /* read */ + serial_ftdi_write, /* write */ + NULL, /* flush */ + serial_ftdi_purge, /* purge */ + NULL, /* sleep */ + serial_ftdi_close, /* close */ + }; + + rc = serial_ftdi_open(&io, context); + if (rc != DC_STATUS_SUCCESS) + return rc; + + return dc_custom_open(iostream, context, DC_TRANSPORT_SERIAL, &callbacks, io); +} diff --git a/desktop-widgets/downloadfromdivecomputer.cpp b/desktop-widgets/downloadfromdivecomputer.cpp index ad8416a07..e185960c9 100644 --- a/desktop-widgets/downloadfromdivecomputer.cpp +++ b/desktop-widgets/downloadfromdivecomputer.cpp @@ -84,7 +84,7 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) : ui.downloadCancelRetryButton->setText(tr("Download")); QString deviceText = dc->dc_device(); -#if defined(BT_SUPPORT) && defined(SSRF_CUSTOM_IO) +#if defined(BT_SUPPORT) ui.bluetoothMode->setText(tr("Choose Bluetooth download mode")); ui.bluetoothMode->setChecked(dc->downloadMode() == DC_TRANSPORT_BLUETOOTH); btDeviceSelectionDialog = 0; @@ -318,7 +318,7 @@ void DownloadFromDCWidget::on_downloadCancelRetryButton_clicked() dc->setProduct(data->product()); dc->setDevice(data->devName()); -#if defined(BT_SUPPORT) && defined(SSRF_CUSTOM_IO) +#if defined(BT_SUPPORT) dc->setDownloadMode(ui.bluetoothMode->isChecked() ? DC_TRANSPORT_BLUETOOTH : DC_TRANSPORT_SERIAL); #endif @@ -477,7 +477,7 @@ void DownloadFromDCWidget::updateDeviceEnabled() descriptor = descriptorLookup.value(ui.vendor->currentText() + ui.product->currentText()); // call dc_descriptor_get_transport to see if the dc_transport_t is DC_TRANSPORT_SERIAL - if (dc_descriptor_get_transport(descriptor) == DC_TRANSPORT_SERIAL) { + if (dc_descriptor_get_transports(descriptor) & DC_TRANSPORT_SERIAL) { // if the dc_transport_t is DC_TRANSPORT_SERIAL, then enable the device node box. ui.device->setEnabled(true); } else { |