# BTool的使用 BTool是一个用于蓝牙设备调试的PC软件工具,工作在Central/Master 。它可以让用户通过PC软件同Peripheral/Slave BLE设备之间建立连接,你可以在TI SDK安装路径下的**Tools**(`C:\ti\simplelink_cc2640r2_sdk_1_35_00_33\tools\ble5stack\btool`)中找到并打开它。BTool利用HCI供应商特定的命令与作为网络处理器的CC13x0/CC26x0 开发板进行通信。而CC2640R2F上必须烧写运行主机测试示例应用程序`cc2640r2lp_host_test.hex`,该文件你可以在**Examples** (`C:\ti\simplelink_cc2640r2_sdk_1_35_00_33\examples\rtos\CC2640R2_LAUNCHXL\ble5stack\hexfiles`)路径下找到,利用软件Flash Programmer 2就可以进行直接烧写到CC2640R2F了。 >**注意**:以上绝对路径针对CC2640R2F BLE5.0,其他路径触类旁通, 第一次下载后请尝试复位或者重新上电保证程序运行。 这部分的内容,对于使用Windows 7和其他Windows版本的步骤基本是相同的。 ## 打开工具 ## 将烧写有`cc2640r2lp_host_test.hex`程序的CC2640R2F通过USB连接到PC,打开BTool后,首先进行串口设置。将端口(Port)值设置为与 **XDS110 Class Application/User**加关联的COM端口号。其他设置使用如图1所示的默认值就可以了。 ![图1 BTool串口设置](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure1.png) 点击OK连接成功之后你可以看到如图2所示的界面。在界面上你可以看到有一个串口和CC13x0/CC26x0 开发板相连。我们可以看到界面分为几部分:左边的部分显示有关状态或着已经连接的设备的信息。中间部分显示从PC发送到CC13x0/CC26x0 开发板以及PC从CC13x0/CC26x0 开发板接收到的所有消息日志。右边部分显示了用于控制CC13x0/CC26x0 开发板的界面。 ![图2 BTool连接到主机测试设备后的界面](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure2.png) ## 创建CC13x0/CC26x0 开发板与外围设备之间的连接 ## 此时,CC13x0/CC26x0 开发板(中央设备)可以扫描发现其他正在广播的BLE设备。这里我们将使用运行`Simple Peripheral`示例应用程序的CC2640R2F作为要连接的外围设备。有关如何在CC2640R2F上运行`Simple Peripheral`示例应用程序,你可以在[编译第一个工程](http://docs.leconiot.com/doku.php?id=cc2640r2f:get_started:first_build:first_project_buid)和[运行第一个例程](http://docs.leconiot.com/doku.php?id=cc2640r2f:get_started:first_example:first_example)中查看。简单外围设备在启动后就立即开始广播。 ### 扫描设备 ### 在BTool右边的控制界面中,在**Discover/Connect**选项下,点击**Scan**按钮, 如图3所示。运行**Host Test**的中央设备将开始搜索其他BLE设备。 ![图3 点击扫描按钮](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure3.png) 当找到设备后,屏幕中间区域日志将会打印被发现的设备。十秒钟之后,设备扫描过程就会结束,运行**Host Test**的设备将会停止扫描。所有扫描到的设备的摘要信息会在日志窗口中显示。以图4为例,你可以看到扫描时发现了19个外围设备。当然如果你不想等待10秒的扫描时间,你可以按**Cancel**按钮来停止**Host Test**设备的扫描。已经扫描到的设备的地址会在**Link Control**部分中的**Slave BDA**下拉框中显示。 ![图4 发现的设备](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure4.png) ### 选择连接参数 ### 在与外围设备建立连接之前,您可以根据自己的需要设置连接参数。BTool默认的参数值为连接间隔:100ms,从机延迟:0,超时监控:20s,您可以使用默认值进行调试, 但是对于不同的应用程序,您可能需要设置成其他值。 在设置完所需的值之后,一定要点击**Set**按钮; 不然设置的参数将不会保存,设置无效。再有,连接参数必须在建立连接之前设置; 在连接激活后更改参数值然后点击**Set**按钮将不会更改连接设备的设置。新的参数必须在终止此次连接然后重新建立连接之后才能生效。(蓝牙规范中对于处于连接状态下的设备是支持连接参数更新;但是必须使用L2CAP连接参数更新请求或直接使用HCI命令来完成连接参数更新。有关更多信息,可以查看蓝牙系统规范。 ![图5 连接设置](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure5.png) ### 建立连接 ### 中央设备要与外围设备建立连接,需要在**Slave BDA**条目下选择要连接的设备的地址,然后单击**Establish**按钮,如下图所示。 ![图6 建立连接](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure6.png) 如果外围设备处于可发现模式,就可以建立连接。建立连接后,中间的消息窗口会显示一个返回的“GAP_EstablishLink”事件消息,它的状态值**0x00** ** (Success) **如下图所示。 ![图7 链接成立](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure7.png) 在BTool中,您可以在设备信息区域看到所连接的外围(Peripheral)设备,如图8所示。 ![图8 设备信息](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure8.png) ## 简单外设配置文件 ## 简单外设(Simple Peripheral)应用程序中包含几个GATT服务配置文件(更多信息可以查看[Generic Attribute Profile (GATT)](http://docs.leconiot.com/doku.php?id=cc2640r2f:ble_stack_app:stack:gatt:gatt) )。GATT服务的数据包含在**特征值**(characteristic values)中。所有低功耗蓝牙发送或接收的应用数据必须包含在**特征值**内。本节将一步一步地详细演示使用BTool读取,写入,发现和通知GATT特征值的几个过程。 在低功耗蓝牙系统中,建立连接之后,中央设备(GATT 客户端)会在外围设备(GATT 服务器)上执行服务发现(service discovery)来建立属性表。属性表中会提供句柄(特征值的内部地址),客户端利用这些句柄就可以访问位于服务器中的数据。设备发现(device discovery)是通过单个命令就可以启动的自动过程。在BTool中,可以通过右键单击句柄(**Handle**)(在软件左侧的连接信息(Connection Info)下),然后选择**发现UUID**(Discover UUIDs)如图9所示 ![图9 发现UUIDs](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/discoverUUIDs.png) 这样您就可以在中间消息窗口的下面部分看到属性表了,如图10所示。 ![图10 GATT属性表](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/GATTattribute.png) ### 通过UUID读取特征值 ### 特征值本质上就是存储数据的地方,比如说温度数据或电池电量。在服务器中存储在特征值中的数据就是客户端想要访问的。特征值中包含了以下三种与其相关的属性值: 1. 句柄(地址) 2. 类型(UUID) 3. 权限 读取特征值最简单的方法是利用工具中提供的一个功能**Read Characteristic by UUID**。下面简单介绍一下如何使用这个功能,首先单击BTool右边控制界面中的**读/写**(Read/Write)选项。在界面的顶部**特征值读取**(Characteristic Read)部分中的**子程序**(Sub-Procedure)选项下选择**Read Using Characteristic UUID**选项。在**Characteristic UUID**框中输入UUID(注意首先输入LSB(低位),后输入MSB(高位)),然后单击**Read**按钮。属性协议读取命令包就通过无线从Host Test设备发送到Simple Peripheral设备,属性协议读取响应包从Simple Peripheral设备发送回Host Test设备。这时特征值就会显示在**Value**框中,在**Status**框中会显示**Success**,如图11所示是利用UUID 0xFFF1(注意:输入的时候先输入低位F1再输高位FF)读取Characteristic 1的特征值,可以看到读出的特征值为01,与图10中的值是符合的。每个特征值的UUID你可以在图10中看到。 ![图11 利用UUID读特征值](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/readcharacteristicbyUUID.png) 中间的消息窗口将会显示Host Test设备接收到的读取响应数据包的信息,这里的信息不仅包含了特征值还包括了特征值的句柄,如图12所示。 ![图12 特征值和句柄](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/handleanddata.png) ### 通过句柄来读取特征值 ### 如果我们知道特征值的句柄,我们也可以通过这个句柄来读取特征值。使用该功能的步骤如下,首先**特征值读取**(Characteristic Read)部分中的**子程序**(Sub-Procedure)选项下选择**Read Characteristic Value/Descriptor**选项;然后在**Characteristic Value Handle**框中输入句柄;最后点击**Read**按钮来进行读取。属性协议读取命令包就通过无线从Host Test设备发送到Simple Peripheral设备,属性协议读取响应包从Simple Peripheral设备发送回Host Test设备。这时特征值就会显示在**Value**框中,在**Status**框中会显示**Success**。如图13所示是利用Handle 0x0021来读取Characteristic 2的特征值,可以看到读出的特征值为02,与图10中的值是符合的,每个特征值的Handle可以在图10中看到。这个值是应该与之前写入这个特征值的值相匹配。 ![图13 利用Handle读特征值](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/readcharacteristicbyhandle.png) ### 写特征值 ### 如果一个特征值具有写入权限,客户端就可以通过此特征值向服务器写入一个值。这个功能通过在**特征值写入**(Characteristic Write)部分,在**Characteristic Value Handle**框中输入句柄,在**Value**框中的输入需要写入的值(格式可以设置为十进制或十六进制),最后点击**Write Value**按钮就可以写入数据了。在程序中会定义每个特征值的读写属性,要想往特征值里写入一个值要求这个特征值必须是可写的。这里我们向Characteristic1中写入值5,如图14所示。属性协议写入命令包通过无线从Host Test设备发送到Simple Peripheral设备,然后属性协议写入响应包从Simple Peripheral设备发送回Host Test设备。状态框显示**Success**,就表示写入成功。 ![图14 利用handle写特征值](images/writevaluebyhandle.png, 由于Characteristic1是可读可写的,这时我们可以再去读取Characteristic1中的值,查看我们是否真的将值写进去了,如图15所示,我们可以看到Characteristic1的值已经变为5。 ![图15 读取Characteristic1的值](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/readCharacteristic1.png) ### 通过UUID得到特征值 ### 通过UUID得到特征值,UUID的句柄,特征值的属性(句柄和权限)都包含在里面了。使用此功能操作步骤如下,首先在BTool操控界面选择**Read/Write**选项,在它的**Characteristic Read**区域的**Sub-Procedure**下拉框中选择**Discover Characteristic by UUID**,然后在下面**Characteristic UUID**框中输入UUID值,最后点击**Read**按钮就可以了。点击**Read**按钮之后,一系列属性协议读请求数据包通过无线从Host Test设备发送到Simple Peripheral设备,然后对于每个请求,都有属性协议读响应包从Simple Peripheral设备发送回Host Test设备。Host Test设备基本上会读取Simple Peripheral设备上UUID为0x2803(这是特征值声明的UUID)的每个属性,并检查每个声明的“Characteristic Value UUID”部分,看它是否与您输入的UUID类型匹配。 当每个特征值声明都被读取之后,这个过程就完成了。 根据蓝牙规范,第一个字节是特征值的属性,第二和第三个字节是特征值的句柄,第四和第五个字节是该特征值的UUID,如图16所示。 ![图16 利用UUID发现特征值属性](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/discovercharacteristicbyUUID.png) ### 阅读多个特征值 ### 只要知道每个特征值的句柄,您就可以通过一个请求读取多个特征值。使用此功能的操作步骤如下,首先在BTool操控界面选择**Read/Write**选项,在它的**Characteristic Read**区域的**Sub-Procedure**下拉框中选择**Read Multiple Characteristic Values**,然后在**Characteristic Value Handle**框中输入你要读取的特征值的句柄(例如**0x0022;0x0025**),最后单击**Read**按钮。属性协议多个读取请求数据包通过无线从Host Test设备发送到Simple Peripheral设备,属性协议多个读取响应数据包从Simple Peripheral设备发送回Host Test设备。读取成功之后您就可以在**Value**框中看到读取的特征值,在**Status**框中看到**Success**。如图17所示,我们同时读取Characteristic1和Characteristic2的特征值,分别输入他们的句柄0x1E,0x0021,可以看到成功读出它们的值为05,02。 ![图17 同时读多个特征值](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/readmultiplecharacteristicvalues.png) >**注意**:Simple Peripheral设备返回的响应数据不会被解析。所以客户端在读取这些值的时候必须知道它们各自是多大。上面这个例程中我们读取的值都只有两个字节,不太容易弄错,但是我们使用这个功能的时候必须注意这一点。 ### 启用通知 ### 在BLE中,GATT服务器设备在没有收到客户端的读请求时也可以将特征值数据“推送”到客户端设备。这个过程被称为**特征值通知(characteristic value notification)**。通知比较有用的地方在于它们允许连接中的BLE设备在任何时间点发送尽可能少的数据。此外,由于通知不需要来自客户端的请求就可以发送数据,因此降低了开销并且更有效地传输了数据。 客户端设备需要向客户端特征配置描述符(CCCD)写入一个值为0x0001的特定特征值来启用通知。CCCD的句柄紧跟特征值的句柄。因此,必须将值0x0001写入**handle + 1**,这个配置在`simple_gatt_profile.c`文件中的特征值属性配置表`simpleProfileAttrTbl[]`可以进行设置,例如我们可以将特征值4启用通知,将CCCD值设置为0x0001,如list1所示。 List1 启用特征值4的通知属性 ```C // Characteristic 4 Value Declaration { { SNP_16BIT_UUID_SIZE, simpleProfilechar4UUID }, /* UUID */ SNP_GATT_PROP_NOTIFICATION, /* Properties */ 0, /* Permissions */ &char4UserDesc, /* User Description */ 0x0001 /* CCCD */ /* Format */ }, ``` ## 使用BLE的安全功能 ## BTool还有使用BLE中安全功能的能力,包括加密,认证和绑定。 ### 加密连接 ### 要加密链接,需要初始化配对过程。在BTool右边的操控界面,首先选择**Pairing/Bonding**选项,在选项下的**Initiate Pairing**区域勾选**Bonding Enabled**和**Authentication(MITM)Enabled**,然后点击**Send Pairing Request**按钮,这时会向外围设备发送一个配对请求,如图9所示。 ![图9 发送配对请求](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure9.png) 外围设备收到配对请求后将发送配对响应,这时**Passkey Input**区域会处于可输入状态,用户需要在**Passkey**框中输入一个六位密码,然后点击**Send Passkey**来完成配对过程,如图10所示。注意,如果在收到配对响应消息后30秒内没有发送密钥,配对过程将失败,您将需要重新发送配对请求。通常,这个需要输入的密码会在外围设备上显示出来,用户再输入到中央设备中,然后该链路被认证,因为这样做已经证实该连接没有被中间人劫持( MITM)攻击。 ![图10 发送密码](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure10.png) 配对成功完成后,您可以在日志窗口中看到一个“GAP_AuthenticationComplete”事件,并显示状态为“Success”。这样BLE连接就已经被加密,如图11所示。 ![图11 加密连接](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure11.png) ### 使用绑定和长期密钥 ### 绑定(Bonding)是BLE中的一个功能,允许设备在与对等设备初始配对之后记住有关该对等设备的特定信息。比如说使用绑定功能之后初始配对过程中产生的长期密钥数据就可以在本地存储下来。如果两个设备断开连接稍后重新连接,这个存储在本地的长期密钥数据就可以用来快速重新启动加密,而不需要重新输入密码启动配对过程。另外,如果客户端设备在两个设备绑定时启用了服务器设备上某些特征值的通知功能,服务器设备会记住该设置,在重新连接之后客户端将不必重新启用它们。 在启用绑定功能配对完成后,**长期密钥(LTK)数据**将填充到“GAP_AuthenticationComplete”事件在加密过程中生成的一些数据中去。在重新连接时,重新启动加密就需要**长期密钥(LTK)数据**。点击**Save Long-term Key Data to File**按钮可以将此信息保存到文件中去。数据以**comma separated value**(CSV)格式保存为简单文本,您可以将它存储在磁盘上的您想要存储的位置。您需要记一下文件所存储的位置。 ![图12 保存长期密码](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure12.png) 简单外设示例应用程序中包含一个绑定管理器用来存储在加密期间生成的长期密钥数据,所以上面所说的存储**长期密钥(LTK)数据**过程得以在外围设备中进行。由于简单外设示例应用程序没有文件系统,所以数据会被存储在CC2640R2的非易失性存储器中。关于绑定管理器的更多信息您可以在低功耗蓝牙软件开发人员指南中查看。当两个设备之间处于绑定过程,您可以启用特征值的通知,该设置就可以被存储下来供下次使用。注意,如果在通过绑定配对过程之前就启用了通知,则该设置不会被存储。如果你需要启用通知,就要将值**01:00**重新写入CCCD。在设备在启用绑定的情况下,要验证绑定是否有效,您需要断开连接并重新连接。在BTool操控界面选择**Discover/Connect**选项,然后单击底部的**Terminate**按钮,断开与外围设备的连接。中间的消息窗口会显示具有**Success**状态的**GAP_TerminateLink**事件,如图13所示。BTool界面左上角的连接信息也会消失。 ![图13 终止链接](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure13.png) 稍后重新启动与外围设备的连接。注意,如果连接终止或设备重置,则特征值的CCCD的值会被重置为**00:00**。 要重新启动加密以及重新启用在先前连接中启用的通知,需要在**Pairing/Bonding**选项下,在**Encrypt Using Long-Term Key**部分中,点击**Load Long-Term Key Data From File**按钮,然后选择先前存储数据的文件。数据字段就会自动从文件中的数据填充。点击**Encrypt Link**按钮重新启动加密连接,如图14所示。 ![图14 使用长期密钥重新加密](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure14.png) 在日志窗口中会显示具有**Success**状态的**GAP_BondComplete**事件。这就表示连接已被重新加密,如图15所示。这样您就可以收到在上一次连接中启用的任何通知。对特征值CCCD值的任何更改将被保存到非易失性存储器中,用于下一次使用**长期密钥(LTK)数据**加密连接。 ![图15 完成绑定](http://www.leconiot.com/md_res/cc2640r2f/tool_kits/btool/Images/figure15.png) ## TroubleShooting ## * 现象 ``` --------------------------- BTool - Error --------------------------- Device Reset Timeout Device May Not Function Properly --------------------------- 确定 --------------------------- ``` * 解决 1、确保硬件串口正确连接; 2、正确选择串口-XDS110 Class Application/User UART而不是 XDS110 Class Auxiliary Data Port 3、烧写正确的程序-cc2640r2lp_host_test.hex; 4、尝试硬件复位和断电重启; ## 加入我们 ## 文章所有代码、工具、文档开源。加入我们[**QQ群 591679055**](http://shang.qq.com/wpa/qunwpa?idkey=d94f12d37c3b37892af4b757c6dc34bea140f3f3128a8d68e556a3d728148e85)获取更多支持,共同研究CC2640R2F&BLE5.0。

CC2640R2F&BLE5.0-乐控畅联 © Copyright 2017, 成都乐控畅联科技有限公司.