簡體   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