尝试在 dbus-next 中为 Bluez LEAdvertisement1 接口创建对象

问题描述

我对 DBUS 和 BlueZ 非常陌生。我一直在遵循几个指南,直到我需要创建一个 LEAdvertisement1 接口并将其注册到 LEAdvertisingManager1。

我一直在阅读 LEAdvertisement1 的 BlueZ 文档:

Service     org.bluez
Interface   org.bluez.LEAdvertisement1
Object path freely definable

我不确定可自由定义的对象路径是什么意思。我试图遵循 BlueZ 示例(使用 dbus-next 而不是 python),但是当我运行 Registeradvertisement 时,我一直遇到错误“org.bluez.Error.Failed”。该错误没有提供任何有用的信息,因此为了排除故障,我运行了 dbus 监视器。

sudo dbus-monitor --system "destination='org.bluez'" "sender='org.bluez'"

在监视器中,我收到以下错误

method call time=1622421524.320548 sender=:1.18 -> destination=org.freedesktop.DBus serial=71 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender=':1.37',path='/org/bluez/example/advertisement0',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.bluez.LEAdvertisement1'"
method return time=1622421524.320650 sender=org.freedesktop.DBus -> destination=:1.18 serial=35 reply_serial=71
method call time=1622421524.322726 sender=:1.18 -> destination=org.freedesktop.DBus serial=72 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=StartServiceByName
   string ":1.37"
   uint32 0
error time=1622421524.322852 sender=org.freedesktop.DBus -> destination=:1.18 error_name=org.freedesktop.DBus.Error.ServiceUnkNown reply_serial=72
   string "The name :1.37 was not provided by any .service files" 

接口类:

const LE_ADVERTISEMENT_IFACE = 'org.bluez.LEAdvertisement1';
const PATH_BASE = '/org/bluez/example/advertisement';

export class BLEAdvertisementInterface extends dbus.interface.Interface {
    adType: string = "peripheral";
    serviceUuids: Array<any> = [];
    manufacturerData: any; //none
    solicitUuids: Array<any> = []; //none
    serviceData: any; //none
    localName: string = "Testing";
    includeTxPower: boolean = false;
    data: any; //none

    constructor() {
        super(LE_ADVERTISEMENT_IFACE);
        this.serviceUuids = [uuidv4()];
    }

    @method({ inSignature: "s",outSignature: "a{sv}" })
    GetAll(): Variant {
        console.log("This does not run due to service unkNown error");
        let includes = [];
        if(this.includeTxPower) includes.push("tx-power");
        const allProperties = {
            LocalName: new Variant("s",this.localName),ServiceUUIDs: new Variant("as",this.serviceUuids),Includes: new Variant("as",includes),Type: new Variant("s",this.adType)
        };
        return new Variant("a{sv}",allProperties);
    }

    @method({ inSignature: "",outSignature: "" })
    Release() {
        console.log("released!");
    }
}

适配器代码(不确定是否需要 requestName):

let advertisement = new BLEAdvertisementInterface();
this.getAdvertisingManager().Registeradvertisement("/org/bluez/example/advertisement0",{}).then((result: any) => {
  console.log(result)
},(err: any) => {
  console.log(err);
});

我不确定我错过了什么。我尝试了多种方法,例如 requestName 和 export。以及检查system.d下的安全设置。我觉得我需要在 Linux (raspbian) 中进行一些配置才能使其正常工作,但我不确定在哪里。任何人都可以为我找出下一步的任何帮助将不胜感激。大多数在线指南似乎掩盖了这一步并引用了一个库。可悲的是,他们都在 python 中。

BlueZ 文档:https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/advertising-api.txt

BlueZ 示例:https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-advertisement

dbus-next:https://github.com/dbusjs/node-dbus-next

谢谢

解决方法

要使用 DBus API 在 BlueZ 中创建广告,需要做两件事。第一个是您使用接口 org.bluez.LEAdvertisement1 创建 DBus 服务,第二个是使用 RegisterAdvertisement 告诉 BlueZ 该服务的位置。

从您在问题中发布的错误消息来看,BlueZ 似乎找不到位于 /org/bluez/example/advertisement0 的服务。

我对 node-js 的经验很少,但是可以快速浏览 node-dbus-next 的文档,看来您需要

bus.export('/org/bluez/example/advertisement0',advertisement)

发布您定义的 DBus 服务。

在命令行上,如果您执行 busctl list,即使您不执行 RegisterAdvertisement 的第二步,您也应该能够看到出现了新服务。该服务将有一个唯一的名称(即 :x.xxx)而不使用请求名称。由于安全设置,您将无法使用该服务做太多事情,但它会证明您正在发布某些内容。 下一步是向 BlueZ 注册服务。如果广告的格式不是 BlueZ 所期望的,那么在那个阶段您很可能会看到 Failed to parse advertisement 错误。