summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2017-06-27 11:59:11 -0700
committerGravatar Linus Torvalds <torvalds@linux-foundation.org>2017-06-27 13:58:15 -0700
commitd01b7bf89167ff8ab40c4b663398816da678084a (patch)
tree33b5b554b6ec8ed42febc46ba4a560b06ba52107
parente79bede0aa5b3bd169a29dbb907002d6ac717c6e (diff)
downloadsubsurface-d01b7bf89167ff8ab40c4b663398816da678084a.tar.gz
Switch over to SSRF_CUSTOM_IO v2
I hate changing the IO interfaces this often, but when I converted the custom serial interface to the more generic custom IO interface, I intentionally left the legacy serial operations alone, because I didn't want to change something I didn't care about. But it turns out that leaving them with the old calling convention caused extra problems when converting the bluetooth serial code to have the BLE GATT packet fall-back, which requires mixing two kinds of operations. Also, the packet_open() routine was passed a copy of the 'dc_context_t', which makes it possible to update the 'dc_custom_io_t' field on the fly at open time. That makes a lot of chaining operations much simpler, since now you can chain the 'custom_io_t' at open time and then libdivecomputer will automatically call the new routines instead of the old ones. That dc_context_t availability gets rid of all the if (device && device->ops) return device->ops->serial_xyz(..); hackery inside the rfcomm routines - now we can just at open time do a simple dc_context_set_custom_io(context, &ble_serial_ops); to switch things over to the BLE version of the serial code instead. Finally, SSRF_CUSTOM_IO v2 added an opaque "dc_user_device_t" pointer argument to the custom_io descriptor, which gets filled in as the custom_io is registered with the download context. Note that unlike most opaque pointers, this one is opaque to *libdivecomputer*, and the type is supposed to be supplied by the user. We define the "dc_user_device_t" as our old "struct device_data_t", making it "struct user_device_t" instead. That means that the IO routines now get passed the device info showing what device they are supposed to download for. That, in turn, means that now our BLE GATT open code can take the device type it opens for into account if it wants to. And it will want to, since the rules for Shearwater are different from the rules for Suunto, for example. NOTE! Because of the interface change with libdivecomputer, this will need a flag-day again where libdivecomputer and subsurface are updated together. It may not be the last time, either. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--core/configuredivecomputer.cpp4
-rw-r--r--core/libdivecomputer.c6
-rw-r--r--core/libdivecomputer.h2
-rw-r--r--core/qtserialbluetooth.cpp96
-rw-r--r--core/serial_ftdi.c54
-rw-r--r--core/uemis-downloader.c2
6 files changed, 76 insertions, 88 deletions
diff --git a/core/configuredivecomputer.cpp b/core/configuredivecomputer.cpp
index 2b6d3da16..1e34e2546 100644
--- a/core/configuredivecomputer.cpp
+++ b/core/configuredivecomputer.cpp
@@ -635,11 +635,11 @@ QString ConfigureDiveComputer::dc_open(device_data_t *data)
#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());
+ 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);
+ rc = dc_context_set_custom_io(data->context, &serial_ftdi_ops, data);
#endif
}
diff --git a/core/libdivecomputer.c b/core/libdivecomputer.c
index 2f0a303e3..7d41b9d06 100644
--- a/core/libdivecomputer.c
+++ b/core/libdivecomputer.c
@@ -605,7 +605,7 @@ static void parse_string_field(struct dive *dive, dc_field_string_t *str)
}
#endif
-static dc_status_t libdc_header_parser(dc_parser_t *parser, struct device_data_t *devdata, struct dive *dive)
+static dc_status_t libdc_header_parser(dc_parser_t *parser, dc_user_device_t *devdata, struct dive *dive)
{
dc_status_t rc = 0;
dc_datetime_t dt = { 0 };
@@ -1091,11 +1091,11 @@ const char *do_libdivecomputer_import(device_data_t *data)
#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());
+ 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);
+ rc = dc_context_set_custom_io(data->context, &serial_ftdi_ops, data);
INFO(0, "setting up ftdi ops");
#else
INFO(0, "FTDI disabled");
diff --git a/core/libdivecomputer.h b/core/libdivecomputer.h
index a618f49f2..83a6bab79 100644
--- a/core/libdivecomputer.h
+++ b/core/libdivecomputer.h
@@ -23,7 +23,7 @@ extern "C" {
/* don't forget to include the UI toolkit specific display-XXX.h first
to get the definition of progressbar_t */
-typedef struct device_data_t
+typedef struct dc_user_device_t
{
dc_descriptor_t *descriptor;
const char *vendor, *product, *devname;
diff --git a/core/qtserialbluetooth.cpp b/core/qtserialbluetooth.cpp
index e6b004f03..5f4419c5e 100644
--- a/core/qtserialbluetooth.cpp
+++ b/core/qtserialbluetooth.cpp
@@ -8,6 +8,7 @@
#include <QDebug>
#include <libdivecomputer/version.h>
+#include <libdivecomputer/context.h>
#if defined(SSRF_CUSTOM_IO)
@@ -37,7 +38,6 @@ void addBtUuid(QBluetoothUuid uuid)
extern "C" {
typedef struct qt_serial_t {
- dc_custom_io_t *ops;
/*
* RFCOMM socket used for Bluetooth Serial communication.
*/
@@ -51,15 +51,17 @@ typedef struct qt_serial_t {
#ifdef BLE_SUPPORT
-static dc_status_t ble_serial_open(void **userdata, const char* devaddr);
-static dc_status_t ble_serial_close(void **userdata);
-static dc_status_t ble_serial_read(void **userdata, void* data, size_t size, size_t *actual);
-static dc_status_t ble_serial_write(void **userdata, const void* data, size_t size, size_t *actual);
-static dc_status_t ble_serial_purge(void **userdata, dc_direction_t queue);
-static dc_status_t ble_serial_get_available(void **userdata, size_t *available);
+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,
@@ -67,7 +69,7 @@ static dc_custom_io_t ble_serial_ops = {
.serial_write = ble_serial_write,
.serial_purge = ble_serial_purge,
.serial_get_available = ble_serial_get_available,
- .serial_set_timeout = NULL, // the regular qt_set_timeout is fine
+ .serial_set_timeout = ble_serial_set_timeout,
// These doesn't make sense over bluetooth
// NULL means NOP
.serial_configure = NULL,
@@ -83,15 +85,11 @@ static dc_custom_io_t ble_serial_ops = {
.packet_write = qt_ble_write,
};
-static struct qt_serial_t serial_over_ble = {
- .ops = &ble_serial_ops,
-};
-
-static dc_status_t ble_serial_open(void **userdata, const char* devaddr)
+static dc_status_t ble_serial_open(dc_custom_io_t *io, dc_context_t *context, const char* devaddr)
{
- *userdata = &serial_over_ble;
- return qt_ble_open(&ble_serial_ops, NULL, devaddr);
+ dc_context_set_custom_io(context, &ble_serial_ops, io->user_device);
+ return qt_ble_open(&ble_serial_ops, context, devaddr);
}
#define BUFSZ 1024
@@ -117,14 +115,14 @@ static dc_status_t ble_serial_flush_read(void)
return DC_STATUS_SUCCESS;
}
-static dc_status_t ble_serial_close(void **userdata)
+static dc_status_t ble_serial_close(dc_custom_io_t *io)
{
ble_serial_flush_write();
- *userdata = NULL;
+ io->userdata = NULL;
return qt_ble_close(&ble_serial_ops);
}
-static dc_status_t ble_serial_read(void **userdata, void* data, size_t size, size_t *actual)
+static dc_status_t ble_serial_read(dc_custom_io_t *io, void* data, size_t size, size_t *actual)
{
int len;
@@ -153,7 +151,7 @@ static dc_status_t ble_serial_read(void **userdata, void* data, size_t size, siz
return DC_STATUS_SUCCESS;
}
-static dc_status_t ble_serial_write(void **userdata, const 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)
{
dc_status_t rc = DC_STATUS_SUCCESS;
size_t transferred = 0;
@@ -181,27 +179,33 @@ static dc_status_t ble_serial_write(void **userdata, const void* data, size_t si
return DC_STATUS_SUCCESS;
}
-static dc_status_t ble_serial_purge(void **userdata, dc_direction_t queue)
+static dc_status_t ble_serial_purge(dc_custom_io_t *io, dc_direction_t queue)
{
/* Do we care? */
return DC_STATUS_SUCCESS;
}
-static dc_status_t ble_serial_get_available(void **userdata, size_t *available)
+static dc_status_t ble_serial_get_available(dc_custom_io_t *io, size_t *available)
{
*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)
+{
+ /* Do we care? */
+ return DC_STATUS_SUCCESS;
+}
+
#endif
-static dc_status_t qt_serial_open(void **userdata, const char* devaddr)
+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(userdata, devaddr);
+ return ble_serial_open(io, context, devaddr);
#endif
// Allocate memory.
@@ -210,8 +214,6 @@ static dc_status_t qt_serial_open(void **userdata, const char* devaddr)
return DC_STATUS_NOMEMORY;
}
- serial_port->ops = NULL;
-
// Default to blocking reads.
serial_port->timeout = -1;
@@ -348,21 +350,18 @@ static dc_status_t qt_serial_open(void **userdata, const char* devaddr)
}
}
#endif
- *userdata = serial_port;
+ io->userdata = serial_port;
return DC_STATUS_SUCCESS;
}
-static dc_status_t qt_serial_close(void **userdata)
+static dc_status_t qt_serial_close(dc_custom_io_t *io)
{
- qt_serial_t *device = (qt_serial_t*) *userdata;
+ qt_serial_t *device = (qt_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_SUCCESS;
- if (device && device->ops)
- return device->ops->serial_close(userdata);
-
#if defined(Q_OS_WIN)
// Cleanup
closesocket(device->socket);
@@ -379,17 +378,14 @@ static dc_status_t qt_serial_close(void **userdata)
free(device);
#endif
- *userdata = NULL;
+ io->userdata = NULL;
return DC_STATUS_SUCCESS;
}
-static dc_status_t qt_serial_read(void **userdata, void* data, size_t size, size_t *actual)
+static dc_status_t qt_serial_read(dc_custom_io_t *io, void* data, size_t size, size_t *actual)
{
- qt_serial_t *device = (qt_serial_t*) *userdata;
-
- if (device && device->ops)
- return device->ops->serial_read(userdata, data, size, actual);
+ qt_serial_t *device = (qt_serial_t*) io->userdata;
#if defined(Q_OS_WIN)
if (device == NULL)
@@ -448,12 +444,9 @@ static dc_status_t qt_serial_read(void **userdata, void* data, size_t size, size
return DC_STATUS_SUCCESS;
}
-static dc_status_t qt_serial_write(void **userdata, const void* data, size_t size, size_t *actual)
+static dc_status_t qt_serial_write(dc_custom_io_t *io, const void* data, size_t size, size_t *actual)
{
- qt_serial_t *device = (qt_serial_t*) *userdata;
-
- if (device && device->ops)
- return device->ops->serial_write(userdata, data, size, actual);
+ qt_serial_t *device = (qt_serial_t*) io->userdata;
#if defined(Q_OS_WIN)
if (device == NULL)
@@ -500,12 +493,9 @@ static dc_status_t qt_serial_write(void **userdata, const void* data, size_t siz
return DC_STATUS_SUCCESS;
}
-static dc_status_t qt_serial_purge(void **userdata, dc_direction_t queue)
+static dc_status_t qt_serial_purge(dc_custom_io_t *io, dc_direction_t queue)
{
- qt_serial_t *device = (qt_serial_t*) *userdata;
-
- if (device && device->ops)
- return device->ops->serial_purge(userdata, queue);
+ qt_serial_t *device = (qt_serial_t*) io->userdata;
(void)queue;
if (device == NULL)
@@ -519,12 +509,9 @@ static dc_status_t qt_serial_purge(void **userdata, dc_direction_t queue)
return DC_STATUS_SUCCESS;
}
-static dc_status_t qt_serial_get_available(void **userdata, size_t *available)
+static dc_status_t qt_serial_get_available(dc_custom_io_t *io, size_t *available)
{
- qt_serial_t *device = (qt_serial_t*) *userdata;
-
- if (device && device->ops)
- return device->ops->serial_get_available(userdata, available);
+ qt_serial_t *device = (qt_serial_t*) io->userdata;
#if defined(Q_OS_WIN)
if (device == NULL)
@@ -563,9 +550,9 @@ static int qt_serial_get_transmitted(qt_serial_t *device)
#endif
}
-static dc_status_t qt_serial_set_timeout(void **userdata, long timeout)
+static dc_status_t qt_serial_set_timeout(dc_custom_io_t *io, long timeout)
{
- qt_serial_t *device = (qt_serial_t*) *userdata;
+ qt_serial_t *device = (qt_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -577,6 +564,7 @@ static dc_status_t qt_serial_set_timeout(void **userdata, long timeout)
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,
diff --git a/core/serial_ftdi.c b/core/serial_ftdi.c
index 0c9e6c428..ade104a1c 100644
--- a/core/serial_ftdi.c
+++ b/core/serial_ftdi.c
@@ -71,9 +71,9 @@ typedef struct ftdi_serial_t {
unsigned int nbits;
} ftdi_serial_t;
-static dc_status_t serial_ftdi_get_received (void **userdata, size_t *value)
+static dc_status_t serial_ftdi_get_received (dc_custom_io_t *io, size_t *value)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -145,7 +145,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 (void **userdata, const char* name)
+static dc_status_t serial_ftdi_open (dc_custom_io_t *io, dc_context_t *context, const char* name)
{
INFO(0, "serial_ftdi_open called");
// Allocate memory.
@@ -203,7 +203,7 @@ static dc_status_t serial_ftdi_open (void **userdata, const char* name)
device->ftdi_ctx = ftdi_ctx;
- *userdata = device;
+ io->userdata = device;
return DC_STATUS_SUCCESS;
}
@@ -211,9 +211,9 @@ static dc_status_t serial_ftdi_open (void **userdata, const char* name)
//
// Close the serial port.
//
-static dc_status_t serial_ftdi_close (void **userdata)
+static dc_status_t serial_ftdi_close (dc_custom_io_t *io)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_SUCCESS;
@@ -233,7 +233,7 @@ static dc_status_t serial_ftdi_close (void **userdata)
// Free memory.
free (device);
- *userdata = NULL;
+ io->userdata = NULL;
return DC_STATUS_SUCCESS;
}
@@ -241,9 +241,9 @@ static dc_status_t serial_ftdi_close (void **userdata)
//
// Configure the serial port (baudrate, databits, parity, stopbits and flowcontrol).
//
-static dc_status_t serial_ftdi_configure (void **userdata, 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 (dc_custom_io_t *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*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -341,9 +341,9 @@ static dc_status_t serial_ftdi_configure (void **userdata, unsigned int baudrate
//
// Configure the serial port (timeouts).
//
-static dc_status_t serial_ftdi_set_timeout (void **userdata, long timeout)
+static dc_status_t serial_ftdi_set_timeout (dc_custom_io_t *io, long timeout)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -355,9 +355,9 @@ static dc_status_t serial_ftdi_set_timeout (void **userdata, long timeout)
return DC_STATUS_SUCCESS;
}
-static dc_status_t serial_ftdi_set_halfduplex (void **userdata, unsigned int value)
+static dc_status_t serial_ftdi_set_halfduplex (dc_custom_io_t *io, unsigned int value)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -370,9 +370,9 @@ static dc_status_t serial_ftdi_set_halfduplex (void **userdata, unsigned int val
return DC_STATUS_SUCCESS;
}
-static dc_status_t serial_ftdi_read (void **userdata, void *data, size_t size, size_t *actual)
+static dc_status_t serial_ftdi_read (dc_custom_io_t *io, void *data, size_t size, size_t *actual)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -421,9 +421,9 @@ static dc_status_t serial_ftdi_read (void **userdata, void *data, size_t size, s
return DC_STATUS_SUCCESS;
}
-static dc_status_t serial_ftdi_write (void **userdata, const void *data, size_t size, size_t *actual)
+static dc_status_t serial_ftdi_write (dc_custom_io_t *io, const void *data, size_t size, size_t *actual)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -488,9 +488,9 @@ static dc_status_t serial_ftdi_write (void **userdata, const void *data, size_t
return DC_STATUS_SUCCESS;
}
-static dc_status_t serial_ftdi_flush (void **userdata, dc_direction_t queue)
+static dc_status_t serial_ftdi_flush (dc_custom_io_t *io, dc_direction_t queue)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -525,9 +525,9 @@ static dc_status_t serial_ftdi_flush (void **userdata, dc_direction_t queue)
return DC_STATUS_SUCCESS;
}
-static dc_status_t serial_ftdi_send_break (void **userdata)
+static dc_status_t serial_ftdi_send_break (dc_custom_io_t *io)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -542,9 +542,9 @@ static dc_status_t serial_ftdi_send_break (void **userdata)
return DC_STATUS_UNSUPPORTED;
}
-static dc_status_t serial_ftdi_set_break (void **userdata, int level)
+static dc_status_t serial_ftdi_set_break (dc_custom_io_t *io, int level)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -556,9 +556,9 @@ static dc_status_t serial_ftdi_set_break (void **userdata, int level)
return DC_STATUS_UNSUPPORTED;
}
-static dc_status_t serial_ftdi_set_dtr (void **userdata, int level)
+static dc_status_t serial_ftdi_set_dtr (dc_custom_io_t *io, int level)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -573,9 +573,9 @@ static dc_status_t serial_ftdi_set_dtr (void **userdata, int level)
return DC_STATUS_SUCCESS;
}
-static dc_status_t serial_ftdi_set_rts (void **userdata, int level)
+static dc_status_t serial_ftdi_set_rts (dc_custom_io_t *io, int level)
{
- ftdi_serial_t *device = (ftdi_serial_t*) *userdata;
+ ftdi_serial_t *device = (ftdi_serial_t*) io->userdata;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
diff --git a/core/uemis-downloader.c b/core/uemis-downloader.c
index e65c1fd46..7c91f985a 100644
--- a/core/uemis-downloader.c
+++ b/core/uemis-downloader.c
@@ -1120,7 +1120,7 @@ static void get_uemis_divespot(const char *mountpath, int divespot_id, struct di
}
}
-static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, struct device_data_t *data, const char *mountpath, const char deviceidnr)
+static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, dc_user_device_t *data, const char *mountpath, const char deviceidnr)
{
struct dive *dive = data->download_table->dives[idx];
char log_file_no_to_find[20];