diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-27 15:14:27 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-27 15:14:27 -0700 |
commit | 526595644fbef79aba53bc96f5e1507a13294805 (patch) | |
tree | 95180c8ccb8b15b8eb4ca0f1fcca2c969661ad66 | |
parent | d01b7bf89167ff8ab40c4b663398816da678084a (diff) | |
download | subsurface-526595644fbef79aba53bc96f5e1507a13294805.tar.gz |
Use SSRF_CUSTOM_IO v2 to implement device data quirks for BLE GATT
Right now we have a quirk for Shearwater devices to set the random
address flag, but also to handle the differences at read/write time.
With this, I can finally download from both the Suunto EON Steel and the
Shearwater Perdix AI with the same binary.
It's not *pretty*, but it works.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | core/qt-ble.cpp | 25 | ||||
-rw-r--r-- | core/qt-ble.h | 3 |
2 files changed, 23 insertions, 5 deletions
diff --git a/core/qt-ble.cpp b/core/qt-ble.cpp index 85dd0b1d1..246b59ee9 100644 --- a/core/qt-ble.cpp +++ b/core/qt-ble.cpp @@ -80,9 +80,10 @@ void BLEObject::addService(const QBluetoothUuid &newService) } } -BLEObject::BLEObject(QLowEnergyController *c) +BLEObject::BLEObject(QLowEnergyController *c, dc_user_device_t *d) { controller = c; + device = d; } BLEObject::~BLEObject() @@ -90,7 +91,13 @@ BLEObject::~BLEObject() qDebug() << "Deleting BLE object"; } -dc_status_t BLEObject::write(const void* data, size_t size, size_t *actual) +/* Yeah, I could do the C++ inline member thing */ +static int device_is_shearwater(dc_user_device_t *device) +{ + return !strcmp(device->vendor, "Shearwater"); +} + +dc_status_t BLEObject::write(const void *data, size_t size, size_t *actual) { QList<QLowEnergyCharacteristic> list = preferredService()->characteristics(); QByteArray bytes((const char *)data, (int) size); @@ -103,6 +110,9 @@ dc_status_t BLEObject::write(const void* data, size_t size, size_t *actual) QLowEnergyService::WriteWithoutResponse : QLowEnergyService::WriteWithResponse; + if (device_is_shearwater(device)) + bytes.prepend("\1\0", 2); + preferredService()->writeCharacteristic(c, bytes, mode); return DC_STATUS_SUCCESS; } @@ -110,7 +120,7 @@ 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::read(void *data, size_t size, size_t *actual) { if (receivedPackets.isEmpty()) { QList<QLowEnergyCharacteristic> list = preferredService()->characteristics(); @@ -133,6 +143,10 @@ dc_status_t BLEObject::read(void* data, size_t size, size_t *actual) return DC_STATUS_IO; QByteArray packet = receivedPackets.takeFirst(); + + if (device_is_shearwater(device)) + packet.remove(0,2); + if (size > packet.size()) size = packet.size(); memcpy(data, packet.data(), size); @@ -161,6 +175,9 @@ dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *d qDebug() << "qt_ble_open(" << devaddr << ")"; + if (device_is_shearwater(io->user_device)) + controller->setRemoteAddressType(QLowEnergyController::RandomAddress); + // Try to connect to the device controller->connectToDevice(); @@ -184,7 +201,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! */ - BLEObject *ble = new BLEObject(controller); + BLEObject *ble = new BLEObject(controller, io->user_device); ble->connect(controller, SIGNAL(serviceDiscovered(QBluetoothUuid)), SLOT(addService(QBluetoothUuid))); qDebug() << " .. discovering services"; diff --git a/core/qt-ble.h b/core/qt-ble.h index cd27423a4..247f7d64c 100644 --- a/core/qt-ble.h +++ b/core/qt-ble.h @@ -11,7 +11,7 @@ class BLEObject : public QObject Q_OBJECT public: - BLEObject(QLowEnergyController *c); + BLEObject(QLowEnergyController *c, dc_user_device_t *); ~BLEObject(); 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); @@ -32,6 +32,7 @@ private: QLowEnergyController *controller = nullptr; QList<QByteArray> receivedPackets; QEventLoop waitForPacket; + dc_user_device_t *device; }; |