[英]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.