summaryrefslogtreecommitdiffstats
path: root/core/qtserialbluetooth.cpp
diff options
context:
space:
mode:
authorGravatar Anton Lundin <glance@acc.umu.se>2016-09-17 17:27:56 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2016-09-17 15:47:37 -0700
commitffa3c4859327a78288cfb74e633ac3845a86ed86 (patch)
tree2576d8a298875a750f7b05ba9bd5bfebdeff9335 /core/qtserialbluetooth.cpp
parent1219dc693170e4a04fff992bd5aed990674779c1 (diff)
downloadsubsurface-ffa3c4859327a78288cfb74e633ac3845a86ed86.tar.gz
Rewrite libdivecomputer custom serial code
This rewrites the custom serial code to use the new api which I implemented in the Subsurface-branch of libdivecomputer. This is a bit to big patch but I haven't had the time to break it down into more sensible patches. This rewrite enables us to support more ftdi based divecomputer communication and is tested with both a OSTC3, OSTC2N and a Suunto Vyper, all over the libftdi driver. The bluetooth code paths are tested to, and should work as before. Signed-off-by: Anton Lundin <glance@acc.umu.se> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'core/qtserialbluetooth.cpp')
-rw-r--r--core/qtserialbluetooth.cpp135
1 files changed, 60 insertions, 75 deletions
diff --git a/core/qtserialbluetooth.cpp b/core/qtserialbluetooth.cpp
index 6b104157a..a7856af64 100644
--- a/core/qtserialbluetooth.cpp
+++ b/core/qtserialbluetooth.cpp
@@ -19,9 +19,7 @@
#include <libdivecomputer/custom_serial.h>
extern "C" {
-typedef struct serial_t {
- /* Library context. */
- dc_context_t *context;
+typedef struct qt_serial_t {
/*
* RFCOMM socket used for Bluetooth Serial communication.
*/
@@ -31,22 +29,16 @@ typedef struct serial_t {
QBluetoothSocket *socket;
#endif
long timeout;
-} serial_t;
+} qt_serial_t;
-static int qt_serial_open(serial_t **out, dc_context_t *context, const char* devaddr)
+static dc_status_t qt_serial_open(void **userdata, const char* devaddr)
{
- if (out == NULL)
- return DC_STATUS_INVALIDARGS;
-
// Allocate memory.
- serial_t *serial_port = (serial_t *) malloc (sizeof (serial_t));
+ qt_serial_t *serial_port = (qt_serial_t *) malloc (sizeof (qt_serial_t));
if (serial_port == NULL) {
return DC_STATUS_NOMEMORY;
}
- // Library context.
- serial_port->context = context;
-
// Default to blocking reads.
serial_port->timeout = -1;
@@ -172,17 +164,19 @@ static int qt_serial_open(serial_t **out, dc_context_t *context, const char* dev
case QBluetoothSocket::NetworkError:
return DC_STATUS_IO;
default:
- return QBluetoothSocket::UnknownSocketError;
+ return DC_STATUS_IO;
}
}
#endif
- *out = serial_port;
+ *userdata = serial_port;
return DC_STATUS_SUCCESS;
}
-static int qt_serial_close(serial_t *device)
+static dc_status_t qt_serial_close(void **userdata)
{
+ qt_serial_t *device = (qt_serial_t*) *userdata;
+
if (device == NULL)
return DC_STATUS_SUCCESS;
@@ -202,36 +196,38 @@ static int qt_serial_close(serial_t *device)
free(device);
#endif
+ *userdata = NULL;
+
return DC_STATUS_SUCCESS;
}
-static int qt_serial_read(serial_t *device, void* data, unsigned int size)
+static dc_status_t qt_serial_read(void **userdata, void* data, size_t size, size_t *actual)
{
+ qt_serial_t *device = (qt_serial_t*) *userdata;
+
#if defined(Q_OS_WIN)
if (device == NULL)
return DC_STATUS_INVALIDARGS;
- unsigned int nbytes = 0;
+ size_t nbytes = 0;
int rc;
while (nbytes < size) {
rc = recv (device->socket, (char *) data + nbytes, size - nbytes, 0);
if (rc < 0) {
- return -1; // Error during recv call.
+ return DC_STATUS_IO; // Error during recv call.
} else if (rc == 0) {
break; // EOF reached.
}
nbytes += rc;
}
-
- return nbytes;
#else
if (device == NULL || device->socket == NULL)
return DC_STATUS_INVALIDARGS;
- unsigned int nbytes = 0;
+ size_t nbytes = 0;
int rc;
while(nbytes < size && device->socket->state() == QBluetoothSocket::ConnectedState)
@@ -242,7 +238,7 @@ static int qt_serial_read(serial_t *device, void* data, unsigned int size)
if (errno == EINTR || errno == EAGAIN)
continue; // Retry.
- return -1; // Something really bad happened :-(
+ return DC_STATUS_IO; // Something really bad happened :-(
} else if (rc == 0) {
// Wait until the device is available for read operations
QEventLoop loop;
@@ -254,23 +250,27 @@ static int qt_serial_read(serial_t *device, void* data, unsigned int size)
loop.exec();
if (!timer.isActive())
- return nbytes;
+ break;
}
nbytes += rc;
}
-
- return nbytes;
#endif
+ if (actual)
+ *actual = nbytes;
+
+ return DC_STATUS_SUCCESS;
}
-static int qt_serial_write(serial_t *device, const void* data, unsigned int size)
+static dc_status_t qt_serial_write(void **userdata, const void* data, size_t size, size_t *actual)
{
+ qt_serial_t *device = (qt_serial_t*) *userdata;
+
#if defined(Q_OS_WIN)
if (device == NULL)
return DC_STATUS_INVALIDARGS;
- unsigned int nbytes = 0;
+ size_t nbytes = 0;
int rc;
while (nbytes < size) {
@@ -282,13 +282,11 @@ static int qt_serial_write(serial_t *device, const void* data, unsigned int size
nbytes += rc;
}
-
- return nbytes;
#else
if (device == NULL || device->socket == NULL)
return DC_STATUS_INVALIDARGS;
- unsigned int nbytes = 0;
+ size_t nbytes = 0;
int rc;
while(nbytes < size && device->socket->state() == QBluetoothSocket::ConnectedState)
@@ -299,20 +297,23 @@ static int qt_serial_write(serial_t *device, const void* data, unsigned int size
if (errno == EINTR || errno == EAGAIN)
continue; // Retry.
- return -1; // Something really bad happened :-(
+ return DC_STATUS_IO; // Something really bad happened :-(
} else if (rc == 0) {
break;
}
nbytes += rc;
}
-
- return nbytes;
#endif
+ if (actual)
+ *actual = nbytes;
+
+ return DC_STATUS_SUCCESS;
}
-static int qt_serial_flush(serial_t *device, int queue)
+static dc_status_t qt_serial_flush(void **userdata, dc_direction_t queue)
{
+ qt_serial_t *device = (qt_serial_t*) *userdata;
(void)queue;
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -325,24 +326,27 @@ static int qt_serial_flush(serial_t *device, int queue)
return DC_STATUS_SUCCESS;
}
-static int qt_serial_get_received(serial_t *device)
+static dc_status_t qt_serial_get_received(void **userdata, size_t *available)
{
+ qt_serial_t *device = (qt_serial_t*) *userdata;
#if defined(Q_OS_WIN)
if (device == NULL)
return DC_STATUS_INVALIDARGS;
// TODO use WSAIoctl to get the information
- return 0;
+ *available = 0;
#else
if (device == NULL || device->socket == NULL)
return DC_STATUS_INVALIDARGS;
- return device->socket->bytesAvailable();
+ *available = device->socket->bytesAvailable();
#endif
+
+ return DC_STATUS_SUCCESS;
}
-static int qt_serial_get_transmitted(serial_t *device)
+static int qt_serial_get_transmitted(qt_serial_t *device)
{
#if defined(Q_OS_WIN)
if (device == NULL)
@@ -359,8 +363,10 @@ static int qt_serial_get_transmitted(serial_t *device)
#endif
}
-static int qt_serial_set_timeout(serial_t *device, long timeout)
+static dc_status_t qt_serial_set_timeout(void **userdata, long timeout)
{
+ qt_serial_t *device = (qt_serial_t*) *userdata;
+
if (device == NULL)
return DC_STATUS_INVALIDARGS;
@@ -369,48 +375,27 @@ static int qt_serial_set_timeout(serial_t *device, long timeout)
return DC_STATUS_SUCCESS;
}
-
-const dc_serial_operations_t qt_serial_ops = {
+dc_custom_serial_t qt_serial_ops = {
+ .userdata = NULL,
.open = qt_serial_open,
.close = qt_serial_close,
.read = qt_serial_read,
.write = qt_serial_write,
- .flush = qt_serial_flush,
- .get_received = qt_serial_get_received,
- .get_transmitted = qt_serial_get_transmitted,
- .set_timeout = qt_serial_set_timeout
+ .purge = qt_serial_flush,
+ .get_available = qt_serial_get_received,
+ .set_timeout = qt_serial_set_timeout,
+// These doesn't make sense over bluetooth
+// NULL means NOP
+ .configure = NULL,
+ .set_dtr = NULL,
+ .set_rts = NULL,
+ .set_halfduplex = NULL,
+ .set_break = NULL
};
-extern void dc_serial_init (dc_serial_t *serial, void *data, const dc_serial_operations_t *ops);
-
-dc_status_t dc_serial_qt_open(dc_serial_t **out, dc_context_t *context, const char *devaddr)
-{
- if (out == NULL)
- return DC_STATUS_INVALIDARGS;
-
- // Allocate memory.
- dc_serial_t *serial_device = (dc_serial_t *) malloc (sizeof (dc_serial_t));
-
- if (serial_device == NULL) {
- return DC_STATUS_NOMEMORY;
- }
-
- // Initialize data and function pointers
- dc_serial_init(serial_device, NULL, &qt_serial_ops);
-
- // Open the serial device.
- dc_status_t rc = (dc_status_t)qt_serial_open (&serial_device->port, context, devaddr);
- if (rc != DC_STATUS_SUCCESS) {
- free (serial_device);
- return rc;
- }
-
- // Set the type of the device
- serial_device->type = DC_TRANSPORT_BLUETOOTH;
-
- *out = serial_device;
-
- return DC_STATUS_SUCCESS;
+dc_custom_serial_t* get_qt_serial_ops() {
+ return (dc_custom_serial_t*) &qt_serial_ops;
}
+
}
#endif