2017-06-25 05:00:52 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2017-06-13 02:47:50 +00:00
|
|
|
#ifndef QT_BLE_H
|
|
|
|
#define QT_BLE_H
|
|
|
|
|
2017-07-18 21:42:38 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
#include "core/libdivecomputer.h"
|
2017-06-27 12:56:30 +00:00
|
|
|
#include <QVector>
|
2017-06-13 02:47:50 +00:00
|
|
|
#include <QLowEnergyController>
|
|
|
|
#include <QEventLoop>
|
|
|
|
|
2022-01-29 15:47:56 +00:00
|
|
|
#define TELIT_DATA_RX 0
|
|
|
|
#define TELIT_DATA_TX 1
|
|
|
|
#define TELIT_CREDITS_RX 2
|
|
|
|
#define TELIT_CREDITS_TX 3
|
|
|
|
|
|
|
|
#define UBLOX_DATA_RX 0
|
|
|
|
#define UBLOX_DATA_TX 0
|
|
|
|
#define UBLOX_CREDITS_RX 1
|
|
|
|
#define UBLOX_CREDITS_TX 1
|
2017-07-03 17:24:39 +00:00
|
|
|
|
2017-06-13 02:47:50 +00:00
|
|
|
class BLEObject : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2024-05-02 19:26:22 +00:00
|
|
|
BLEObject(QLowEnergyController *c, device_data_t &);
|
2017-06-13 02:47:50 +00:00
|
|
|
~BLEObject();
|
2018-10-06 18:43:48 +00:00
|
|
|
inline void set_timeout(int value) { timeout = value; }
|
2017-06-13 02:47:50 +00:00
|
|
|
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);
|
2024-05-02 19:26:22 +00:00
|
|
|
dc_status_t get_name(char *res, size_t size);
|
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>
2020-01-26 20:42:57 +00:00
|
|
|
dc_status_t poll(int timeout);
|
2017-06-27 12:56:30 +00:00
|
|
|
|
2018-09-23 19:07:01 +00:00
|
|
|
inline QLowEnergyService *preferredService() { return preferred; }
|
2018-10-06 18:26:26 +00:00
|
|
|
inline int descriptorWritten() { return desc_written; }
|
2024-05-04 16:53:41 +00:00
|
|
|
dc_status_t select_preferred_service();
|
2017-06-13 02:47:50 +00:00
|
|
|
|
|
|
|
public slots:
|
|
|
|
void addService(const QBluetoothUuid &newService);
|
|
|
|
void serviceStateChanged(QLowEnergyService::ServiceState s);
|
|
|
|
void characteristcStateChanged(const QLowEnergyCharacteristic &c, const QByteArray &value);
|
2017-07-03 19:21:02 +00:00
|
|
|
void characteristicWritten(const QLowEnergyCharacteristic &c, const QByteArray &value);
|
2017-06-13 02:47:50 +00:00
|
|
|
void writeCompleted(const QLowEnergyDescriptor &d, const QByteArray &value);
|
2019-04-01 20:15:19 +00:00
|
|
|
dc_status_t setupHwTerminalIo(const QList<QLowEnergyCharacteristic> &allC);
|
2017-07-05 16:37:21 +00:00
|
|
|
dc_status_t setHwCredit(unsigned int c);
|
2017-06-13 02:47:50 +00:00
|
|
|
private:
|
2017-06-27 12:56:30 +00:00
|
|
|
QVector<QLowEnergyService *> services;
|
|
|
|
|
2024-05-02 19:26:22 +00:00
|
|
|
QLowEnergyController *controller;
|
2018-09-23 19:07:01 +00:00
|
|
|
QLowEnergyService *preferred = nullptr;
|
2017-06-13 02:47:50 +00:00
|
|
|
QList<QByteArray> receivedPackets;
|
2017-07-03 17:24:39 +00:00
|
|
|
bool isCharacteristicWritten;
|
2024-05-02 19:26:22 +00:00
|
|
|
device_data_t &device;
|
2017-07-05 16:37:21 +00:00
|
|
|
unsigned int hw_credit = 0;
|
2018-10-06 18:26:26 +00:00
|
|
|
unsigned int desc_written = 0;
|
2018-10-06 18:43:48 +00:00
|
|
|
int timeout;
|
2017-07-03 17:24:39 +00:00
|
|
|
|
2022-02-10 00:13:20 +00:00
|
|
|
QList<QBluetoothUuid> telit = {
|
|
|
|
QBluetoothUuid(QUuid("{00000001-0000-1000-8000-008025000000}")), // TELIT_DATA_RX
|
|
|
|
QBluetoothUuid(QUuid("{00000002-0000-1000-8000-008025000000}")), // TELIT_DATA_TX
|
|
|
|
QBluetoothUuid(QUuid("{00000003-0000-1000-8000-008025000000}")), // TELIT_CREDITS_RX
|
|
|
|
QBluetoothUuid(QUuid("{00000004-0000-1000-8000-008025000000}")) // TELIT_CREDITS_TX
|
2022-01-29 15:47:56 +00:00
|
|
|
};
|
|
|
|
|
2022-02-10 00:13:20 +00:00
|
|
|
QList<QBluetoothUuid> ublox = {
|
|
|
|
QBluetoothUuid(QUuid("{2456e1b9-26e2-8f83-e744-f34f01e9d703}")), // UBLOX_DATA_RX, UBLOX_DATA_TX
|
|
|
|
QBluetoothUuid(QUuid("{2456e1b9-26e2-8f83-e744-f34f01e9d704}")) // UBLOX_CREDITS_RX, UBLOX_CREDITS_TX
|
2017-07-03 17:24:39 +00:00
|
|
|
};
|
2017-06-13 02:47:50 +00:00
|
|
|
};
|
|
|
|
|
2020-10-19 16:42:43 +00:00
|
|
|
dc_status_t qt_ble_open(void **io, dc_context_t *context, const char *devaddr, device_data_t *user_device);
|
2018-10-06 18:43:48 +00:00
|
|
|
dc_status_t qt_ble_set_timeout(void *io, int timeout);
|
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>
2020-01-26 20:42:57 +00:00
|
|
|
dc_status_t qt_ble_poll(void *io, int timeout);
|
2018-04-17 01:14:59 +00:00
|
|
|
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);
|
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>
2020-01-26 20:42:57 +00:00
|
|
|
dc_status_t qt_ble_ioctl(void *io, unsigned int request, void *data, size_t size);
|
2018-04-17 01:14:59 +00:00
|
|
|
dc_status_t qt_ble_close(void *io);
|
2017-06-13 02:47:50 +00:00
|
|
|
|
|
|
|
#endif
|