Update to new libdivecomputer version

Jef has changed the libdivecomputer iostream layer and extended it in
two different ways:

 - iostram's now have a 'poll()' method, which does what the name
   implies: waits for data to be available with a timeout.

 - iostreams now have a 'ioctl()' method, which can be used to implement
   miscellaneous operations. Right now the two ones that you can do are
   "set latency" (this replaces the old 'set_latency()' method) and "get
   BLE name" (this replaces our 'get_name()' method that was never part
   of the upstream libdivecomputer interfaces)

Neither of these is all that complicated, and the transition is fairly
obvious.

HOWEVER.

I have absolutely no idea how to do 'poll()' on Windows sockets, and I
have no intention of figuring it out.  We use a direct socket interface
to implement the (non-BLE) RFCOMM bluetooth serial protocol, and I'm not
sure why Windows is so special here.  I suspect - but cannot test - that
we should just switch the Windows RFCOMM implementation over to the use
the same QtBluetooth code that we use on other platforms.

I assume that the Windows Bluetooth support was originally not
sufficiently good for that, but these days we depend on Qt doing BLE for
us even on Windows, so presumably FRCOMM works too.

That would be a nice cleanup, and would make 'poll()' work on RFCOMM
under Windows too.  However, since I can't test it, I've not done that,
but instead just made the Windows RFCOMM 'poll()' method always return
success.  That may or may not get the thing limping along.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2020-01-26 12:42:57 -08:00 committed by Dirk Hohndel
parent 5b81997459
commit 9543f53150
4 changed files with 75 additions and 11 deletions

View file

@ -14,6 +14,7 @@
#include <QLoggingCategory>
#include <libdivecomputer/version.h>
#include <libdivecomputer/ble.h>
#include "libdivecomputer.h"
#include "core/qt-ble.h"
@ -198,10 +199,8 @@ dc_status_t BLEObject::write(const void *data, size_t size, size_t *actual)
return DC_STATUS_IO;
}
dc_status_t BLEObject::read(void *data, size_t size, size_t *actual)
dc_status_t BLEObject::poll(int timeout)
{
if (actual)
*actual = 0;
if (receivedPackets.isEmpty()) {
QList<QLowEnergyCharacteristic> list = preferredService()->characteristics();
if (list.isEmpty())
@ -215,6 +214,21 @@ dc_status_t BLEObject::read(void *data, size_t size, size_t *actual)
return DC_STATUS_TIMEOUT;
}
return DC_STATUS_SUCCESS;
}
dc_status_t BLEObject::read(void *data, size_t size, size_t *actual)
{
dc_status_t rc;
if (actual)
*actual = 0;
// Wait for a packet
rc = poll(timeout);
if (rc != DC_STATUS_SUCCESS)
return rc;
QByteArray packet = receivedPackets.takeFirst();
// Did we get more than asked for?
@ -549,10 +563,24 @@ dc_status_t qt_ble_write(void *io, const void* data, size_t size, size_t *actual
return ble->write(data, size, actual);
}
const char *qt_ble_get_name(void *io)
dc_status_t qt_ble_poll(void *io, int timeout)
{
BLEObject *ble = (BLEObject *) io;
return ble->get_name();
return ble->poll(timeout);
}
dc_status_t qt_ble_ioctl(void *io, unsigned int request, void *data, size_t size)
{
BLEObject *ble = (BLEObject *) io;
switch (request) {
case DC_IOCTL_BLE_GET_NAME:
return ble->get_name((char *) data, size);
default:
return DC_STATUS_UNSUPPORTED;
}
}
} /* extern "C" */

View file

@ -23,7 +23,13 @@ public:
inline void set_timeout(int value) { timeout = value; }
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);
inline const char *get_name() { return device->btname; }
inline 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);
inline QLowEnergyService *preferredService() { return preferred; }
inline int descriptorWritten() { return desc_written; }
@ -61,10 +67,11 @@ private:
extern "C" {
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_set_timeout(void *io, int timeout);
dc_status_t qt_ble_poll(void *io, int timeout);
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_ioctl(void *io, unsigned int request, void *data, size_t size);
dc_status_t qt_ble_close(void *io);
const char *qt_ble_get_name(void *io);
}
#endif

View file

@ -12,6 +12,7 @@
#include <libdivecomputer/version.h>
#include <libdivecomputer/context.h>
#include <libdivecomputer/custom.h>
#include <libdivecomputer/serial.h>
#if defined(Q_OS_WIN)
#include <winsock2.h>
@ -302,6 +303,33 @@ static dc_status_t qt_serial_write(void *io, const void* data, size_t size, size
return DC_STATUS_SUCCESS;
}
static dc_status_t qt_serial_poll(void *io, int timeout)
{
qt_serial_t *device = (qt_serial_t*) io;
if (!device)
return DC_STATUS_INVALIDARGS;
#if defined(Q_OS_WIN)
// FIXME FIXME FIXME!! But how ?
// I have no idea about windows socket programming - Linus
// We'll just pretend it's always readable, and hope for the best
// Why is the windows side not using QBluetoothSocket?
return DC_STATUS_SUCCESS;
#else
if (!device->socket)
return DC_STATUS_INVALIDARGS;
if (device->socket->waitForReadyRead(timeout))
return DC_STATUS_SUCCESS;
return DC_STATUS_TIMEOUT;
#endif
}
static dc_status_t qt_serial_ioctl(void *io, unsigned int request, void *data, size_t size)
{
return DC_STATUS_UNSUPPORTED;
}
static dc_status_t qt_serial_purge(void *io, dc_direction_t)
{
qt_serial_t *device = (qt_serial_t*) io;
@ -385,20 +413,20 @@ ble_packet_open(dc_iostream_t **iostream, dc_context_t *context, const char* dev
static const dc_custom_cbs_t callbacks = {
qt_ble_set_timeout, /* set_timeout */
NULL, /* set_latency */
NULL, /* set_break */
NULL, /* set_dtr */
NULL, /* set_rts */
NULL, /* get_lines */
NULL, /* get_received */
NULL, /* configure */
qt_ble_poll, /* poll */
qt_ble_read, /* read */
qt_ble_write, /* write */
qt_ble_ioctl, /* ioctl */
NULL, /* flush */
NULL, /* purge */
qt_custom_sleep, /* sleep */
qt_ble_close, /* close */
qt_ble_get_name, /* get_name */
};
rc = qt_ble_open(&io, context, devaddr, (dc_user_device_t *) userdata);
@ -419,15 +447,16 @@ rfcomm_stream_open(dc_iostream_t **iostream, dc_context_t *context, const char*
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_poll, /* poll */
qt_serial_read, /* read */
qt_serial_write, /* write */
qt_serial_ioctl, /* ioctl */
NULL, /* flush */
qt_serial_purge, /* purge */
qt_custom_sleep, /* sleep */

@ -1 +1 @@
Subproject commit 4eb34b1466e7dff3ee2c0dfbeeef3642c2166d8c
Subproject commit f2f775b9aaec76abf9a534b9385dfd2d5fe5058d