Can't get notifications from BLE device working.
-
Hello.
I have a problem with receiving notifications from BLE device. I'm developing an app which is supposed to receive data from weight scale UC-352BLE. Here is my code:
#include "bletest.h" #include "ui_bletest.h" #include <QtEndian> Bletest::Bletest(QWidget *parent) : QMainWindow(parent) , ui(new Ui::Bletest) { ui->setupUi(this); if (localDevice.isValid()) { localDevice.powerOn(); localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable); connect(&localDevice, &QBluetoothLocalDevice::deviceConnected, this, &Bletest::deviceConnected); connect(&localDevice, &QBluetoothLocalDevice::deviceDisconnected, this, &Bletest::deviceDisconnected); connect(&localDevice, &QBluetoothLocalDevice::pairingFinished, this, &Bletest::pairingFinished); } discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &Bletest::addDevice); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &Bletest::scanFinished); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &Bletest::scanFinished); discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); } Bletest::~Bletest() { delete ui; } // Local device slots void Bletest::deviceConnected(const QBluetoothAddress &address) { qDebug() << address.toString() << " connected"; } void Bletest::deviceDisconnected(const QBluetoothAddress &address) { qDebug() << address.toString() << " disconnected"; } void Bletest::pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing) { } // Agent slots void Bletest::addDevice(const QBluetoothDeviceInfo &device) { if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) { if (device.name().contains("352")) { bleDevice = device; qDebug() << "Found: " + device.name() + "\t" + device.address().toString(); } } } void Bletest::scanFinished() { qDebug() << "Devices scan finished"; } /////////// void Bletest::on_connectButton_clicked() { controller = QLowEnergyController::createCentral(bleDevice, this); connect(controller, &QLowEnergyController::serviceDiscovered, this, &Bletest::serviceDiscovered); connect(controller, &QLowEnergyController::discoveryFinished, this, &Bletest::serviceScanFinished); connect(controller, static_cast<void (QLowEnergyController::*)(QLowEnergyController::Error)>(&QLowEnergyController::error), this, [this](QLowEnergyController::Error error) { qDebug() << "Cannot connect to device: " + QString::number(error); }); connect(controller, &QLowEnergyController::connected, this, [this]() { qDebug() << "Connected to device"; controller->discoverServices(); }); connect(controller, &QLowEnergyController::disconnected, this, [this]() { qDebug() << "Disconnected"; }); controller->connectToDevice(); } // Controller slots void Bletest::serviceDiscovered(const QBluetoothUuid &gatt) { qDebug() << "Service discovered: " << gatt.toString(); if (gatt.toString().contains("0000181d-0000-1000-8000-00805f9b34fb")) { service = controller->createServiceObject(QBluetoothUuid(QBluetoothUuid::WeightScale)); if (service) { qDebug() << "Found weight scale service"; connect(service, &QLowEnergyService::stateChanged, this, &Bletest::serviceStateChanged); connect(service, &QLowEnergyService::characteristicChanged, this, &Bletest::updateWeight); connect(service, &QLowEnergyService::characteristicRead, this, &Bletest::updateWeight); connect(service, &QLowEnergyService::descriptorWritten, this, &Bletest::descriptorWritten); service->discoverDetails(); } } } void Bletest::serviceScanFinished() { qDebug() << "Service scan finished"; } //////////////////////////// // Service slots void Bletest::serviceStateChanged(QLowEnergyService::ServiceState newState) { if (controller->state() == QLowEnergyController::UnconnectedState) return; if (newState == QLowEnergyService::DiscoveringServices) { qDebug() << "Discovering services state"; } else if (QLowEnergyService::ServiceDiscovered) { qDebug() << "Service discovered."; const QLowEnergyCharacteristic weightChar = service->characteristic(QBluetoothUuid(QBluetoothUuid::WeightMeasurement)); if (!weightChar.isValid()) { qDebug() << "Weight data not found"; return; } qDebug() << "Weight data found"; //service->readCharacteristic(weightChar); desc = weightChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); if (desc.isValid()) { qDebug() << "Writing descriptor"; service->writeDescriptor(desc, QByteArray::fromHex("0100")); } } } void Bletest::updateWeight(const QLowEnergyCharacteristic &c, const QByteArray &value) { qDebug() << "Updating weight"; if (c.uuid() != QBluetoothUuid(QBluetoothUuid::WeightMeasurement)) return; double weight = qFromLittleEndian<qint16>(value.mid(1, 2).data()) * RESOLUTION; qDebug() << "New weight: " << value.mid(1, 2); qDebug() << "New weight: " + QString::number(weight, 'f', 2); } void Bletest::descriptorWritten(const QLowEnergyDescriptor &info, const QByteArray &value) { qDebug() << "Descriptor written: " << info.name() << ", value: " << (int) *value.data(); }
As I understand it, to get notifications when the scale sends a measurement I need to set the ClientCharacteristicConfiguration descriptor to 1. I do so at first connection and pairing and I receive in descriptorWritten slot that descriptor has been written and it's value is 1. But what am I supposed to do next? After pairing and initial connect the device disconnects with my app and then when I take a measurement, the scale is sending it but nothing happens in my app. Don't even get any system notifications in bluetooth manager that something is trying to connect. Can anyone help me with this?
Thanks.