|
|
|
|
|
|
|
|
//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 |