当前位置: 首页 > 知识库问答 >
问题:

Qt-无法读取特征的描述符-BLE

孟子墨
2023-03-14

我在使用蓝牙低能Qt api读取特性时遇到问题。我正在使用的设备是Decawave DWM1001模块。我在遵循文档中的教程。我成功地连接到设备,读取并创建了它的服务。该设备具有UUID为680c21d9-c946-4c1f-9c11-baa1c21329e7的“网络节点服务”,我正在尝试从中读取特征。我调用QLowEnergyController::connectToDevice()方法,它找到服务,我为它创建一个QLowEnergyService对象,名为nodeService。

void BluetoothConnector::serviceDiscovered(const QBluetoothUuid &newService)
{
    qDebug() << "Service discovered: " << newService.toString();

    if (newService == QBluetoothUuid(nodeServiceUUID)) {
        nodeService = controller->createServiceObject(QBluetoothUuid(nodeServiceUUID), this);

        if (nodeService) {
            qDebug() << "Node service created";
            connect(nodeService, &QLowEnergyService::stateChanged, this, &BluetoothConnector::serviceStateChanged);
            connect(nodeService, &QLowEnergyService::characteristicChanged, this, &BluetoothConnector::updateCharacteristic);
            //connect(nodeService, &QLowEnergyService::descriptorWritten, this, &BLTest::confirmedDescriptorWrite);
            nodeService->discoverDetails();
        } else {
            qDebug() << "Node service not found.";
        }
    }
}

成功创建nodeService(我获得“创建的节点服务”日志),然后连接服务的信号和插槽,然后在nodeService上调用discoverDetails()。serviceStateChanged()插槽如下所示:

void BluetoothConnector::serviceStateChanged(QLowEnergyService::ServiceState newState)
{
    if (newState == QLowEnergyService::DiscoveringServices) {
        qDebug() << "Discovering services";

    } else if (newState == QLowEnergyService::ServiceDiscovered) {
        qDebug() << "Service discovered";

        const QLowEnergyCharacteristic networkIdChar = nodeService->characteristic(QBluetoothUuid(networkIdUUID));
        const QLowEnergyCharacteristic dataModeChar = nodeService->characteristic(QBluetoothUuid(dataModeUUID));
        const QLowEnergyCharacteristic locationChar = nodeService->characteristic(QBluetoothUuid(locationUUID));

        if (networkIdChar.isValid() && dataModeChar.isValid() && locationChar.isValid()) {
            auto idValue = networkIdChar.value();
            auto modeValue = dataModeChar.value();
            auto locValue = locationChar.value();

            qDebug() << "Network ID: " << idValue;
            qDebug() << "Mode: " << modeValue;
            qDebug() << "Location: " << locValue;

            auto notificationDesc = locationChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
            if (notificationDesc.isValid()) {
                qDebug() << "Notification desc valid";
                nodeService->writeDescriptor(notificationDesc, QByteArray::fromHex("0100"));
            }
        } else {
            qDebug() << "Characteristic invalid";
        }
    }
}

我得到了“发现服务”日志,之后应用程序会挂起一段时间,然后我得到:

"Cannot read descriptor (onDescReadFinished 3):  \"{00002902-0000-1000-8000-00805f9b34fb}\" \"{3f0afd88-7770-46b0-b5e7-9fc099598964}\" \"org.freedesktop.DBus.Error.NoReply\" \"Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.\""
"LowEnergy controller disconnected"
"Aborting onCharReadFinished due to disconnect"

它无法读取00002902-0000-1000-8000-00805f9b34fb,这是3f0afd88-7770-46b0-b5e7-9fc099598964特性的CCCD描述符(供应商特定)。无法找出问题所在以及为什么它无法从设备中读取特性。我需要做其他事情才能使其工作吗?

谢谢

---更新---

BluetoothConnector类:

#include "bluetoothconnector.h"

#include <QTimer>

BluetoothConnector::BluetoothConnector(QObject *parent) : QObject(parent)
{
    configureDiscoveryAgent();
}

void BluetoothConnector::scan()
{
    agent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
}

void BluetoothConnector::connectToDevice(QString &addr)
{
    auto it = std::find_if(devices.begin(), devices.end(),
                           [&] (const QBluetoothDeviceInfo& d) { return d.address().toString() == addr; });

    if (it == devices.end())
        return;

    device = *it;
    controller = QLowEnergyController::createCentral(device, this);
    connect(controller, &QLowEnergyController::serviceDiscovered, this, &BluetoothConnector::serviceDiscovered);
    connect(controller, &QLowEnergyController::discoveryFinished, this, &BluetoothConnector::serviceScanDone);
    connect(controller, static_cast<void (QLowEnergyController::*)(QLowEnergyController::Error)>(&QLowEnergyController::error),
            this, [this](QLowEnergyController::Error error) {
        Q_UNUSED(error);
        qDebug() << "Controller error: " << error;
        emit controllerError();
    });
    connect(controller, &QLowEnergyController::connected, this, [this]() {
        qDebug() << "Controller connected. Search services...";
        controller->discoverServices();
    });
    connect(controller, &QLowEnergyController::disconnected, this, [this]() {
        qDebug() << "LowEnergy controller disconnected";
    });
    controller->connectToDevice();
}

void BluetoothConnector::configureDiscoveryAgent()
{
    agent = new QBluetoothDeviceDiscoveryAgent(this);
    agent->setLowEnergyDiscoveryTimeout(5000);
    connect(agent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothConnector::addDevice);
    connect(agent, static_cast<void (QBluetoothDeviceDiscoveryAgent::*)(QBluetoothDeviceDiscoveryAgent::Error)>(&QBluetoothDeviceDiscoveryAgent::error),
            this, &BluetoothConnector::scanError);

    connect(agent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothConnector::scanFinished);
    connect(agent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &BluetoothConnector::scanFinished);
}

void BluetoothConnector::addDevice(const QBluetoothDeviceInfo &info)
{
    if (!devices.contains(info)) {
        qDebug() << "Found device: " << info.name();
        devices.append(info);
        emit deviceFound(info);
    }
}

void BluetoothConnector::scanError(QBluetoothDeviceDiscoveryAgent::Error error)
{
    qDebug() << "Scan error: " << error;
}

void BluetoothConnector::scanFinished()
{
    emit scanFinishedSignal();
}

void BluetoothConnector::serviceDiscovered(const QBluetoothUuid &newService)
{
    qDebug() << "Service discovered: " << newService.toString();

    if (newService == QBluetoothUuid(nodeServiceUUID)) {
        nodeService = controller->createServiceObject(QBluetoothUuid(nodeServiceUUID), this);
        qDebug() << "State: " << nodeService->state();

        if (nodeService) {
            qDebug() << "Node service created";
            connect(nodeService, &QLowEnergyService::stateChanged, this, &BluetoothConnector::serviceStateChanged);
            connect(nodeService, &QLowEnergyService::characteristicChanged, this, &BluetoothConnector::updateCharacteristic);
            connect(nodeService, &QLowEnergyService::characteristicWritten, this, &BluetoothConnector::characteristicWritten);
            connect(nodeService, QOverload<QLowEnergyService::ServiceError>::of(&QLowEnergyService::error),
                    [=](QLowEnergyService::ServiceError newError){ qDebug() << newError; });

            //connect(nodeService, &QLowEnergyService::descriptorWritten, this, &BLTest::confirmedDescriptorWrite);
            nodeService->discoverDetails();
        } else {
            qDebug() << "Node service not found.";
        }
    }
}

void BluetoothConnector::serviceScanDone()
{
    qDebug() << "Services scan done";
}

void BluetoothConnector::characteristicWritten(const QLowEnergyCharacteristic &info, const QByteArray &value)
{
    qDebug() << "Characteristic written: " << info.name();
}

void BluetoothConnector::serviceStateChanged(QLowEnergyService::ServiceState newState)
{
    qDebug() << "State changed: " << newState;

    if (newState == QLowEnergyService::ServiceDiscovered) {
        qDebug() << "Service discovered";

        const QLowEnergyCharacteristic networkIdChar = nodeService->characteristic(QBluetoothUuid(networkIdUUID));
        const QLowEnergyCharacteristic dataModeChar = nodeService->characteristic(QBluetoothUuid(dataModeUUID));
        const QLowEnergyCharacteristic locationChar = nodeService->characteristic(QBluetoothUuid(locationUUID));

        if (networkIdChar.isValid() && dataModeChar.isValid() && locationChar.isValid()) {
            auto idValue = networkIdChar.value();
            auto modeValue = dataModeChar.value();
            auto locValue = locationChar.value();

            qDebug() << "Network ID: " << idValue;
            qDebug() << "Mode: " << modeValue;
            qDebug() << "Location: " << locValue;

            auto notificationDesc = locationChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
            if (notificationDesc.isValid()) {
                qDebug() << "Notification desc valid";
                nodeService->writeDescriptor(notificationDesc, QByteArray::fromHex("0100"));
            }
        } else {
            qDebug() << "Characteristic invalid";
        }
    }
}

void BluetoothConnector::updateCharacteristic(const QLowEnergyCharacteristic &info, const QByteArray &value)
{
    if (info.uuid() == QBluetoothUuid(networkIdUUID)) {
        qDebug() << "Update ID: " << value;
    } else if (info.uuid() == QBluetoothUuid(dataModeUUID)) {
        qDebug() << "Update mode: " << value;
    } else if (info.uuid() == QBluetoothUuid(locationUUID)) {
        qDebug() << "Update location: " << value;
    }
}

共有1个答案

顾乐池
2023-03-14

我想,问题出在遥远的地方(你的关贸总协定服务器)。检查qloenergyservice::error()和qloenergyservice::characteristicwrited()信号,查看是否得到任何响应。您在远程使用哪种蓝牙协议栈?可能是,由于实施失败,您无权更改CCCD。请检查远程端的实现。

 类似资料:
  • 问题内容: 我的Maven POM文件遇到问题,无法找到火花依赖关系,并返回错误:无法读取org.apache.spark:spark-streaming- kafka_2.10:jar:1.2.1的工件描述符 我已经确认这对任何公司防火墙都不是问题,因为其他所有依赖项都已正确加载,仅此一项。 我还能够在我的Maven设置中确认它正在尝试从以下存储库中提取。我尝试删除本地计算机上的.m2存储库以重

  • 我还可以在我的maven设置中确认它正试图从以下回购中提取。我尝试删除本地机器上的.m2回购,以便重新加载它,但仍然没有骰子。 http://repo.maven.apache.org/maven2/org/apache/spark/spark-streaming-kafka2.10/1.2.1/ 下面是我的pom文件

  • @subpage tutorial_py_features_meaning_cn 图像中的主要特征是什么?如果找出对我们来说有用的特征? @subpage tutorial_py_features_harris_cn 好吧, 边角是好的特征。但我们该如何找到它们呢? @subpage tutorial_py_shi_tomasi_cn 我们将会研究Shi-Tomasi角点检测。 @subpage

  • 目标 在这一章中我们将学习 BRIEF 算法的基础知识 理论基础 SIFT^2算法使用 128 维的向量描述符。由于它使用的是浮点数,因此它至少需要 512 字节。相似地,SURF^3 算法也至少需要 256 字节(64 维)。创建这样一个数以千计的特征向量需要大量的内存,这对于一个资源有限的应用,尤其是嵌入式系统上的应用来说是不可接受的。而且所消耗的内存空间越多,匹配花费的时间也越长。 但是实际

  • 我正在使用最新的EclipseforJavaEE,并安装了JBoss工具,因此包含了Maven。我将一个现有的Maven项目导入到我的工作区,并尝试更新依赖项,但我只在POM中得到错误,即某些参数无效,并且无法传输任何工件。实际上有两种不同的错误,也许它们相互依赖?您可以检查:服务器可用,我还尝试重新安装Eclipse和JBoss。那么还缺少什么呢? 无法读取edu.kit.aifb.ai2.sq

  • 我对Java和OOP都是新手。但是,我使用notify读取一个特征,然后使用read读取回调中的多个特征。 我想知道,为什么在使用readCharacteristic(我的特征)时,只能从单个特征(除了通知的特征)中获取值。蓝牙gatt回调声明如下: 公共布尔值 (BluetoothGattCharacteristic characteristic characteristic)从相关远程设备读取