利用PC和蓝牙dongle实现ibeacon

第一次写技术博客,既当作对本身的技术总结,也看成和广大网友们分享讨论的一个平台吧。linux

最近在研究BLE技术,而ibeacon是其中比较简单的一个应用。虽然由苹果公司推出已经四五年了,网上的资料仍是稍显的零散。下面就从理论和实践两个方面来总结一下这项技术,力求刚刚接触这个的朋友也能很快的了解而且能本身动手实现ibeacon,毕竟我以为本身动手实践才能真正的学会。固然,不足或者错漏之处请你们不吝赐教。ubuntu

一:ibeacon的基本原理和数据包结构服务器

ibeacon是由苹果公司在2013年推出的,其初衷是解决室内定位的问题。由于GPS在室内很难发挥做用,而如今手机上标配蓝牙。利用低功耗的BLE多点定位来解决室内(大型商场、停车场、医院等)定位的问题也就理所应当了。微信

ibeacon本质上就是BLE的广播,不涉及到BLE设备间的连接,不过这里的广播包有特定的格式。这里须要两个设备,ibeacon基站和带蓝牙4.0以上的手机,而整个定位过程的实现涉及三个方面。除了基站和手机以外,还有个远程的服务器提供的服务,这里通常以APP的方式存在于手机之上。数据结构

整个的过程是这样的:工具

          ibeacon基站一直在广播,广播包里包含的主要是一、本基站的设备类型。 二、本基站的编号。三、本基站的发射功率。三个重要信息;spa

          打开蓝牙的手机靠近基站以后收到了广播包的信息,经过广播包的设备类型判断出这是个ibeacon设备,经过广播包里记载的发射功率与本身接受到的信号功率对比得出和基站的距离(经验公式D =10^((abs(RSSI)-A)/(10*n),其中D是得出的距 离,                                      A是发射设备和接收设备相距一米时的信号强度,n为环境因子)。而后经过手机上特定的APP将基站编号发送给服务器(这个过程要求手机必定要能联网),服务器查询该编号返回该基站所在的具体详细地址;命令行

          根据服务器返回的具体基站地址,加上前面测算的和该基站的距离,就可以定位本身位置啦!固然,多个基站存在时,多点定位就能更加准确肯定本身的位置了。code

苹果ibeacon的定位功能在国内实用的例子还不太多,反却是借助于Ibeacon的微信摇一摇火爆了起来。相比于室内定位,微信摇一摇更加侧重于商家用来展现广告和促销信息等。前面讲到了须要一个手机上的APP,这里国内的超级APP微信就承担了这样一个角色。其基本原理和过程与上述相同,可是这里微信后台查询基站编号以后返回的是一个网页地址。商家在此网页上配置本身的促销信息,优惠券以及其余广告。这样一来,客户一旦走近商家店铺,手机上就自动可以获得该商家优惠信息等等。blog

说完了原理,如今来详细的解析ibeacon广播包的数据结构。ibeacon基于BLE的广播,而BLE广播限定数据长度不能超过31 Bytes。ibeacon将广播包的长度固定为30 Bytes。

这30个Bytes分为两个AD structure(这是BLE广播数据的一种组织形式)。每一个AD structure由 1字节的length+1字节的AD Type+用户数据 构成。下面拿一个实例来讲明:

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 1c

这是一个ibeacon包的payload,其中“02 01 06”是第一个AD structure,“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 1c”是第二个AD structure的内容。

对第一个AD structure,

1 02 ,// AD structure的长度 这里表示接下来还有两个字节
2 01, //AD Type 这是由蓝牙联盟定义的标识,这里表示蓝牙支持类型
3 06, //0x06=0000 0110 每一个位的意义以下
4         bit0=0 OFF // LE Limited Discoverable Mode  
5         bit1=1 ON  // LE General Discoverable Mode 
6         bit2=1 ON  // BR/EDR Not Supported        
7         bit3=0 OFF // Simultaneous LE and BR/EDR to Same Device Capable (controller)  
8         bit4=0 OFF //Simultaneous LE and BR/EDR to Same Device Capable (Host) 

对第二个AD structure,

1a,               // AD structure长度,这里是26个字节
ff,               // ADType. 由于ibeacon并未写入官方协议,这里使用自定义类型Manufacturer Specific Data
4c, 00,          //这个指公司, 00 4c是APPLE
02, 15,          //这是ibeacon的标识,指示这个广播是ibeacon广播
fd,a5,06,93,a4,e2,4f,b1,af,cf,c6,eb,07,64,78,25,//16字节的proximity UUID 由设备厂商和设备用途决定,这里用的是微信的UUID
29,11,           // Major 
30, 39           //Minor  Major和Minor共同决定设备的编号
1c               //1米距离上的信号功率

二:利用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的配置已经所有完成了! 

打开手机蓝牙你会看到一个"ubuntu"的蓝牙设备(可能根据具体设备名字不一样),打开微信->发现->摇一摇, 而后摇一摇你会发现出现了一个“周边”的栏目,若是你配置的Major,和Minor是向微信申请的正式编号,这里就会显示出相应的商家页面。

我随便编的因此是黑屏:)

相关文章
相关标签/搜索