使用 QT/C++ 中的 DBUS 连接到新的 Bluez HDP 插件;

发布于 2024-10-17 07:33:39 字数 1859 浏览 1 评论 0原文

我正在尝试使用蓝牙健康设备配置文件(特别是 Nonin Onyx II 9560BT)从设备获取读数。使用这个指南,我已经能够做到所以使用python而不是dbus。现在我正在尝试将其移植到 C++,并且由于我已经在应用程序中使用 QT,因此我正在使用 QT DBus 绑定。

到目前为止,我已经根据 这个 API 来测试它:

#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QStringList>
#include <QtDBus/QtDBus>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    if (!QDBusConnection::sessionBus().isConnected()) {
        fprintf(stderr, "Cannot connect to the D-Bus session bus.\n"
                "To start it, run:\n"
                "\teval `dbus-launch --auto-syntax`\n");
        return 1;
    }

    QDBusInterface iface("org.bluez","/org/bluez","org.bluez.HealthManager",QDBusConnection::systemBus(),0);

    QVariantMap map;
    map.insert("DataType",ushort(1004));//same result with simply 1004
    map.insert("Role","Sink");
    map.insert("Description","HDP Test Manager"); //Optional
    //map.insert("ChannelType","Reliable");//Optional, same result with or without
    //QList<QVariant> argumentList;
    //argumentList.append(map);

    QDBusPendingReply<> r = iface.call("CreateApplication",map);

    qDebug() << r.reply();
    qDebug() << r.error();
    return 0;
}

据我所知,“CreateApplication”获取的 dict 对象对应于 a{sv},在 QT 中对应于 QVariantMap 。 但是,我不断收到此错误:

QDBusMessage(type=Error, service="", error name="org.bluez.Error.InvalidArguments", error message="Invalid arguments in method call", signature="", contents=([]) )

问题:我做错了什么? 根据 freedesktop.org 上的指南、qt 文档和强大的谷歌,这是我所了解到的。

感谢您的任何/所有帮助!

/Keyz182

I'm attempting to get readings from a device using the bluetooth Health Device Profile (specifically, an Nonin Onyx II 9560BT). Using this guide, I've been able to do so using python over dbus. Now I'm trying to port it over to C++, and as I'm already using QT in the application, I'm using the QT DBus bindings.

So far I've gotten to the following short program based on this API to test it:

#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QStringList>
#include <QtDBus/QtDBus>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    if (!QDBusConnection::sessionBus().isConnected()) {
        fprintf(stderr, "Cannot connect to the D-Bus session bus.\n"
                "To start it, run:\n"
                "\teval `dbus-launch --auto-syntax`\n");
        return 1;
    }

    QDBusInterface iface("org.bluez","/org/bluez","org.bluez.HealthManager",QDBusConnection::systemBus(),0);

    QVariantMap map;
    map.insert("DataType",ushort(1004));//same result with simply 1004
    map.insert("Role","Sink");
    map.insert("Description","HDP Test Manager"); //Optional
    //map.insert("ChannelType","Reliable");//Optional, same result with or without
    //QList<QVariant> argumentList;
    //argumentList.append(map);

    QDBusPendingReply<> r = iface.call("CreateApplication",map);

    qDebug() << r.reply();
    qDebug() << r.error();
    return 0;
}

As far as I can tell, the dict object taken by "CreateApplication" corresponds to an a{sv} which in QT corresponds to the QVariantMap.
However, I keep getting this error:

QDBusMessage(type=Error, service="", error name="org.bluez.Error.InvalidArguments", error message="Invalid arguments in method call", signature="", contents=([]) )

Question: What am I doing wrong?
Based on the guides at freedesktop.org, the qt docs and the mighty google, this is as far as I've gotten.

Thanks for any/all help!

/Keyz182

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

逆夏时光 2024-10-24 07:33:39

现在可以了。看起来 ushort(0x1004) 被 QVariant 转换为 int,因此被 bluez 代码拾取为 uint32,这不是预期的。

为了解决这个问题,我做了以下操作(可能还有另一种方法,但这对我有用)。

我为 ushort 添加了元类型声明,然后注册了它。然后,创建一个包含该值的 QVariant,并使用 QVariants 转换方法将元类型设置为 ushort(或暴露于 dbus 时为 uint16)。

#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QStringList>
#include <QtDBus/QtDBus>

Q_DECLARE_METATYPE(ushort); //Added this to declare ushort as a metatype

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    int ushorttype = qDBusRegisterMetaType<ushort>(); //Register the ushort metatype and get it's id

    if (!QDBusConnection::sessionBus().isConnected()) {
        fprintf(stderr, "Cannot connect to the D-Bus session bus.\n"
                "To start it, run:\n"
                "\teval `dbus-launch --auto-syntax`\n");
        return 1;
    }

    QDBusInterface iface("org.bluez","/org/bluez","org.bluez.HealthManager",QDBusConnection::systemBus(),0);

    QVariant dt(0x1004);
    dt.convert((QVariant::Type)ushorttype); //convert to the new type

    QVariantMap map;
    map.insert("DataType",dt);
    map.insert("Role","Sink");
    map.insert("Description","HDP Test Manager"); //Optional

    QDBusPendingReply<> r = iface.call("CreateApplication",map);

    qDebug() << r.isValid();
    qDebug() << r.reply();
    return 0;
}

It works now. It seems that the ushort(0x1004) was getting cast by the QVariant to an int, and thus being picked up as a uint32 by the bluez code, which is not what was expected.

To fix it I did the following (there may be another way, but this worked for me).

I added a Metatype declaration for ushort, then registered it. then, created a QVariant containing the value, and used the QVariants convert method to set the metatype as a ushort (or uint16 when exposed to dbus).

#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QStringList>
#include <QtDBus/QtDBus>

Q_DECLARE_METATYPE(ushort); //Added this to declare ushort as a metatype

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    int ushorttype = qDBusRegisterMetaType<ushort>(); //Register the ushort metatype and get it's id

    if (!QDBusConnection::sessionBus().isConnected()) {
        fprintf(stderr, "Cannot connect to the D-Bus session bus.\n"
                "To start it, run:\n"
                "\teval `dbus-launch --auto-syntax`\n");
        return 1;
    }

    QDBusInterface iface("org.bluez","/org/bluez","org.bluez.HealthManager",QDBusConnection::systemBus(),0);

    QVariant dt(0x1004);
    dt.convert((QVariant::Type)ushorttype); //convert to the new type

    QVariantMap map;
    map.insert("DataType",dt);
    map.insert("Role","Sink");
    map.insert("Description","HDP Test Manager"); //Optional

    QDBusPendingReply<> r = iface.call("CreateApplication",map);

    qDebug() << r.isValid();
    qDebug() << r.reply();
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文