繁体   English   中英

如何从bluez5 dbus api访问sdp?

[英]How to access sdp from bluez5 dbus api?

我正在尝试将 pybluez 移植到 bluez5,但我不知道如何检索有关服务的数据。

我可以通过从 org.bluez.Device1 dbus 接口检索 UUIDs 属性来获取设备通告的 UUID,但我无法检索有关此服务的更多信息(例如名称)。 从我的角度来看,这个信息应该可以从 ServiceData 属性中获得,但这个字段确实显示为空。

出于测试目的,我正在 d-feet 应用程序中尝试所有这些。

编辑:我认为我想要做的是从 bluez dbus api 访问 sdp

如果您查看Core Specification Supplement 10,它没有详细说明如何为服务数据构造数据。

在此处输入图片说明

服务数据字段很少使用,并且当它是特定于该服务的数据时,因此很难有一个通用工具以有意义的方式呈现该数据。

使用有意义的名称呈现 UUID 的一种典型方法是在工具中进行一些查找。 例如,BlueZ 将此信息用于其工具(如 bluetoothctl)来查找 UUID 的名称: https : //github.com/bluez/bluez/blob/e0ea1c9c0d72fd4ee8a182098b23a3f859d81d35/src/shared/util.c#L153

作为 Python 代码中的示例:

from time import sleep
import pydbus

BLUEZ_SERVICE = 'org.bluez'
BLUEZ_DEVICE = 'org.bluez.Device1'
BLUEZ_SRVC = 'org.bluez.GattService1'
BLUEZ_CHAR = 'org.bluez.GattCharacteristic1'
DEVICE_ADDRESS = 'C6:F9:D5:8C:D5:3C'
UUID_NAMES = {
    '00001800-0000-1000-8000-00805f9b34fb': "Generic Access Profile",
    '00001801-0000-1000-8000-00805f9b34fb': "Generic Attribute Profile",
    '0000180a-0000-1000-8000-00805f9b34fb': "Device Information",
    'e95d6100-251d-470a-a062-fa1922dfa9a8': "MicroBit Temperature Service",
    'e95d93af-251d-470a-a062-fa1922dfa9a8': "MicroBit Event Service",
    'e95d93b0-251d-470a-a062-fa1922dfa9a8': "MicroBit DFU Control Service",
    'e95d9882-251d-470a-a062-fa1922dfa9a8': "MicroBit Button Service",
    'e95dda90-251d-470a-a062-fa1922dfa9a8': "MicroBit Button A State",
    'e95dda91-251d-470a-a062-fa1922dfa9a8': "MicroBit Button B State",
}

bus = pydbus.SystemBus()
mngr = bus.get(BLUEZ_SERVICE, '/')


def get_device_path(address):
    for path, ifaces in mngr.GetManagedObjects().items():
        if ifaces.get(BLUEZ_DEVICE, {}).get('Address') == address.upper():
            return path
    return None


def get_device_gatt_char(device_address):
    gatt_info = dict()
    dev_path = get_device_path(device_address)
    mngd_objs = mngr.GetManagedObjects()
    for path in mngd_objs:
        ifaces = mngd_objs[path]
        if path.startswith(dev_path) and BLUEZ_CHAR in ifaces:
            owning_srv = ifaces.get(BLUEZ_CHAR, {}).get('Service')
            srv_uuid = mngd_objs[owning_srv][BLUEZ_SRVC]['UUID']
            char_uuid = ifaces.get(BLUEZ_CHAR, {}).get('UUID')
            try:
                gatt_info[srv_uuid].append(char_uuid)
            except KeyError:
                gatt_info[srv_uuid] = [char_uuid]
    return gatt_info


def print_gatt_info(gatt_info):
    for gatt_srv in gatt_info:
        print(f'\n{UUID_NAMES.get(gatt_srv, gatt_srv)}')
        for gatt_chrc in gatt_info[gatt_srv]:
            print(f'\t{UUID_NAMES.get(gatt_chrc, gatt_chrc)}')


if __name__ == '__main__':
    # Create dbus bindings for Bluetooth device
    device = bus.get(BLUEZ_SERVICE, get_device_path(DEVICE_ADDRESS))
    # Connect to device
    device.Connect()
    # Wait for services to be resolved
    while not device.ServicesResolved:
        sleep(0.5)
    # Print out device properties
    for dev_prop, prop_value in device.GetAll(BLUEZ_DEVICE).items():
        if dev_prop == 'UUIDs':
            print(f'\t{dev_prop:<20}:')
            for uuid in prop_value:
                print(f'\t{" "*22}{UUID_NAMES.get(uuid, uuid)}')
        else:
            print(f'\t{dev_prop:<20}: {prop_value}')
    # Build GATT info of BLE device
    gatt_data = get_device_gatt_char(DEVICE_ADDRESS)
    print_gatt_info(gatt_data)
    # Disconnect from device
    device.Disconnect()

对于我的设备,它给出了以下输出:

Address             : C6:F9:D5:8C:D5:3C
    AddressType         : random
    Name                : BBC micro:bit [pivep]
    Alias               : BBC micro:bit [pivep]
    Appearance          : 512
    Paired              : False
    Trusted             : False
    Blocked             : False
    LegacyPairing       : False
    Connected           : True
    UUIDs               :
                          Generic Access Profile
                          Generic Attribute Profile
                          Device Information
                          MicroBit Temperature Service
                          MicroBit Event Service
                          MicroBit DFU Control Service
                          MicroBit Button Service
                          e97dd91d-251d-470a-a062-fa1922dfa9a8
    Adapter             : /org/bluez/hci0
    ServicesResolved    : True

MicroBit Button Service
    MicroBit Button B State
    MicroBit Button A State

MicroBit Temperature Service
    e95d1b25-251d-470a-a062-fa1922dfa9a8
    e95d9250-251d-470a-a062-fa1922dfa9a8

MicroBit Event Service
    e95db84c-251d-470a-a062-fa1922dfa9a8
    e95d23c4-251d-470a-a062-fa1922dfa9a8
    e95d5404-251d-470a-a062-fa1922dfa9a8
    e95d9775-251d-470a-a062-fa1922dfa9a8

Device Information
    00002a26-0000-1000-8000-00805f9b34fb
    00002a25-0000-1000-8000-00805f9b34fb
    00002a24-0000-1000-8000-00805f9b34fb

e97dd91d-251d-470a-a062-fa1922dfa9a8
    e97d3b10-251d-470a-a062-fa1922dfa9a8

MicroBit DFU Control Service
    e95d93b1-251d-470a-a062-fa1922dfa9a8

Generic Attribute Profile
    00002a05-0000-1000-8000-00805f9b34fb

Generic Access Profile
    00002a04-0000-1000-8000-00805f9b34fb
    00002a01-0000-1000-8000-00805f9b34fb
    00002a00-0000-1000-8000-00805f9b34fb

设备发现是使用StartDiscovery方法通过适配器 API 完成的,该方法记录在: https : StartDiscovery

当发现新设备时,它将在 GLib 事件循环运行时触发InterfacesAdded DBus 信号。 这些信号可以触发回调。 例如:

import pydbus
from gi.repository import GLib

BUS_NAME = 'org.bluez'
ROOT = '/'
ADAPTER = '/org/bluez/hci0'
DEV_IFACE = 'org.bluez.Device1'
bus = pydbus.SystemBus()
mainloop = GLib.MainLoop()

mngr = bus.get(BUS_NAME, ROOT)
dongle = bus.get(BUS_NAME, ADAPTER)


def stop_discovery():
    print('Discovery stopped.')
    dongle.StopDiscovery()
    mainloop.quit()


def interface_added_handler(dbus_path, interfaces):
    if DEV_IFACE in interfaces:
        print('Device found')
        addr = interfaces[DEV_IFACE].get('Address')
        name = interfaces[DEV_IFACE].get('Name', addr)
        print(f'\tNew device found! Address:{addr}  Name:{name}')


mngr.onInterfacesAdded = interface_added_handler

dongle.StartDiscovery()
GLib.timeout_add_seconds(15, stop_discovery)
try:
    print('Starting discovery...')
    mainloop.run()
    print('Exiting...')
except KeyboardInterrupt:
    mainloop.quit()

这只会发现新设备。 如果您想监视现有设备上的更改,那么它将是设备上的PropertiesChanged DBus 信号。

BlueZ 源中还有一个发现示例: https : //git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/test-discovery

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM