//
// Created by watering on 2017/6/22.
// Copyright © 2017年 watering. All rights reserved.
//
#import "ViewController.h"
#import
#import "DeviceCommand.h"
@interface ViewController ()
/** 中心设备管理器 */
@property (nonatomic, strong) CBCentralManager *centralManager;
/** 外设【注意:对要连接的外设需要进行强引用,否则会报错】 */
@property (nonatomic, strong) CBPeripheral *peripheral;
/** 配对信息(存放Data) */
@property (nonatomic, strong) NSArray *pairAuthDatas;
/** 显示外设名称,点击并连接外设 */
@property (weak, nonatomic) IBOutlet UIButton *showPeripheralName;
/** com */
@property (nonatomic, strong) DeviceCommand *deciceCommand;
@end
@implementation ViewController
#pragma mark - othe
/**
一、
1、CBUUID 对象是用于 BLE 通信中 128 位的唯一标示符。peripheral 的 service,characteristic,characteristic descriptor 都包含这个属性。这个类包含了一系列生成 UUID 的方法。
2、UUID 有 16 位的,也有 128 位的。其中 SIG 组织提供了一部分 16 位的 UUID,这部分 UUID 主要用于公共设备,例如有个用蓝牙连接的心率监测仪,如果是用的公共的 UUID,那么无论谁做一个 app,都可以进行连接,因为它的 UUID 是 SIG 官方提供的,是公开的。如果公司是要做一个只能自己的 app 才能连接的设备,那么就需要硬件方面自定义 UUID。(关于这方面,包括通信的 GATT 协议、广播流程等详细介绍,可以看 http://www.cnblogs.com/QianChia/p/6366672.html 这篇文章。讲得比较详细,能在很大程度上帮助我们理解 BLE 通信)。
3、CBUUID 类提供了可以将 16 位 UUID 转为 128 位 UUID 的方法。下面的代码是 SIG 提供的 16 位的心率 service UUID 转为 128 位 UUID 的方法: CBUUID *heartRateServiceUUID = [CBUUID UUIDWithString:@"180D"];
4、如果需要获取 NSString 形式的 UUID,可以访问 CBUUID 的 UUIDString 只读属性。
NSString *uuidString = [CBUUID UUIDWithString:ServiceUUIDString1].UUIDString;
二、外设唯一标识符
在有些时候,需要获取 peripheral 的唯一标示符(比如要做自动连接或绑定用户等操作),但是在搜索到 peripheral 之后,只能拿到 identifier,而且这个 identifier 根据连接的 central 不同而不同。也就是说,不同的手机连上之后,identifier 是不同的。虽然比较坑爹,但是这并不影响你做蓝牙自动连接。
以下都是CBPeripheral(外设)系统自带属性:
name:蓝牙设备的名称(我们可以通过名称做蓝牙自动连接,一般同意外设名称是有自己的风格的)
RSSI:蓝牙设备的信号强度
state:蓝牙设备的连接状态,枚举值(CBPeripheralState)
services:蓝牙设备包含的服务(服务都是存在一个数组中)
identifier:蓝牙设备的 UUID 标识符
三、接收 characteristic 数据
接收 characteristic 数据的方式有两种:
1、在需要接收数据的时候,调用 readValueForCharacteristic:,这种是需要主动去接收的。
2、用 setNotifyValue:forCharacteristic: 方法订阅,当有数据发送时,可以直接在回调中接收。
如果 characteristic 的数据经常变化,那么采用订阅的方式更好。
四、再次连接外设(重连)
1、调用 retrievePeripheralsWithIdentifiers: 方法,重连已知的 peripheral 列表中的 peripheral(以前发现的,或者以前连接过的)。
2、调用 retrieveConnectedPeripheralsWithServices: 方法,重新连接当前【系统】已经连接的 peripheral。
3、调用 scanForPeripheralsWithServices:options: 方法,连接搜索到的 peripheral。
*/
#pragma mark - lazy
#pragma mark -
- (NSArray *)pairAuthDatas
{
if (!_pairAuthDatas) {
// 具体开发时,根据配对协议加载配对需要的数据
// _pairAuthDatas = ;
}
return _pairAuthDatas;
}
#pragma mark - 系统回调
#pragma mark -
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - 事件响应
#pragma mark -
/** 初始化 中心设备管理器 */
- (IBAction)start:(UIButton *)sender
{
// 1、初始化 中心设备管理器, 将 self 设置为代理,用于接收各种 central 事件,触发回调【centralManagerDidUpdateState:】将 queue 设置为 nil,则表示直接在主线程中运行
// 2、初始化 中心设备管理器 之后,设置的代理会调用 centralManagerDidUpdateState: 方法,所以需要去遵循 协议。这个 centralManagerDidUpdateState 的方法,能获得当前设备是否能作为 central。
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
/** 连接外设 */
- (IBAction)connectionBut:(UIButton *)sender
{
}
/** 断开连接 */
- (IBAction)clickDisconnectBut:(UIButton *)sender
{
[self disconnectPeripheral:self.centralManager peripheral:self.peripheral];
}
/** 初始化 */
- (void)deciceCommandInit:(CBPeripheral *)peripheral
{
self.deciceCommand = [[DeviceCommand alloc] init];
self.deciceCommand.delegate = self;
[self.deciceCommand peripheral:peripheral receiveData:0];
// [self.deciceCommand peripheral:peripheral deleteData:0];
}
#pragma mark - 数据传输代理
- (void)getDeviceData:(NSDictionary *)dicDeviceData
{
NSLog(@"手环获取数据 == %@",dicDeviceData);
}
- (void)getError:(NSDictionary *)dicError
{
NSLog(@"错误码 == %@",dicError);
}
-(void)getOperateResult:(NSDictionary *)dicOperateResult
{
NSLog(@"操作结果 == %@",dicOperateResult);
}
#pragma mark - 私有方法
#pragma mark -
// 2、扫描外设
/** 开始扫描周围外设 */
- (void)sacnNearPerpherals
{
NSLog(@"调用【开始扫描周围外设】方法");
// 第一个参数为 Services(服务) 的 UUID(外设端的 UUID),nil 为扫描周围所有的外设。在实际应用中,你可以传入一个 CBUUID 的数组(注意,这个 UUID 是 service 的 UUID 数组),表示只搜索当前数组包含的设备(每个 peripheral 的 service 都有唯一标识 UUID)。所以,如果你传入了这样一个数组,那么 central manager 则只会去搜素包含这些 service UUID 的 Peripheral。CBUUID 是和 peripheral 相关的,和 central 本身关系不大,如果你是做的硬件对接,那么可以向硬件同事询问。
// 第二参数的 CBCentralManagerScanOptionAllowDuplicatesKey 为已发现的设备是否重复扫描,YES 同一设备会多次回调。nil 时默认为 NO。
NSDictionary *dic = @{CBCentralManagerScanOptionAllowDuplicatesKey : @NO};
// 此方法为连接搜索到的 外设,也就是说每次搜索到 外设 后由用户连接指定 外设
[self.centralManager scanForPeripheralsWithServices:nil options:dic];
}
// 3、连接外设
/** 连接指定的设备 */
- (void)connectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@"调用【连接指定的设备】方法");
// 设置外设连接的规则
if ([peripheral.name hasPrefix:@"S"]) {
self.peripheral = peripheral;
// 显示外设名称
[self.showPeripheralName setTitle:peripheral.name forState:UIControlStateNormal];
// 扫描到指定设备之后便可调用系统Api来连接外设
[self.centralManager connectPeripheral:peripheral options:nil];
}
}
// 4、扫描外设中的服务和特征
/** 扫描外设中的服务和特征 */
- (void)discoverPeripheralServices:(CBPeripheral *)peripheral
{
/** 【注意】设备连接成功后,就可以扫描设备的服务了,同样是通过委托形式,扫描到结果后会进入委托方法。但是这个委托已经不再是主设备的委托(CBCentralManagerDelegate),而是外设的委托(CBPeripheralDelegate),这个委托包含了主设备与外设交互的许多回调方法,包括获取 services,获取 characteristics,获取 characteristics 的值,获取 characteristics 的 Descriptor,和 Descriptor的值,写数据,读 RSSI,用通知的方式订阅数据等等。*/
// 1、设置外设代理
self.peripheral.delegate = self;
// 2、开始扫描外设的所有服务(nil则代表扫描所有服务,实际中最好是传入所需要的service的UUID数组,这样会省时省电)。第一步是先找到当前 peripheral 提供的 service因为 service 广播的数据有大小限制(貌似是 31 bytes),所以你实际找到的 service 的数量可能要比它广播时候说的数量要多。
[self.peripheral discoverServices:nil];
}
// 5、把数据写到 Characteristic 中
/** 把数据写到 特征 Characteristic 中 */
- (void)writeCharacteristic:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic value:(NSData *)value
{
NSLog(@"当前特征的属性【%lu】",characteristic.properties);
// 只有 characteristic.properties(特征属性) 有 write(写入) 的权限才可以写,所以要做判断,反之出现错误
if (characteristic.properties & CBCharacteristicPropertyWrite ||
characteristic.properties & CBCharacteristicWriteWithoutResponse) {
// 往 characteristic 写入数据, CBCharacteristicWriteWithResponse 表示当写入成功之后,要执行 peripheral:didWriteValueForCharacteristic:error: 方法回调
[peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}else{
NSLog(@"该字段(数据)不可写入Characteristic(特征)中!");
}
}
// 6、订阅 Characteristic 的通知【此方法决定是否能实现实时传输数据】
/** 设置通知 */
- (void)notifyCharacteristic:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic
{
// 设置通知,数据通知会进入:didUpdateValueForCharacteristic(获取到特征的值)方法中
// 如果是订阅,成功与否的回调是 peripheral:didUpdateNotificationStateForCharacteristic:error:,读取中的错误会以 error 形式传回。
// 当然也不是所有 特征 都允许订阅,可以通过 CBCharacteristicPropertyNoify options 来进行判断。
if (characteristic.properties & CBCharacteristicPropertyNotify) {
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
}
/** 取消通知 */
- (void)cancelNotifyCharacteristic:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic
{
[peripheral setNotifyValue:NO forCharacteristic:characteristic];
}
// 7、断开外设连接
/** 停止扫描且断开外设连接 */
- (void)disconnectPeripheral:(CBCentralManager *)centralManager peripheral:(CBPeripheral *)peripheral
{
// 1、停止扫描
[centralManager stopScan];
// 2、断开连接
[centralManager cancelPeripheralConnection:peripheral];
}
// 8、重新连接
/** 重新连接外设 */
- (void)reconnectThe
{
}
#pragma mark - 中心设备管理器代理
#pragma mark -
// 1、建立中心角色
// 检查当前app蓝牙设备是否可用
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
// 在初始化 【中心设备管理器】 的时候会打开设备,只有当设备正确打开后才能使用
switch (central.state) {
// 蓝牙已打开,开始扫描外设
case CBManagerStatePoweredOn:
{
NSLog(@">>>>>>> 蓝牙已打开,开始扫描外设");
// 开始扫描周围的设备,自定义方法
[self sacnNearPerpherals];
}
break;
case CBManagerStatePoweredOff:
{
NSLog(@">>>>>>> 蓝牙未打开,系统会自动提示打开,不用自行提示");
}
break;
case CBManagerStateUnsupported:
{
NSLog(@">>>>>>> 设备不支持蓝牙或者蓝牙4.0BLE");
}
break;
case CBManagerStateUnauthorized:
{
NSLog(@">>>>>>> 未授权打开蓝牙");
}
break;
default:
break;
}
}
/* 发现外设设备
* central 中心设备
* peripheral 外围设备
* advertisementData 特征数据
* RSSI 信号强度
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
// 该方法会返回找到的peripheral(如果你设置了外设过滤,那么只能找到你过滤之后的外设),所以可以使用数组将找到的 peripheral 存起来
NSMutableString *string = [NSMutableString stringWithString:@"\n"];
// 外设的名字
[string appendFormat:@"NAME: %@\n",peripheral.name];
// 外设UUID
[string appendFormat:@"UUID(identifier):%@\n",peripheral.identifier];
// 外设的信号强度
[string appendFormat:@"RSSI:%@\n",RSSI];
// 外设的特征数据
[string appendFormat:@"advertisementData:%@\n",advertisementData];
NSLog(@"发现的外设信息:%@",string);
// 连接指定的设备 自定义方法
[self connectPeripheral:peripheral];
}
// 外设连接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
// 在这个方法中,可以去记录当前的连接状态等数据
NSLog(@"当前【%@】外设连接状态 -->【成功】",peripheral.name);
// 一旦外设连接成功,中心设备便要调用停止扫描外设
[central stopScan];
// 扫描外设中的服务和特征,自定义方法
[self discoverPeripheralServices:peripheral];
}
// 连接外设失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"当前【%@】外设连接状态 -->【失败】",peripheral.name);
}
// 连接外设断开,协议方法
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(@"当前【%@】外设连接状态 -->【断开】", peripheral.name);
}
#pragma mark - 外设代理
#pragma mark -
// 扫描到外设服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
// 如果有错误
if (error) {
NSLog(@"发现【%@】外设的服务。存在【%@】错误",peripheral.name, error.localizedDescription);
}
// 框架 提供了 CBService 类来表示 service,找到以后,它们以数组的形式存入了当前 peripheral 的 services 属性中,你可以在当前回调中遍历这个属性。
for (CBService *service in peripheral.services) {
NSLog(@"扫描到外设服务:【%@】",service);
// 1、如果是搜索的全部 service 的话,你可以选择在遍历的过程中,去对比 UUID 是不是你要找的那个,进行筛选
// 2、扫描服务的所有特征(传nil则表示所有服务的特征)
[peripheral discoverCharacteristics:nil forService:service];
}
}
// 扫描到服务的特征
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
// 如果有错误
if (error) {
NSLog(@"发现服务【%@】的特征。存在【%@】错误",service.UUID, error.localizedDescription);
return;
}
// 此时 框架 提供了 CBCharacteristic 类来表示 characteristic。可以通过以下代码来遍历找到的 characteristic。
for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(@"扫描到服务【%@】 的特征【%@】", service.UUID, characteristic.UUID);
#warning【重点※※】:characteristic 包含了 service 要传输的数据。获取特征的值。 当readValueForCharacteristic获取到特征的值之后会回调协议方法:peripheral:didUpdateValueForCharacteristic:error: 其中包含了要读取的数据。如果读取正确,可以用 NSData *data = characteristic.value; 来获得值。其实 readValueForCharacteristic 获取值并不是实时获取的,如果数据需要连续传输,那么就需要订阅 characteristic 了!!!
// 接收数据方法根据实际情况选择(1或者2)
// 1、手动接收特征数据(适用于数据传输不是实时)
[peripheral readValueForCharacteristic:characteristic];
// 搜索特征的描述(Descriptors)
[peripheral discoverDescriptorsForCharacteristic:characteristic];
// // 2、自动接收特征数据,订阅特征(适用于实时传输数据)
// [self notifyCharacteristic:peripheral characteristic:characteristic];
// if (!characteristic.isNotifying) {
// // 2.1、如果使用订阅实时接收数据的话,需要判断,如果特征不再发送数据时,则需要结束订阅
// [self cancelNotifyCharacteristic:peripheral characteristic:characteristic];
// // 2.2、断开连接【注意】cancelPeripheralConnection:是非阻塞性的,如果在外设挂起的状态去尝试断开连接,可以能执行可能不执行,但当决定断开外设时,会调用 centralManager:didDisconnectPeripheral:error: 方法。
// [self.centralManager cancelPeripheralConnection:peripheral];
// }
// 连接成功,开始配对,发送第一次校验的数据(也就是说往characteristic(特征)中写入数据去做校验),自定义方法
// [self writeCharacteristic:peripheral characteristic:characteristic value:self.pairAuthDatas[0]];
}
}
// 获取到特征的值(如果订阅了特征,那么订阅成功之后,那么数据便会实时的传回执行此回调放)
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
// value 的类型是 NSData,需要自己进行数据转换解析
NSLog(@"获取到特征【%@】的值【%@】", characteristic.UUID, [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding]);
// 获取特征的值【注意】不是所有 characteristic 的值都是可读的,你可以通过 CBCharacteristicPropertyRead options 来进行判断。如果你尝试读取不可读的数据,那上面的代理方法会返回相应的 error。
if (characteristic.properties & CBCharacteristicPropertyRead) {
NSData *data = characteristic.value;
NSLog(@"获取特征的值【%@】",data);
}
}
// 搜索到特征的描述Descriptors
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
for (CBDescriptor *descriptor in characteristic.descriptors) {
NSLog(@"搜索到特征:%@ 的 Descriptors:%@", characteristic.UUID, descriptor.UUID);
// 获取到 描述 的值
[peripheral readValueForDescriptor:descriptor];
}
}
// 获取到 描述Descriptors 的值
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error{
// 这个 descriptor 都是对于特征的描述,一般都是字符串
NSLog(@"获取到 描述Descriptors【%@】 的值【%@】", descriptor.UUID, descriptor.value);
// 3、手环返回数据
[self deciceCommandInit:peripheral];
}
// 写数据到特征中完成
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
// 如果数据写入特征失败,返回错误
if (error) {
NSLog(@"数据写入特征发生【%@】错误", [error localizedDescription]);
}else {
NSLog(@"写数据完成到特征【%@】中完成【%@】", characteristic.UUID, characteristic.value);
}
}
// 特征订阅成功与否的回调
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
// 存在错误
if (error) {
NSLog(@"错误通知状态: %@", [error localizedDescription]);
}
}
log日志
2017-06-26 15:14:58.248367 Bluetooth[2636:850796] >>>>>>> 蓝牙已打开,开始扫描外设
2017-06-26 15:14:58.248480 Bluetooth[2636:850796] 调用【开始扫描周围外设】方法
2017-06-26 15:14:58.367056 Bluetooth[2636:850796] 发现的外设信息:
NAME: (null)
UUID(identifier):C6B4B830-3E4C-4270-970F-CD69A00B8922
RSSI:-78
advertisementData:{
kCBAdvDataIsConnectable = 1;
}
2017-06-26 15:14:58.367275 Bluetooth[2636:850796] 调用【连接指定的设备】方法
2017-06-26 15:14:59.251422 Bluetooth[2636:850796] 发现的外设信息:
NAME: SpO2023516
UUID(identifier):9B30BD01-045B-4CBD-9A0B-8FF06B1DE99F
RSSI:-66
advertisementData:{
kCBAdvDataIsConnectable = 1;
kCBAdvDataLocalName = SpO2023516;
kCBAdvDataTxPowerLevel = 2;
}
2017-06-26 15:14:59.251614 Bluetooth[2636:850796] 调用【连接指定的设备】方法
2017-06-26 15:14:59.317137 Bluetooth[2636:850796] 发现的外设信息:
NAME: (null)
UUID(identifier):E1811981-CFFA-4D00-BEE7-B4D466F9025E
RSSI:-77
advertisementData:{
kCBAdvDataIsConnectable = 0;
kCBAdvDataManufacturerData = <06000109 2000ada3 19a2941a 63cad1cf 3056112d 58a5da47 b9355065 ce>;
}
2017-06-26 15:14:59.317347 Bluetooth[2636:850796] 调用【连接指定的设备】方法
2017-06-26 15:14:59.509500 Bluetooth[2636:850796] 当前【SpO2023516】外设连接状态 -->【成功】
2017-06-26 15:14:59.572133 Bluetooth[2636:850796] 扫描到外设服务:【】
2017-06-26 15:14:59.573099 Bluetooth[2636:850796] 扫描到外设服务:【】
2017-06-26 15:14:59.577729 Bluetooth[2636:850796] 扫描到服务【Device Information】 的特征【Manufacturer Name String】
2017-06-26 15:14:59.578347 Bluetooth[2636:850796] 扫描到服务【Device Information】 的特征【Model Number String】
2017-06-26 15:14:59.578930 Bluetooth[2636:850796] 扫描到服务【Device Information】 的特征【Serial Number String】
2017-06-26 15:14:59.579367 Bluetooth[2636:850796] 扫描到服务【Device Information】 的特征【Hardware Revision String】
2017-06-26 15:14:59.579798 Bluetooth[2636:850796] 扫描到服务【Device Information】 的特征【Firmware Revision String】
2017-06-26 15:14:59.580215 Bluetooth[2636:850796] 扫描到服务【Device Information】 的特征【Software Revision String】
2017-06-26 15:14:59.580626 Bluetooth[2636:850796] 扫描到服务【Device Information】 的特征【System ID】
2017-06-26 15:14:59.581047 Bluetooth[2636:850796] 扫描到服务【Device Information】 的特征【IEEE Regulatory Certification】
2017-06-26 15:14:59.582100 Bluetooth[2636:850796] 扫描到服务【49535343-FE7D-4AE5-8FA9-9FAFD205E455】 的特征【49535343-6DAA-4D02-ABF6-19569ACA69FE】
2017-06-26 15:14:59.582467 Bluetooth[2636:850796] 扫描到服务【49535343-FE7D-4AE5-8FA9-9FAFD205E455】 的特征【49535343-ACA3-481C-91EC-D85E28A60318】
2017-06-26 15:14:59.582880 Bluetooth[2636:850796] 扫描到服务【49535343-FE7D-4AE5-8FA9-9FAFD205E455】 的特征【49535343-1E4D-4BD9-BA61-23C647249616】
2017-06-26 15:14:59.583259 Bluetooth[2636:850796] 扫描到服务【49535343-FE7D-4AE5-8FA9-9FAFD205E455】 的特征【49535343-8841-43F4-A8D4-ECBE34729BB3】
2017-06-26 15:14:59.583538 Bluetooth[2636:850796] 扫描到服务【49535343-FE7D-4AE5-8FA9-9FAFD205E455】 的特征【49535343-026E-3A9B-954C-97DAEF17E26E】
2017-06-26 15:14:59.624711 Bluetooth[2636:850796] 获取到特征【Manufacturer Name String】的值【ISSC】
2017-06-26 15:14:59.624885 Bluetooth[2636:850796] 获取特征的值【<49535343>】
2017-06-26 15:14:59.685441 Bluetooth[2636:850796] 获取到特征【Model Number String】的值【BT5050】
2017-06-26 15:14:59.685773 Bluetooth[2636:850796] 获取特征的值【<42543530 3530>】
2017-06-26 15:14:59.744974 Bluetooth[2636:850796] 获取到特征【Serial Number String】的值【8CDE52EFA344】
2017-06-26 15:14:59.745185 Bluetooth[2636:850796] 获取特征的值【<38434445 35324546 41333434>】
2017-06-26 15:14:59.806558 Bluetooth[2636:850796] 获取到特征【Hardware Revision String】的值【5050_SPP】
2017-06-26 15:14:59.806767 Bluetooth[2636:850796] 获取特征的值【<35303530 5f535050 00000000 00>】
2017-06-26 15:14:59.864906 Bluetooth[2636:850796] 获取到特征【Firmware Revision String】的值【2043032】
2017-06-26 15:14:59.865105 Bluetooth[2636:850796] 获取特征的值【<32303433 303332>】
2017-06-26 15:14:59.956905 Bluetooth[2636:850796] 获取到特征【Software Revision String】的值【0000】
2017-06-26 15:14:59.957106 Bluetooth[2636:850796] 获取特征的值【<30303030>】
2017-06-26 15:15:00.029934 Bluetooth[2636:850796] 获取到特征【System ID】的值【】
2017-06-26 15:15:00.030071 Bluetooth[2636:850796] 获取特征的值【<00000000 00000000>】
2017-06-26 15:15:00.074246 Bluetooth[2636:850796] 获取到特征【IEEE Regulatory Certification】的值【】
2017-06-26 15:15:00.074437 Bluetooth[2636:850796] 获取特征的值【<00010004 00000000>】
2017-06-26 15:15:00.256983 Bluetooth[2636:850796] 获取到特征【49535343-6DAA-4D02-ABF6-19569ACA69FE】的值【】
2017-06-26 15:15:00.257193 Bluetooth[2636:850796] 获取特征的值【<00180018 00000048 00>】
2017-06-26 15:15:00.344898 Bluetooth[2636:850796] 获取到特征【49535343-ACA3-481C-91EC-D85E28A60318】的值【】
2017-06-26 15:15:00.346958 Bluetooth[2636:850796] 搜索到特征:49535343-ACA3-481C-91EC-D85E28A60318 的 Descriptors:Client Characteristic Configuration
2017-06-26 15:15:00.464541 Bluetooth[2636:850796] 获取到特征【49535343-1E4D-4BD9-BA61-23C647249616】的值【】
2017-06-26 15:15:00.464642 Bluetooth[2636:850796] 获取特征的值【<00000000 00>】
2017-06-26 15:15:00.464920 Bluetooth[2636:850796] 搜索到特征:49535343-1E4D-4BD9-BA61-23C647249616 的 Descriptors:Client Characteristic Configuration
2017-06-26 15:15:00.556644 Bluetooth[2636:850796] 获取到特征【49535343-8841-43F4-A8D4-ECBE34729BB3】的值【】
2017-06-26 15:15:00.614704 Bluetooth[2636:850796] 获取到特征【49535343-026E-3A9B-954C-97DAEF17E26E】的值【】
2017-06-26 15:15:00.616546 Bluetooth[2636:850796] 搜索到特征:49535343-026E-3A9B-954C-97DAEF17E26E 的 Descriptors:Client Characteristic Configuration
2017-06-26 15:15:00.674995 Bluetooth[2636:850796] 获取到 描述Descriptors【Client Characteristic Configuration】 的值【0】