Skip to content

Commit

Permalink
Use SSRF_CUSTOM_IO v2 to implement device data quirks for BLE GATT
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
torvalds committed Jun 27, 2017
1 parent d01b7bf commit 5265956
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
25 changes: 21 additions & 4 deletions core/qt-ble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,24 @@ 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()
{
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);
Expand All @@ -103,14 +110,17 @@ 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;
}

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();
Expand All @@ -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);
Expand Down Expand Up @@ -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();

Expand All @@ -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";
Expand Down
3 changes: 2 additions & 1 deletion core/qt-ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -32,6 +32,7 @@ public slots:
QLowEnergyController *controller = nullptr;
QList<QByteArray> receivedPackets;
QEventLoop waitForPacket;
dc_user_device_t *device;
};


Expand Down

0 comments on commit 5265956

Please sign in to comment.