[英]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.