Как добавить запись SDP в MacOS с помощью Python?

Моя текущая цель — добавить запись SDP в службу Bluetooth, работающую на MacBook Pro, чтобы я мог рекламировать эту службу другим устройствам Bluetooth. В идеале я хотел бы выполнить эту задачу на Python.

На данный момент я успешно создал, добавил и рекламировал запись SDP в Linux в стеке BlueZ Bluetooth, однако у меня возникли некоторые проблемы с тем, чтобы аналогичный процесс работал на MacOS.

После небольшого исследования я понял, что взаимодействие с Bluetooth API в MacOS предполагает использование IOBluetooth Среда Objective-C, которую можно реализовать в Python с помощью pyobjc. С другой стороны, я также понимаю, что инфраструктура CoreBluetooth существует, однако функциональность этой инфраструктуры не подходит, поскольку в ней отсутствуют функции добавления/удаления записей SDP.

В настоящее время я решаю две проблемы:

<сильный>1. Создание подходящей для MacOS записи SDP

MacOS использует формат PLIST для загрузки/указания записей SDP. У меня есть существующая запись в формате XML, которую может загрузить BlueZ. Можно ли преобразовать эту запись в формат PLIST, или мне следует переписать запись с нуля?

<сильный>2. Добавление записи SDP через pyobjc

Я могу взаимодействовать/запрашивать базовые функции Bluetooth через pyobjc/IOBluetooth. Проблема возникает, когда я пытаюсь использовать класс IOBluetoothSDPServiceRecord. Из некоторых примеров, которые я видел в другом месте (один пример op">здесь), кажется, именно этот класс вы бы использовали для добавления новой записи? Когда я пытаюсь загрузить/использовать этот класс, я не могу получить доступ ни к одной из его функций.

Заранее извиняюсь, если тем, кто знаком с Objective-C, это покажется тривиальной или любительской проблемой! Python — это то, в чем заключается мой опыт, поэтому взаимодействие с этим языком немного выходит за рамки моей рулевой рубки.

Я также приведу минимальный рабочий пример того, над чем я работал ниже:

IOBluetooth.py

import objc as _objc

_objc.loadBundle('IOBluetooth', globals(),\
  bundle_path=u'/System/Library/Frameworks/IOBluetooth.framework')

bluetooth_test.py

from IOBluetooth import *


sdp = None
with open("record.plist", "r") as f:
    sdp = f.read()

# This functions correctly
devs = IOBluetoothDevice.recentDevices_(0)
print(devs[0].getNameOrAddress())

# This does not
sdp_sr = IOBluetoothSDPServiceRecord.alloc().init()
sdp_sr.publishedServiceRecord(sdp)

Вывод bluetooth_test.py

Apple Watch
Traceback (most recent call last):
  File "bluetooth_test.py", line 12, in <module>
    sdp_sr.publishedServiceRecord(sdp)
AttributeError: 'IOBluetoothSDPServiceRecord' object has no attribute 'publishedServiceRecord'

Любой вклад в это будет высоко оценен!


person Brikwerk    schedule 24.10.2020    source источник


Ответы (1)


Поработав над этим еще немного, я смог найти ответ. Для тех, кто работает над чем-то подобным, я опубликую, как я это решил:

Ответ на вопрос 1

Немного поискав, я решил, что лучше вручную переписать существующую запись XML SDP. Я не смог найти никакой утилиты, которая обрабатывала бы преобразование 16-битных UUID Bluetooth из формата XML в формат PLIST.

Ответ на вопрос 2

Приведенный выше файл IOBluetooth.py не изменился по сравнению с моим вопросом.

bluetooth_test.py

from IOBluetooth import *
from Cocoa import NSDictionary
import time


plist = NSDictionary.dictionaryWithContentsOfFile_("service.plist")
sdp_sr = IOBluetoothSDPServiceRecord.publishedServiceRecordWithDictionary_(plist)

time.sleep(10)

sdp_sr.removeServiceRecord()
print("Removed Service Record")

Что действительно помогло в изучении IOBluetooth API, так это использование функции dir() в Python. На самом деле вы можете добавить к нему экземпляр или класс pyobjc, и вы получите список всех доступных методов.

Надеюсь, это поможет кому-то в будущем!

person Brikwerk    schedule 25.10.2020