// // ENPangaoBPDevice.m // ENBLEProject // // Created by lvwang2002 on 16/5/8. // Copyright © 2016年 Facebook. All rights reserved. // #import "ENPangaoBPDevice.h" static NSString *UUID_BTLE_SERVICE = @"0000fc00-0000-1000-8000-00805f9b34fb"; static NSString *UUID_BTLE_SEND = @"0000fca0-0000-1000-8000-00805f9b34fb"; static NSString *UUID_BTLE_RECEIVE = @"0000fca1-0000-1000-8000-00805f9b34fb"; static NSString *UUID_BTLE_SETTING_CODE = @"0000fca2-0000-1000-8000-00805f9b34fb"; @implementation ENPangaoBPDevice{ CBCharacteristic *_sendCharacteristic; CBCharacteristic *_settingCharacteristic; NSTimer *_timer; BOOL _isReceivedFlag; BOOL _isAllowSendBattery; } -(instancetype)initWithPeripheral:(CBPeripheral *)peripheral WithCentralManager:(CBCentralManager *)centerManager WithDevice:(BLEDevice *)device{ self = [super initWithPeripheral:peripheral WithCentralManager:centerManager WithDevice:device]; if(self){ _isReceivedFlag = false; _isAllowSendBattery = false; } return self; } - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{ //找到服务,开始扫描指定的服务 NSArray *array = [peripheral services]; for( CBService *service in array ){ // NSString *uuid = [NSString stringWithFormat:@"%@",service.UUID]; CBUUID *serviceUUID = [CBUUID UUIDWithString:UUID_BTLE_SERVICE]; // ENDLog([NSString stringWithFormat:@"service uuid%@",serviceUUID]); if([serviceUUID isEqual:service.UUID]){ NSArray *uuids = @[[CBUUID UUIDWithString:UUID_BTLE_SEND], [CBUUID UUIDWithString:UUID_BTLE_RECEIVE], [CBUUID UUIDWithString:UUID_BTLE_SETTING_CODE]]; [peripheral discoverCharacteristics:uuids forService:service]; break; } } } - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error;{ CBUUID *sendUUID = [CBUUID UUIDWithString:UUID_BTLE_SEND]; CBUUID *receiveUUID = [CBUUID UUIDWithString:UUID_BTLE_RECEIVE]; CBUUID *settingServiceUUID = [CBUUID UUIDWithString:UUID_BTLE_SETTING_CODE]; for( CBCharacteristic *characteristic in service.characteristics){ NSString *log =[NSString stringWithFormat:@"characteristic is %@",characteristic]; ENLog(log); if([characteristic.UUID isEqual:settingServiceUUID]){ _settingCharacteristic = characteristic; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), [[ENBLEDeviceManager shareDeviceManager] getPostQueue], ^{ [self sendSettingCode]; }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.8 * NSEC_PER_SEC)), [[ENBLEDeviceManager shareDeviceManager] getPostQueue], ^{ [self sendStatusConnected]; }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), [[ENBLEDeviceManager shareDeviceManager] getPostQueue], ^{ [self sendGetBatteryValue]; }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), [[ENBLEDeviceManager shareDeviceManager] getPostQueue], ^{ _isAllowSendBattery = true; if(!_isReceivedFlag){ [[_device getDeviceManager] uhoh:_device]; } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if([(id)self.deviceDelegate respondsToSelector:@selector(onCheckConnectFinishWithDevice:Status:)]){ [(id)self.deviceDelegate onCheckConnectFinishWithDevice:_device Status:_isReceivedFlag]; } }); }); continue; } if([characteristic.UUID isEqual:sendUUID]){ _sendCharacteristic = characteristic; continue; } if([characteristic.UUID isEqual:receiveUUID]){ [peripheral setNotifyValue:YES forCharacteristic:characteristic]; } } } - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{ CBUUID *receiveUUID = [CBUUID UUIDWithString:UUID_BTLE_RECEIVE]; if( [receiveUUID isEqual:characteristic.UUID]){ [[ENDLog share] log:[NSString stringWithFormat:@"receive gluco data:%@",characteristic.value]]; [self handlerReceivedData:characteristic.value]; } } /* 发送设置码 */ -(void)sendSettingCode { const unsigned char data[15] ={0xf0, 0xD2, 0xa9, 0xC6, 0x0F, 0x01, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; NSData *sendData = [NSData dataWithBytes:data length:15]; [_peripheral writeValue:sendData forCharacteristic:_settingCharacteristic type:CBCharacteristicWriteWithResponse]; } /** 发送连接状态 */ -(void)sendStatusConnected{ const unsigned char data[4] ={0x04,0xa1,0xa0,0x45}; NSData *sendData = [NSData dataWithBytes:data length:4]; [self sendData:sendData]; } /** 开始测量 */ -(void)startTest{ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil]; [self sendStartTest]; } /** 停止测量 */ -(void)stopTest{ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil]; [self sendStopTest]; } /** 开始测量 */ -(void)sendStartTest{ ENLog(@"开始测量"); const unsigned char data[4] = {0x04,0xa1,0xa1,0x46}; NSData *sendData = [NSData dataWithBytes:data length:4]; [self sendData:sendData]; } /** 停止测量 */ -(void)sendStopTest{ ENLog(@"发送停止测量"); const unsigned char data[4] = {0x04,0xa1,0xa2,0x47}; NSData *sendData = [NSData dataWithBytes:data length:4]; [self sendData:sendData]; } /** 获取电量 */ -(void)sendGetBatteryValue{ ENLog(@"获取电量"); unsigned char data[4] = {0x04,0xa1,0xa5,0x4a}; NSData *sendData = [NSData dataWithBytes:data length:4]; [self sendData:sendData]; } /** 获取设备id */ -(void)sendGetDeviceID{ ENLog(@"获取DeviceID"); const unsigned char data[4] = {0x04,0xa1,0xa4,0x49}; NSData *sendData = [NSData dataWithBytes:data length:4]; [self sendData:sendData]; } /** 血压计关机 */ -(void)sendPowerOffDevice{ ENLog(@"要求设备关机"); const unsigned char data[4] = {0x04,0xa1,0xa6,0x4b}; NSData *sendData = [NSData dataWithBytes:data length:4]; [self sendData:sendData]; } /** 设置血压ID */ -(void)sendSetDeviceID{ ENLog(@"设置DeviceID"); const unsigned char data[7] = {0x07,0xa1,0xa3,0x01,0xff,0xaa,0xf5}; NSData *sendData = [NSData dataWithBytes:data length:7]; [self sendData:sendData]; } /** 查询咨询密码 */ -(void)searchSettingCode{ ENLog(@"查询配置码"); const unsigned char data[4] = {0x04,0x55,0xaa,0x03}; NSData *sendData = [NSData dataWithBytes:data length:4]; [self sendData:sendData]; } /** 设置血压计日期 */ -(void)sendSetDeviceDate{ ENLog(@"设置日期"); const unsigned char data[7] = {0x07,0xa1,0xa8,0x0e,0x0a,0x08,0x70}; NSData *sendData = [NSData dataWithBytes:data length:7]; [self sendData:sendData]; } /** 设置血压时间 */ -(void)sendSetDeviceTime{ ENLog(@"设置时间"); const unsigned char data[7] = {0x07,0xa1,0xa9,0x17,0x2d,0x08,0x9d}; NSData *sendData = [NSData dataWithBytes:data length:7]; [self sendData:sendData]; } /** 读取血糖历史 */ -(void)sendGetHistory{ ENLog(@"获取历史数据"); const unsigned char data[4] = {0x04,0xa1,0xac,0x51}; NSData *sendData = [NSData dataWithBytes:data length:4]; [self sendData:sendData]; } /** 断开蓝牙 */ -(void)sendTurnOffBT{ ENLog(@"断开蓝牙"); const unsigned char data[4] = {0x04,0xa1,0xad,0x52}; NSData *sendData = [NSData dataWithBytes:data length:4]; [self sendData:sendData]; } /** 发送数据 */ -(void)sendData:(NSData *)data{ if(_peripheral == nil || _sendCharacteristic == nil){ //如果附件和属性有为空项,不发送. return; } dispatch_async([[ENBLEDeviceManager shareDeviceManager] getPostQueue], ^{ [_peripheral writeValue:data forCharacteristic:_sendCharacteristic type:CBCharacteristicWriteWithResponse]; }); } #pragma mark - #pragma mark 接收处理函数 /** 对接收的数据进行处理 */ -(void)handlerReceivedData:(NSData *)data{ Byte byteData[20]; [data getBytes:byteData length:data.length]; if(data.length<4){ return; } if(byteData[0] != data.length){ ENLog(@"指令长度不符"); return; } Byte commandFlag = byteData[2]; switch (commandFlag){ case 0x55:{ // Log.i(TAG,"配置码:"+data[2]+" "+data[3]); NSString *code = [NSString stringWithFormat:@"配置码:%d %d",byteData[2],byteData[3]]; ENLog(code); } break; case 0xb1:{ //血压计通知开始测量 ENLog(@"start test"); dispatch_async(dispatch_get_main_queue(), ^{ if([(id)self.deviceDelegate respondsToSelector:@selector(onStartTestWithDevice:)]){ [(id)self.deviceDelegate onStartTestWithDevice:_device]; } }); } break; case 0xb2:{ //血压计通知测量停止测量 ENLog(@"stop test"); dispatch_async(dispatch_get_main_queue(), ^{ if([self.deviceDelegate respondsToSelector:@selector(onStopTestWithDevice:)]){ [(id)self.deviceDelegate onStopTestWithDevice:_device]; } }); } break; case 0xb3:{ //血压计通知正在归零 // Log.i(TAG,"stop test start zero"); ENLog(@"stop test start zero"); } break; case 0xb4:{ //血压计通知归零结束 // Log.i(TAG,"stop test stop zero"); ENLog(@"stop test stop zero"); dispatch_async(dispatch_get_main_queue(), ^{ if([self.deviceDelegate respondsToSelector:@selector(onStopZeroWithDevice:)]){ [(id)self.deviceDelegate onStopZeroWithDevice:_device]; } }); } break; case 0xb5:{ // Log.i(TAG,"电池电量:"+data[3]); _isReceivedFlag = true; if(!_isAllowSendBattery){ return; } NSUInteger power = (NSUInteger)byteData[3]; dispatch_async(dispatch_get_main_queue(), ^{ if([self.deviceDelegate respondsToSelector:@selector(onPower:WithDevice:)]){ [(id)self.deviceDelegate onPower:(int)power WithDevice:_device]; } // if(power<50){ // //小于50电量不足 // if([self.deviceDelegate respondsToSelector:@selector(onError:WithDevice:)]){ // [(id)self.deviceDelegate onError:@"电量不足,请更换电池" WithDevice:_device]; // } // return; // } // // [self sendStartTest]; }); } break; case 0xb6:{ // Log.i(TAG,"ID号:"+data[3]+data[4]+data[5]); } break; case 0xb7:{ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil]; //血压计发送过程数据 Boolean isHeart = ((byteData[3] & 0b00010000) == 0b00010000); int value = (byteData[3] & 0x0f)*256 + byteData[4]; //Log.i(TAG,"blood value:"+value+" is heart:"+isHeart); // [self performSelector:@selector(onDeviceStopTest) withObject:nil afterDelay:6]; dispatch_async(dispatch_get_main_queue(), ^{ if([self.deviceDelegate respondsToSelector:@selector(onProgressValue:IsHeart:WithDevice:)]){ [(id)self.deviceDelegate onProgressValue:value IsHeart:isHeart WithDevice:_device]; } }); } break; case 0xb8:{ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil]; //血压计发送测量结果 Boolean isHeart = ((byteData[3] & 0b10000000) == 0b10000000); int sysValue = ((byteData[3] & 0x0f))*256 + (byteData[4]&0xff); int diaValue = byteData[5] ; int pulValue = byteData[6] ; //Log.i(TAG,"dia value:"+diaValue+" sys value:"+sysValue); //Log.i(TAG,"pul:"+pulValue+"is heart:"+isHeart); NSDictionary *info = @{ @"dia":@(diaValue), @"sys":@(sysValue), @"pul":@(pulValue), @"isHeart":@(isHeart) }; dispatch_async(dispatch_get_main_queue(), ^{ if([self.deviceDelegate respondsToSelector:@selector(onResult:WithDevice:)]){ [(id)self.deviceDelegate onResult:info WithDevice:_device]; } }); } break; case 0xb9:{ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil]; //血压计发送测量错误信息 // Log.i(TAG,"error:"+data[3]); NSArray *errorInfos = @[@"测量不到有效脉搏", @"气袋没绑好", @"测量结果数值有误", @"进入超压保护", @"测量中干预过多"]; NSString *errorInfo = errorInfos[byteData[3]]; NSDictionary *error = @{ @"errorCode":@(byteData[3]).stringValue, @"error":errorInfo }; dispatch_async(dispatch_get_main_queue(), ^{ if([self.deviceDelegate respondsToSelector:@selector(onError:WithDevice:)]){ [(id)self.deviceDelegate onError:error WithDevice:_device ]; } }); } break; case 0xba:{ //血压计发送关机信号 // Log.i(TAG,"血压计发送关机信号"); ENLog(@"血压计发送关机信号"); dispatch_async(dispatch_get_main_queue(), ^{ if([self.deviceDelegate respondsToSelector:@selector(onTurnOffWithDevice:)]){ [(id)self.deviceDelegate onDeviceShutDownWithDevice:_device]; } }); } break; case 0xbb:{ //血压计发送低电信号 // Log.i(TAG,"血压计发送低电信号"); ENLog(@"血压计发送低电信号"); dispatch_async(dispatch_get_main_queue(), ^{ if([self.deviceDelegate respondsToSelector:@selector(onError:WithDevice:)]){ NSDictionary *error = @{ @"errorCode":@"101", @"error":@"电量不足,请更换电池" }; [(id)self.deviceDelegate onError:error WithDevice:_device]; } }); } break; case 0xbc:{ //接收时间设置 // Log.i(TAG,"血压计时间设置成功"); ENLog(@"血压计时间设置成功"); } break; } } -(void)onDeviceStopTest{ dispatch_async(dispatch_get_main_queue(), ^{ if([self.deviceDelegate respondsToSelector:@selector(onError:WithDevice:)]){ NSDictionary *error = @{ @"errorCode":@"102", @"error":@"设备停止测量" }; [(id)self.deviceDelegate onError:error WithDevice:_device]; } }); } /** 得到设备显示名字 */ -(NSString *)getDeviceDisplayName{ return @"攀高电子血压计"; } @end