我正在尝试构建一个Qt应用程序,用于在Linux设备上配对/连接蓝牙设备。我正在使用BlueZ API(https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc)over D-Bus,如BlueZ官方网站(http://www.bluez.org/page/8/)中所述。
一般程序如下所述:
https://www.kynetics.com/docs/2018/pairing_agents_bluez/
目前,我可以使用api来配对/连接设备,没有问题。
但我不知道如何使用配对代理。
我正试着按照这里指出的方向走:
How can i set the bluetooth pin number in linux C/C++
QDBusAbstractAdaptor object does not export implemented dbus interface
我在网上搜索了很多代码:
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”则给出错误:
接口上“签名”“O”的“RequestPinCode”与签名“O”不存在
“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"));
我的目标在哪里
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”
只有在那之后智能手机才会要求插入一个密码。
我认为这必须异步完成。有什么建议吗?
最佳答案
好的,现在可以了。方法在QDBusAbstractAdaptor object does not export implemented dbus interface
实现的细节在这个问题的最后一次编辑中。最后一件事是使用callWithCallback异步地在设备1接口上实现“Pair”方法:
void cBluetoothDevice::Pair() {
QList<QVariant> args;
args.clear();
device->callWithCallback("Pair",args, this, SLOT(PairSlot(QDBusMessage)));
}
其中设备是QDBusInterface*
关于c++ - 如何使用Qt在D-Bus上创建/实例化配对代理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57872510/