簡體   English   中英

如何使用Qt在D-Bus上創建/實例化配對代理

[英]How to create / instantiate pairing agent on D-Bus with Qt

我正在嘗試構建Qt應用程序以在Linux設備上配對/連接藍牙設備。 我在BlueZ官方網站( http://www.django.com/ )上通過D-Bus使用BlueZ API( https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc。 bluez.org/page/8/ )。

此處描述了一般過程: https : //www.kynetics.com/docs/2018/pairing_agents_bluez/

目前,我可以使用API​​配對/連接設備而不會出現問題。

但是我不知道如何使用配對代理。

我試圖遵循此處指出的方向: 如何在linux C / C ++中設置藍牙針腳號

QDBusAbstractAdaptor對象不導出已實現的dbus接口

我在網上搜索了很多,有很多代碼:

https://github.com/sdemario/qt-bluez-demos

https://github.com/KDE/bluez-qt

https://android.googlesource.com/platform/external/bluetooth/bluez/+/froyo-release/test/agent.c

https://github.com/pauloborges/bluez/blob/master/client/agent.c

https://www.linumiz.com/bluetooth-connectdevice-without-scanning/

但是,我仍然不明白它是如何工作的。 python中也有很多腳本,但是我正在使用C ++。

我的(偽)代碼如下:

agentManager = new QDBusInterface("org.bluez","/org/bluez","org.bluez.AgentManager1",QDBusConnection::systemBus(),this);
agent = new QDBusInterface("org.bluez","/org/bluez/agent","org.bluez.Agent1",QDBusConnection::systemBus(),this);


QDBusReply<void> reply;

reply = agentManager->call("RegisterAgent", QVariant::fromValue(QDBusObjectPath(path)), capability);
if (!reply.isValid()) {
    qDebug() << reply.error().message() << reply.error().name();
}

reply = agentManager->call("RequestDefaultAgent", QVariant::fromValue(QDBusObjectPath(path)));
if (!reply.isValid()) {
    qDebug() << reply.error().message() << reply.error().name();
}

QDBusReply<QString> reply_str = agent->call("RequestPinCode", QVariant::fromValue(QDBusObjectPath(path)));
if (reply_str.isValid()) {
    pincode = reply_str.value();
} else {
    qDebug() << reply_str.error().message() << reply.error().name();
}

“ RegisterAgent”和“ RequestDefaultAgent”調用給出有效的答復,而“ RequestPinCode”給出錯誤:

接口“ org.bluez.Agent1”上具有簽名“ o”的“方法” RequestPinCode”不存在“”“ org.freedesktop.DBus.Error.UnknownObject”

為什么? 我做錯了什么?

謝謝

編輯

我在D-Bus上實現了一項全新的服務,該服務實現了org.bluez.Agent1接口(其中的一部分)。 現在,代碼如下所示:

MyObject* myObject = new MyObject();
MyAdaptor* myAdaptor = new MyQDusAdaptor(myObject);

if (QDBusConnection::systemBus().registerService("org.test")) {
    qDebug() << "registerService was Succesfull!";
} else {
    qDebug() << "registerService was not Succesfull!";
}

if(QDBusConnection::systemBus().registerObject("/pairing/agent",myObject)){
    qDebug() << "registerObject was Succesfull!";
} else {
    qDebug() << "registerObject was not Succesfull!";
}

agentManager->RegisterAgent(QDBusObjectPath("/pairing/agent"),"NoInputNoOutput");
agentManager->RequestDefaultAgent(QDBusObjectPath("/pairing/agent"));


MyObject在哪里


class MyObject : public QObject
{
    Q_OBJECT

public:
    MyObject();

public Q_SLOTS:
    QString RequestPinCode(const QDBusObjectPath &in0);
};


MyObject::MyObject() {

}
QString MyObject::RequestPinCode(const QDBusObjectPath& in0)
{
    qDebug() << "MyObject" << in0.path();


    QString str = "2974";
    return str;
}


而適配器是


class MyQDusAdaptor: public QDBusAbstractAdaptor
{

    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "org.bluez.Agent1")
    Q_CLASSINFO("D-Bus Introspection", ""
                                                                         "  <interface name=\"org.bluez.Agent1\">\n"
                                                                         "    <method name=\"RequestPinCode\">\n"
                                                                         "      <arg direction=\"in\" type=\"o\"/>\n"
                                                                         "      <arg direction=\"out\" type=\"s\"/>\n"
                                                                         "    </method>\n"
                                                                         "  </interface>\n"
                                                                         "")

public:
        MyQDusAdaptor(QObject *parent);
        virtual ~MyQDusAdaptor();

public: // PROPERTIES
public Q_SLOTS: // METHODS
        QString RequestPinCode(const QDBusObjectPath &in0);
};


MyQDusAdaptor::MyQDusAdaptor(QObject* parent) : QDBusAbstractAdaptor(parent) {

    setAutoRelaySignals(true);
}

MyQDusAdaptor::~MyQDusAdaptor() {

}

QString MyQDusAdaptor::RequestPinCode(const QDBusObjectPath& in0)
{
    qDebug() << "MyQDusAdaptor" << in0.path();

    QString out0;
         QMetaObject::invokeMethod(parent(), "RequestPinCode", Q_RETURN_ARG(QString, out0), Q_ARG(QDBusObjectPath, in0));
         return out0;
}

當我嘗試配對智能手機時,該應用程序凍結約30秒鍾,我收到以下錯誤消息:

“未收到答復。可能的原因包括:遠程應用程序未發送答復,消息總線安全策略阻止了答復,答復超時到期或網絡連接斷開。” “ org.freedesktop.DBus.Error.NoReply”

並且只有在此之后,智能手機才會要求插入PIN碼。

我認為必須異步完成。 有小費嗎?

好的,現在可以了。 QDBusAbstractAdaptor對象中解釋的方法不導出已實現的dbus接口

實現的詳細信息在此問題的最后一個EDIT中。 最后要做的是使用callWithCallback異步在Device1接口上實現“對”方法:

void cBluetoothDevice::Pair() {

    QList<QVariant> args;
    args.clear();

    device->callWithCallback("Pair",args, this, SLOT(PairSlot(QDBusMessage)));
}

其中設備是QDBusInterface *

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM