react-native-bt-device/ios/RNBTDevice/Device/ENBLEDeviceManager.m

534 lines
15 KiB
Mathematica
Raw Permalink Normal View History

2024-03-24 09:45:44 +00:00
//
// PPDeviceManager.m
// PaoPao
//
// Created by lvwang2002 on 14/12/11.
// Copyright (c) 2014 paopao. All rights reserved.
//
#import "ENBLEDeviceManager.h"
#import "NSArray+LinqExtensions.h"
@implementation ENBLEDeviceManager{
CBCentralManager *_centralManager;
NSMutableArray *_supportMacs;
NSArray *_searchedPeripherals; //mac
NSArray *_connectedPeripherals; //
NSDictionary *_deviceInfo;
BOOL _isScan;
NSTimer *_timer;
dispatch_queue_t _scanQueue;
dispatch_queue_t _centerQueue;
dispatch_queue_t _postQueue;
NSArray *_supportDeviceServerUDID;
NSArray *_supportDeviceNames;
NSMutableArray *_holdDevices;
NSArray *bleDevices;
ENSearchedType _searchedType;
NSTimer *_searchedDeviceTimer;
NSTimer *_updateSearchedDeviceTimer;
CBPeripheral *_peripheral;
}
#pragma mark
#pragma mark centerBlueManagere Delegate
-(instancetype)init{
self = [super init];
if (self) {
_supportMacs = [[NSMutableArray alloc]initWithCapacity:20];
_searchedPeripherals = [[NSArray alloc] init];
_connectedPeripherals = [[NSArray alloc] init];
// _supportDeviceServerUDID = @[];
_supportDeviceNames = @[@"BLE-",@"iGate",@"ENUO_",@"Glucose",@"INVS300",@"RBP",@"ClinkBlood",@"O",@"TH-",@"ENUO-G"];
_holdDevices =[[NSMutableArray alloc] initWithCapacity:20];
_isScan = NO;
_searchedType = ENSearchedAllType;
_BTStatus = ENBTPreparedStatus;
_postQueue = dispatch_queue_create("com.device.post.bleCenter", NULL);
[ENDLog share].isDisplayLog = true;
_searchedDeviceTimer =[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(searchedDevices) userInfo:nil repeats:YES];
_updateSearchedDeviceTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(upgradeSearchedDevices) userInfo:nil repeats:YES];
}
return self;
}
+(instancetype)shareDeviceManager{
static ENBLEDeviceManager *deviceManager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
deviceManager = [[ENBLEDeviceManager alloc] init];
[deviceManager run];
});
return deviceManager;
}
-(void)run{
_centerQueue = dispatch_queue_create("com.device.bleCenter", NULL);
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:_centerQueue];
}
-(BLEDevice *)getDeviceWithUUID:(NSUUID *)uuid{
NSArray *devices = [_holdDevices linq_where:^BOOL(id item) {
return [[item getUUID] isEqual:uuid];
}];
if(devices.count == 0){
return nil;
}
return devices[0];
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
switch (central.state) {
case CBCentralManagerStatePoweredOff:{
NSLog(@"CoreBluetooth BLE hardware is Powered off");
self.BTStatus = ENBTPowerOffStatus;
[self poweroffHand];
dispatch_async(dispatch_get_main_queue(), ^{
if([self.deviceManagerDelegate respondsToSelector:@selector(didUpdateBTStatus:)]){
[self.deviceManagerDelegate didUpdateBTStatus:ENBTPowerOffStatus];
};
});
}
break;
case CBCentralManagerStatePoweredOn:{
NSLog(@"CoreBluetooth BLE hardware is Powered on and ready");
self.BTStatus = ENBTPowerOnStatus;
dispatch_async(dispatch_get_main_queue(), ^{
if([self.deviceManagerDelegate respondsToSelector:@selector(didUpdateBTStatus:)]){
[self.deviceManagerDelegate didUpdateBTStatus:ENBTPowerOnStatus];
};
});
}
break;
case CBCentralManagerStateResetting:
NSLog(@"CoreBluetooth BLE hardware is resetting");
break;
case CBCentralManagerStateUnauthorized:
NSLog(@"CoreBluetooth BLE state is unauthorized");
break;
case CBCentralManagerStateUnknown:
NSLog(@"CoreBluetooth BLE state is unknown");
break;
case CBCentralManagerStateUnsupported:
NSLog(@"CoreBluetooth BLE hardware is unsupported on this platform");
break;
default:
break;
}
}
- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)dict{
NSLog(@"willRestoreState :%@",dict);
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
if(!_isScan){
NSLog(@"已经停止扫描");
return;
}
NSString *deviceName = peripheral.name;
BOOL isSupport = [_supportDeviceNames linq_any:^BOOL(id item) {
return [deviceName hasPrefix:item];
}];
if(!isSupport){
// [[ENDLog share] log:@"搜索到不支持设备"];
return;
}
//
BOOL isConnectedType = [self isSearchedTypeWithDeviceName:deviceName];
if(!isConnectedType){
return;
}
ENLog(@"device name:");
ENLog(deviceName);
NSUUID *uuid = peripheral.identifier;
BLEDevice *device = [self getBleDevice:uuid];
BOOL isNewly = YES;
if (device == nil) {
NSString *scanContent =[NSString stringWithFormat:@"Did discover peripheral. peripheral: %@ rssi: %@, UUID: %@ advertisementData: %@ ", peripheral, RSSI, peripheral.identifier, advertisementData];
ENLog(scanContent);
//,,.
device = [[BLEDevice alloc] initWithPeripheral:peripheral CentralManager:_centralManager DeviceManager:self];
device.advertisementData = advertisementData;
peripheral.delegate = device;
[_holdDevices addObject:device];
}else{
isNewly = NO;
}
device.searchDate = [NSDate date]; //
dispatch_async(dispatch_get_main_queue(), ^{
if([_deviceManagerDelegate respondsToSelector:@selector(didDiscoverDevice:IsNewly:)]){
[_deviceManagerDelegate didDiscoverDevice:device IsNewly:isNewly];
}
});
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
//
dispatch_async(dispatch_get_main_queue(), ^{
BLEDevice *device = [self getBleDevice:peripheral.identifier];
[device setConnectStatus:DeviceConnectedStatus];
if([_deviceManagerDelegate respondsToSelector:@selector(didConnectedDevice:)]){
[_deviceManagerDelegate didConnectedDevice:device];
}
[device setConnectedDevice];
});
[peripheral discoverServices:nil];
//
[peripheral performSelector:@selector(readRSSI) withObject:nil afterDelay:1];
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
//,,.
ENLog(@"设备断开连接");
BLEDevice *device = [self getBleDevice:peripheral.identifier];
peripheral.delegate = nil;
if(device == nil){
ENLog(@"断开设备已经从存储数组中删除");
return;
}
@try {
[_holdDevices removeObject:device];
} @catch (NSException *exception) {
ENLog(@"删除不存在设备,报错");
}
device.connectStatus = DeviceDisconnectedStatus;
dispatch_async(dispatch_get_main_queue(), ^{
if([device.deviceDelegate respondsToSelector:@selector(didDisconnectDevice:)]){
[device.deviceDelegate didDisconnectDevice:device];
}
});
}
- (NSString *)getHexStringWithValue:(int)values{
NSString *newHexStr = [NSString stringWithFormat:@"%x",values&0xff];
if([newHexStr length]==1)
newHexStr = [NSString stringWithFormat:@"0%@",newHexStr];
else
newHexStr = [NSString stringWithFormat:@"%@",newHexStr];
newHexStr = [NSString stringWithFormat:@"0x%@",newHexStr];
return newHexStr ;
}
/** */
-(void)startScan{
//,,
if(_scanQueue){
_isScan = YES;
return;
}
_isScan = YES;
_scanQueue = dispatch_queue_create("com.device.scanqueue", NULL);
dispatch_async(_scanQueue, ^{
while (1) {
if(!_isScan){
[NSThread sleepForTimeInterval:0.5];
continue;
}
dispatch_async(dispatch_get_main_queue(), ^{
ENLog(@"enable scan");
[_centralManager scanForPeripheralsWithServices:nil
options:nil];
});
[NSThread sleepForTimeInterval:2.5];
dispatch_async(dispatch_get_main_queue(), ^{
ENLog(@"disable scan");
[_centralManager stopScan];
});
[NSThread sleepForTimeInterval:0.5];
}
});
}
/** */
-(void)stopScan{
[_centralManager stopScan];
_isScan = NO;
}
-(void)emptySearchedPeripherals{
_searchedPeripherals = [[NSArray alloc]init];
}
//.
-(void)poweroffHand{
ENLog(@"设备断开连接");
_isScan = NO;
for (BLEDevice *device in _holdDevices) {
[device disconnect];
dispatch_async(dispatch_get_main_queue(), ^{
if([device.deviceDelegate respondsToSelector:@selector(didDisconnectDevice:)]){
[device.deviceDelegate didDisconnectDevice:device];
}
});
}
_holdDevices = [[NSMutableArray alloc] initWithCapacity:20];
}
/** */
-(BLEDevice *)getBleDevice:(NSUUID *)uuid{
NSArray *devices = [_holdDevices linq_where:^BOOL(id item) {
BLEDevice *device = item;
return [device.getUUID isEqual:uuid];
}];
if([devices count]<=0){
return nil;
}else{
return devices[0];
}
};
/** */
-(void)uhoh:(BLEDevice *)device{
[_holdDevices removeObject:device];
[device disconnect];
}
/** */
-(BOOL)hasDeviceConnectedWithType:(ENSearchedType)type{
NSArray *connectedDevices = [_holdDevices linq_where:^BOOL(id item) {
BLEDevice *device = (BLEDevice *)item;
if(type == ENSearchedKetoneType){
NSString *deviceName = [device getDeviceName];
return (device.connectStatus == DeviceConnectedStatus && [deviceName hasPrefix:@"BLE-ENUO"])
|| (device.connectStatus == DeviceConnectedStatus && [deviceName hasPrefix:@"ENUO-G"])
|| (device.connectStatus == DeviceConnectedStatus && type == ENSearchedAllType);
}else{
ENSearchedType deviceType = [self getDeviceTypeWithDeviceName:[device getDeviceName]];
return ((device.connectStatus == DeviceConnectedStatus && type == deviceType) ||
(device.connectStatus == DeviceConnectedStatus && type == ENSearchedAllType));
}
}];
return (connectedDevices.count > 0);
}
/** */
-(BOOL)hasDeviceConnectingWithType:(ENSearchedType)type{
NSArray *connectingDevices = [_holdDevices linq_where:^BOOL(id item) {
BLEDevice *device = (BLEDevice *)item;
if(type == ENSearchedKetoneType){
NSString *deviceName = [device getDeviceName];
return (device.connectStatus == DeviceConnectingStatus &&[deviceName hasPrefix:@"BLE-ENUO"])
|| (device.connectStatus == DeviceConnectingStatus &&[deviceName hasPrefix:@"ENUO-G"])
|| (device.connectStatus == DeviceConnectingStatus && type == ENSearchedAllType);
}else{
ENSearchedType deviceType = [self getDeviceTypeWithDeviceName:[device getDeviceName]];
return ((device.connectStatus == DeviceConnectingStatus && type == deviceType) ||
(device.connectStatus == DeviceConnectingStatus && type == ENSearchedAllType));
}
}];
return (connectingDevices.count > 0);
}
/** */
-(void)setSearchedDeviceType:(ENSearchedType)searchedDeviceType{
_searchedType = searchedDeviceType;
}
/** */
-(BOOL)isSearchedTypeWithDeviceName:(NSString *)deviceName{
if(_searchedType == ENSearchedAllType){
return true;
}else if(_searchedType == ENSearchedGlucoType) {
if([deviceName hasPrefix:@"Glucose"]
|| [deviceName hasPrefix:@"BLE-ENUO"]
|| [deviceName hasPrefix:@"ENUO-G"]){
return true;
}else{
return false;
}
}else if(_searchedType == ENSearchedBPType){
if([deviceName hasPrefix:@"RBP"] ||
[deviceName hasPrefix:@"ClinkBlood"]){
return true;
}else{
return false;
}
}else if(_searchedType == ENSearchedCholesterolType ){
if([deviceName hasPrefix:@"iGate"]){
return true;
}else{
return false;
}
}else if(_searchedType == ENSearchedKetoneType){
if([deviceName hasPrefix:@"BLE-ENUO"]){
return true;
}else{
return false;
}
}
return false;
}
-(NSArray *)getSearchedDevices{
return [_holdDevices copy];
}
-(void)postUpdateDeviceList{
dispatch_async(dispatch_get_main_queue(), ^{
[self searchedDevices];
});
}
/** */
-(void)searchedDevices{
dispatch_async(dispatch_get_main_queue(), ^{
if([self.deviceManagerDelegate respondsToSelector:@selector(didUpdateSearchedDevices:)]){
NSArray *typeDevices = [_holdDevices linq_where:^BOOL(id item) {
BLEDevice *device = (BLEDevice *)item;
ENSearchedType type = [self getDeviceTypeWithDeviceName:[device getDeviceName]];
return ((_searchedType == ENSearchedAllType) || (_searchedType == type));
}];
[self.deviceManagerDelegate didUpdateSearchedDevices:typeDevices];
}
});
}
/** */
-(void)upgradeSearchedDevices{
// ENLog(@"1S刷新扫描设备列表");
NSArray *updateDevices = [_holdDevices linq_where:^BOOL(id item) {
BLEDevice *device = (BLEDevice *)item;
if((fabs([device.searchDate timeIntervalSinceDate:[NSDate date]])>=10.0) &&
device.connectStatus == DeviceSearchedStatus){
return NO;
}else{
return YES;
}
}];
NSString *log =[NSString stringWithFormat:@"update device count:%lu",(unsigned long)updateDevices.count];
//ENLog(log);
_holdDevices = [updateDevices mutableCopy];
}
/** */
-(void)setIsShowLog:(BOOL)isShow{
[ENDLog share].isDisplayLog = isShow;
}
/** */
-(BLEDevice *)getCurrentConnectedDeviceWithType:(ENSearchedType)type{
NSArray *connectedDevices = [_holdDevices linq_where:^BOOL(id item) {
BLEDevice *device = (BLEDevice *)item;
ENSearchedType deviceType = [self getDeviceTypeWithDeviceName:[device getDeviceName]];
return ((device.connectStatus == DeviceConnectedStatus && type == deviceType) ||
(device.connectStatus == DeviceConnectedStatus && type == ENSearchedAllType));
}];
return connectedDevices.count>0?[connectedDevices firstObject]:nil;
}
/** , */
-(ENSearchedType)getDeviceTypeWithDeviceName:(NSString *)deviceName{
if([deviceName hasPrefix:@"Glucose"]
|| [deviceName hasPrefix:@"BLE-ENUO"]
|| [deviceName hasPrefix:@"ENUO-G"]){
return ENSearchedGlucoType;
}else if([deviceName hasPrefix:@"RBP"] ||
[deviceName hasPrefix:@"ClinkBlood"]){
return ENSearchedBPType;
}else if([deviceName hasPrefix:@"iGate"]){
return ENSearchedCholesterolType;
}
return ENSearchedAllType;
}
/** */
-(void)removeDevice:(BLEDevice *)device{
@try {
[_holdDevices removeObject:device];
} @catch (NSException *exception) {
} @finally {
}
}
/** */
-(void)disconnectAllDevices{
for(BLEDevice *device in _holdDevices){
[device disconnect];
}
}
-(dispatch_queue_t)getPostQueue{
return _postQueue;
}
@end