Ibeacon

Ibeacon

如何使用 CC2540 制作一个 iBeacon

准备工作

  1. 一台 PC
  2. IAR Embedded Workbench 集成开发环境,可以用30天试用版本。
  3. 支持 蓝牙 4.0 的智能手机一部,并安装下列应用之一
  4. CC2540 开发板
  5. CCDebugger 下载器

创建 iBeacon 工程文档

  • 安装 TI 官方的 CC254x 开发环境
  • 复制 C:\Texas Instruments\BLE-CC254x-1.3.2\Projects\ble\SimpleBLEBroadcaster 文件夹
  • 粘贴到:C:\Texas Instruments\BLE-CC254x-1.3.2\Projects\ble\iBeacon
  • 运行 IAR Embedded Workbench,点击 File > Open > Workspace

修改源代码

simpleBLEBroadcaster.c

// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
static uint8 advertData[] =
{
  // Flags; this sets the device to use limited discoverable
  // mode (advertises for 30 seconds at a time) instead of general
  // discoverable mode (advertises indefinitely)
  0x02,   // length of this data
  GAP_ADTYPE_FLAGS,
  GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

  // three-byte broadcast of the data "1 2 3"
  0x04,   // length of this data including the data type byte
  GAP_ADTYPE_MANUFACTURER_SPECIFIC,      // manufacturer specific advertisement data type
  1,
  2,
  3
};

修改下面关键字

  • UID: E2C56DB5-DFFB-48D2-B060-D0F5A71096E0
  • Major: 1 (0x0001)
  • Minor: 1 (0x0001)
  • Measured Power: -59 (0xc5)
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
static uint8 advertData[] =
{
  // 25 byte ibeacon advertising data
  // Preamble: 0x4c000215
  // UUID: E2C56DB5-DFFB-48D2-B060-D0F5A71096E0
  // Major: 1 (0x0001)
  // Minor: 1 (0x0001)
  // Measured Power: -59 (0xc5)
  0x1A, // length of this data including the data type byte
  GAP_ADTYPE_MANUFACTURER_SPECIFIC, // manufacturer specific advertisement data type
  0x4c,
  0x00,
  0x02,
  0x15,
  0xe2,
  0xc5,
  0x6d,
  0xb5,
  0xdf,
  0xfb,
  0x48,
  0xd2,
  0xb0,
  0x60,
  0xd0,
  0xf5,
  0xa7,
  0x10,
  0x96,
  0xe0,
  0x00,
  0x01,
  0x00,
  0x01,
  0xc5
};

接下来修改广播类型,将下面代码

//uint8 advType = GAP_ADTYPE_ADV_NONCONN_IND;// use non-connectable advertisements
uint8 advType = GAP_ADTYPE_ADV_DISCOVER_IND; // use scannable unidirected advertisements

修改为

uint8 advType = GAP_ADTYPE_ADV_NONCONN_IND;   // use non-connectable advertisements
//uint8 advType = GAP_ADTYPE_ADV_DISCOVER_IND; // use scannable unidirected advertisements

接下来修改 GAP

// Set the GAP Role Parameters
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );

GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), &advType );

因为 iBeacon 必须不间断广播,并且不响应任何数据请求,所以我们要修改 GAPROLE_ADVERT_OFF_TIME 和 GAPROLE_SCAN_RSP_DATA。

// Set the GAP Role Parameters
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
//GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );

//GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), &advType );

保存工程后,进行编译,并通过 CCDebugger 下载程序到开发板中。

  1. Select Project > Clean to clean the project.
  2. Select Project > Make to make the project.
  3. Select Project > Download and Debug to send the code to the CC2540 Key Fob
  4. Select Debug > Go to Run the code on the CC2540 Key Fob

基于 CC254xSmartRF 开发板的 iBeacon 基站制作

 1.iBeacon的前世今生

image001

苹果公司,其产品的开发对外历来都是神秘的,正当三星和诺基亚大力推进NFC应用的时候,苹果却没有跟进,这是为何?在WWDC2013上,苹果发布了全新颠覆性的iOS系统:iOS 7。除了全新的扁平化外观UI设计之外,苹果还发布了许多iOS7的新特性。作为iOS7中最重要的新特性之一,iBeacon引起了各大科技巨头的注意。

美国老牌商场梅西百货(Macy)已经开始在纽约和旧金山的门店中部署iBeacon传感器,在同应用程序 Shopkick配合使用后,顾客将会在进店的同时感受到新技术所带来的便捷,因为他们可以在不同楼层的不同商铺即时获取到不同的优惠信息。此外,苹果上周也宣布在全美254家苹果零售店中部署iBeacon技术。

在国内, 各种 iBeacon应用正如雨后春笋一样冒出来,相信,这一次,我们电子工程师大有作为。

1.1    iBeacon的技术原理 

通过使用低功耗蓝牙技术(BluetoothLowEnergy,也就是通常所说的Bluetooth4.0或者Bluetooth Smart),iBeacon基站可以创建一个信号区域,当设备进入该区域时,相应的应用程序便会提示用户是否需要接入这个信号网络。通过能够放置在任何物体中的小型无线传感器和低功耗蓝牙技术,用户便能使用iPhone来传输数据。

2.iBeacon的应用方向 

综合了一下,iBeacon的应用目前主要有如下:

【1】, 零售业, 当客户进入 iBeacon信号区域是推送相关信息

【2】, 球馆和演唱会馆等,指引客户找到座位和出入口洗手间等

【3】, 车库汽车定位,当你走进车库, iBeacon会指引你找到你的爱车再也不用到处找了。

【4】, 学生上课点名,别笑哦,一款名为BeHere的基于iBeacon 的应用 已经在AppStore 免费上架,iPad、iPhone和 iPod touch 都可以下载使用,该应用还具有“求助”功能,要是我当年上学的时候学校用这个来点名那我当年要睡少很多懒觉哦。

【5】,苹果将用iBeacon实现短距离支付,替换NFC,只是不知鹿死谁手短期肩部了分晓哦。

【6】,............

3.需要的开发环境

 3.1硬件环境 

【1】SmartRF开发板一套

【2】cc debugger 或smartRF04eb仿真器

【3】 cc2540 usb dongle 协议分析仪或 用 cc debugger 或 smartRF04eb 仿真器加

SmartRF开发板 实现的分析仪。(可选,但非常必要选)

3.2软件环境 

【1】SmartRF FlashProgrammer   下载工具软件(可选)

【2】IAR8.10.3

【3】Texas Instruments PacketSniffer BLE协议分析仪

 

4.实战实践 

iBeacon 基站的实现, 实际上除了硬件以外,在软件上仅表现为周期性地发送特定的数据包, 而这个数据包的格式,可以通过网络抓包破解分析出来。

对于一个UUID是E2C56DB5-DFFB-48D2-B060-D0F5A71096E0,major是0,minjor是0

的iBeacon,此时的Tx的信号是-59RSSI,他的BLE的广播包如下:

d6 be 89 8e 40 24 05 a2 17 6e 3d 71 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0

f5 a7 10 96 e0 00 00 00 00 c5 52 ab 8d 38a5 

以上协议包拆解内容如下:

d6 be 89 8e # Access address for advertising data (this is always the same fixedvalue)

40 # Advertising Channel PDU Header byte0.   Contains: (type = 0), (tx add = 1), (rx add =0)

24 # Advertising Channel PDU Header byte   1.    Contains:       (length = total bytes of   the advertising payload + 6 bytes for the BLE macaddress.)

05 a2 17 6e 3d 71 # Bluetooth Mac address (note this is a spoofedaddress)

02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 00 c5#Bluetoothadvertisement

52 ab 8d 38 a5 #checksum

协议包中的关键部分就是蓝牙的广播部分,这些被分解为如下:

02 01 1a 1a ff 4c 00 0215  # Apple's fixed iBeacon advertisingprefix

e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon profileuuid

00 00 #major

00 00 #minor

c5 # The 2's complement of the calibrated TxPower

通过BLE设备发送这样的数据包,iOS收到后,即可实现iBeacon了。

4.1源码修改 

好通过前面的协议分析,我们来修改一下源码,我们在《1.BLE入门与提高教程.pdf》的第 4 章 BLE 协议栈入门 里边已经验证过 SimpleBLEPeripheral作为从机时的功能,现在我们直接在这个TI官方的例程上修改来实现我们的iBeacon基站。

【1】修改广播数据:

image002

4.2 用 iOS测试 

笔者手机上装了很多Appstore上的蓝牙4.0BLE的软件,其中AirLocate是苹果公司推出iBeacon 的测试软件, Locate iBeacons 是一款第三方的软件, 能实现iBeacon的距离定位和校准, 下面我们来看看 Locate iBeacons 实现的距离显示和室内定位。

【1】, 手机上安装Locate iBeacons, 你的 iphone至少是4s 或以上, 系统必须是ios7.0

以上, iphone4s ios7.0 以后的系统才支持蓝牙4.0BLE。

 image004

 

【2】, 点击Locate iB 进去后如下图,

image005

【3】, 点击 Locate iBeacons 进入如下界面,如果你的基站已经打开,即可看到如图所示的设备, 下图中 就直接显示了你的手机与 iBeacon 基站间的距离,这个距离可能随着不同的硬件设备而有所差异, 所以需要校准, 请看下一步如何校准。这里为什么一打开这个软件就实现了距离显示了呢,主要是该软件内默认添加了苹果公司发布的UUID,我们亦可以修改基站的uuid,然后在该软件中添加该uuid,同样也能实现该功能的,这个做起来就要深入开发了。

 image006

 

【4】,校准,     点击第一行 ,进入下一步。

image007

【5】,校准提示,把你的iphone放到距离iBeacon基站约1米处,按下Calibrate   ,并且保持30秒到1分钟,过程如下面图。

 image008

image009

【6】, 校准完毕, 下面图显示聚焦校准完毕了, 你可以随意拿你的 iphone到处走,神奇的iBeacon就告诉你你所处的距离,如果有3个以上的iBeacon基站信号能够被收到,那么就可以实现比较真正的室内定位了。

 image010

【7】,显示距离如下。

distance

4.3数据分析 

好吧, 上述的iBeacon功能基本完成了,那么, 到底SmartRF开发板与iOS的数据交互如何的呢,这个时候就需要网络协议分析仪来抓包并分析数据了。

如何使用 CC2540 制作一个 iBeacon

准备工作

  1. 一台 PC
  2. IAR Embedded Workbench 集成开发环境,可以用30天试用版本。
  3. 支持 蓝牙 4.0 的智能手机一部,并安装下列应用之一
  4. CC2540 开发板
  5. CCDebugger 下载器

创建 iBeacon 工程文档

  • 安装 TI 官方的 CC254x 开发环境
  • 复制 C:\Texas Instruments\BLE-CC254x-1.3.2\Projects\ble\SimpleBLEBroadcaster 文件夹
  • 粘贴到:C:\Texas Instruments\BLE-CC254x-1.3.2\Projects\ble\iBeacon
  • 运行 IAR Embedded Workbench,点击 File > Open > Workspace

修改源代码

simpleBLEBroadcaster.c

// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
static uint8 advertData[] =
{
  // Flags; this sets the device to use limited discoverable
  // mode (advertises for 30 seconds at a time) instead of general
  // discoverable mode (advertises indefinitely)
  0x02,   // length of this data
  GAP_ADTYPE_FLAGS,
  GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

  // three-byte broadcast of the data "1 2 3"
  0x04,   // length of this data including the data type byte
  GAP_ADTYPE_MANUFACTURER_SPECIFIC,      // manufacturer specific advertisement data type
  1,
  2,
  3
};

修改下面关键字

  • UID: E2C56DB5-DFFB-48D2-B060-D0F5A71096E0
  • Major: 1 (0x0001)
  • Minor: 1 (0x0001)
  • Measured Power: -59 (0xc5)
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
static uint8 advertData[] =
{
  // 25 byte ibeacon advertising data
  // Preamble: 0x4c000215
  // UUID: E2C56DB5-DFFB-48D2-B060-D0F5A71096E0
  // Major: 1 (0x0001)
  // Minor: 1 (0x0001)
  // Measured Power: -59 (0xc5)
  0x1A, // length of this data including the data type byte
  GAP_ADTYPE_MANUFACTURER_SPECIFIC, // manufacturer specific advertisement data type
  0x4c,
  0x00,
  0x02,
  0x15,
  0xe2,
  0xc5,
  0x6d,
  0xb5,
  0xdf,
  0xfb,
  0x48,
  0xd2,
  0xb0,
  0x60,
  0xd0,
  0xf5,
  0xa7,
  0x10,
  0x96,
  0xe0,
  0x00,
  0x01,
  0x00,
  0x01,
  0xc5
};

接下来修改广播类型,将下面代码

//uint8 advType = GAP_ADTYPE_ADV_NONCONN_IND;// use non-connectable advertisements
uint8 advType = GAP_ADTYPE_ADV_DISCOVER_IND; // use scannable unidirected advertisements

修改为

uint8 advType = GAP_ADTYPE_ADV_NONCONN_IND;   // use non-connectable advertisements
//uint8 advType = GAP_ADTYPE_ADV_DISCOVER_IND; // use scannable unidirected advertisements

接下来修改 GAP

// Set the GAP Role Parameters
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );

GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), &advType );

因为 iBeacon 必须不间断广播,并且不响应任何数据请求,所以我们要修改 GAPROLE_ADVERT_OFF_TIME 和 GAPROLE_SCAN_RSP_DATA。

// Set the GAP Role Parameters
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
//GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );

//GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), &advType );

保存工程后,进行编译,并通过 CCDebugger 下载程序到开发板中。

  1. Select Project > Clean to clean the project.
  2. Select Project > Make to make the project.
  3. Select Project > Download and Debug to send the code to the CC2540 Key Fob
  4. Select Debug > Go to Run the code on the CC2540 Key Fob.