#import <Foundation/Foundation.h>
 #import <CoreBluetooth/CoreBluetooth.h>
 #import <AudioToolbox/AudioToolbox.h> #define channelOnPeropheral @"BleContectModelChannel"
 NS_ASSUME_NONNULL_BEGIN
@interface BleContectModel : NSObject
@property(strong, nonatomic)FBluetooth *Fblue;//蓝牙类
 @property __block NSMutableArray *services;//蓝牙服务数组
 @property(strong,nonatomic)dispatch_source_t gcdTimer;
 @property(strong,nonatomic)CBPeripheral *currPeripheral;//蓝牙硬件
 @property(strong, nonatomic)NSMutableData *bluedata;
 @property(strong, nonatomic)NSString *datelength;//返回数据长度计算
 @property(strong, nonatomic)CBCharacteristic *writeCharacteristic;//写入特征
 @property(assign, nonatomic)BOOL isKey;//是否是加密数据
 @property(assign, nonatomic)BOOL blockIsSendData;//判断连接蓝牙后是否直接发送数据
 @property(assign, nonatomic)BOOL timerIsRun;//判断定时器是否运行
 @property(assign, nonatomic)NSInteger gcdIdx;
 @property (nonatomic, copy) void(^block25)(void);//新设备绑定,发送手机号返回结果
 @property (nonatomic, copy) void(^block23)(void);//新设备绑定,时间同步返回结果
 @property (nonatomic, copy) void(^block36)(void);//新设备绑定,验证信道密码
 @property (nonatomic, copy) void(^block34)(void);//新设备绑定,注册设备
 @property (nonatomic, copy) void(^sendbindblock)(void);//新设备绑定,加密后block返回
 @property (nonatomic, copy) void(^blueErrorBlock)(NSString *error);  //新设备绑定,蓝牙返回错误
 @property (nonatomic, copy) void(^blueSendData)(void); //block 蓝牙返回的数据 //初始化
 + (instancetype)shared;
 //发送cmd命令到蓝牙,并等待返回数据
 + (void)sendDatacmd:(NSString *)packetType
        packetLength:(NSString *)packetLength
                 cmd:(NSString *)cmd
             payload:(NSString *)payload
            nativeId:(NSString *)nativeId
             success:(void (^)(NSString *msg))success
                fail:(void (^)(NSString *msg))fail;
 //绑定设备
 + (void)bindBlowerDevice:(NSString *)phone success:(void (^)(NSString *msg))success fail:(void (^)(NSString *msg))fail;
 + (void)bisciddsex:(NSData *)data;
 -(void)FblueDelegate:(NSString *)bind;
 -(void)CBPeripheralManagerStatePoweredOn;//  校验CRC
 - (BOOL)checkCRC:(NSData *)didGetData;
 // 断开后重连
 -(void)beginscan;@end
----------------------  .m文件 -----------------------
#import "BleContectModel.h"


 #import "NSTimer+Addition.h"
 #import "NoumenonModel.h"
 #import "YUTimer.h"
 #import "Common.h"
 #import "DataMgr.h"
   #define blueName @"蓝牙名字"
 #define uuidStrHont0        @"自己的UUID"
 #define uuidWrite           @"自己的UUID"
 #define uuidNotify2         @"自己的UUID"
 #define uuidHistoryNotify3  @"自己的UUID"//#define blueName @"蓝牙名字"
 //#define uuidStrHont @"自己的UUID"
 //#define uuidOther   @"自己的UUID"
 //#define uuidMOM     @"自己的UUID" 
// 秘钥
 uint8_t KeyaSph[16] =
 {
 };
 uint8_t KeyTSph[16] =
 {
 };
 //公钥 二进制文件
 //uint8_t Key_ContcaSph[16] =
 //{
 //    0x07, 0xba, 0x06, 0xa7, 0x66, 0xcf, 0xfd, 0xa6, 0x3b, 0x58, 0xb9, 0x63, 0x97, 0x83, 0x75, 0x5F
 //};uint8_t Key_ContcaSph[16] =
 {
     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
 };@interface SphygmomanometerBleContectModel ()<CBPeripheralDelegate>
 @property (nonatomic,strong) NSTimer* updateTimer;@property (nonatomic,assign) BOOL isRepeat;
 @property (nonatomic,assign) BOOL isCmd; //是否允许发送Cmd
 @property (nonatomic , assign) int threeIndex; // 参数three标识 未了看log 定义标识
 @property (nonatomic, strong) YUTimer *timerIndex;@property (nonatomic , copy) NSString *TypeFour;//  参数配置分发:
 @property (nonatomic , copy) NSString *modelFive; //模式
 @property (nonatomic , copy) NSString *autoHandSix; // 0:自動/1:手動/FF:skip
 @property (nonatomic , copy) NSString *flowSeven;
 @property (nonatomic , copy) NSString *longShotEight;
 @property (nonatomic , copy) NSString *otherNine;//@property (nonatomic , copy) NSString *productKey; //16位随机数秘钥
 @property (nonatomic, assign) int seqNumber;
 @property (nonatomic, strong) NoumenonModel *model; @property (nonatomic , strong) NSMutableData *subcontractData; // 分包接收 A6 数据
 @property (nonatomic , assign) BOOL isTimeOut;
 @property (nonatomic , copy) NSString *nativeId;
 @property (nonatomic , assign) BOOL dataEnd; // 数据是否接收完成
 @property (nonatomic , assign) BOOL oneFor; // 只遍历一次
 @property (nonatomic , copy) NSString *packetType;
 @property (nonatomic , copy) NSString *packetLength;
 @property (nonatomic , assign) BOOL isSecret; // 是否是秘钥
 @property (nonatomic , assign) int packLengthTmp;
 @property (nonatomic , strong) NSMutableArray *pinArray;
 @property (nonatomic , strong) CBCharacteristic *notify2Characteristic;
 @property (nonatomic , strong) CBCharacteristic *notify3Characteristic;
 @property (nonatomic , assign) BOOL onceRunning;
 @end@implementation SphygmomanometerBleContectModel
//重写init
 - (instancetype)init {
     self = [super init];
     if (self) {
         self.seqNumber = 1;
         self.model = [[NoumenonModel alloc]init];
         //初始化对象
         _Fblue = [FBluetooth shareFBluetooth];
         [_Fblue cancelAllPeripheralsConnection];
         [_Fblue cancelScan];
         _Fblue.scanForPeripherals().begin();
         _gcdTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
         
         _oneFor = NO;
         _pinArray = [[NSMutableArray alloc]init];
         //        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(CBPeripheralManagerStatePoweredOn) name:@"CBPeripheralManagerStatePoweredOn" object:nil];
     }
     return self;
 }
 //监听蓝牙是否打开
 -(void)CBPeripheralManagerStatePoweredOn{
     [_Fblue cancelAllPeripheralsConnection];
     _Fblue.scanForPeripherals().begin();
 }
 - (UIViewController *)findCurrentViewController
 {
     UIWindow *window = [[UIApplication sharedApplication].delegate window];
     UIViewController *topViewController = [window rootViewController];
     
     while (true) {
         
         if (topViewController.presentedViewController) {
             
             topViewController = topViewController.presentedViewController;
             
         } else if ([topViewController isKindOfClass:[UINavigationController class]] && [(UINavigationController*)topViewController topViewController]) {
             
             topViewController = [(UINavigationController *)topViewController topViewController];
             
         } else if ([topViewController isKindOfClass:[UITabBarController class]]) {
             
             UITabBarController *tab = (UITabBarController *)topViewController;
             topViewController = tab.selectedViewController;
             
         } else {
             break;
         }
     }
     return topViewController;
 }- (NSMutableData *)subcontractData {
     if (_subcontractData == nil) {
         _subcontractData = [[NSMutableData alloc]init];
     }
     return _subcontractData;
 }//蓝牙的block
 -(void)FblueDelegate:(NSString *)bind{
     
     self.isRepeat = YES;
     self.isCmd = NO;
     
     
     // ---- 500 毫秒 ----
     
     __weak typeof(self) weakSelf = self;
     [_Fblue setBlockOnCentralManagerDidUpdateState:^(CBCentralManager *central) {
         //手机蓝牙是否开启
         if (@available(iOS 10.0, *)) {
             if (central.state == CBManagerStatePoweredOff) {
                 if (weakSelf.blueErrorBlock != nil) {
                     weakSelf.blueErrorBlock(@"请打开蓝牙开关");
                 }
             }
         } else {
             
         }
     }];
     
     //设置扫描到设备的委托
     [_Fblue setBlockOnDiscoverToPeripherals:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
         NSLog(@"搜索到了设备:%@",peripheral.name);
         
         [[NSNotificationCenter defaultCenter] postNotificationName:@"otherBleContentSuccess" object:nil userInfo:nil];
         
         if ([peripheral.name containsString:blueName]) {
             
             
             weakSelf.currPeripheral = peripheral;
             // 搜索到了设备就停止扫描
             [weakSelf.Fblue cancelScan];
             
             if ([bind isEqualToString:@"bind"]) {
                 weakSelf.Fblue.having(weakSelf.currPeripheral).and.channel(channelOnPeropheral).then.connectToPeripherals().discoverServices().discoverCharacteristics().readValueForCharacteristic().discoverDescriptorsForCharacteristic().begin();
             } else {
                 weakSelf.Fblue.having(weakSelf.currPeripheral).and.channel(channelOnPeropheral).then.connectToPeripherals().discoverServices().discoverCharacteristics().discoverDescriptorsForCharacteristic().begin();
             }
         }
     }];
     
     //设置查找设备的过滤器
     [_Fblue setFilterOnDiscoverPeripherals:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
         NSLog(@"搜索设备:%@",peripheralName);

         if ([peripheralName containsString:blueName]) {
             return YES;
         }
         return NO;
     }];
     
     NSDictionary *scanForPeripheralsWithOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@YES};
     
     //设置设备连接成功的委托,同一个_Fblue对象,使用不同的channel切换委托回调
     [_Fblue setBlockOnConnectedAtChannel:channelOnPeropheral block:^(CBCentralManager *central, CBPeripheral *peripheral) {
         weakSelf.currPeripheral = peripheral;
         CBUUID *macServiceUUID = [CBUUID UUIDWithString:@"180A"];
         [peripheral discoverServices:@[macServiceUUID]];
         // PANAQBLE EH-XD30_B923 // 暂时 固定值 避免其他人连接 上传时把 B923删除 EH-XD30_B325是吹风机蓝牙名称
         NSLog(@"蓝牙名字:%@",peripheral.name);
         // liuwen bletest123
         if ([peripheral.name containsString:blueName]) {
             //            [[NSNotificationCenter defaultCenter] postNotification:[[NSNotification alloc]initWithName:@"deviceConnect" object:@"1" userInfo:nil]];
             //            [[NSUserDefaults standardUserDefaults] setObject:@"yes" forKey:@"deviceConnect"];
         }
     }];
     
     //设置设备连接失败的委托
     [_Fblue setBlockOnFailToConnectAtChannel:channelOnPeropheral block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
         NSLog(@"设备:%@--连接失败",peripheral.name);
         if ([peripheral.name containsString:blueName]) {
             
         }
     }];
     
     //设置设备断开连接的委托
     [_Fblue setBlockOnDisconnectAtChannel:channelOnPeropheral block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
         NSLog(@"设备:%@--断开连接",peripheral.name);
         // 想H5发送断开链接操作
         [[NSNotificationCenter defaultCenter] postNotificationName:@"SphygmomanometerBleDiscontect" object:nil userInfo:nil];
         weakSelf.updateTimer = nil;
         [weakSelf.updateTimer invalidate];
         weakSelf.currPeripheral = nil;
         weakSelf.writeCharacteristic = nil;
         weakSelf.timerIsRun = NO;
     }];
     
     //设置发现设service的Characteristics的委托 == old
     [_Fblue setBlockOnDiscoverCharacteristicsAtChannel:channelOnPeropheral block:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
         NSLog(@"===service name:%@",service.UUID);
         NSLog(@"peripheral.name:%@",peripheral.name);
         //        weakSelf.writeCharacteristic = nil;
         if ([bind isEqualToString:@"bind"]) {


             if ([service.UUID.UUIDString isEqualToString:uuidStrHont0]) {
                 // 00001C00-D102-11E2-9B23-000E5B00A5A5
                 [weakSelf insertService:service];
             }
         } else {
             
         }
     }];
     
     NSDictionary *connectOptions = @{CBConnectPeripheralOptionNotifyOnConnectionKey:@YES,
                                      CBConnectPeripheralOptionNotifyOnDisconnectionKey:@YES,
                                      CBConnectPeripheralOptionNotifyOnNotificationKey:@YES};
     
     [_Fblue setFOptionsAtChannel:channelOnPeropheral scanForPeripheralsWithOptions:scanForPeripheralsWithOptions connectPeripheralWithOptions:connectOptions scanForPeripheralsWithServices:nil discoverWithServices:nil discoverWithCharacteristics:nil];
     
     [_Fblue setBlockOnDidWriteValueForCharacteristicAtChannel:channelOnPeropheral block:^(CBCharacteristic *characteristic, NSError *error) {
         NSLog(@"---\\????\\---%@", characteristic);
     }];
     
     [weakSelf.Fblue setBlockOnReadValueForCharacteristicAtChannel:channelOnPeropheral block:^(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSError *error) {
         if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bleMAC"] == nil) {
             if ([characteristic.UUID.UUIDString isEqualToString:@"2A23"]) {
                 NSString *value = [NSString stringWithFormat:@"%@",characteristic.value];
                 NSMutableString *macString = [[NSMutableString alloc] init];
                 [macString appendString:[[value substringWithRange:NSMakeRange(12, 2)] uppercaseString]];
                 [macString appendString:[[value substringWithRange:NSMakeRange(14, 2)] uppercaseString]];
                 [macString appendString:[[value substringWithRange:NSMakeRange(16, 2)] uppercaseString]];
                 [macString appendString:[[value substringWithRange:NSMakeRange(5, 2)] uppercaseString]];
                 [macString appendString:[[value substringWithRange:NSMakeRange(7, 2)] uppercaseString]];
                 [macString appendString:[[value substringWithRange:NSMakeRange(10, 2)] uppercaseString]];
                 NSLog(@"macstring:%@", macString);
                 [[NSUserDefaults standardUserDefaults] setObject:macString forKey:@"bleMAC"];
                 if (self.sendbindblock != nil) {
                     weakSelf.sendbindblock();
                 }
             } else {
                 return;
             }
         }
     }];
 } - (void)timeer {
     __block NSInteger second = 0.8;
     //(1)
     dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     //(2)
     dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, quene);
     //(3)
     dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
     //(4)
     dispatch_source_set_event_handler(timer, ^{
         dispatch_async(dispatch_get_main_queue(), ^{
             if (second == 0) {
                 //如果超时添加Bool值
                 self.isCmd = YES;
                 self.isRepeat = YES;
                 dispatch_cancel(timer);
             } else {
                 second--;
             }
         });
     });
     //(5)
     dispatch_resume(timer);
 }
 //#pragma mark - 轮循方法
 //- (void)repeatData {
 //    if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"deviceConnect"] isEqualToString:@"yes"]) {
 //        if (self.updateTimer != nil) {
 //            NSLog(@"轮循方法");
 //            if (self.isRepeat == YES) {
 //                // 发送数据
 //                [SphygmomanometerBleContectModel sendDatacmd:@"A3" payload:@"" success:^(NSString * _Nonnull msg) {
 //                    NSLog(@"%@",msg);
 //                } fail:^(NSString * _Nonnull msg) {
 //                    NSLog(@"%@",msg);
 //                }];
 //            }
 //        }
 //    }
 //}
 //遍历获取特征
 -(void)insertService:(CBService *)service {
     
     for (int row=(int)service.characteristics.count-1;row>=0;row--) {
         NSLog(@"<<<<<<<<+++:%@", service.characteristics[row]);
         if ([service.characteristics[row].UUID.UUIDString isEqualToString:uuidWrite]) {
             _writeCharacteristic = service.characteristics[row];
         } else if ([service.characteristics[row].UUID.UUIDString isEqualToString:uuidNotify2]) {
             _notify2Characteristic = service.characteristics[row];
             // 去注册notify 一个notify服务,对应一个write服务,可以write的时候把notify的订阅开启,接收完把notify的订阅关掉
             // 关闭订阅的代码 [self->_Fblue cancelNotify:self.currPeripheral characteristic:characteristic];
             [self setnotif:service.characteristics[row]];
         } //最好把注册服务分开写
 //        else if ([service.characteristics[row].UUID.UUIDString isEqualToString:uuidHistoryNotify3]) {
 //            _notify3Characteristic = service.characteristics[row];
 //            // 不去注册notify [注]
 //            [self setnotif:service.characteristics[row]];
 //        }
     }
     [self sendrandNums];
     _isSecret = YES;
 }//发送数据到蓝牙。需要处理分包发送,每次发送20字节
 -(void)sendDatacmd:(NSString *)cmd payload:(NSString *)payload{
     if (self.currPeripheral == nil || _writeCharacteristic == nil) {
         return;
     }
     // 开订阅
     if (_notify2Characteristic != nil) {
         [self setnotif:_notify2Characteristic];
     }
     if (_notify3Characteristic != nil) {
         [self setnotif:_notify3Characteristic];
     }
     
     NSData *writeData = [self sendDatatoBlue:cmd payLoad:payload];
     for (int i = 0; i < writeData.length; i += 20) {
         if ((i + 20) <= [writeData length]) {
             NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, 20];
             NSData *subData = [writeData subdataWithRange:NSRangeFromString(rangeStr)];
             NSLog(@"subDataUUUUU:%d:%@",i,subData);
             [self.currPeripheral writeValue:subData forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithResponse];
         } else {
             NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, (int)([writeData length] - i)];
             NSData *subData = [writeData subdataWithRange:NSRangeFromString(rangeStr)];
             NSLog(@"subDataXXXXX:%d:%@",i,subData);
             [self.currPeripheral writeValue:subData forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithResponse];
         }
     }
 }//发送16位随机数,获取秘钥
 -(void)sendrandNums {
     //没有发现服务就退出,不能注释掉
     if (self.currPeripheral == nil || _writeCharacteristic == nil) {
         return;
     }
     NSString *randStr = @"";
     for (int i = 0;i<16; i++) {
         //        NSUInteger r = arc4random_uniform(255); //随机数
         
         NSUInteger r = (18 + (arc4random() % (255 - 18 + 1)));
         
         randStr = [NSString stringWithFormat:@"%@%@",randStr,[FToy getHexByDecimal:r]];
     }
     _productKey = randStr;
     NSData *tempData = [FToy convertHexStrToData:randStr];
     // 发送16位随机数时 已经把 Kaya赋值了,等待回来解析数据把解析完的数据在存入到Kaya 中
     NSData *writeData = [SphygmomanometerBleContectModel sendrandNumspayload:@[randStr]];
     
     // 保存起来 蓝牙会返回给新秘钥 用 productKey 解密  用 解出来之后的 秘钥
     // 16位随机数 写入秘钥中,蓝牙回来的时候用秘钥解密
     NSLog(@"16位随机数是:%@",_productKey);
     for (int i = 0; i < 16; i++) {
         NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, 1];
         NSData *as = [tempData subdataWithRange:NSRangeFromString(rangeStr)]; //ios 的二进制(16)
         /// 把解析回来的数据 把之前的私钥替换掉,之后发数据是都用私钥
         KeyTSph[i] = [FToy ConvertDataToInt:as];
     }
     NSLog(@"fuqiang发送随机数%@",writeData);
     for (int i = 0; i < writeData.length; i += 20) {
         if ((i + 20) <= [writeData length]) {
             NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, 20];
             NSData *subData = [writeData subdataWithRange:NSRangeFromString(rangeStr)];
             
             NSLog(@"subData+++:%d:%@",i,subData);
             [self.currPeripheral writeValue:subData forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithResponse];
         } else {
             NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, (int)([writeData length] - i)];
             NSData *subData = [writeData subdataWithRange:NSRangeFromString(rangeStr)];
             NSLog(@"subData+++:%d:%@",i,subData);
             [self.currPeripheral writeValue:subData forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithResponse];
         }
     }
 }
 //蓝牙断开后重开扫描
 -(void)beginscan{
     _Fblue = [FBluetooth shareFBluetooth];
     [_Fblue cancelAllPeripheralsConnection];
     [_Fblue cancelScan];
     _Fblue.scanForPeripherals().begin();
     [[SphygmomanometerBleContectModel shared] FblueDelegate:@"bind"];
 }
 //蓝牙监听,接受返回值
 -(void)setnotif:(CBCharacteristic *)characteristic{
     NSLog(@"????%@", characteristic.UUID);    // 把需要订阅的特正 发送给蓝牙, notify 注册yes (封装的已经做好)
     __weak typeof(self)weakSelf = self;
     [_Fblue notify:self.currPeripheral
     characteristic:characteristic
              block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
         
         NSString *dataStr = [[[[characteristics.value description] stringByReplacingOccurrencesOfString:@"<"withString:@""]stringByReplacingOccurrencesOfString:@">" withString:@""]stringByReplacingOccurrencesOfString:@" " withString:@""];
         
         NSLog(@"收到数据:%@",dataStr);
         
         if (self.blueSendData != nil) {
             self.blueSendData();
         }
         NSMutableArray *byteArray = [NSMutableArray array];
         // 美隔两个截取字符串
         for (int i = 0 ; i < dataStr.length ; i += 2) {
             NSString *strTmp = [dataStr substringWithRange:NSMakeRange(i, 2)];
             [byteArray addObject:strTmp];
         }
         if ([characteristic.UUID.UUIDString isEqualToString:uuidNotify2]) {
             if (byteArray.count > 0) {
                 if ([byteArray[0] isEqualToString:@"fd"] ) { // 秘钥反信
                     [SphygmomanometerBleContectModel keyAesDec:characteristics.value];
 //                    if(weakSelf.updateTimer == nil) {
 //                        weakSelf.updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.8 block:^{
 //                            if (self.isRepeat == YES) {
 //                                [self timeer];
 //                                // 轮询方法
 //                                //                        [self repeatData];
 //                                self.isRepeat = NO;
 //                            }
 //                        } repeats:YES];
 //                        [weakSelf.updateTimer fire];
 //                    }
                     return;
                 } else {
                     [SphygmomanometerBleContectModel bisciddsex:characteristics.value];
                     NSLog(@"--------:%@",characteristic.value);
                     
                     // 关订阅
 //                    [self->_Fblue cancelNotify:self.currPeripheral characteristic:characteristic];
                 }
             }
         }
         else { // 03一对多 不能关订阅
             [[NSUserDefaults standardUserDefaults] setObject:characteristics.value forKey:@"charValue"];
             [SphygmomanometerBleContectModel bisciddsex:characteristics.value];        }
     }];
 }#pragma mark - 锁蓝牙类方法
 //单利模式,初始化
 + (instancetype)shared {
     static SphygmomanometerBleContectModel *share = nil;
     static dispatch_once_t oneToken;
     dispatch_once(&oneToken, ^{
         share = [[SphygmomanometerBleContectModel alloc]init];
     });
     return share;
 }//发送数据到蓝牙
 - (NSData *)sendDatatoBlue:(NSString *)Cmd payLoad:(NSString *)payLoad {
     
     // 体脂秤
     _isTimeOut = YES;
     NSMutableData *newdata = [[NSMutableData alloc]init];
     
     NSData *header = [FToy convertHexStrToData:_packetType];
     NSData *length = [FToy convertHexStrToData:_packetLength];
     
     [newdata appendData:header];
     [newdata appendData:length];
     
     NSMutableData *aesData = [[NSMutableData alloc]init];
     NSData *playLoadZero = [FToy convertHexStrToData:payLoad];
     [aesData appendData:playLoadZero];
     NSData *payloadCome = [SphygmomanometerBleContectModel aesEncrypt:aesData typeFlag:2];
     
     [newdata appendData: payloadCome];
     // 原来有crc加密
     NSData *crcCome = [SphygmomanometerBleContectModel crcCome:newdata];
     [newdata appendData: crcCome];
     
     // 超时时间
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
         if (self->_isTimeOut == YES) { // 超时
             NSLog(@"%@",@"超时");
             [self centerSendData:NO data:[NSData new] errorCode:@"1"];
         } else { // 没有超时
             NSLog(@"%@",@"不超时");
         }
     });
     
     return newdata;
 }//解析返回的私钥
 + (void)keyAesDec:(NSData *)data {
     NSString *dataStr_Aes = [[[[data description] stringByReplacingOccurrencesOfString:@"<"withString:@""]stringByReplacingOccurrencesOfString:@">" withString:@""]stringByReplacingOccurrencesOfString:@" " withString:@""];
     NSInteger datelength = [FToy getDecimalByBinary:[FToy getBinaryByHex:[dataStr_Aes substringWithRange:NSMakeRange(2,2)]]];
     NSString *rangeStr = [NSString stringWithFormat:@"%i,%li", 2, (long)datelength];
     NSData *Aes_ayData = [data subdataWithRange:NSRangeFromString(rangeStr)];
     
     // 用私钥解密,私钥匙 _productKey 用公钥加密时写入了 二进制私钥文件
     NSData *aesData = [SphygmomanometerBleContectModel aesDecryp:Aes_ayData typeFlag:3];
     
     NSLog(@"收到解密数据:%@",aesData);
     for (int i = 0; i < 16; i++) {
         NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, 1];
         NSData *as = [aesData subdataWithRange:NSRangeFromString(rangeStr)]; //ios 的二进制(16)
         /// 把解析回来的数据 把之前的私钥替换掉,之后发数据是都用私钥
         KeyaSph[i] = [FToy ConvertDataToInt:as];
     }
     
 }//发送随机数给蓝牙,获取秘钥
 + (NSData *)sendrandNumspayload:(NSArray *)payload {
     NSString *payload1 = @"";
     //计算length
     NSString *str = payload[0];
     payload1 = str;
     NSData *payloadData1 = [FToy convertHexStrToData:payload1];
     NSMutableData *newdata = [[NSMutableData alloc]init];
     [newdata appendData:payloadData1];
     NSMutableData *aesData = [[NSMutableData alloc]init];
     NSData *typeCome = [FToy convertHexStrToData:@"FE"];
     [aesData appendData: typeCome];
     NSData *payloadCome = [SphygmomanometerBleContectModel aesEncrypt:newdata typeFlag:1];
     NSData *lenCome = [FToy convertHexStrToData:@"10"];
     [aesData appendData: lenCome];
     [aesData appendData: payloadCome];
     NSData *crcCome = [SphygmomanometerBleContectModel crcCome:aesData];
     [aesData appendData: crcCome];
     
     return aesData;
 }//计算crc
 + (NSData *)crcCome:(NSData *)data{
     int crc = 0;
     for (int i = 0; i < data.length; i++) {
         NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, 1];
         NSData *as = [data subdataWithRange:NSRangeFromString(rangeStr)];
         crc = crc + [FToy ConvertDataToInt:as];
     }
     NSString *crcCome = [FToy getHexByDecimal:crc];
     for (int i = 0; i < 4 - crcCome.length; i++) {
         crcCome = [NSString stringWithFormat:@"0%@",crcCome];
     }
     return [FToy convertHexStrToData:crcCome];
 }//aes解密
 + (NSData *)aesDecryp:(NSData *)data typeFlag:(NSInteger)flag{
     
     //flag = 1 获取秘钥,key使用公钥; flag = 2 发送cmd指令,key使用秘钥
     cf_aes_context stu;
     if (flag == 1) {
         cf_aes_init(&stu, Key_ContcaSph, 16);
     } else if (flag == 2) {
         cf_aes_init(&stu, KeyaSph, 16);
     } else if (flag == 3) {
         cf_aes_init(&stu, KeyTSph, 16);
     }
     
     //解密数据数组
     uint8_t out_data[16] =
     {
     };
     uint8_t aesclo[16];
     NSMutableData *newdata = [[NSMutableData alloc]init];
     for (int i = 0; i < data.length; i++) {
         //16位一组解密
         int flag = (i)%16;
         NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, 1];
         NSData *as = [data subdataWithRange:NSRangeFromString(rangeStr)];
         aesclo[flag] = [FToy ConvertDataToInt:as];
         if (flag == 15) {
             cf_aes_decrypt(&stu, aesclo, out_data);
             for (int i = 0; i < 16; i++) {
                 NSInteger it = out_data[i];
                 [newdata appendData:[NSData dataWithBytes: &it length: 1]];
             }
             for (int i = 0; i < 16; i++) {
                 aesclo[i] = 0;
             }
         }
     }
     return newdata;
 }//aes加密
 + (NSData *)aesEncrypt:(NSMutableData *)data typeFlag:(NSInteger)flag{
     
     //flag = 1 获取秘钥,key使用公钥; flag = 2 发送cmd指令,key使用秘钥
     //16位一组加密,不足16位补0
     NSInteger addCount = 16 - (data.length%16);
     if (data.length%16 != 0) {
         for (int i = 0; i < addCount; i++) {
             [data appendData:[FToy convertHexStrToData:@"00"]];
         }
     }
     
     cf_aes_context stu;
     if (flag == 1) {
         cf_aes_init(&stu, Key_ContcaSph, 16);
     }else if (flag == 2) {
         cf_aes_init(&stu, KeyaSph, 16);
     }else if (flag == 3) {
         cf_aes_init(&stu, KeyTSph, 16);
     }
     
     //加密数据数组
     uint8_t out_data[16] =
     {
     };
     uint8_t aesclo[16];
     NSMutableData *newdata = [[NSMutableData alloc]init];
     for (int i = 0; i < data.length; i++) {
         //16位一组加密
         int flag = (i)%16;
         NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, 1];
         NSData *as = [data subdataWithRange:NSRangeFromString(rangeStr)];
         aesclo[flag] = [FToy ConvertDataToInt:as];
         if (flag == 15) {
             cf_aes_encrypt(&stu, aesclo, out_data);
             for (int i = 0; i < 16; i++) {
                 NSInteger it = out_data[i];
                 [newdata appendData:[NSData dataWithBytes: &it length: 1]];
             }
             for (int i = 0; i < 16; i++) {
                 aesclo[i] = 0x00;
             }
         }
     }
     return newdata;
 }+ (NSString *)DictionaryToString:(NSDictionary *)initDic {
     NSError * err;
     NSString * jsonString;
     
     if (!initDic || [initDic count] == 0) {
         return @"";
     }
     
     NSData *jsonData = [NSJSONSerialization dataWithJSONObject:initDic options:NSJSONWritingPrettyPrinted error:&err];
     
     if (!jsonData) {
         
         return @"";
     }else{
         jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
     }
     
     return jsonString;
 }
 // 发送数据
 + (void)sendDatacmd:(NSString *)packetType
        packetLength:(NSString *)packetLength
                 cmd:(NSString *)cmd
             payload:(NSString *)payload
            nativeId:(NSString *)nativeId
             success:(void (^)(NSString *msg))success
                fail:(void (^)(NSString *msg))fail{
     
     SphygmomanometerBleContectModel *Lockblue = [SphygmomanometerBleContectModel shared];
     [Lockblue FblueDelegate:@"cmd"];
     __weak typeof(Lockblue) weakLockblue = Lockblue;
     __strong typeof(weakLockblue) strongSelf = weakLockblue;
     Lockblue.blockIsSendData = YES;
     
     Lockblue.nativeId = nativeId;
     Lockblue.packetType = packetType;
     Lockblue.packetLength = packetLength;
     Lockblue.onceRunning = NO;
     
     weakLockblue.blueSendData = ^{
         success(@"成功");
     };
     if (Lockblue.timerIsRun == NO) {
         Lockblue.gcdIdx = 0;
         Lockblue.timerIsRun = YES;
     }
     if (Lockblue.writeCharacteristic != nil) {
         if (payload == nil) {
             payload = @"";
         }
         // 发送数据
         [strongSelf sendDatacmd:cmd payload:payload];
         strongSelf.blockIsSendData = NO;
     } else {
         [Lockblue sendrandNums];
     }
 }
 + (void)bindBlowerDevice:(NSString *)phone success:(void (^)(NSString *msg))success fail:(void (^)(NSString *msg))fail{
     
     SphygmomanometerBleContectModel *Lockblue = [SphygmomanometerBleContectModel shared];
     [Lockblue FblueDelegate:@"bind"];
     __weak typeof(Lockblue) weakLockblue = Lockblue;
     weakLockblue.blueErrorBlock = ^(NSString * _Nonnull error) {
         fail(error);
     };
     Lockblue.blockIsSendData = YES;
     if (Lockblue.timerIsRun == NO) {
         Lockblue.gcdIdx = 0;
         Lockblue.timerIsRun = YES;
     }
     
     weakLockblue.sendbindblock = ^{
         success(@"设备绑定成功");
     };
 }- (YUTimer *)timerIndex {
     if (_timerIndex == nil) {
         _timerIndex = [[YUTimer alloc] init];
     }
     return _timerIndex;
 }
 #pragma mark - 解析数据
 + (void)bisciddsex:(NSData *)data {
     
     SphygmomanometerBleContectModel *Lockblue = [SphygmomanometerBleContectModel shared];
     __weak typeof(Lockblue) weakLockblue = Lockblue;
     
     // ----- 是不是分包的处理 -----
     NSString *dataLength = [[[[data description] stringByReplacingOccurrencesOfString:@"<"withString:@""]stringByReplacingOccurrencesOfString:@">" withString:@""]stringByReplacingOccurrencesOfString:@" " withString:@""];
     NSString *packLength = [dataLength substringWithRange:NSMakeRange(2, 2)];
     // 16进制-->二进制
     NSString *secondNumber = [FToy getBinaryByHex:packLength];
     // 2进制-->十进制
     NSInteger tenNumber = [FToy getDecimalByBinary:secondNumber];
     // ----- 是不是分包的处理 -----
     
     NSString *rangeStr = NULL;
     NSData *Aes_ayData = NULL;
     if (tenNumber > 16) {
         rangeStr = [NSString stringWithFormat:@"%i,%lu", 2, ((dataLength.length)/2) - 4];
         Aes_ayData = [data subdataWithRange:NSRangeFromString(rangeStr)];
     } else {
         rangeStr = [NSString stringWithFormat:@"%i,%li", 2, (long)16];
         Aes_ayData = [data subdataWithRange:NSRangeFromString(rangeStr)];
     }
     
     // 用私钥解密,私钥匙 _productKey 用公钥加密时写入了 二进制私钥文件
     NSData *aesData = [SphygmomanometerBleContectModel aesDecryp:Aes_ayData typeFlag:2];
     
     // ---- 数据放在数组中截取 -----
     NSString *dataStr = [[[[aesData description] stringByReplacingOccurrencesOfString:@"<"withString:@""]stringByReplacingOccurrencesOfString:@">" withString:@""]stringByReplacingOccurrencesOfString:@" " withString:@""];
     
     NSMutableArray *byteArray = [NSMutableArray array];
     // 美隔两个截取字符串
     for (int i = 0 ; i < dataStr.length ; i += 2) {
         NSString *strTmp = [dataStr substringWithRange:NSMakeRange(i, 2)];
         [byteArray addObject:strTmp];
     }
     NSLog(@"byteArray----:%@",byteArray);
     
     //    SphygmomanometerBleContectModel *Lockblue = [SphygmomanometerBleContectModel shared];
     //    __weak typeof(Lockblue) weakLockblue = Lockblue;
     
     // 接收到数据没有超时
     Lockblue.isTimeOut = NO;
     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(timeOutFun) object:nil];
     
     if (Lockblue.isSecret == YES) {
         if (tenNumber > 16) {
             if (Lockblue.onceRunning == NO) {
                 if ([weakLockblue checkCRC:data]) { //CRC校验正确
                     // 大于16字节只执行一次
                     [Lockblue centerSendData:YES data:aesData errorCode:@"0"];
                     Lockblue.onceRunning = YES;
                 } else {
                     NSLog(@"%@",@"CRC校验错误");
                     [Lockblue centerSendData:NO data:[NSData new] errorCode:@"2"];
                 }
             }
         } else {
             if (Lockblue.onceRunning == NO) {
                 if ([weakLockblue checkCRC:data]) {
                     [Lockblue centerSendData:YES data:aesData errorCode:@"0"];
                 } else {
                     NSLog(@"%@",@"CRC校验错误");
                     [Lockblue centerSendData:NO data:[NSData new] errorCode:@"2"];
                 }
             }
         }
     } else {
         NSLog(@"%@",@"秘钥执行不发送数据给H5");
         Lockblue.isSecret = NO;
     }
 }- (void)timeOutFun {
     NSLog(@"体脂计 A5超时");
     [self centerSendData:NO data:[NSData new] errorCode:@"1"];
 }
 - (void)centerSendData:(BOOL)success data:(NSData *)data errorCode:(NSString *)coerrorCodede {
     
     NSString *lastDataStr = [[[[data description] stringByReplacingOccurrencesOfString:@"<"withString:@""]stringByReplacingOccurrencesOfString:@">" withString:@""]stringByReplacingOccurrencesOfString:@" " withString:@""];    
     NSLog(@"向H5发送的数据%@",lastDataStr);
     
     if (success) {
         
         NSDictionary *dic = @{
             @"errorCode":@(0),
             @"nativeId":@([_nativeId intValue]),
             @"results":lastDataStr
         };
         
         [[NSNotificationCenter defaultCenter] postNotificationName:@"SphygmomanometerBleContectModelNotification" object:nil userInfo:dic];
     } else {
         NSDictionary *dic = @{
             @"errorCode":@([coerrorCodede intValue]),
             @"nativeId":@([_nativeId intValue]),
             @"results":@""
         };
         
         [[NSNotificationCenter defaultCenter] postNotificationName:@"SphygmomanometerBleContectModelNotification" object:nil userInfo:dic];
     }
 }#pragma mark - 校验CRC
 - (BOOL)checkCRC:(NSData *)didGetData {
     
     NSString *dataStr = [[[[didGetData description] stringByReplacingOccurrencesOfString:@"<"withString:@""]stringByReplacingOccurrencesOfString:@">" withString:@""]stringByReplacingOccurrencesOfString:@" " withString:@""];
     
 //    dataStr = @"0710150a3b146b54bb6b3a5c86cb9f6f9e82067f";    NSMutableArray *byteArray = [NSMutableArray array];
     // 美隔两个截取字符串
     for (int i = 0 ; i < dataStr.length - 4; i += 2) {
         NSString *strTmp = [dataStr substringWithRange:NSMakeRange(i, 2)];
         // 16进制-->二进制
         NSString *secondNumber = [FToy getBinaryByHex:strTmp];
         // 2进制-->十进制
         NSInteger tenNumber = [FToy getDecimalByBinary:secondNumber];        [byteArray addObject:[NSNumber numberWithInteger:tenNumber]];
     }
     
 //    NSLog(@"UUUUUUUU:%@",byteArray);
     
     int ind = 0;
     for (NSNumber *number in byteArray) {
         ind = ind + [number intValue];
     }
     
     NSLog(@"十进制数加和:%d",ind);
     
     NSString *strInt = [NSString stringWithFormat:@"%d",ind];
     // 10 --> 16
     NSString *strLast = [FToy getHexByDecimal:[strInt integerValue]].lowercaseString;
     if (strLast.length == 4) {
         strLast = [NSString stringWithFormat:@"%@",strLast];
     } else if (strLast.length == 3) {
         strLast = [NSString stringWithFormat:@"0%@",strLast];
     } else if (strLast.length == 2) {
         strLast = [NSString stringWithFormat:@"00%@",strLast];
     } else if (strLast.length == 1) {
         strLast = [NSString stringWithFormat:@"000%@",strLast];
     } else {
         
     }
     
     NSString *strMMP = [dataStr substringFromIndex:dataStr.length - 4];
     
     NSLog(@"strMMP:%@",strMMP);
     if ([strMMP isEqualToString:strLast]) {
         NSLog(@"%@",@"YES");
         return YES;
     } else {
         NSLog(@"%@",@"NO");
         return NO;
     }
 }