玩转BLE(2)_使用bluepy扫描BLE的广播数据

作者:wowo 发布于:2016-5-19 15:17 分类:蓝牙

1. 前言

在linux平台下,bluez是一个很不错的软件,提供了很多基于命令行的测试工具,如hciconfig、hcitool、hcidump、bluetoothctl等。利用这些工具,我们可以方便的测试、demo各种蓝牙功能。例如,在“玩转BLE(1)_Eddystone beacon”中,我们利用hcitool命令,演示了将手机变成一个Beacon设备的神奇效果。

Beacon的演示,从本质上看,是BLE Advertising(广播)功能的测试和验证。自然而然的,我们会好奇:怎么接收这些广播数据呢(其实就是BLE Scanning功能)?这就是本文要介绍的内容。

虽然hcitool(以及后来的bluetoothctl)可以进行简单的LE scan操作,但返回的结果仅包括简单的地址和名称,显然无法满足我们的需求(要知道,BLE的广播数据可能包含其它内容哦,如我们的Beacon演示)。怎么办呢?不着急,强大的python出马了。

2. bluepy[1]介绍

bluepy是linux平台中,用python脚本封装的BLE接口。为什么用python呢?说实话,在写这篇文章之前,我对python的印象是极其平淡的,但此时却好感大增。以蓝牙的测试为例:

在linux下,bluez提供的原生接口是一个C库(bluetooth lib),我们想利用这个接口,在命令行里面玩转一些功能,几乎不可能;

提供C库的同时,为了图形界面操作方便,bluez又封装出来了一层dbus API。虽然从理论上讲,使用dbus-send等命令,可以满足我们在命令行的测试需求。但是,我觉得没有人喜欢dbus-send后面带的那长长的一串参数……

在开源的世界里,有需求就有动力,因此就出现了很多有python封装的蓝牙API。以BLE为例,bluepy是一个比较好的一个。有了该接口之后,蓝牙功能的测试,真的是很爽!

3. bluepy安装

bluepy的安装非常简单,开始之前先交代一下我的测试环境:

硬件环境是树莓派2(大家随便用一个运行linux的PC、开发板应该都okay);

OS是raspbian(Ubuntu),版本应该不是很重要;

bluez的版本是5.23(比较新的一个版本了,不过旧版本应该也没有问题)。

安装bluepy只需要两个命令,如下:

#安装python的包管理工具—pip

sudo apt-get install python-pip libglib2.0-dev

#使用pip安装bluepy

sudo pip install bluepy

4. 使用bluepy

本章我们将使用bluepy的Scanner class,扫描正在广播的BLE设备。bluepy的文档中有sample code:
http://ianharvey.github.io/bluepy-doc/scanner.html
在本地新建一个python脚本(ble_scan.py),将sample code中的代码拷贝进去即可,如下:
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)

按照“玩转BLE(1)_Eddystone beacon”中的说明,将自己的手机变成一个Eddystone Beacon设备。然后执行python脚本,扫描:

sudo python ble_scan.py

结果如下:

pi@raspberrypi:~$ sudo python ble_scan.py
Discovered device cb:07:c8:52:ce:d6
Discovered device 18:dc:56:a6:25:6f
Device 18:dc:56:a6:25:6f (public), RSSI=-59 dB
  Flags = 06
  Complete 16b Services = aafe
  16b Service Data = aafe00f0000102030405060708090a0b0e0f000000
Device cb:07:c8:52:ce:d6 (random), RSSI=-85 dB
  Complete Local Name = My Mambo
  Complete 16b Services = e7fe
  Manufacturer = 0000cb07c852ced6
  128b Service Solicitation = d0002d121e4b0fa4994eceb531f40579
  Flags = 06

对比一下我们在“玩转BLE(1)_Eddystone beacon”中广播的数据(对应三个颜色):

1e 02 01 06 03 03 aa fe 17 16 aa fe 00 -10 00 01 02 03 04 05 06 07 08 09 0a 0b 0e 0f 00 00 00 00

成功了!

5. 总结

本文简单的介绍了利用bluepy功能,扫描BLE的广播包的过程。并没有对bluepy的软件逻辑,以及BLE Advertising的细节,做过多的说明,感兴趣的同学可以自行阅读,不理解的地方可以留言讨论。

另外,后续BLE Advertising & Scanning有关的分析文章中,会借助该工具,以帮助理解。

6. 参考文档

[1] bluepy github主页,https://github.com/IanHarvey/bluepy
 
原创文章,转发请注明出处。蜗窝科技,www.wowotech.net

标签: 蓝牙 Bluetooth BLE scan bluepy advertising

评论:

出手无招
2020-04-13 16:03
@wowo,大神,最近刚接触blueZ5.50的应用开发,有没有demo可以参考的,如何发广播包,收发数据,连接等
出手无招
2020-04-17 14:03
@出手无招:朋友们,hcitool -i hci0 cmd 如何发送指定类型和内容的广播数据
星辰
2019-06-27 20:30
wowo 你好,就是我已经吧我的手机变成了一个Eddystone beacon了 就是我已经可以在手机beacon
scanner上面可以扫描到一些蓝牙信息了  但是我运行那个python程序的时候扫描不到手机的beacon信息 为什么呀 
博主最帅
2018-01-28 16:25
博主我想问一下bluepy能不能控制树莓派发广播啊?我查了一遍他的代码,没有看到相关的类和方法,如果不能,有没有开源的工具可以让树莓派即能解析收到的广播又能发广播?给博主拜个早年啦哈哈~
wowo
2018-01-30 08:49
@博主最帅:你可以看看树莓派里面的协议栈是不是bluez,如果是,就可以用bluepy。
EE
2017-12-17 12:50
wowo,帮忙请问:BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]中,
On every two consecutive failures, the  upperLimit shall be doubled until it reaches
the value of 256.如何理解其中的 doubled,是1变2,2变4,4变8-----到256,如果我想知道有多少次我得算个等比数列这样才太费事了吧?还有就是every two consecutive failures,是指扫描监听广播失败算一次再加本次监听扫描回应算一次共两次,还是说两次扫描回应失败算两次?upperLimit可以设置吗, 这个参数有点难理解?
ah
2017-11-25 13:43
你好,《基于Android和Arduino的蓝牙考勤系统实现》这篇文章中的蓝牙基站是如何实现的?
EE
2017-12-17 12:52
@ah:哥哥,你当wowo是百科全书呀,wawa!
叶青
2016-11-09 15:11
你好,我想用蓝牙rssi做定位,通过测量不同距离上蓝牙模块的信号强度,拟合出信号与距离的曲线。但是看到一个文章上提到蓝牙底层在通信时会自动调整信号强度,从而影响计算结果,请问是这样吗?
wowo
2016-11-09 15:34
@叶青:从协议层面上看,是不会规定是否要调整TX power的。
当然,EDR的链路管理,提供了“请求对端设备改变发射功率”的功能,以便根据距离自适应TX power,以达到功耗和性能的平衡。
到BLE的时候,这个功能也不再提供了。当然,“底层”(具体到哪里才是底层,先存疑)如果觉得必要,确实可以调整TX power(是否动态也存疑),这和具体的实现有关。

回到你的问题上,我相信用RSSI做定位,应该是BLE吧?
不过是什么都没有关系,但有如下两点要求(或的关系):
1)要么,不能动态改变TX power(不然的话接收端会晕菜);
2)要么,改变可以,但发送的packet里面,应该包含TX power的信息。

回到定位这个场景里面,其实很多BLE beacon协议,广播包里面是包含了当前的TX power的,其实是考虑了这种场景。
叶青
2016-11-09 15:50
@wowo:嗯,多谢了,看来不能只获取到rssi,还要把每个广播包的发送功率取出来分析。
叶青
2016-11-09 16:04
@叶青:BLE可以请对对端设备使用固定power发送广播包吗?
wowo
2016-11-09 16:13
@叶青:这是软件层面的事情了,如果两个设备都是自己做的,就没有问题。否则,如果碰到这样的设备的话,估计不行。
星辰
2019-06-30 13:54
@叶青:你好 我现在也是在做一个rssi值定位的一个东西 但是遇到了一些小问题 请问你的那个扫描可以扫到自己的手机吗 我已经把我的手机就是已经变成一个beacon节点了(我就是了那个测试软件,里面可以扫描到一些基站的信 息,但是我不是很确定是不是手机已经成为了一个beacon)我运行那个程序的时候但是没有扫描出来那个手机的信息 为什么呀
wowo
2019-07-02 14:00
@星辰:可以买个简单的抓包工具,看看广播包是不是正确。

发表评论:

Copyright @ 2013-2015 蜗窝科技 All rights reserved. Powered by emlog