如何使用BlueZ和Python创建EddyStone Beacon?

问题描述

我正在开发嵌入式Linux板上的BLE(蓝牙低功耗)。我们使用BlueZ和Python。我需要创建EddyStone Beacon。我发现有一种创建iBeacon的方法https://scribles.net/creating-ibeacon-using-bluez-example-code-on-raspberry-pi/。我尝试过这个。有效。 但是我们需要创建EddyStone Beacon。因此,我使用此处(https://ukbaz.github.io/howto/beacon_scan_cmd_line.html)的信标数据格式来创建制造商数据。 但是我的代码不起作用。我的代码有什么问题?这是我的代码

def __init__(self,bus,index):
    eddystone_id = 0xAAFE
    beacon_type = [0x14,0x16]  # Length = 0x14,EddyStone type = 0x16
    uuid = [0xAA,0xFE] # EddyStone UUID = 0xAAFE
    frame_type = [0x10] # Frame Type = 0x10
    power = [0x00]      # Power = 0x00
    prefix = [0x02]     # URL scheme = 0x02 (http://)
    url = [0x73,0x61,0x6D,0x70,0x6C,0x65,0x77,0x62,0x73,0x69,0x74,0x07]

    Advertisement.__init__(self,index,'peripheral')
    self.add_manufacturer_data(eddystone_id,beacon_type + uuid + frame_type + power + prefix + url)
    

但是,如果我使用此命令,则会创建EddyStone Beacon。我可以看到它在nRF移动应用中显示了EddyStone Beacon:

sudo hcitool -i hci0 cmd 0x08 0x0008 1c 02 01 06 03 03 aa fe 14 16 aa fe 10 00 02 73 61 6d 70 6c 65 77 65 62 73 69 74 65 07 00 00 00

如您所见,我放入add_manufacturer_data()函数中的数据与命令中的数据相同。但是为什么Python代码不起作用?

解决方法

iBeacon使用manufacturer_data,而Eddystone beacon使用service_data,所以我希望您的代码看起来像这样:

    def __init__(self,bus,index):
        Advertisement.__init__(self,index,'broadcast')
        self.add_service_uuid('FEAA')
        frame_type = [0x10] # Eddystone frame Type = 0x10
        power = [0x00]      # Beacon broadcast power = 0x00
        prefix = [0x02]     # URL scheme = 0x02 (http://)
        url = [0x73,0x61,0x6D,0x70,0x6C,0x65,0x77,0x62,0x73,0x69,0x74,0x07]
        eddystone_data = frame_type + power + prefix + url
        self.add_service_data('FEAA',eddystone_data)

请注意,hcitool是BlueZ开发人员deprecated所使用的工具之一。当前支持从命令行创建Eddystone信标的方法是使用bluetoothctl。命令的顺序为:

bluetoothctl 
menu advertise
uuids 0xFEAA
service 0xFEAA 0x10 0x00 0x02 0x73 0x61 0x6D 0x70 0x6C 0x65 0x77 0x65 0x62 0x73 0x69 0x74 0x65 0x07
back
advertise broadcast
discoverable on

我将advertisement typeperipheral更改为broadcast,因为通常人们不希望信标可连接,但这取决于您的应用程序。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...