|  |  |  |  |  |  | 
													
												
													
														|  |  | //APP <-> BLE 二者双向交互的UUID,同时有write和notify |  |  | //APP <-> BLE 二者双向交互的UUID,同时有write和notify | 
													
												
													
														|  |  | static NSString *const writeAndNotifyCharactisticUUID = @"FFE3"; |  |  | static NSString *const writeAndNotifyCharactisticUUID = @"FFE3"; | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  |  |  |  | //AILink广播设备服务UUID | 
													
												
													
														|  |  |  |  |  | static NSString *const broadcastServiceUUID = @"F0A0"; | 
													
												
													
														|  |  |  |  |  | 
 | 
													
												
													
														|  |  | //握手超时时间 |  |  | //握手超时时间 | 
													
												
													
														|  |  | static NSInteger const HandShakeTimeout = 5.0; |  |  | static NSInteger const HandShakeTimeout = 5.0; | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
											
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  | @property (nonatomic, strong) NSMutableArray<ELPeripheralModel *> *peripheralArray;//扫描到的外设 |  |  | @property (nonatomic, strong) NSMutableArray<ELPeripheralModel *> *peripheralArray;//扫描到的外设 | 
													
												
													
														|  |  | 
 |  |  |  | 
													
												
													
														|  |  |  |  |  | //广播设备 | 
													
												
													
														|  |  |  |  |  | @property(nonatomic, strong) NSMutableArray<ELPeripheralModel *> *broadcastPeripheralArray; | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  | @property (nonatomic, assign) ELBluetoothState state;//蓝牙状态 |  |  | @property (nonatomic, assign) ELBluetoothState state;//蓝牙状态 | 
													
												
													
														|  |  | @property (nonatomic, assign) BOOL isOn;// |  |  | @property (nonatomic, assign) BOOL isOn;// | 
													
												
											
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  | return _peripheralArray; |  |  | return _peripheralArray; | 
													
												
													
														|  |  | } |  |  | } | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  | 
 |  |  |  | 
													
												
													
														|  |  | - (void)setNeedScanBindSysDevice:(BOOL)needScanBindSysDevice { |  |  |  | 
													
												
													
														|  |  | _needScanBindSysDevice = needScanBindSysDevice; |  |  |  | 
													
												
													
														|  |  |  |  |  | - (NSMutableArray<ELPeripheralModel *> *)broadcastPeripheralArray { | 
													
												
													
														|  |  |  |  |  | if (_broadcastPeripheralArray == nil) { | 
													
												
													
														|  |  |  |  |  | _broadcastPeripheralArray = [[NSMutableArray alloc] init]; | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | return _broadcastPeripheralArray; | 
													
												
													
														|  |  | } |  |  | } | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  |  |  |  | 
 | 
													
												
													
														|  |  |  |  |  | 
 | 
													
												
													
														|  |  | #pragma mark ============ 自定义方法 ============== |  |  | #pragma mark ============ 自定义方法 ============== | 
													
												
													
														|  |  | -(void)startScan{ |  |  | -(void)startScan{ | 
													
												
													
														|  |  |  |  |  |  | 
													
												
											
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  | [self.peripheralArray removeAllObjects];//移除之前扫描的设备 |  |  | [self.peripheralArray removeAllObjects];//移除之前扫描的设备 | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  | CBUUID *uuid = [CBUUID UUIDWithString:serviceUUID];//serviceUUID |  |  | CBUUID *uuid = [CBUUID UUIDWithString:serviceUUID];//serviceUUID | 
													
												
													
														|  |  | [self.centralManager scanForPeripheralsWithServices:@[uuid] options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:YES]}]; |  |  |  | 
													
												
													
														|  |  |  |  |  | CBUUID *broadcastUUID = [CBUUID UUIDWithString:broadcastServiceUUID];//广播设备UUID | 
													
												
													
														|  |  |  |  |  | [self.centralManager scanForPeripheralsWithServices:@[uuid,broadcastUUID] options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:YES]}]; | 
													
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  | }else{ |  |  | }else{ | 
													
												
													
														|  |  | NSLog(@"please open bluetooth"); |  |  | NSLog(@"please open bluetooth"); | 
													
												
											
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  | } else { |  |  | } else { | 
													
												
													
														|  |  | NSLog(@"Other perpheral = %@",advertisementData.description); |  |  | NSLog(@"Other perpheral = %@",advertisementData.description); | 
													
												
													
														|  |  | } |  |  | } | 
													
												
													
														|  |  |  |  |  | } else if ([serviceUUIDs.description rangeOfString:broadcastServiceUUID].length) { | 
													
												
													
														|  |  |  |  |  | //MARK: 广播设备 | 
													
												
													
														|  |  |  |  |  | if (manufactureData.length != 20) { | 
													
												
													
														|  |  |  |  |  | NSLog(@"Broadcast device error"); | 
													
												
													
														|  |  |  |  |  | return; | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | NSLog(@"=====AILink广播设备:%@", manufactureData); | 
													
												
													
														|  |  |  |  |  | //CID.VID.PID----MAC-------校验和----自定义数据(前8个byte要解密) | 
													
												
													
														|  |  |  |  |  | //0x010101-----06000070b801 3c       6bfae71d19cb18d7 0000 | 
													
												
													
														|  |  |  |  |  | Byte byteCid = byte[0]; | 
													
												
													
														|  |  |  |  |  | int cid = byte[0] + 65535; | 
													
												
													
														|  |  |  |  |  | int vid = byte[1]; | 
													
												
													
														|  |  |  |  |  | int pid = byte[2]; | 
													
												
													
														|  |  |  |  |  | //mac地址 | 
													
												
													
														|  |  |  |  |  | NSData *macData = [manufactureData subdataWithRange:NSMakeRange(3, 6)]; | 
													
												
													
														|  |  |  |  |  | NSString *macStr = [self getBroadcastPeripheralWithData:macData]; | 
													
												
													
														|  |  |  |  |  | //回调到广播设备列表 | 
													
												
													
														|  |  |  |  |  | [self addBroadcastPeriphralWithName:peripheralName withMacAddress:macStr withRSSI:RSSI.integerValue withPeripheral:peripheral withVendorID:vid withProductID:pid withDeviceType:cid devData:manufactureData]; | 
													
												
													
														|  |  |  |  |  | //校验和 | 
													
												
													
														|  |  |  |  |  | NSData *chechsumData = [manufactureData subdataWithRange:NSMakeRange(9, 11)]; | 
													
												
													
														|  |  |  |  |  | if ([self broadcastChecksum:chechsumData]) { | 
													
												
													
														|  |  |  |  |  | //获取加密数据 | 
													
												
													
														|  |  |  |  |  | NSData *data = [manufactureData subdataWithRange:NSMakeRange(10, 8)]; | 
													
												
													
														|  |  |  |  |  | //对加密数据进行解密 | 
													
												
													
														|  |  |  |  |  | data = [ELEncryptTool broadcastDecryptTEA:data cid:byteCid vid:vid pid:pid]; | 
													
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  |  |  |  | //获取包尾2个byte数据 | 
													
												
													
														|  |  |  |  |  | NSData *tailData = [manufactureData subdataWithRange:NSMakeRange(18, 2)]; | 
													
												
													
														|  |  |  |  |  | //获取最终的数据 | 
													
												
													
														|  |  |  |  |  | NSMutableData *result = [NSMutableData dataWithData:data]; | 
													
												
													
														|  |  |  |  |  | [result appendData:tailData]; | 
													
												
													
														|  |  |  |  |  | // | 
													
												
													
														|  |  |  |  |  | //在主线程上回调数据 | 
													
												
													
														|  |  |  |  |  | dispatch_async(dispatch_get_main_queue(), ^{ | 
													
												
													
														|  |  |  |  |  | if ([self.delegate respondsToSelector:@selector(bleBroadcastWithCid:vid:pid:mac:data:)]) { | 
													
												
													
														|  |  |  |  |  | [self.delegate bleBroadcastWithCid:cid vid:vid pid:pid mac:macStr data:result]; | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | }); | 
													
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  |  |  |  | } else { | 
													
												
													
														|  |  |  |  |  | NSLog(@"Broadcast equipment verification failed"); | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  | } |  |  | } | 
													
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  | } |  |  | } | 
													
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  | } |  |  | } | 
													
												
											
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  | }); |  |  | }); | 
													
												
													
														|  |  | } |  |  | } | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  |  |  |  | //MARK: 回调广播设备 | 
													
												
													
														|  |  |  |  |  | - (void)addBroadcastPeriphralWithName:(NSString *)name withMacAddress:(NSString *)mac withRSSI:(NSInteger)rssi withPeripheral:(CBPeripheral *)peripheral withVendorID:(NSInteger)vid withProductID:(NSInteger)pid withDeviceType:(NSInteger)cid devData:(NSData *)devData { | 
													
												
													
														|  |  |  |  |  | 
 | 
													
												
													
														|  |  |  |  |  | for (ELPeripheralModel *model in self.broadcastPeripheralArray) { | 
													
												
													
														|  |  |  |  |  | if ([model.macAddress isEqualToString:mac]) { | 
													
												
													
														|  |  |  |  |  | return; | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | 
 | 
													
												
													
														|  |  |  |  |  | ELPeripheralModel *model = [[ELPeripheralModel alloc] init]; | 
													
												
													
														|  |  |  |  |  | model.deviceName = name; | 
													
												
													
														|  |  |  |  |  | model.macAddress = mac; | 
													
												
													
														|  |  |  |  |  | model.rssi = rssi; | 
													
												
													
														|  |  |  |  |  | model.peripheral = peripheral; | 
													
												
													
														|  |  |  |  |  | model.deviceType = cid; | 
													
												
													
														|  |  |  |  |  | model.vendorID = vid; | 
													
												
													
														|  |  |  |  |  | model.productID = pid; | 
													
												
													
														|  |  |  |  |  | model.manufactureData = devData; | 
													
												
													
														|  |  |  |  |  | [self.broadcastPeripheralArray addObject:model]; | 
													
												
													
														|  |  |  |  |  | //    [self.broadcastPeripheralArray sortUsingFunction:bluetoothManagerPeriphelRSSIsortUsingFunction context:NULL]; | 
													
												
													
														|  |  |  |  |  | dispatch_async(dispatch_get_main_queue(), ^{ | 
													
												
													
														|  |  |  |  |  | NSArray<ELPeripheralModel *> *peripherals = self.broadcastPeripheralArray.copy; | 
													
												
													
														|  |  |  |  |  | if ([self.delegate respondsToSelector:@selector(bluetoothManagerScanedBroadcastPeripherals:)]) { | 
													
												
													
														|  |  |  |  |  | [self.delegate bluetoothManagerScanedBroadcastPeripherals:peripherals]; | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | }); | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | 
 | 
													
												
													
														|  |  |  |  |  | 
 | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  | //MARK: 获取连接类设备mac地址 |  |  | //MARK: 获取连接类设备mac地址 | 
													
												
													
														|  |  | -(NSString *)getMacAddressWithByte:(NSData *)data{ |  |  | -(NSString *)getMacAddressWithByte:(NSData *)data{ | 
													
												
											
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  | } |  |  | } | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  |  |  |  | -(BOOL)broadcastChecksum:(NSData *)data{ | 
													
												
													
														|  |  |  |  |  | if (data.length != 11) { | 
													
												
													
														|  |  |  |  |  | return NO; | 
													
												
													
														|  |  |  |  |  | }else{ | 
													
												
													
														|  |  |  |  |  | BOOL is = NO; | 
													
												
													
														|  |  |  |  |  | Byte *bytes = (Byte *)[data bytes]; | 
													
												
													
														|  |  |  |  |  | //校验和 | 
													
												
													
														|  |  |  |  |  | Byte checksum = 0x00; | 
													
												
													
														|  |  |  |  |  | for (int i=1; i<data.length; i++) { | 
													
												
													
														|  |  |  |  |  | checksum += bytes[i]; | 
													
												
													
														|  |  |  |  |  |  | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | if (checksum == bytes[0]) { | 
													
												
													
														|  |  |  |  |  | is = YES; | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | return is; | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | 
 | 
													
												
													
														|  |  |  |  |  | //MARK: 解析广播设备mac地址 | 
													
												
													
														|  |  |  |  |  | - (NSString *)getBroadcastPeripheralWithData:(NSData *)macData { | 
													
												
													
														|  |  |  |  |  | Byte *macBytes = (Byte *) macData.bytes; | 
													
												
													
														|  |  |  |  |  | NSMutableString *macStr = [[NSMutableString alloc] init]; | 
													
												
													
														|  |  |  |  |  | for (NSInteger i = macData.length - 1; i >= 0; i--) { | 
													
												
													
														|  |  |  |  |  | NSString *bStr = [NSString stringWithFormat:@"%02x", macBytes[i]]; | 
													
												
													
														|  |  |  |  |  | [macStr appendString:bStr.uppercaseString]; | 
													
												
													
														|  |  |  |  |  | if (i > 0) { | 
													
												
													
														|  |  |  |  |  | [macStr appendString:@":"]; | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  |  |  |  | return macStr.copy; | 
													
												
													
														|  |  |  |  |  | } | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  | 
 |  |  | 
 | 
													
												
													
														|  |  | @end |  |  | @end |