/* 切换连接 断开上一个连接 */ //传数据所用标识g /* 发一条标记一条。 发一条 隔一段时间发一条 隔一段时间发一条 */ #define ReceiveData @"RECEIVEDATA" #define DataTag @"DataTag" #import "BabyBluetoothSwift.h" #import //#import "VMUserInfoPlist.h" #import "NSData+CRC16.h" #import "NSString+WithCRCModbus.h" #import "SolarBT-Swift.h" @interface BabyBluetoothSwift() { BabyBluetooth *baby;//蓝牙单例 NSMutableData* mUartRecvData;//接收到的数据 NSLock *dataLock;//线程锁 NSString *gUartMessageType;//消息类型 NSMutableArray *dataDictionary;//传进来的消息类型 NSMutableData *allrecevedata; NSMutableData *_loopallrecevedata; NSMutableDictionary *recciveDataDictionary;//接收到的消息类型 BOOL isLoop;//是否是循环的 BOOL isUpdateFirmware;//是否更新固件 } @property (nonatomic,assign) BOOL reConnectedToRead; //@property (nullable,strong) NSMutableArray *connectArray //写入特征 @property (nonatomic,strong)CBCharacteristic *writeCharacteristic; //密码特征 @property (nonatomic,strong)CBCharacteristic *passwordCharacteristic; //复位特征 @property (nonatomic,strong)CBCharacteristic *restoreCharacteristic; @property (nonatomic,copy) void (^CompleteHandle)(NSString *reacive); @property (nonatomic,copy) void (^CompleteHandle2)(NSDictionary *reaciveDic); @property (nonatomic,copy) void (^loopCompleteHandle)(NSString *reacive); @property (nonatomic,copy) void (^loopCompleteHandle2)(NSDictionary *reaciveDic); @property (nonatomic,copy) void (^connectCompletHandle)(CBPeripheral *peripheral, BOOL isSuccess); @property (nonatomic,copy) void (^StartWriteCallback)(void); @end //写入服务的UUID const static NSString* writeServerUUIDString = @"FFF0"; //读取服务的UUID const static NSString* readServerUUIDString = @"FFD0"; //参数设置服务的UUID const static NSString* setServerUUIDString = @"FF50"; //密码服务的UUID const static NSString* passwordServerUUIDString = @"FF80"; //写入特征的UUID const static NSString* writeCharacteristicUUIDString = @"FFD1"; //读取特征的UUID const static NSString* readCharacterosticUUIDString = @"FFF1"; //修改名称 uuid const static NSString* writeNameCharacteristicUUIDString = @"FF51"; //复位模块 const static NSString* restoreSystermCharacteristicUUIDString = @"FF54"; //设置密码特征值 const static NSString* writePasswordCharacteristicUUIDString = @"FF81"; //通知密码特征值 const static NSString* notityPasswordCharacteristicUUIDString = @"FF82"; @implementation BabyBluetoothSwift static BOOL isReadChFound = false;//是否读? static BOOL isWriteCHFound = false;//是否写? _Bool isAutoConnect = true;//是否自动连接 _Bool mCMDConnect = false;//CMD是否连接 _Bool connected = false;//连接 bool isFirstStart = true;//是否是第一次开始 _Bool isStartWrite = true;//为真代表可以写入 NSTimer *timer; //单例模式 + (instancetype)shareInstance { static BabyBluetoothSwift *share = nil; static dispatch_once_t oneToken; dispatch_once(&oneToken, ^{ share = [[BabyBluetoothSwift alloc]init]; }); return share; } //初始化蓝牙并设置代理 - (instancetype)init { self = [super init]; if (self) { baby = [BabyBluetooth shareBabyBluetooth]; _peripherals = [[NSMutableArray alloc]init]; mUartRecvData = [NSMutableData data]; allrecevedata = [NSMutableData data]; dataLock = [[NSLock alloc] init]; recciveDataDictionary = [NSMutableDictionary dictionary]; // self.newRead = false; isUpdateFirmware = false; self.reConnectedToRead = false ; ; [self babyDelegate]; } return self; } -(BOOL)canWrite{ return isWriteCHFound; } -(BOOL) isConnected { return connected; } -(void)autoConnect { [baby retrievePeripheralWithUUIDString:@""]; } -(void)scanForPeripherals { baby.scanForPeripherals().begin(); } -(void)cancelScan{ baby.cancelScan; } -(void)reconnectPeripheralWithName:(NSString *)name{ for (id peripherial in _peripherals) { if([((CBPeripheral *)peripherial).name isEqualToString:name]) { _currPeripheral = (CBPeripheral *)peripherial; NSLog(@""); baby.having(_currPeripheral).connectToPeripherals().discoverServices().discoverCharacteristics().begin(); NSLog(@"重新连接 - %@",_currPeripheral); mCMDConnect = true; [baby cancelScan]; } } [_peripherals removeAllObjects]; } //判断是否存在设备 -(BOOL)peripheralExitsAtPeripheralName:(NSString *)peripheralName{ for (id peripherial in _peripherals) { if([((CBPeripheral *)peripherial).name isEqualToString:peripheralName]) { NSLog(@"存在设备 ---%@",peripheralName); return YES; } } return NO; } -(void)connectPeripheralWithName:(NSString *)name { [NSThread sleepForTimeInterval:0.5]; NSLog(@"当前设备数组 - %@",_peripherals); for (id peripherial in _peripherals) { if([((CBPeripheral *)peripherial).name isEqualToString:name]) { _currPeripheral = (CBPeripheral *)peripherial; NSLog(@"---- %@",_currPeripheral); baby.having(_currPeripheral).connectToPeripherals().discoverServices().discoverCharacteristics().begin(); mCMDConnect = true; [baby cancelScan]; } } [_peripherals removeAllObjects]; } -(void)connectPeripheralWithName:(NSString *)name connectCompletionHandler:(void (^)(CBPeripheral *, BOOL))connectCompletionHandler startWriteDataCallback:(void (^)(void))startWriteDataCallback{ self.reConnectedToRead = true; isLoop = false; __weak BabyBluetoothSwift *weakSelf = self; self.StartWriteCallback = startWriteDataCallback; // .创建一个数目为1的信号量,用于“卡”for循环,等上次循环结束在执行下一次的for循环 dispatch_semaphore_t sema = dispatch_semaphore_create(1); // 开始执行for循环,让信号量-1,这样下次操作须等信号量>=0才会继续,否则下次操作将永久停止 long result = dispatch_semaphore_wait(sema, 15 * NSEC_PER_SEC); printf("连接 --- 信号量等待中\n"); if (result == 0) { //返回0时可以安全的执行进行排他控制的处理,该处理结束后,通过dispath)semaphore_signal 函数Dispath Semphore 的计数值加1 [self asynConnectPeripheralWithName:name connectCompletionHandler:^(CBPeripheral *perhpheral, BOOL isSuccess) { connectCompletionHandler(perhpheral,isSuccess); dispatch_semaphore_signal(sema); }]; } else { /* 说明semaphore的值等于0.此时timeout指定d时间内函数处于线程阻塞*/ for (id peripherial in weakSelf.peripherals) { if([((CBPeripheral *)peripherial).name isEqualToString:name]) { connectCompletionHandler(peripherial,false); } } } } -(void)connectPeripheralWithName:(NSString *)name connectCompletionHandler:(void (^)(CBPeripheral *, BOOL))connectCompletionHandler{ __weak BabyBluetoothSwift *weakSelf = self; // .创建一个数目为1的信号量,用于“卡”for循环,等上次循环结束在执行下一次的for循环 dispatch_semaphore_t sema = dispatch_semaphore_create(1); // 开始执行for循环,让信号量-1,这样下次操作须等信号量>=0才会继续,否则下次操作将永久停止 long result = dispatch_semaphore_wait(sema, 15 * NSEC_PER_SEC); printf("连接 --- 信号量等待中\n"); if (result == 0) { //返回0时可以安全的执行进行排他控制的处理,该处理结束后,通过dispath)semaphore_signal 函数Dispath Semphore 的计数值加1 [self asynConnectPeripheralWithName:name connectCompletionHandler:^(CBPeripheral *perhpheral, BOOL isSuccess) { connectCompletionHandler(perhpheral,isSuccess); dispatch_semaphore_signal(sema); }]; } else { /* 说明semaphore的值等于0.此时timeout指定d时间内函数处于线程阻塞*/ for (id peripherial in weakSelf.peripherals) { if([((CBPeripheral *)peripherial).name isEqualToString:name]) { connectCompletionHandler(peripherial,false); } } } } -(void)asynConnectPeripheralWithName:(NSString *)name connectCompletionHandler:(void (^)(CBPeripheral *, BOOL))connectCompletionHandler{ self.connectCompletHandle = connectCompletionHandler; [NSThread sleepForTimeInterval:0.5]; NSLog(@"当前设备数组 - %@",_peripherals); for (id peripherial in _peripherals) { if([((CBPeripheral *)peripherial).name isEqualToString:name]) { _currPeripheral = (CBPeripheral *)peripherial; NSLog(@"开始连接 ---- %@",_currPeripheral); baby.having(_currPeripheral).connectToPeripherals().discoverServices().discoverCharacteristics().begin(); // [self WaitPostConnect:15]; mCMDConnect = true; [baby cancelScan]; } } [_peripherals removeAllObjects]; } - (BOOL)WaitPostConnect:(int)timerout{ while( timerout >0) { usleep(1000); timerout--; NSLog(@"当前设备 --- %@ --- %d",self.currPeripheral,timerout); } if(timerout <= 0) { NSLog(@"false and timeout is %d", timerout); return false; } NSLog(@"true and timeout is %d", timerout); return true; } //断开连接 -(void)disconnectPeripheralWithName:(NSString *)name{ NSLog(@"断开设备"); for (id peripherial in _peripherals) { if([((CBPeripheral *)peripherial).name isEqualToString:name]) { mCMDConnect = false; [baby cancelPeripheralConnection:peripherial]; NSLog(@"断开设备++++++=="); } } } -(void)cancelAllPeripheralsConnection { if (_currPeripheral == nil) { return; } mCMDConnect = false; [baby cancelAllPeripheralsConnection]; } -(BOOL) crcCheck:(NSData *) data { [dataLock lock]; [mUartRecvData appendData:data]; [dataLock unlock]; return YES; } -(void) ClearRecvFifo { [dataLock lock]; [mUartRecvData setLength:0]; [dataLock unlock]; } -(BOOL) WaitPostMessage:(int) timerout { while(![self PostRecvMessage] && timerout >0) { usleep(1000); timerout--; } if(timerout <= 0) { NSLog(@"false and timeout is %d", timerout); return false; } NSLog(@"true and timeout is %d", timerout); return true; } -(void) StartLoopRecvOneMessage:(int) timeout { __weak BabyBluetoothSwift *weakSelf = self; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ [weakSelf WaitPostMessage:timeout]; }); } /** 获取接收到的通知信息 @param msg 通知信息 */ -(void) OnRecvMessage:(NSData *) msg { [dataLock lock]; [mUartRecvData appendData:msg]; [dataLock unlock]; } /** 发送接收到的信息 @return 是否成功? */ -(BOOL) PostRecvMessage { // if(mUartRecvData == nil) // [dataLock unlock]; // return false; // if(![ModbusData dataCrcCheck:mUartRecvData]) // { // // [dataLock unlock]; // return false; // } // if ([mUartRecvData length] == 0) { // // return false; // } // // [dataLock lock]; // Uart_UserInfo *info = [[Uart_UserInfo alloc] init]; // info.type = [[NSNumber alloc] initWithInteger:gUartMessageType]; // info.data = mUartRecvData; // [[NSNotificationCenter defaultCenter] postNotificationName:kBabyBluetoothNotificationUartDataRecieve object:info]; // NSLog(@"收到蓝牙完整数据: %@", mUartRecvData); // [ModbusData print:[[NSString alloc] initWithFormat:@"RecvData: %@", mUartRecvData]]; // // [self ClearRecvFifo]; // [dataLock unlock]; return true; } -(void)setPasswordCharacterNotify:(CBCharacteristic *) ch { NSLog(@"设置密码通知 --- "); // __weak typeof(self) weakSelf = self; NSMutableData *_allrecevedata; // 设置通知 [baby notify:_currPeripheral characteristic:ch block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) { NSData *data = characteristics.value; [self OnRecvMessage:data]; [_allrecevedata appendData:data]; NSLog(@"收到蓝牙完整数据 ========: %@", _allrecevedata); }]; } -(void) setReadCharacterNotify3:(CBCharacteristic *) ch { __weak typeof(self) weakSelf = self; // 设置通知 [baby notify:_currPeripheral characteristic:ch block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) { NSData *data = characteristics.value; [self OnRecvMessage:data]; [_loopallrecevedata appendData:data]; // if (_loopallrecevedata.length > 4) { NSLog(@"setReadCharacterNotify3 ----%@",_loopallrecevedata); NSString *str1 = [NSString stringWithFormat:@"%@",[_loopallrecevedata subdataWithRange:NSMakeRange(0, _loopallrecevedata.length-2)]]; NSString *str2 = [NSString stringWithFormat:@"%@",[_loopallrecevedata subdataWithRange:NSMakeRange( _loopallrecevedata.length-2,2)]]; str2 = [str2 substringWithRange:NSMakeRange(1, str2.length-2)]; NSString *ssss = [NSString stringWithFormat:@"%@",[str1 substringWithRange:NSMakeRange(1, str1.length-2)]]; ssss = [ssss stringByReplacingOccurrencesOfString:@" " withString:@""]; NSString *crcbuss = [ssss withCrc16Modbus]; NSString *res = [crcbuss substringWithRange:NSMakeRange(crcbuss.length-4, 4)]; NSLog(@"res -- %@ str2 ---%@",res,str2); if ([res isEqualToString:str2]) { NSLog(@"收到蓝牙完整数据========: %@", allrecevedata); NSString *datastr = [NSString stringWithFormat:@"%@",_loopallrecevedata]; self.loopCompleteHandle(datastr); _loopallrecevedata = nil; } } }]; } -(void) setReadCharacterNotify2:(CBCharacteristic *) ch { NSLog(@"返回控制器数3"); __weak typeof(self) weakSelf = self; // 设置通知 [baby notify:_currPeripheral characteristic:ch block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) { NSLog(@"返回控制器数据4"); NSData *data = characteristics.value; [self OnRecvMessage:data]; [allrecevedata appendData:data]; // if (allrecevedata.length > 4) { // NSLog(@"setReadCharacterNotify2!!! ----%@",[self convertDataToHexStr:allrecevedata]); //NSString *str1 = [NSString stringWithFormat:@"%@",[allrecevedata subdataWithRange:NSMakeRange(0, allrecevedata.length-2)]]; // NSLog(@"str1 -- %@",); NSData *data1 = [allrecevedata subdataWithRange:NSMakeRange(0, allrecevedata.length-2)]; NSString *str2 = [self convertDataToHexStr:[allrecevedata subdataWithRange:NSMakeRange(allrecevedata.length-2,2)]]; // ssss = [ssss stringByReplacingOccurrencesOfString:@" " withString:@""]; NSString *str1 = [self convertDataToHexStr:allrecevedata]; // NSLog(@"str1 - %@",str1); NSString *ssss = [str1 substringWithRange:NSMakeRange(0, str1.length-4)]; //NSLog(@"ssss - %@",ssss); NSString *crcbuss = [ssss withCrc16Modbus]; // NSLog(@"crcbuss - %@",crcbuss); NSString *res = [crcbuss substringWithRange:NSMakeRange(crcbuss.length-4, 4)]; // NSLog(@"res -- %@ str2 ---%@",res,str2); if ([res isEqualToString:str2]) { NSLog(@"收到蓝牙完整数据========: %@", allrecevedata); // NSString *datastr = [NSString stringWithFormat:@"%@",allrecevedata]; NSString *datastr = [NSString stringWithFormat:@"<%@>",[self convertDataToHexStr:allrecevedata]]; self.CompleteHandle(datastr); // NSLog(@"datastr - %@ ",datastr); allrecevedata = nil; } } }]; } - (NSString *)convertDataToHexStr:(NSData *)data { if (!data || [data length] == 0) { return @""; } NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]]; [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) { unsigned char *dataBytes = (unsigned char*)bytes; for (NSInteger i = 0; i < byteRange.length; i++) { NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff]; if ([hexStr length] == 2) { [string appendString:hexStr]; } else { [string appendFormat:@"0%@", hexStr]; } } }]; return string; } /** 设置读特征的通知 欢迎来到深圳市云之声科技有限公司 @param ch 特征 */ -(void) setReadCharacterNotify:(CBCharacteristic *) ch { NSLog(@"返回控制器数据5"); __weak typeof(self) weakSelf = self; // 设置通知 [baby notify:_currPeripheral characteristic:ch block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) { NSData *data = characteristics.value; NSLog(@"返回控制器数据= %@ ",data); [self OnRecvMessage:data]; [_loopallrecevedata appendData:data]; NSLog(@"返回控制器数据= %@ ",_loopallrecevedata); if (_loopallrecevedata.length > 4) { NSString *str1 = [NSString stringWithFormat:@"%@",[_loopallrecevedata subdataWithRange:NSMakeRange(0, _loopallrecevedata.length-2)]]; NSString *str2 = [NSString stringWithFormat:@"%@",[_loopallrecevedata subdataWithRange:NSMakeRange( _loopallrecevedata.length-2,2)]]; str2 = [str2 substringWithRange:NSMakeRange(1, str2.length-2)]; NSString *ssss = [NSString stringWithFormat:@"%@",[str1 substringWithRange:NSMakeRange(1, str1.length-2)]]; ssss = [ssss stringByReplacingOccurrencesOfString:@" " withString:@""]; NSString *crcbuss = [ssss withCrc16Modbus]; NSString *res = [crcbuss substringWithRange:NSMakeRange(crcbuss.length-4, 4)]; if ([res isEqualToString:str2]) { [[NSNotificationCenter defaultCenter] postNotificationName:kBabyBluetoothNotificationUartDataRecieve object:nil]; isStartWrite = true; NSLog(@"收到蓝牙完整数据========: %@", allrecevedata); NSString *allrecevedataStr = [NSString stringWithFormat:@"%@",_loopallrecevedata]; [recciveDataDictionary setObject:_loopallrecevedata forKey:ReceiveData]; [recciveDataDictionary setObject:allrecevedataStr forKey:ReceiveData]; if (weakSelf.testBlock) { weakSelf.testBlock(recciveDataDictionary); } if (weakSelf.testBlock2) { weakSelf.testBlock2(recciveDataDictionary); } /* let dataTagValue : String = deviceData?.value(forKey: DataTag) as! String if dataTagValue == "FF0300490010" */ NSString *dataTag = [recciveDataDictionary valueForKey:DataTag]; if ([dataTag isEqualToString:@"FF0300490010"]) { if (weakSelf.updateNameBlock) { weakSelf.updateNameBlock(recciveDataDictionary); } } //清除历史记录 //FF06DF050001 FF7900000001 if ([dataTag isEqualToString:@"FF06DF050001"] || [dataTag isEqualToString:@"FF7900000001"] ) { if (weakSelf.clearHistoryDataBlock) { weakSelf.clearHistoryDataBlock(recciveDataDictionary); } } // let arr = ["FF7800000001"] // let arr = ["FF06DF010001"] 恢复出厂设置 if ([dataTag isEqualToString:@"FF7800000001"] || [dataTag isEqualToString:@"FF06DF020001"] ) { if (weakSelf.resetBlock) { weakSelf.resetBlock(recciveDataDictionary); } } } } }]; } -(void)firmwareUpdateReadCharacterNotify:(CBCharacteristic *) ch { __weak typeof(self) weakSelf = self; // 设置通知 [baby notify:_currPeripheral characteristic:ch block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) { NSData *data = characteristics.value; [self OnRecvMessage:data]; NSString *dataStr = [NSString stringWithFormat:@"%@",data]; NSLog(@"收到的数据为 --%@",dataStr); }]; } - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { NSLog(@"%s, line = %d", __FUNCTION__, __LINE__); // if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"FFF1"]]) { NSLog(@"获取蓝牙最新值%@",characteristic.value); // }else { // NSLog(@"失败"); // } } - (void)actions { for (int i = 0; i < dataDictionary.count; i++) { if (dataDictionary.count > 0) { // 循环数组 if (isStartWrite && self.isConnected) { NSData *data = [[[dataDictionary[i] objectForKey:DataTag] withCrc16Modbus] toNSData]; NSLog(@"发送完整aaaaaa %@",data); // 1.创建串行队列 dispatch_queue_t queue = dispatch_queue_create("UUUUU", DISPATCH_QUEUE_SERIAL); // 2.将任务加到队列当中 dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(queue, ^{ _loopallrecevedata = [NSMutableData dataWithLength:0]; // 写入操作 [recciveDataDictionary removeAllObjects]; NSLog(@"写入特征值 >>>>>>>>>>>>>>>.writeCharacteristic ---- %@",self.writeCharacteristic); if (self.writeCharacteristic != nil) { [self.currPeripheral writeValue:data forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithoutResponse]; } [recciveDataDictionary setObject:[dataDictionary[i] valueForKey:DataTag] forKey:DataTag]; NSLog(@"recciveDataDictionary = %@",recciveDataDictionary); [dataDictionary removeObjectAtIndex:i]; }); }); isStartWrite = false; } }else { [timer invalidate]; } } } -(void) writeData1:(NSMutableArray *)type{ NSLog(@"写数据 ---%@",type); // isLoop = true; //在这里执行事件 dataDictionary = type; timer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(actions) userInfo:nil repeats:YES]; } -(NSString *)getCurrentTime{ NSDate *date = [NSDate date]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateStyle:NSDateFormatterMediumStyle]; [formatter setTimeStyle:NSDateFormatterShortStyle]; [formatter setDateFormat:@"YYYYMMddhhmmss"]; NSString *DateTime = [formatter stringFromDate:date]; NSLog(@"%@============年-月-日 时:分:秒=====================",DateTime); return DateTime; } //写固件更新 -(void)updateFirmwareData:(NSString *)data{ if (self.isConnected) { isUpdateFirmware = true; NSData *cmd = [[data withCrc16Modbus] toNSData]; [NSThread sleepForTimeInterval:0.05]; if (self.currPeripheral != nil && self.writeCharacteristic != nil) { NSLog(@"writeData --发送的指令数据---- %@ ",data); [self.currPeripheral writeValue:cmd forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithoutResponse]; } } } //循环写入 -(void)loopWriteDataWite:(NSArray *)dataArr type:(NSString *)type completionHandler:(void (^)(NSDictionary *))completionHandler{ if (self.isConnected) { __block BOOL isFinish = false; __block NSMutableDictionary *reaciveData = [NSMutableDictionary dictionary]; NSString *queueName = [NSString stringWithFormat:@"serialQueue%@%@",type,[self getCurrentTime]]; // 1.创建一个串行队列,保证for循环依次执行 dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL); // 2.异步执行任务 dispatch_async(serialQueue, ^{ // 3.创建一个数目为1的信号量,用于“卡”for循环,等上次循环结束在执行下一次的for循环 dispatch_semaphore_t sema = dispatch_semaphore_create(1); for (int i = 0 ; i < dataArr.count; i++) { isLoop = true; // 开始执行for循环,让信号量-1,这样下次操作须等信号量>=0才会继续,否则下次操作将永久停止 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); printf("信号量等待中\n"); NSLog(@"任务%d:%@",i,[NSThread currentThread]); NSString *dataStr = dataArr[i]; [self writeData:dataStr completionHandler:^(NSString * result) { NSLog(@"结果 ---%@",dataStr); [NSThread sleepForTimeInterval:0.1]; reaciveData[dataStr] = result; if (i == dataArr.count - 1) { //当执行到最后一个时 则跳出 NSLog(@"完成了所有任务"); dispatch_async(dispatch_get_main_queue(), ^{ completionHandler(reaciveData); }); } dispatch_semaphore_signal(sema); }]; } }); } } -(void)_loopWriteDataWite:(NSArray *)dataArr type:(NSString *)type completionHandler:(void (^)(NSDictionary *))completionHandler{ if (self.isConnected) { for (int i = 0 ; i < dataArr.count; i++) { } } } -(void)writeData2222:(NSArray *)dataArr completionHandler:(void (^)(NSDictionary *))completionHandler{ if ([self isConnected] == true) { __block BOOL isFinish = false; __block NSMutableDictionary *reaciveData = [NSMutableDictionary dictionary]; // 1.创建一个串行队列,保证for循环依次执行 dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL); // 2.异步执行任务 dispatch_async(serialQueue, ^{ // 3.创建一个数目为1的信号量,用于“卡”for循环,等上次循环结束在执行下一次的for循环 dispatch_semaphore_t sema = dispatch_semaphore_create(1); for (int i = 0 ; i < dataArr.count; i++) { isLoop == false; // 开始执行for循环,让信号量-1,这样下次操作须等信号量>=0才会继续,否则下次操作将永久停止 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); printf("信号量等待中\n"); NSLog(@"任务%d:%@",i,[NSThread currentThread]); NSString *dataStr = dataArr[i]; [self writeData:dataStr completionHandler:^(NSString * result) { NSLog(@"结果 ---%@",dataStr); [NSThread sleepForTimeInterval:0.1]; reaciveData[dataStr] = result; allrecevedata = nil; if (i == dataArr.count - 1) { //当执行到最后一个时 则跳出 NSLog(@"完成了所有任务"); dispatch_async(dispatch_get_main_queue(), ^{ completionHandler(reaciveData); }); } dispatch_semaphore_signal(sema); }]; } }); } } - (void)loopWriteData:(NSString *)dataStr completionHandler:(void (^)(NSString *))completionHandler{ [NSThread sleepForTimeInterval:0.05]; // self.newRead = true; if (self.isConnected) { _loopallrecevedata = [NSMutableData dataWithLength:0]; self.loopCompleteHandle = completionHandler; // NSData *data = [[dataStr withCrc16Modbus] toNSData]; [NSThread sleepForTimeInterval:0.05]; if (self.currPeripheral != nil && self.writeCharacteristic != nil) { NSLog(@"看看loopWriteData --发送的指令数据---- %@ ---- characteristic = %@",data,self.writeCharacteristic.UUID.UUIDString); [self.currPeripheral writeValue:data forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithoutResponse]; } } } - (void)writeData:(NSString *)dataStr completionHandler:(void (^)(NSString *))completionHandler{ // self.newRead = true; if (self.isConnected) { allrecevedata = [NSMutableData dataWithLength:0]; self.CompleteHandle = completionHandler; // NSData *data = [[dataStr withCrc16Modbus] toNSData]; if (self.currPeripheral != nil && self.writeCharacteristic != nil) { NSLog(@"看看1writeData --发送的指令数据---- %@ ---- characteristic = %@",data,self.writeCharacteristic.UUID.UUIDString); [self.currPeripheral writeValue:data forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithoutResponse]; } } } - (void)writePasswordData:(NSString *)data{ if (self.isConnected) { NSLog(@"特征值FF81"); //转为ASCII NSData *dataAT = [data dataUsingEncoding:NSASCIIStringEncoding]; [NSThread sleepForTimeInterval:0.05]; if (self.currPeripheral != nil && self.passwordCharacteristic != nil) { NSLog(@"发送的指令数据---- %@ ---- characteristic = %@",dataAT,self.passwordCharacteristic.UUID.UUIDString); [self.currPeripheral writeValue:dataAT forCharacteristic:self.passwordCharacteristic type:CBCharacteristicWriteWithoutResponse]; } [NSThread sleepForTimeInterval:0.05]; } } - (void)writeRestoreSystemData:(NSString *)data{ if (self.isConnected) { NSLog(@"特征值 FF54"); //转为ASCII NSData *dataAT = [data toNSData]; [NSThread sleepForTimeInterval:0.05]; if (self.currPeripheral != nil && self.restoreCharacteristic != nil) { [self.currPeripheral writeValue:dataAT forCharacteristic:self.restoreCharacteristic type:CBCharacteristicWriteWithoutResponse]; } [NSThread sleepForTimeInterval:0.05]; } } -(void) writeData:(NSString *)type withData:(NSData *) data { if (self.isConnected) { gUartMessageType = type; [NSThread sleepForTimeInterval:0.05]; if (self.currPeripheral != nil && self.writeCharacteristic != nil) { [self.currPeripheral writeValue:data forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithoutResponse]; } [NSThread sleepForTimeInterval:0.05]; }else { //[MBProgressHUD showInfoMessage:NSLocalizedString(@"can_not_connect_device_info", nil)]; } } -(void)babyDelegate{ __weak typeof(self) weakSelf = self; // 连接回调 [baby setBlockOnCentralManagerDidUpdateState:^(CBCentralManager *central) { if (weakSelf.centralBlock) { weakSelf.centralBlock(central); } NSLog(@"读取状态回调 -- %ld",central.state); if (central.state == CBManagerStatePoweredOn) { // [SVProgressHUD showInfoWithStatus:@"设备打开成功,开始扫描设备"]; } }]; //设置扫描到设备的委托 [baby setBlockOnConnected:^(CBCentralManager *central, CBPeripheral *peripheral) { weakSelf.currPeripheral = nil; NSLog(@"UUID -- %@",peripheral.identifier); NSLog(@"已经连接蓝牙 %@", [peripheral name]); weakSelf.currPeripheral = peripheral; connected = true; // NSLog(@"连接状态--- %d isconcect %d",connected,[self isConnected]); weakSelf.connectCompletHandle(peripheral, true); [[NSNotificationCenter defaultCenter] postNotificationName:kBabyBluetoothNotificationServiceStatus object:[[NSNumber alloc] initWithInteger:BabyBluetooth_ConnectedStatus]]; }]; //设置连接失败代理 [baby setBlockOnFailToConnect:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) { NSLog(@"连接失败%@",peripheral.name); connected = false; weakSelf.connectCompletHandle(peripheral, false); }]; // 断开蓝牙的回调 __block BabyBluetooth *weakBaby = baby; [baby setBlockOnDisconnect:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) { isReadChFound = false; isWriteCHFound = false; if (mCMDConnect == true) { // 添加断开自动重连的外设 } else { // 删除断开自动重连的外设 } connected = false; NSLog(@"已经断开蓝牙 %@", [peripheral name]); // 设置通知的蓝牙服务状态为断开连接状态 [[NSNotificationCenter defaultCenter] postNotificationName:kBabyBluetoothNotificationServiceStatus object:[[NSNumber alloc] initWithInteger:BabyBluetooth_DisConnectedStatus]]; NSDictionary *periDict = @{@"peripheral":[peripheral name] }; // [[NSNotificationCenter defaultCenter]postNotificationName:kBabyBluetoothNotificationDeviceWasDisconect object:nil]; [[NSNotificationCenter defaultCenter]postNotificationName:kBabyBluetoothNotificationDeviceWasDisconect object:nil userInfo:periDict]; }]; //设置 Characteristics 过滤值 [baby setBlockOnDiscoverToPeripherals:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) { NSLog(@"搜索到了设备:%@ --- uuid - %@ ",peripheral.name,peripheral.identifier.UUIDString); // [[weakSelf peripherals] addObject:peripheral]; // 如果搜索到的外设不在数组中 if (![weakSelf.peripherals containsObject:peripheral]) { // 添加到外设数组中 [weakSelf.peripherals addObject:peripheral]; // 设置通知的搜索结果状态为nil [[NSNotificationCenter defaultCenter] postNotificationName:kBabyBluetoothNotificationScanResult object:nil]; } NSString *uuidString = [[NSUserDefaults standardUserDefaults] objectForKey:@"periheralUUID"]; if (uuidString != nil && isFirstStart) { if ([[[NSUUID alloc] initWithUUIDString:uuidString] isEqual:peripheral.identifier]) { // [baby retrievePeripheralWithUUIDString:uuidString]; weakBaby.having(peripheral).connectToPeripherals().discoverServices().discoverCharacteristics().begin(); _currPeripheral = peripheral; mCMDConnect = true; isFirstStart = false; [weakBaby cancelScan]; } } }]; //设置发现设备的Services的委托 [baby setBlockOnDiscoverServices:^(CBPeripheral *peripheral, NSError *error) { for (CBService *service in peripheral.services) { NSLog(@"搜索到服务:%@",service.UUID.UUIDString); if (weakSelf.DiscoverServicesBlock != nil) { weakSelf.DiscoverServicesBlock(service.UUID.UUIDString); } } //找到cell并修改detaisText }]; //设置发现设service的Characteristics的委托 [baby setBlockOnDiscoverCharacteristics:^(CBPeripheral *peripheral, CBService *service, NSError *error) { NSLog(@"===service name:%@",service.UUID); for (CBCharacteristic *c in service.characteristics) { NSLog(@"charateristic name is :%@",c.UUID); if ([c.UUID isEqual:[CBUUID UUIDWithString:writeCharacteristicUUIDString]]) { NSLog(@"writeCharacteristicUUIDString"); isWriteCHFound = true; weakSelf.writeCharacteristic = c; if (weakSelf.StartWriteCallback != nil) { NSLog(@"开始读写"); weakSelf.StartWriteCallback(); } if (c == nil) { NSLog(@"FFF1不存在 "); }else{ NSLog(@"FFF1 --存在 --%@ ", weakSelf.writeCharacteristic.UUID); } } if ([c.UUID isEqual:[CBUUID UUIDWithString:readCharacterosticUUIDString]]) { NSLog(@"返回控制器数据0"); isReadChFound = true; if (isLoop == false || weakSelf.reConnectedToRead == true) { [weakSelf setReadCharacterNotify2:c]; NSLog(@"返回控制器数据1"); } else if (isLoop == true){ NSLog(@"返回控制器数据2"); [weakSelf setReadCharacterNotify:c]; } //更新固件返回 if (isUpdateFirmware == true) { [weakSelf firmwareUpdateReadCharacterNotify:c]; } // [weakSelf setReadCharacterNotify:c]; connected = true; } //发送 //通知 if ([c.UUID isEqual:[CBUUID UUIDWithString:writePasswordCharacteristicUUIDString]]) { weakSelf.passwordCharacteristic = c ; } //通知 if ([c.UUID isEqual:[CBUUID UUIDWithString:notityPasswordCharacteristicUUIDString]]) { [weakSelf setPasswordCharacterNotify:c]; } if ([c.UUID isEqual:[CBUUID UUIDWithString:restoreSystermCharacteristicUUIDString]]) { weakSelf.restoreCharacteristic = c; } } // 可读可写 if (isReadChFound && isWriteCHFound) { [[NSNotificationCenter defaultCenter] postNotificationName:kBabyBluetoothNotificationServiceStatus object:[[NSNumber alloc] initWithInteger:BabyBluetooth_ReadyToSendCMDStatus]]; } }]; //设置读取characteristics的委托 [baby setBlockOnReadValueForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) { NSLog(@"characteristic name:%@ value is:%@",characteristics.UUID,characteristics.value); }]; //设置发现characteristics的descriptors的委托 [baby setBlockOnDiscoverDescriptorsForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSError *error) { NSLog(@"===characteristic name:%@",characteristic.service.UUID); for (CBDescriptor *d in characteristic.descriptors) { NSLog(@"CBDescriptor name is :%@",d.UUID); } }]; //设置读取Descriptor的委托 [baby setBlockOnReadValueForDescriptors:^(CBPeripheral *peripheral, CBDescriptor *descriptor, NSError *error) { NSLog(@"Descriptor name:%@ value is:%@",descriptor.characteristic.UUID, descriptor.value); mCMDConnect = true; }]; //设置查找设备的过滤器 [baby setFilterOnDiscoverPeripherals:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) { //最常用的场景是查找某一个前缀开头的设备 非空字符串 if (![peripheralName hasPrefix:@""] && peripheralName != nil) { NSLog(@"搜索到的设备 %@",peripheralName); NSLog(@"广播数据 -- %@",advertisementData); return YES; } //设置查找规则是名称大于0 , the search rule is peripheral.name length > 0 if (peripheralName.length >0) { return YES; } return NO; }]; [baby setBlockOnCancelAllPeripheralsConnectionBlock:^(CBCentralManager *centralManager) { NSLog(@"setBlockOnCancelAllPeripheralsConnectionBlock"); connected = NO; }]; [baby setBlockOnCancelScanBlock:^(CBCentralManager *centralManager) { NSLog(@"setBlockOnCancelScanBlock"); }]; //示例: //扫描选项->CBCentralManagerScanOptionAllowDuplicatesKey:忽略同一个Peripheral端的多个发现事件被聚合成一个发现事件 NSDictionary *scanForPeripheralsWithOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@YES,CBCentralManagerOptionShowPowerAlertKey:@YES}; NSArray *uuidServices = @[[CBUUID UUIDWithString:readServerUUIDString], [CBUUID UUIDWithString:writeServerUUIDString], [CBUUID UUIDWithString:passwordServerUUIDString], [CBUUID UUIDWithString:setServerUUIDString],]; //连接设备-> [baby setBabyOptionsWithScanForPeripheralsWithOptions:scanForPeripheralsWithOptions connectPeripheralWithOptions:nil scanForPeripheralsWithServices:nil discoverWithServices:nil discoverWithCharacteristics:nil]; } @end /* 切换设备 断开当前设备 ----> 搜索设备----> 连接 */