0

我一直在使用复制、粘贴和魔法通过 Python DBU 注册蓝牙代理,hci0这对hci1. 我尝试选择控制器并将其设置为默认设置bluetoothctl和其他侧通道。

有人可以告诉我代理与控制器关联的位置吗?这一切都太神奇了。我也无法使用 D-Feet 找到代理或上面的任何内容 - 请问我应该或可以如何找到它?

一个愚蠢的玩具示例如下:


import dbus
import dbus.service

AGENT_PATH = "/org/bluez/anAgent"

class Agent(dbus.service.Object):
  
    @dbus.service.method(AGENT_INTERFACE,
                    in_signature="os", out_signature="")
    def AuthorizeService(self, device, uuid):
      print("Some stuff and things")
      
if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    bus = dbus.SystemBus()

    capability = "DisplayYesNo"

    agent = Agent(bus, AGENT_PATH)

    obj = bus.get_object("org.bluez", "/org/bluez")

    # Create the agent manager
    manager = dbus.Interface(obj, "org.bluez.AgentManager1")
    manager.RegisterAgent(AGENT_PATH, capability)
    manager.RequestDefaultAgent(AGENT_PATH)

4

1 回答 1

0

当蓝牙需要代理时,它会查看 D-Bus 对象路径上的org.bluez.AgentManager1接口,以查找/org/bluez已注册代理的位置。org.bluez.Agent1然后它在该注册对象路径的接口上调用相关方法(/org/bluez/anAgent在您的示例中)。需要为org.bluez.Agent1接口实现的方法记录在: https ://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/agent-api.txt

无论系统上有多少适配器,都只有一个代理。

问题可能是正在配对的设备与“错误”的适配器相关联吗?

设备 API具有Adapter跟踪设备所属适配器的对象路径的属性。

要查找您创建的代理,使用busctl. Usingbusctl list将列出所有可用的SystemBus服务。由于您没有为代理声明总线名称,因此它将是匿名的,因此格式为:x.xxx. 这可能是一个很长的列表,所以busctl list | grep python我通常会这样做来缩小列表范围。

要反省那里有什么,您可以执行以下操作:

$ busctl introspect :1.174 /org/bluez/anAgent

测试已发布的代理服务:

$ busctl call :1.174 /org/bluez/anAgent org.bluez.Agent1 AuthorizeService os /org/bluez/hci1/dev_12_34_56_78 1234

该服务需要是异步的,因此您需要启动MainLoop事件循环。

pydbus下面是使用D-Bus 绑定创建代理的完整示例。

唯一提到适配器的地方是开始发现的指令。如果您有另一台设备尝试使用代理发现您的设备,那么它将取决于可发现哪个适配器和/或其他设备尝试连接。

import threading
import pydbus
from gi.repository import GLib

BUS_NAME = 'org.bluez'
AGENT_IFACE = 'org.bluez.Agent1'
AGNT_MNGR_IFACE = 'org.bluez.AgentManager1'
ADAPTER_IFACE = 'org.bluez.Adapter1'
AGENT_PATH = '/org/bluez/anAgent'
AGNT_MNGR_PATH = '/org/bluez'
DEVICE_IFACE = 'org.bluez.Device1'
CAPABILITY = 'KeyboardDisplay'
bus = pydbus.SystemBus()


class Agent:
    """
    <node>
        <interface name="org.bluez.Agent1">
            <method name="Release" />
            <method name="RequestPinCode">
                <arg name="device" direction="in" type="o" />
                <arg name="pincode" direction="out" type="s" />
            </method>
            <method name="DisplayPinCode">
                <arg name="device" direction="in" type="o" />
                <arg name="pincode" direction="in" type="s" />
            </method>
            <method name="RequestPasskey">
                <arg name="device" direction="in" type="o" />
                <arg name="passkey" direction="out" type="u" />
            </method>
            <method name="DisplayPasskey">
                <arg name="device" direction="in" type="o" />
                <arg name="passkey" direction="in" type="u" />
                <arg name="entered" direction="in" type="q" />
            </method>
            <method name="RequestConfirmation">
                <arg name="device" direction="in" type="o" />
                <arg name="passkey" direction="in" type="u" />
            </method>
            <method name="RequestAuthorization">
              <arg name="device" direction="in" type="o" />
            </method>
            <method name="AuthorizeService">
                <arg name="device" direction="in" type="o" />
                <arg name="uuid" direction="in" type="s" />
            </method>
            <method name="Cancel" />
        </interface>
    </node>
    """

    def Release(self):
        print('Release')

    def RequestPinCode(self, device):
        print('RequestPinCode', device)
        return '1234'

    def DisplayPinCode(self, device, pincode):
        print('DisplayPinCode', device, pincode)

    def RequestPasskey(self, device):
        print('RequestPasskey', device)
        return 1234

    def DisplayPasskey(self, device, passkey, entered):
        print('DisplayPasskey', device, passkey, entered)

    def RequestConfirmation(self, device, passkey):
        print('RequestConfirmation', device, passkey)

    def RequestAuthorization(self, device):
        print('RequestAuthorization', device)

    def AuthorizeService(self, device, uuid):
        print('AuthorizeService', device, uuid)

    def Cancel(self):
        return


def pair_reply(*args):
    print('reply', args)


def pair_error(*args):
    print('error', args)


def dbus_path_up(dbus_obj):
    return '/'.join(dbus_obj.split('/')[:-1])


def device_found(dbus_obj, properties):
    adapter = bus.get(BUS_NAME, dbus_path_up(dbus_obj))
    device = bus.get(BUS_NAME, dbus_obj)
    print('Stopping discovery')
    adapter.StopDiscovery()
    if device.Paired:
        device.Connect()
    else:
        print('Pairing procedure starting...')
        device.Pair()


def interface_added(path, ifaces):
    if DEVICE_IFACE in ifaces.keys():
        dev_name = ifaces[DEVICE_IFACE].get('Name')
        print('Device found:', dev_name)
        if dev_name == 'HC-06':
            device_found(path, ifaces[DEVICE_IFACE])


def publish_agent():
    bus.register_object(AGENT_PATH, Agent(), None)
    aloop = GLib.MainLoop()
    aloop.run()
    print('Agent Registered')


def create_agent():
    thread = threading.Thread(target=publish_agent, daemon=True)
    thread.start()
    print('Agent running...')


def my_app(hci_idx=0):
    adapter_path = f'/org/bluez/hci{hci_idx}'
    mngr = bus.get(BUS_NAME, '/')
    mngr.onInterfacesAdded = interface_added

    create_agent()
    agnt_mngr = bus.get(BUS_NAME, AGNT_MNGR_PATH)[AGNT_MNGR_IFACE]
    agnt_mngr.RegisterAgent(AGENT_PATH, CAPABILITY)
    print('Agent registered...')
    adapter = bus.get(BUS_NAME, adapter_path)
    # adapter.StartDiscovery()
    mainloop = GLib.MainLoop()
    try:
        mainloop.run()
    except KeyboardInterrupt:
        mainloop.quit()
        adapter.StopDiscovery()


if __name__ == '__main__':
    my_app()
于 2022-01-29T13:44:55.260 回答