react-native-bt-device/ios/RNBTDevice/Device/ENBPDevice.m

416 lines
13 KiB
Objective-C
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// ENBPDevice.m
// ENBLEProject
//
// Created by lvwang2002 on 16/4/8.
// Copyright © 2016年 Facebook. All rights reserved.
//
#import "ENBPDevice.h"
#define kStartCheck @"开始测量"
#define kStopCheck @"停止测量"
// 发给血压计 (带校验码)
Byte SEND_CHECK_POWER_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x04, 0x04, 0x00, 0x01 };// 查询电量
Byte SEND_CONNECT_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x01, 0x01, 0x00, 0x01 };// 连接血压计
Byte SEND_START_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x01, 0x02, 0x00, 0x02 };// 开始测量
Byte SEND_STOP_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x01, 0x03, 0x00, 0x03 };// 停止测量
Byte SEND_CLOSE_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x01, 0x04, 0x00, 0x04 };// 关仪器
// 收到血压计之后(血压计还会回复指令)匹配是否成功的字节数组 (带校验码)
Byte RECEIVE_CHECK_POWER_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x04, 0x04, 0x04 };// 查询电量(数组中没有放入校验码,和数据共3个字节)
Byte RECEIVE_CONNECT_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x03, 0x01, 0x01, 0x00, 0x01 };// 连接血压计
Byte RECEIVE_START_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x03, 0x01, 0x02, 0x00, 0x02 };// 开始测量
Byte RECEIVE_STOP_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x03, 0x01, 0x03, 0x00, 0x03 };// 停止测量
Byte RECEIVE_CLOSE_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x03, 0x01, 0x04, 0x00, 0x04 };// 关仪器
Byte RECEIVE_RESULT[] = { 0xaa, 0x85, 0x02, 0x0f, 0x01};// 接收结果
Byte error_state_a = 0x01;// 请检查血压计佩戴是否正确
Byte error_state_b = 0x02;// 血压计袖带过松或漏气
Byte error_state_c = 0x04;// 请保持安静 ,重新测量
Byte error_state_d = 0x07;// 血压计电量低,请充电
Byte error_state_e = 0x15;// 测量出错,请重新测量 EE21
@implementation ENBPDevice{
BOOL _connected;
NSArray *_characteristics;
}
-(id)initWithPeripheral:(CBPeripheral *)peripheral WithCentralManager:(CBCentralManager *)centerManager WithDevice:(BLEDevice *)device{
self = [super initWithPeripheral:peripheral WithCentralManager:centerManager WithDevice:device];
if(self){
_connected = NO;
}
return self;
}
/**
* 4.发现外围服务
*
* @param peripheral 外围设备
* @param error 错误信息
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
if (error){
NSLog(@"didDiscoverServices : %@", [error localizedDescription]);
// [self cleanup];
return;
}
for (CBService * service in _peripheral.services) {
/**
* 查找自己需要的UUID的服务
*/
if ([[_device.advertisementData[@"kCBAdvDataServiceUUIDs"] firstObject] isEqual:service.UUID]) {
/**
* 查找外围设备特性
*/
[_peripheral discoverCharacteristics:nil forService:service];
return;
}
}
}
/**
* 5.发现外围设备特性
*
* @param peripheral 外围设备
* @param service 外围设备服务
* @param error 错误信息
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
if (error){
NSLog(@"didDiscoverCharacteristicsForService error : %@", [error localizedDescription]);
return;
}
_characteristics = service.characteristics;
/**
* 开启通知(外围设备发数据能收到) service.characteristics 里面两个FFF1(通知的) FFF2(写入的)
*/
[_peripheral setNotifyValue:YES forCharacteristic:[service.characteristics firstObject]];
[_peripheral writeValue:[NSData dataWithBytes:SEND_CONNECT_PRESSURE length:8] forCharacteristic:[service.characteristics lastObject] type:CBCharacteristicWriteWithoutResponse];
}
/**
* 6.发送数据到外围设备回调
*
* @param peripheral 外围设备
* @param characteristic 外围设备特性
* @param error 错误信息
*/
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
NSLog(@"%@---",error);
}
/**
* 6.外围设备发送数据到蓝牙中心
*
* @param peripheral 外围设备
* @param characteristic 外围设备特性
* @param error 错误信息
*/
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
// byte error_state_a = 0x01;// 请检查血压计佩戴是否正确
// byte error_state_b = 0x02;// 血压计袖带过松或漏气
// byte error_state_c = 0x04;// 请保持安静 ,重新测量
// byte error_state_d = 0x07;// 血压计电量低,请充电
// // byte error_state_e = 0x15;// 测量出错,请重新测量 EE21
NSData *data = characteristic.value;
Byte * byte = (Byte *)[data bytes];
//判断是否是连接
{
NSData * connectData = [NSData dataWithBytes:RECEIVE_CONNECT_PRESSURE length:8];
BOOL flag = NO;
if (connectData.length == data.length) {
for (int i=0; i<connectData.length; i++) {
if (RECEIVE_CONNECT_PRESSURE[i] != byte[i]) {
flag = YES;
break;
}
}
}else{
flag = YES;
}
if(!flag){
_connected = YES;
if([self.deviceDelegate respondsToSelector:@selector(onConnectedBPWithDevice:)]){
[(id)self.deviceDelegate onConnectedBPWithDevice:_device];
};
return;
}
}
//获取电池电量
{
NSData * powerData = [NSData dataWithBytes:RECEIVE_CHECK_POWER_PRESSURE length:6];
BOOL power = YES;
if (data.length >= powerData.length) {
for (NSInteger i = 0; i<powerData.length; i++) {
if (RECEIVE_CHECK_POWER_PRESSURE[i] != byte[i]) {
power = NO;
break;
}
}
}else{
power = NO;
}
if(power){
NSMutableArray * array = [NSMutableArray array];
for(int i=0;i<[data length];i++){
NSString *newHexStr = [NSString stringWithFormat:@"%x",byte[i]]; ///16进制数
if([newHexStr length]==1){
newHexStr = [NSString stringWithFormat:@"0%@",newHexStr];
}
[array addObject:newHexStr];
}
/** 计算电池电量 */
unsigned long batteryPower = strtoul([[NSString stringWithFormat:@"%@%@",array[array.count - 3],array[array.count - 2]] UTF8String], 0, 16);
NSLog(@"%ld",strtoul([[NSString stringWithFormat:@"%@%@",array[array.count - 3],array[array.count - 2]] UTF8String], 0, 16));
if(batteryPower<3600){
dispatch_async(dispatch_get_main_queue(), ^{
if([self.deviceDelegate respondsToSelector:@selector(onLowPowerWithDevice:)]){
[(id)self.deviceDelegate onLowPowerWithDevice:_device];
}
});
return;
}
// 发送消息到外围设备
[_peripheral writeValue:[NSData dataWithBytes:SEND_START_PRESSURE length:8] forCharacteristic:[_characteristics lastObject] type:CBCharacteristicWriteWithoutResponse];
dispatch_async(dispatch_get_main_queue(), ^{
if([self.deviceDelegate respondsToSelector:@selector(onBatteryPower:WithDevice:)]){
[(id)self.deviceDelegate onBatteryPower:batteryPower WithDevice:_device];
}
});
return;
}
}
//血压过程数据
{
if (data.length == 13) {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil];
NSMutableArray * array = [NSMutableArray array];
for(int i=0;i<[data length];i++){
NSString *newHexStr = [NSString stringWithFormat:@"%d",byte[i]]; ///10进制数
if([newHexStr length]==1){
newHexStr = [NSString stringWithFormat:@"0%@",newHexStr];
}
[array addObject:newHexStr];
}
// int d5 = UtilityBase.toTenInt(dataList
// .get(totalSize - 7));
// NSLog(@"%@",array);
NSInteger d4 = [array[array.count - 6] integerValue];
// int d3 = UtilityBase.toTenInt(dataList
// .get(totalSize - 5));
// int d2 = UtilityBase.toTenInt(dataList
// .get(totalSize - 4));
NSInteger d1 = [array[array.count - 3] integerValue];
// int d0 = UtilityBase.toTenInt(dataList
// .get(totalSize - 2));
NSInteger p = (d4 << 8) + (d4 ^ d1);
// self.numLabel.text = [NSString stringWithFormat:@"%03ld",(long)p];
[self performSelector:@selector(onDeviceStopTest) withObject:nil afterDelay:6];
dispatch_async(dispatch_get_main_queue(), ^{
if([self.deviceDelegate respondsToSelector:@selector(onProgressValue:WithDevice:)]){
[(id)self.deviceDelegate onProgressValue:p WithDevice:_device];
}
});
return;
}
}
//血压测量结果
{
if(data.length == 20){
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil];
NSData * resultData = [NSData dataWithBytes:RECEIVE_RESULT length:5];
if (data.length >= resultData.length) {
for (NSInteger i = 0; i<resultData.length; i++) {
if (RECEIVE_RESULT[i] != byte[i]) {
return;
}
}
}
// [self.noResponseTime invalidate];
// self.noResponseTime = nil;
NSMutableArray * array = [NSMutableArray array];
for(NSInteger i=0;i<[data length];i++){
NSString *newHexStr = [NSString stringWithFormat:@"%d",byte[i]]; ///10进制数
[array addObject:newHexStr];
}
NSInteger pul_0 = [array[array.count - 2] integerValue];
NSInteger pul_1 = [array[array.count - 3] integerValue];
NSInteger dia_0 = [array[array.count - 4] integerValue];
NSInteger dia_1 = [array[array.count - 5] integerValue];
NSInteger sys_0 = [array[array.count - 6] integerValue];
NSInteger sys_1 = [array[array.count - 7] integerValue];
NSInteger pul = pul_1 ^ pul_0; // 脉搏
NSInteger dia = dia_1 ^ dia_0; // 舒张压
NSInteger sys = sys_1 ^ sys_0; // 收缩压
NSString *result= [NSString stringWithFormat:@"脉搏:%ld舒张压:%ld收缩压:%ld",(long)pul,(long)dia,(long)sys];
NSLog(@"result:%@",result);
// [self saveAndPostWithPul:pul andDia:dia andSys:sys];
NSDictionary *info = @{
@"pul":@(pul),
@"dia":@(dia),
@"sys":@(sys)
};
dispatch_async(dispatch_get_main_queue(), ^{
[(id)self.deviceDelegate onResult:info WithDevice:_device];
});
return;
}
}
//血压测量错误
{
if (data.length == 8){
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil];
NSData * stopCheckData = [NSData dataWithBytes:RECEIVE_STOP_PRESSURE length:8];
BOOL flag1 = NO;
BOOL flag2 = NO;
if (stopCheckData.length == data.length) {
for (int i=0; i<stopCheckData.length; i++) {
if (RECEIVE_STOP_PRESSURE[i] != byte[i]) {
flag1 = YES;
// break;
}
if (RECEIVE_CLOSE_PRESSURE[i] != byte[i]) {
flag2 = YES;
}
}
}
if (flag1 == NO || flag2 == NO) {
// self.startCheck = NO;
// [self.noResponseTime invalidate];
// self.noResponseTime = nil;
}
// 血压测量异常错误提示
BOOL error = NO;
NSString *errorInfo;
if(byte[6] == error_state_a) // EE1
{
// [MBProgressHUD showLineMessage:@"请检查血压计佩戴是否正确"];
errorInfo = @"请检查血压计佩戴是否正确";
error = YES;
}else if (byte[6] == error_state_b) // EE2
{
// [MBProgressHUD showLineMessage:@"血压计袖带过松或漏气"];
errorInfo = @"血压计袖带过松或漏气";
error = YES;
}else if (byte[6] == error_state_c) // EE4
{
// [MBProgressHUD showLineMessage:@"请保持安静重新测量"];
errorInfo = @"请保持安静重新测量";
error = YES;
}else if (byte[6] == error_state_d) // EE7
{
// [MBProgressHUD showLineMessage:@"血压计电量低,请充电"];
errorInfo = @"血压计电量低,请充电";
error = YES;
} else if (byte[6] == error_state_e) { // EE21
// [MBProgressHUD showLineMessage:@"测量出错,请重新测量"];
errorInfo = @"测量出错,请重新测量";
error = YES;
}
if (error) {
// self.startCheck = NO;
// [self.noResponseTime invalidate];
// self.noResponseTime = nil;
// [self back];
dispatch_async(dispatch_get_main_queue(), ^{
if([self.deviceDelegate respondsToSelector:@selector(onError:WithDevice:)]){
[(id)self.deviceDelegate onError:errorInfo WithDevice:_device];
};
});
}
}
return;
}
}
/* 开始测量 */
-(void)startTest{
if(_peripheral == nil || _characteristics == nil){
return;
}
if(_characteristics.count <= 0){
return;
}
[_peripheral writeValue:[NSData dataWithBytes:SEND_CHECK_POWER_PRESSURE length:8] forCharacteristic:[_characteristics lastObject] type:CBCharacteristicWriteWithoutResponse];
}
/** 停止测量 */
-(void)stopTest{
if(_peripheral == nil || _characteristics == nil){
return;
}
if(_characteristics.count <= 0){
return;
}
dispatch_async([[ENBLEDeviceManager shareDeviceManager] getPostQueue], ^{
[_peripheral writeValue:[NSData dataWithBytes:SEND_STOP_PRESSURE length:8] forCharacteristic:[_characteristics lastObject] type:CBCharacteristicWriteWithoutResponse];
});
}
-(void)onDeviceStopTest{
dispatch_async(dispatch_get_main_queue(), ^{
if([self.deviceDelegate respondsToSelector:@selector(onError:WithDevice:)]){
[(id)self.deviceDelegate onError:@"设备停止测量" WithDevice:_device];
}
});
}
/** 得到设备显示名字 */
-(NSString *)getDeviceDisplayName{
return @"脉搏波血压计";
}
@end