How to have 2 advertisements in BLE(BlueTooth Low Energy)?

2024/10/10 12:17:14

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.

Answer

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 = busself.ad_type = advertising_typeself.service_uuids = Noneself.manufacturer_data = Noneself.solicit_uuids = Noneself.service_data = Noneself.local_name = Noneself.include_tx_power = Falseself.data = Nonedbus.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 = 0x10power = [0x00]      # Power = 0x00if 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 + urlself.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 calledexcept 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.

https://en.xdnf.cn/q/118456.html

Related Q&A

How to get Python script to write to existing sheet

I am writing a Python script and stuck on one of the early steps. I am opening an existing sheet and want to add two columns so I have used this:#import the writer import xlwt #import the reader impor…

Python3 - getting the sum of a particular row from all the files [closed]

Closed. This question needs debugging details. It is not currently accepting answers.Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to repro…

Selenium Headers in Python

how can I change my headers in Selenium like I do in requests ,I want to change my cookies and headers . from myCookie import cookie from selenium import webdriver from selenium.webdriver.common.by imp…

Get unique groups from a set of group

I am trying to find unique groups in a column(here for letter column) from an excel file. The data looks like this:id letter1 A, B, D, E, F3 B, C2 B75 T54 K, M9 D, B23 B, D, A34 X, Y, Z67 X, Y12 E, D15…

Move and Rename files using Python

I have .xls files in a directory that i need to move to another directory and renamed. Those files are updated monthly and will have a different name each month. For instance the current name is Geoc…

AttributeError: StringVar object has no attribute encode

Im making a program to generate an encrypted qr from the message and password provided, but it keeps on returning the same error.I tried passing the value to other variablesmain.pyfrom tkinter import *…

Reading specific column from a csv file in python

I am writing some python code to practice for an exam in January. I need to read the second column into my code and print it out. If possible i also need to add data to specific columns. The code i hav…

Date Time Series wise grouping of data and distribution

I am trying the merge the datetime series with a repository data while grouping by name and summing the values. File1.csv Timeseries,Name,count 07/03/2015 06:00:00,Paris,100 07/03/2015 06:00:00,Paris,6…

Trying to run Python in html

I am trying to run a python program in html but I am getting an error. First it says Then if I type anything it appears with this error This was the Html code <html><head><title>Antho…

Removing from a string all the characthers included between two specific characters in Python

Whats a fast way in Python to take all the characters included between two specific characters out of a string?