BLE(蓝牙低功耗)中如何有2个广告? [英] How to have 2 advertisements in BLE(BlueTooth Low Energy)?
问题描述
我正在研究BLE广告.我想知道BLE中是否有2个广告.我需要服务数据和制造商数据.我正在使用Python.该代码基于 https://git .kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-advertisement . 我需要支持EddyStone Beacon和一些制造商数据.但是我不知道如何实现它. 谢谢.
要制作多个广告,关键项是每个广告都必须使用其发布的唯一D-Bus对象路径来创建./p>
在BlueZ示例中,他们通过具有PATH_BASE
并将index
值附加到该值以使其唯一来完成此操作:
class Advertisement(dbus.service.Object):
PATH_BASE = '/org/bluez/example/advertisement'
def __init__(self, bus, index, advertising_type):
self.path = self.PATH_BASE + str(index)
self.bus = bus
self.ad_type = advertising_type
self.service_uuids = None
self.manufacturer_data = None
self.solicit_uuids = None
self.service_data = None
self.local_name = None
self.include_tx_power = False
self.data = None
dbus.service.Object.__init__(self, bus, self.path)
然后他们在调用RegisterAdvertisement
时使用此唯一路径:
ad_manager.RegisterAdvertisement(test_advertisement.get_path(), {},
reply_handler=register_ad_cb,
error_handler=register_ad_error_cb)
为了制作出可以运行的东西,我修改了BlueZ示例. 这些修改的重点是使某些内容以最小的更改运行,而不是我在生产中这样做的方式.
首先,我将TestAdvertisement
更改为做不同的广告,具体取决于是使用索引0
还是索引1
调用
class TestAdvertisement(Advertisement):
def __init__(self, bus, index):
Advertisement.__init__(self, bus, index, 'broadcast')
self.add_service_uuid('FEAA')
frame_type = [0x10] # Frame Type = 0x10
power = [0x00] # Power = 0x00
if index == 0:
prefix = [0x02] # URL scheme = 0x02 (http://)
url = [0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x07]
elif index == 1:
prefix = [0x01] # URL scheme = https://www.
url = [0x62, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68, 0x00]
eddystone_data = frame_type + power + prefix + url
self.add_service_data('FEAA', eddystone_data)
然后我修改了TestAdvertisement
的调用位置,因此它被调用了两次,一次是用index=0
,一次是用index=1
:
ad_manager = dbus.Interface(bus.get_object(BLUEZ_SERVICE_NAME, adapter),
LE_ADVERTISING_MANAGER_IFACE)
mainloop = GLib.MainLoop()
test_advertisement= []
for ad_id in range(2):
test_advertisement.append(TestAdvertisement(bus=bus, index=ad_id))
print(f'{ad_id}: Registering advert path: {test_advertisement[ad_id].get_path()}')
ad_manager.RegisterAdvertisement(test_advertisement[ad_id].get_path(), {},
reply_handler=register_ad_cb,
error_handler=register_ad_error_cb)
if timeout > 0:
threading.Thread(target=shutdown, args=(timeout,)).start()
else:
print('Advertising forever...')
try:
mainloop.run() # blocks until mainloop.quit() is called
except KeyboardInterrupt:
print('Cleaning up advertisements')
for this_ad in test_advertisement:
ad_manager.UnregisterAdvertisement(this_ad)
print('Advertisement unregistered')
dbus.service.Object.remove_from_connection(this_ad)
我还修改了代码,以注销这两个广告,最后进行清理.
该示例应显示两个具有不同URL的Eddystone URL信标.
I'm working on BLE advertisement. I'd like to know if it's possible to have 2 advertisements in BLE. I need to have both service data and manufacturer data. I'm using Python. The code is based on https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-advertisement. I need to support EddyStone Beacon and some manufacturer data. But I don't know how to implement it. Thanks.
The key item when wanting to do multiple advertisements, is that each advertisement must be created with its own unique D-Bus object path that it is published on.
In the BlueZ example they do this by having a PATH_BASE
and appending the index
value to it to make it unique:
class Advertisement(dbus.service.Object):
PATH_BASE = '/org/bluez/example/advertisement'
def __init__(self, bus, index, advertising_type):
self.path = self.PATH_BASE + str(index)
self.bus = bus
self.ad_type = advertising_type
self.service_uuids = None
self.manufacturer_data = None
self.solicit_uuids = None
self.service_data = None
self.local_name = None
self.include_tx_power = False
self.data = None
dbus.service.Object.__init__(self, bus, self.path)
They then use this unique path when calling RegisterAdvertisement
:
ad_manager.RegisterAdvertisement(test_advertisement.get_path(), {},
reply_handler=register_ad_cb,
error_handler=register_ad_error_cb)
To make something that ran, I modified the BlueZ example. These modifications focused on getting something to run with minimal changes rather than this is how I would do it in production.
First, I changed the TestAdvertisement
to do a different advertisement depending if it was called with index 0
or index 1
:
class TestAdvertisement(Advertisement):
def __init__(self, bus, index):
Advertisement.__init__(self, bus, index, 'broadcast')
self.add_service_uuid('FEAA')
frame_type = [0x10] # Frame Type = 0x10
power = [0x00] # Power = 0x00
if index == 0:
prefix = [0x02] # URL scheme = 0x02 (http://)
url = [0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x07]
elif index == 1:
prefix = [0x01] # URL scheme = https://www.
url = [0x62, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68, 0x00]
eddystone_data = frame_type + power + prefix + url
self.add_service_data('FEAA', eddystone_data)
I then modified where TestAdvertisement
was called so it was called twice, once with index=0
and once with index=1
:
ad_manager = dbus.Interface(bus.get_object(BLUEZ_SERVICE_NAME, adapter),
LE_ADVERTISING_MANAGER_IFACE)
mainloop = GLib.MainLoop()
test_advertisement= []
for ad_id in range(2):
test_advertisement.append(TestAdvertisement(bus=bus, index=ad_id))
print(f'{ad_id}: Registering advert path: {test_advertisement[ad_id].get_path()}')
ad_manager.RegisterAdvertisement(test_advertisement[ad_id].get_path(), {},
reply_handler=register_ad_cb,
error_handler=register_ad_error_cb)
if timeout > 0:
threading.Thread(target=shutdown, args=(timeout,)).start()
else:
print('Advertising forever...')
try:
mainloop.run() # blocks until mainloop.quit() is called
except KeyboardInterrupt:
print('Cleaning up advertisements')
for this_ad in test_advertisement:
ad_manager.UnregisterAdvertisement(this_ad)
print('Advertisement unregistered')
dbus.service.Object.remove_from_connection(this_ad)
I also modified the code to unregister both advertisements to clean up at the end.
The example should show two Eddystone URL beacons with different URL's.
这篇关于BLE(蓝牙低功耗)中如何有2个广告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!