利用Bluez的协议栈和工具集实现ibeacon

了解完ibeacon的理论知识之后,现在我们利用linux下的蓝牙官方协议栈Bluez和它提供的工具集来实现Ibeacon。因为我用的不是苹果的手机,我们最后用微信摇一摇来检测ibeacon。周围没有ibeacon设备的时候,微信摇一摇是没有“周边”这个选项的,当检测到ibeacon设备时,摇一摇之后就会出现“周边”这一项,点进去会出现商家配置的页面。而之所以选用PC 上的Linux和Bluez协议栈来实现是因为对我们试验性质来讲他们足够简便,你需要的硬件设备是一台Linux的PC(我用的是Ubuntu的虚拟机),以及一个蓝牙适配器(蓝牙dongle),蓝牙适配器十几块于淘宝上购得。软件上你不需要写代码,因为Bluez已经帮你集成了一套的工具集,你只要使用相应指令就可以。

第一步:插入蓝牙dongle(要支持蓝牙4.0以上的),直到Linux下看到蓝牙设备的图标

第二部:在命令行下输入 hciconfig  检查输出的结果

 

如果是这样显示“DOWN”表示适配器还未启动,需要输入 hciconfig hci0 up 来启动该适配器。直到出现下图

 

接下来使用Bluez的工具 hcitool,输入以下指令:

sudo hcitool -i hci0 cmd 0x08 0x0008 1e 02 01 06 1a ff 4c 00 02 15 fd a5 06 93 a4 e2 4f b1 af cf c6 eb 07 64 78 25 29 11 30 39 cd 00 这里hcitool cmd是Bluez提供的操作蓝牙HCI层的指令,-i hci0是指定使用哪个适配器,0x08是OGF指令、这里指BLE而不是BE/EDR的操作,0x0008是OCF指令、这里是指设置广播数据,后面1e之后到最后00之前的部分正是我们前面讲的ibeacon广播的数据。这里有个小坑注意,1e后面必须跟31个字节的数据,不够的补 00(因为BLE广播数据的长度是31),而1e(30)指的是有效数据的长度,ibeacon的数据长度是30所以这里是1e。更多的hcitool 和hciconfig命令的信息可以在网上搜索,关于OGF OCF指令以及蓝牙HCI层操作的方法可以参见蓝牙核心协议。(BLE操作的部分在core 5.0协议的7.8)

之后在输入 sudo hcitool -i hci0 cmd 0x08 0x000a 01 这里的0x000a是蓝牙广播使能的指令,写入01是开启,写入00是关闭。输入之后的结果如下;

 

到这里ibeacon的配置已经全部完成了! 

---------------------------------------------------------------------------------------

bluepy移植到imx6ul平台使用

参考

1、https://github.com/IanHarvey/bluepy 使用此目录下的bluepy

2、先编译bluepy/bluepy/目录下bluepy-helper.c生成bluepy-helper可执行文件,(注意拷贝后修改权限)。

3、修改setup.py注释掉编译部分。
def pre_install():
    """Do the custom compiling of the bluepy-helper executable from the makefile"""
    try:
        print("Working dir is " + os.getcwd())
        with open("bluepy/version.h","w") as verfile:
            verfile.write('#define VERSION_STRING "%s"\n' % VERSION)
        #for cmd in [ "make -C ./bluepy clean", "make -C bluepy -j1" ]:
        #    print("execute " + cmd)
         #   msgs = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT)
         
4、在此目录下执行python  setup.py install安装。

 

5、执行sacn.py

#!/usr/bin/env python
# coding=utf-8

from bluepy.btle import Scanner, DefaultDelegate

class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)

def handleDiscovery(self, dev, isNewDev, isNewData):
if isNewDev:
print("Discovered device", dev.addr)
elif isNewData:
print("Received new data from", dev.addr)

scanner = Scanner().withDelegate(ScanDelegate())
devices = scanner.scan(10.0)

for dev in devices:
print("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi))
for (adtype, desc, value) in dev.getScanData():
print(" %s = %s" % (desc, value))

 执行后结果

Device 30:ae:a4:01:fc:cd (public), RSSI=-88 dB
Flags = 06
Manufacturer = 4c000215fb349b5f80000080001000003cfe00005476c315b5
Device 0e:47:12:60:6d:56 (random), RSSI=-82 dB
Manufacturer = 0600010920021efad22b113b21b848d90b05042e89d0f9bd4764b73e3d
Device 20:32:33:b0:3d:cd (public), RSSI=-18 dB
Flags = 1a
Manufacturer = 4c000215e2c56db5dffb48d2b060d0f5a71096e000000000c5
Device 1f:23:89:ff:fe:2d (random), RSSI=-76 dB
Manufacturer = 06000109200266b0094e72fd0134827c97faffc640dd4e29c8f1167b46
Device 19:4f:56:c7:8e:f0 (random), RSSI=-84 dB
Manufacturer = 060001092002020552f7867429bfd4ad4c96820a086825614fd0cb5deb
Device ac:bc:32:92:46:64 (public), RSSI=-66 dB