From: liangzhenying <867174124@qq.com> Date: Sat, 24 Aug 2024 10:35:17 +0000 (+0800) Subject: ble hid数据交互修改 X-Git-Tag: 千寻适配d9~40 X-Git-Url: http://git.snicker.com.cn/sitemap.xml?a=commitdiff_plain;h=73651d191efef23a2c58e6c366a44c3c329d54a3;p=mirrors%2FMouseSdk-MacOS.git ble hid数据交互修改 --- diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h index 38f5596..06a012e 100644 --- a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h @@ -69,7 +69,7 @@ typedef NS_ENUM(NSInteger,TlwMouseLogLevel) { /// 切换连接类型 /// - Parameter type: 连接类型 -- (void)switchConnect:(AiMouseConnectType)type; +- (void)switchConnect:(AiMouseConnectType)type isConnected:(BOOL)isConneted; /// 传输业务数据给sdk /// - Parameter data:ai特征传过来的数据 diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m index bd7f9ac..6dd6a43 100644 --- a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m @@ -96,18 +96,20 @@ _logLevel = level; } - (void)didDisconnect{ + _connected = false; [self showLog:@"系统断开连接"]; [self stopRecord]; [self.connectManager disConnected]; } -- (void)switchConnect:(AiMouseConnectType)type{ - if(type != _connectType && self.connected){ - [self.connectManager disConnected]; - } +- (void)switchConnect:(AiMouseConnectType)type isConnected:(BOOL)isConneted{ +// if(type != _connectType && self.connected){ +// [self.connectManager disConnected]; +// } + _connected = isConneted; _connectType = type; [self showLog:type == AiMouseConnectType_bluetooth?@"sdk切换到蓝牙模式":@"sdk切换到usb模式"]; - + [self TlwConnectManager:self.connectManager connectStateDidChange:isConneted]; if (type == AiMouseConnectType_hid) { [self.recordManager checkPermissions]; diff --git a/MouseSdk/MouseSdk.xcodeproj/project.pbxproj b/MouseSdk/MouseSdk.xcodeproj/project.pbxproj index 3bf05b9..96b520a 100644 --- a/MouseSdk/MouseSdk.xcodeproj/project.pbxproj +++ b/MouseSdk/MouseSdk.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 180E7D1A2BD90032008558E8 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18F325772B95737F00CABA2E /* CoreAudio.framework */; }; 180E7D1B2BD9005D008558E8 /* liblzma.5.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 18CB080B2BA401D0005F5854 /* liblzma.5.tbd */; }; 182B548D2BB7EC9B009F53B6 /* DeviceManger.m in Sources */ = {isa = PBXBuildFile; fileRef = 182B548C2BB7EC9B009F53B6 /* DeviceManger.m */; }; + 185EBE042C79D16600B2503B /* TimerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 185EBE032C79D16600B2503B /* TimerManager.m */; }; 1867E5A92BB2706F008FC5FB /* HidManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1867E5A82BB2706F008FC5FB /* HidManager.m */; }; 18BF1DCF2B81AB7C00B8D90F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 18BF1DCE2B81AB7C00B8D90F /* AppDelegate.m */; }; 18BF1DD22B81AB7C00B8D90F /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18BF1DD12B81AB7C00B8D90F /* ViewController.m */; }; @@ -75,6 +76,8 @@ 180E7AB22BD7BBD9008558E8 /* libAiMouseSdk.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libAiMouseSdk.a; sourceTree = BUILT_PRODUCTS_DIR; }; 182B548B2BB7EC9B009F53B6 /* DeviceManger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceManger.h; sourceTree = ""; }; 182B548C2BB7EC9B009F53B6 /* DeviceManger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeviceManger.m; sourceTree = ""; }; + 185EBE022C79D16600B2503B /* TimerManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TimerManager.h; sourceTree = ""; }; + 185EBE032C79D16600B2503B /* TimerManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TimerManager.m; sourceTree = ""; }; 1867E5A72BB2706F008FC5FB /* HidManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HidManager.h; sourceTree = ""; }; 1867E5A82BB2706F008FC5FB /* HidManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HidManager.m; sourceTree = ""; }; 18BF1DCA2B81AB7C00B8D90F /* AiMouseSdk.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AiMouseSdk.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -197,10 +200,10 @@ 18EF7B092C7605BF00AC5223 /* MouseSdkManager.m */, 18BF1DD02B81AB7C00B8D90F /* ViewController.h */, 18BF1DD12B81AB7C00B8D90F /* ViewController.m */, - 18EF7B0B2C76079E00AC5223 /* TlwVC.h */, - 18EF7B0C2C76079E00AC5223 /* TlwVC.m */, 18EF7B0E2C7607C100AC5223 /* FrkVC.h */, 18EF7B0F2C7607C100AC5223 /* FrkVC.m */, + 18EF7B0B2C76079E00AC5223 /* TlwVC.h */, + 18EF7B0C2C76079E00AC5223 /* TlwVC.m */, 18EF7B1A2C760FF700AC5223 /* TlwScanVC.h */, 18EF7B1B2C760FF700AC5223 /* TlwScanVC.m */, 18EF7B1C2C760FF700AC5223 /* TlwScanVC.xib */, @@ -254,6 +257,8 @@ children = ( 182B548B2BB7EC9B009F53B6 /* DeviceManger.h */, 182B548C2BB7EC9B009F53B6 /* DeviceManger.m */, + 185EBE022C79D16600B2503B /* TimerManager.h */, + 185EBE032C79D16600B2503B /* TimerManager.m */, 18BF1E202B83066200B8D90F /* BleManager.h */, 18BF1E212B83066200B8D90F /* BleManager.m */, 1867E5A72BB2706F008FC5FB /* HidManager.h */, @@ -453,6 +458,7 @@ 18BF1DD22B81AB7C00B8D90F /* ViewController.m in Sources */, 18BF1DD92B81AB7F00B8D90F /* main.m in Sources */, 18EF7B172C760A5B00AC5223 /* TlwBleManager.m in Sources */, + 185EBE042C79D16600B2503B /* TimerManager.m in Sources */, 18F328D52B98569D00CABA2E /* Config.m in Sources */, 18EF7B182C760A5B00AC5223 /* TlwHidManager.m in Sources */, 18EF7B0D2C76079E00AC5223 /* TlwVC.m in Sources */, diff --git a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate index eb8da1d..437539d 100644 Binary files a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate and b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MouseSdk/MouseSdk/Ble/BleManager.h b/MouseSdk/MouseSdk/Ble/BleManager.h index 450ab20..171cae5 100644 --- a/MouseSdk/MouseSdk/Ble/BleManager.h +++ b/MouseSdk/MouseSdk/Ble/BleManager.h @@ -7,49 +7,24 @@ #import #import -#import "TlwMouseSdk.h" -#import "AiMouseSdk.h" - -@interface BleManager : NSObject -@property (nonatomic,copy)void (^discoverDevice)(CBPeripheral *peripheral) ;/// 扫描到设备 -@property (nonatomic,copy)void (^didConnectDevice)(CBPeripheral *peripheral);/// 连接成功 -@property (nonatomic,copy)void (^didDisConnectDevice)(CBPeripheral *peripheral);/// 断开连接 -/// -/// -@property (nonatomic,copy)void (^authCallBack)(BOOL isSuccess);/// 鉴权回调 -@property (nonatomic, copy)void (^aiMouseConnectStateDidChangeCallBack)(BOOL connected);/// 设备连接状态回调 -@property (nonatomic, copy)void (^aiMouseSendDeviceInfoDataCallBack)(NSData *data);/// 设备信息数据回调 -@property (nonatomic, copy)void (^aiMouseSendCmdDataCallBack)(NSString *data);/// 鼠标按键指令回调 -@property (nonatomic, copy)void (^begainRecoredCallBack)(void);/// 录音开始回调 -@property (nonatomic, copy)void (^recordingCallBack)(NSData *data);/// 录音进行中回调 -@property (nonatomic, copy)void (^finishRecoredCallBack)(NSData *data);/// 录音结束回调 - -@property (nonatomic, copy)void (^aiMouseAddLogCallBack)(NSString *log);//输出日志 -/// 单利 -+(BleManager *)shared; - -/// 扫描 -- (void)startScanDevice; -/// 停止扫描 -- (void)stopScanDevice; -/// 连接设备 -/// - Parameter peripheral: 蓝牙设备 -- (void)connectPeripheral:(CBPeripheral *)peripheral; -///当前是否处于蓝牙连接状态 -- (BOOL)isDidConnectBleDevice; - -///直连蓝牙设备,该函数已经处理了startScanDevice、connectPeripheral和stopScanDevice的调用 -/// - Parameter bleName:蓝牙设备名称 -- (void)connectBleDeviceWithName:(NSString *)bleName; +@interface BleManager : NSObject +@property (nonatomic, copy)void (^connectStateCallBack)(BOOL connected);/// 设备连接状态回调 +@property (nonatomic, copy)void (^receiveVoiceDataCallBack)(NSData *data);/// 语音数据回调 +@property (nonatomic, copy)void (^receiveInfoDataCallBack)(NSData *data);/// 设备信息数据回调 +@property (nonatomic, copy)void (^logCallBack)(NSString *log);//输出日志 +/// 单利 ++(BleManager *)shared; -/// 获取设备信息 -- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))completation; +// bleName:蓝牙设备名称 +- (void)startScanWithName:(NSString *)bleName; -/// 获取信号强度 -- (void)getRSSI:(void (^)(NSString *value,NSError *error))complete; +//停止扫描 +- (void)stopScan; +//写入数据 +-(void)writeToDevice:(NSData *)data; @end diff --git a/MouseSdk/MouseSdk/Ble/BleManager.m b/MouseSdk/MouseSdk/Ble/BleManager.m index a59f61f..ed718ee 100644 --- a/MouseSdk/MouseSdk/Ble/BleManager.m +++ b/MouseSdk/MouseSdk/Ble/BleManager.m @@ -25,20 +25,10 @@ @interface BleManager () -{ -// dispatch_block_t _block; - //是否是主动断开蓝牙连接的 - bool _isActiveDisconnect; - dispatch_block_t _disconnectBlock; -} @property(nonatomic, strong) CBCentralManager *centralManager;///蓝牙管理 -@property(nonatomic, strong) CBPeripheral *connectPeripheral;//连接的设备 -@property(nonatomic, strong) CBCharacteristic *aiCha;//ai特征 +@property(nonatomic, strong) CBPeripheral *crrentPeripheral;//连接的设备 @property(nonatomic, strong) CBCharacteristic *deviceInfoCha;//设备信息特征 @property (nonatomic,strong) NSMutableData *recordData;//录音的数据 - -@property (nonatomic, copy)void (^activeDisconnectCallBack)(BOOL isSuccess);//主动断开连接的回调 - @property (nonatomic, copy) NSString *targetBleName; @end @@ -57,59 +47,14 @@ if (self) { self.centralManager = [[CBCentralManager alloc]init]; self.centralManager.delegate = self; - _isActiveDisconnect = NO; - -// //链接超时 -// _block = dispatch_block_create(0, ^{ -// [self showLog:(@"(BleManager)执行超时操作 ")]; -// //连接超时走这里 -// if (self.connectPeripheral == nil || self.deviceInfoCha == nil) { -// if (self.connectPeripheral != nil) { -// //立即取消与外围设备的连接 -// [self.centralManager cancelPeripheralConnection:self.connectPeripheral]; -// self.connectPeripheral = nil; -// } -// [self stopScanDevice]; -// [self showLog:(@"(BleManager)执行超时操作成功,回调连接失败回调 ")]; -// if(self.didDisConnectDevice){ -// self.didDisConnectDevice(nil); -// } -// } -// }); - - //断开连接超时 - _disconnectBlock = dispatch_block_create(0, ^{ - [self showLog:(@"(BleManager)断开连接执行超时操作 ")]; - //连接超时走这里 - if (self.connectPeripheral != nil && self.connectPeripheral.state != CBPeripheralStateDisconnected) { - if (self.activeDisconnectCallBack) { - self.activeDisconnectCallBack(NO); - } - } - else { - if (self.activeDisconnectCallBack) { - self.activeDisconnectCallBack(YES); - } - } - }); } return self; } -- (BOOL)isDidConnectBleDevice { - if (self.connectPeripheral == nil) { - return NO; - } - //当前处于蓝牙链接状态 - if (self.connectPeripheral.state == CBPeripheralStateConnected || self.connectPeripheral.state == CBPeripheralStateConnecting) { - return YES; - } - return NO; -} #pragma mark - CBCentralManagerDelegate - (void)centralManagerDidUpdateState:(nonnull CBCentralManager *)central { - [self showLog:[NSString stringWithFormat:@"centralManagerDidUpdateState:蓝牙状态 = %@",@(central.state)]]; + [self showLog:[NSString stringWithFormat:@"当前电脑蓝牙状态 = %@",@(central.state)]]; switch (central.state) { case CBManagerStateUnknown: @@ -127,80 +72,38 @@ break; case CBManagerStatePoweredOn: - [self autoConnectDevice]; +// [self autoConnectDevice]; break; } } - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{ -// [self showLog:[NSString stringWithFormat:@"(BleManager) didDiscoverPeripheral:扫描到设备 = %@, data = %@",peripheral,advertisementData]]; - if(self.discoverDevice){ - self.discoverDevice(peripheral); - } - - //直连 if (self.targetBleName != nil && self.targetBleName.length > 0 && [self.targetBleName isEqualToString:peripheral.name]) { [self connectPeripheral:peripheral]; } - } - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{ - _isActiveDisconnect = NO; - [self showLog:[NSString stringWithFormat:@"(BleManager) didConnectPeripheral:连接成功 name = %@",peripheral.name]]; - //要求在发现特征处返回连接成功 -// if(self.didConnectDevice){ -// self.didConnectDevice(peripheral); -// } + [self showLog:[NSString stringWithFormat:@"didConnectPeripheral:连接成功 name = %@",peripheral.name]]; peripheral.delegate = self; [peripheral discoverServices:nil]; - self.connectPeripheral = peripheral; - - //直连成功后直接停止扫描 - if (self.targetBleName != nil && self.targetBleName.length > 0 && [self.targetBleName isEqualToString:peripheral.name]) { - [self stopScanDevice]; - } - + self.crrentPeripheral = peripheral; } + -(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ - [self showLog:[NSString stringWithFormat:@"(BleManager) didDisconnectPeripheral:断开连接。。。%@",error.description]]; - [self tlwMouseConnectStateDidChange:false]; -// dispatch_block_cancel(_block); // 取消定时的执行 - if (_isActiveDisconnect) { - dispatch_block_cancel(_disconnectBlock);// 取消定时的执行 - - if (self.activeDisconnectCallBack) { - self.activeDisconnectCallBack(YES); - } - if (self.connectPeripheral != nil) { - self.connectPeripheral = nil; - } - } - else{ - //返回设备断开连接 -// [self aiMouseConnectStateDidChange:false]; - [[TlwMouse shared] didDisconnect]; - - if(self.didDisConnectDevice){ - self.didDisConnectDevice(peripheral); - } - self.connectPeripheral = nil; - [self autoConnectDevice]; - } + [self showLog:[NSString stringWithFormat:@"didDisconnectPeripheral:断开连接。。。%@",error.description]]; + self.crrentPeripheral = nil; + self.connectStateCallBack(false); } - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{ - [self showLog:[NSString stringWithFormat:@"(BleManager) didFailToConnectPeripheral:连接失败。。。%@",error.description]]; -// dispatch_block_cancel(_block); // 取消定时的执行 - if(self.didDisConnectDevice){ - self.didDisConnectDevice(peripheral); - } - - self.connectPeripheral = nil; + [self showLog:[NSString stringWithFormat:@"didFailToConnectPeripheral:连接失败。。。%@",error.description]]; + self.crrentPeripheral = nil; + self.connectStateCallBack(false); } #pragma mark - CBPeripheralDelegate //发现服务 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error { - [self showLog:[NSString stringWithFormat:@"(BleManager) didDiscoverServices:发现服务"]]; + [self showLog:[NSString stringWithFormat:@"didDiscoverServices:发现服务"]]; for (CBService *service in peripheral.services){ [peripheral discoverCharacteristics:nil forService:service]; } @@ -220,261 +123,95 @@ else if ([characteristic.UUID.UUIDString isEqualToString:kSetDeviceInfoUUID]) { //设备信息特征 self.deviceInfoCha = characteristic; - //切换代理 - [TlwMouse shared].delegate = self; - //切换当前连接类型 - [[TlwMouse shared] switchConnect:AiMouseConnectType_bluetooth]; - [self showLog:(@"(BleManager)didDiscoverCharacteristicsForService:回调连接成功 ")]; - [self tlwMouseConnectStateDidChange:true]; - //此时才返回连接成功 - if(self.didConnectDevice){ - self.didConnectDevice(peripheral); - } + [self showLog:(@"didDiscoverCharacteristicsForService:回调连接成功 ")]; + self.connectStateCallBack(true); } } } //收到蓝牙数据 - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { NSData *data = characteristic.value; - [self showLog:[NSString stringWithFormat:@"(BleManager) didUpdateValueForCharacteristic:[receive] %@",data]]; - [self showLog:[NSString stringWithFormat:@"(BleManager) didUpdateValueForCharacteristic:characteristicUUID %@",characteristic.UUID.UUIDString]]; - if([characteristic.UUID.UUIDString isEqualToString:kAiUUID]){ //AI数据 - [self showLog:[NSString stringWithFormat:@"(BleManager) didUpdateValueForCharacteristic:发送AI数据sendAiDataToSdk"]]; - [[TlwMouse shared] sendAiDataToSdk:data]; + self.receiveVoiceDataCallBack(data); } else if([characteristic.UUID.UUIDString isEqualToString:kNotifyDeviceInfoUUID]){ //设备信息数据 - [self showLog:[NSString stringWithFormat:@"(BleManager) didUpdateValueForCharacteristic:发送设备信息数据sendDeviceDataToSdk"]]; - [[TlwMouse shared] sendDeviceDataToSdk:data]; - } -} - -#pragma mark - TlwMouseDelegate -/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备 -/// - Parameter data: 数据 --(void)tlwMouseSendDeviceInfoData:(NSData *)data{ - if (self.connectPeripheral ==nil) { - [self showLog:@"peripheral 为空"]; - return; - } - if (self.deviceInfoCha ==nil) { - [self showLog:@"characteristic 为空"]; - return; - } - [self.connectPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithResponse]; - - if (self.aiMouseSendDeviceInfoDataCallBack) { - self.aiMouseSendDeviceInfoDataCallBack(data); - } -} - -/// 鼠标按键指令回调 -/// - Parameter data: 数据。 -/// 前 单击0x06, 按下0x13(开始录音)抬起0x14(结束录音) -/// 中 单击0x03, 按下0x11(开始录音)抬起0x12(结束录音) -/// 后 第一次单击0x01, 第二次单击0x02(结束录音) , 按下0x09(开始录音)抬起0x10(结束录音) -/// 其他未定义 -/// -/// /// 鼠标按键指令回调 富瑞坤 -/// - Parameter data: 数据。 -/// 前 单击43,按下27(开始录音)抬起28(结束录音) -/// 中 单击42, 按下25(开始录音)抬起26(结束录音) -/// 后 第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音) -/// -/// 其他未定义 -- (void)tlwMouseSendCmdData:(NSData *)data{ - uint8 cmd; - [data getBytes:&cmd length:1]; - if( cmd == 0x01){ - cmd = 0x31; - }else if( cmd == 0x02){ - cmd = 0x32; - } - else if( cmd == 0x09){ - cmd = 0x21; - } - else if( cmd == 0x10){ - cmd = 0x22; - } - else if( cmd == 0x03){ - cmd = 0x42; - } - else if( cmd == 0x11){ - cmd = 0x25; - } - else if( cmd == 0x12){ - cmd = 0x26; - } - else if( cmd == 0x06){ - cmd = 0x43; - } - else if( cmd == 0x13){ - cmd = 0x27; - } - else if( cmd == 0x14){ - cmd = 0x28; - } - - [self showLog:[NSString stringWithFormat:@"(BleManager) aiMouseSendCmdData:收到指令 = %X",cmd]]; - - if (self.aiMouseSendCmdDataCallBack) { - self.aiMouseSendCmdDataCallBack([NSString stringWithFormat:@"%X",cmd]); - } - - if(cmd == 0x31 || cmd == 0x21 || cmd == 0x25 ||cmd == 0x27){ - [self showLog:@"(BleManager) aiMouseSendCmdData:开始录音"]; - self.recordData = [[NSMutableData alloc] init]; - if (self.begainRecoredCallBack) { - self.begainRecoredCallBack(); - } - } - else if(cmd == 0x32 || cmd == 0x22 || cmd == 0x26 ||cmd == 0x28){ - [self showLog:@"(BleManager) aiMouseSendCmdData:结束录音"]; - [self finishRecored:self.recordData]; - if (self.finishRecoredCallBack) { - self.finishRecoredCallBack(self.recordData); - } - } -} - -/// 录音回调 -/// - Parameter data: pcm格式语音数据 -- (void)tlwMouseSendRecordData:(NSData *)data{ - NSString *base64String = [data base64EncodedStringWithOptions:0]; - [self showLog:[NSString stringWithFormat:@"(BleManager) aiMouseSendRecordData:[appendData] %@\n%@",data,base64String]]; - [self.recordData appendData:data]; - if (self.recordingCallBack) { - self.recordingCallBack(data); - } -} -/// 输出日志 -- (void)aiMouseAddLog:(NSString *)log { - if (self.aiMouseAddLogCallBack) { - self.aiMouseAddLogCallBack(log); - } -} - -// 连接状态改变 -- (void)tlwMouseConnectStateDidChange:(BOOL)connected{ - [self showLog:[NSString stringWithFormat:@"(BleManager) aiMouseConnectStateDidChange - 设备连接状态返回: %hhd",connected]]; - - if (self.aiMouseConnectStateDidChangeCallBack) { - self.aiMouseConnectStateDidChangeCallBack(connected); - } - if (connected == true) { - self.authCallBack(true); - } - //没有连接 - if (!connected) { - self.connectPeripheral = nil; - self.deviceInfoCha = nil; - self.aiCha = nil; + self.receiveInfoDataCallBack(data); } } #pragma mark - public -- (void)connectBleDeviceWithName:(NSString *)bleName { +- (void)startScanWithName:(NSString *)bleName { //如果是已连接或者正在连接,不需要在链接了 - if (self.connectPeripheral != nil ) { - if ([self.connectPeripheral.name isEqualToString:bleName]) { - if (self.connectPeripheral.state == CBPeripheralStateConnected || self.connectPeripheral.state == CBPeripheralStateConnecting) { + if (self.crrentPeripheral != nil ) { + if ([self.crrentPeripheral.name isEqualToString:bleName]) { + if (self.crrentPeripheral.state == CBPeripheralStateConnected || self.crrentPeripheral.state == CBPeripheralStateConnecting) { return; } } else { - [self.centralManager cancelPeripheralConnection:self.connectPeripheral]; + [self.centralManager cancelPeripheralConnection:self.crrentPeripheral]; } } - [self showLog:[NSString stringWithFormat:@"(BleManager) connectBleDeviceWithName:%@",bleName]]; -// [self stopScanDevice]; self.targetBleName = bleName; - [self startScanDevice]; - -// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), _block); -} -/// 连接设备 -- (void)startScanDevice{ - [self showLog:[NSString stringWithFormat:@"(BleManager) startScanDevice:开始扫描"]]; - [self.centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : [NSNumber numberWithBool:NO]}]; + NSArray *devices = [self.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]]]; + if (devices.count > 0 && [devices[0].name isEqualToString:bleName]) { + [self showLog:[NSString stringWithFormat:@"autoConnectDevice:匹配过的设备%@",devices[0].name]]; + [self connectPeripheral:devices[0]]; + } + else{ + [self showLog:[NSString stringWithFormat:@"开始扫描 设备名称 %@",bleName]]; + [self.centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : [NSNumber numberWithBool:NO]}]; + } } -/// 扫描设备 -- (void)stopScanDevice{ - [self showLog:[NSString stringWithFormat:@"(BleManager) stopScanDevice:停止扫描"]]; + +- (void)stopScan{ + [self showLog:[NSString stringWithFormat:@"ble:停止扫描"]]; [self.centralManager stopScan]; } /// 连接设备 - (void)connectPeripheral:(CBPeripheral *)peripheral{ - //peripheral设备已经链接 - if (self.connectPeripheral == peripheral && (self.connectPeripheral.state == CBPeripheralStateConnected || self.connectPeripheral.state == CBPeripheralStateConnecting)) { - return; - } - - - [self showLog:[NSString stringWithFormat:@"(BleManager) connectPeripheral:连接设备"]]; - self.connectPeripheral = peripheral; + [self showLog:[NSString stringWithFormat:@"connectPeripheral:连接设备"]]; + self.crrentPeripheral = peripheral; [self.centralManager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey : [NSNumber numberWithBool:YES]}]; } -/// 获取设备信息 -- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo * _Nonnull, NSError * _Nonnull))completation{ - [self showLog:[NSString stringWithFormat:@"(BleManager) getDeviceInfo:获取设备信息"]]; - [[TlwMouse shared] getDeviceInfo:^(TlwDeviceInfo *deviceInfo, NSError *error) { - AiMouseDeviceInfo *info = [[AiMouseDeviceInfo alloc] init]; - info.battery_power = [NSString stringWithFormat:@"%d",deviceInfo.batteryValue] ; - info.CPI = [NSString stringWithFormat:@"%d",deviceInfo.DPI]; - info.CPI_list = @"1,2,3,4"; - info.version = [NSString stringWithFormat:@"%d",deviceInfo.version]; - info.brand = @"NNMouse"; - info.sn = @""; - info.mac = @""; - completation(info,nil); -// @property (nonatomic, assign) int DPI;/// DPI值 数值1 ~ 4 (分别对应 800 1200 1800 2400) -// @property (nonatomic, assign) int version;///软件版本 -// @property (nonatomic, assign) int batteryState;/// 电池状态 -// @property (nonatomic, assign) int batteryValue;/// 电池百分百电量,0-100 -// /// -// @property (nonatomic, strong) NSString *battery_power;/// 电池百分百电量,0-100 -// @property (nonatomic, strong) NSString *CPI;/// CPI值 -// @property (nonatomic, strong) NSString *CPI_list;/// 可设置的CPI参数列表 -// @property (nonatomic, strong) NSString *version;///软件版本 -// @property (nonatomic, strong) NSString *brand;/// 品牌名称 -// @property (nonatomic, strong) NSString *sn;/// 设备序列号 -// @property (nonatomic, strong) NSString *mac;///设备MAC地址 - }]; -} - -/// 获取信号强度 -- (void)getRSSI:(void (^)(NSString *value,NSError *error))complete { - [self showLog:@"不支持该接口接口"]; - -} - -#pragma mark - other -//自动连接,获取已配对的蓝牙,取第一个连接 -- (void)autoConnectDevice{ -// [self showLog:[NSString stringWithFormat:@"(BleManager) autoConnectDevice:开始自动重连设备"]]; - //如果是已连接或者正在连接,则不再重连 - if (self.connectPeripheral && (self.connectPeripheral.state == CBPeripheralStateConnected || self.connectPeripheral.state == CBPeripheralStateConnecting)) { +-(void)writeToDevice:(NSData *)data{ + if (self.crrentPeripheral ==nil) { + [self showLog:@"peripheral 为空"]; return; } - NSArray *devices = [self.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]]]; - if (devices.count > 0) { - CBPeripheral *peripheral = devices[0]; - [self showLog:[NSString stringWithFormat:@"(BleManager) autoConnectDevice:匹配过的设备%@",peripheral.name]]; - [self connectPeripheral:peripheral]; + if (self.deviceInfoCha ==nil) { + [self showLog:@"characteristic 为空"]; + return; } - - // 10s自动重连 - [self performSelector:@selector(autoConnectDevice) withObject:nil afterDelay:10]; + + [self.crrentPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithResponse]; } + +////自动连接,获取已配对的蓝牙,取第一个连接 +//- (void)autoConnectDevice{ +// //如果是已连接或者正在连接,则不再重连 +// if (self.crrentPeripheral && (self.crrentPeripheral.state == CBPeripheralStateConnected || self.crrentPeripheral.state == CBPeripheralStateConnecting)) { +// return; +// } +// NSArray *devices = [self.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]]]; +// if (devices.count > 0) { +// CBPeripheral *peripheral = devices[0]; +// [self showLog:[NSString stringWithFormat:@"autoConnectDevice:匹配过的设备%@",peripheral.name]]; +// [self connectPeripheral:peripheral]; +// } +// +// // 10s自动重连 +// [self performSelector:@selector(autoConnectDevice) withObject:nil afterDelay:10]; +//} - (void)showLog:(NSString *)log{ - NSLog(@"%@",log); + if(self.logCallBack)self.logCallBack(log); } //将录音数据保存 diff --git a/MouseSdk/MouseSdk/Ble/DeviceManger.m b/MouseSdk/MouseSdk/Ble/DeviceManger.m index 3435170..b7ac399 100644 --- a/MouseSdk/MouseSdk/Ble/DeviceManger.m +++ b/MouseSdk/MouseSdk/Ble/DeviceManger.m @@ -9,9 +9,10 @@ #import "HidManager.h" #import "BleManager.h" #import "TlwMouseSdk.h" +#import "TimerManager.h" -@interface DeviceManger() - +@interface DeviceManger() +@property (nonatomic,strong) NSMutableData *recordData;//录音的数据 @property (nonatomic,strong) BleManager *ble; @property (nonatomic,strong) HidManager *hid; //connectType 返回为0代表蓝牙,为1代表usb @@ -38,7 +39,7 @@ [self setupHid]; //先默认设置蓝牙管理对象为鼠标 - [[TlwMouse shared] setDelegate:self.ble]; + [[TlwMouse shared] setDelegate:self]; } return self; } @@ -47,81 +48,31 @@ return [TlwMouse shared].connectType; } - -- (NSString *)getCurrentConnectType { - if ([TlwMouse shared].connectType == AiMouseConnectType_bluetooth) { - return @"0"; - } - else { - return @"1"; - } -} - -#pragma mark ------ 设备连接相关 -- (void)begainMonitorAiMouseConnectStateDidChange:(NSString *)mouseName callBack:(void(^)(int connectType, BOOL connected))callBack{ - self.aiMouseConnectStateDidChangeCallBack = callBack; - [self.ble connectBleDeviceWithName:mouseName]; - -} - #pragma mark ------ 设备初始化 - (void)setupHid{ self.hid = [HidManager shared]; __weak typeof(self) ws = self; - self.hid.authCallBack = ^(BOOL isSuccess) { - if(ws.authCallBack)ws.authCallBack(isSuccess); - }; - - self.hid.aiMouseConnectStateDidChangeCallBack = ^(BOOL connected) { + self.hid.connectStateCallBack = ^(BOOL connected) { + if (connected) { + [[TlwMouse shared] switchConnect:AiMouseConnectType_hid isConnected:connected]; + } + + if(ws.authCallBack && connected)ws.authCallBack(true); if (ws.aiMouseConnectStateDidChangeCallBack) { ws.aiMouseConnectStateDidChangeCallBack(AiMouseConnectType_hid,connected); } - //连接失败时,重新初始化USB监听 - if (!connected) { - [ws.hid close]; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [ws.hid open]; - }); - } - }; - - self.hid.aiMouseSendCmdDataCallBack = ^(NSString * _Nonnull data) { - if(ws.aiMouseSendCmdDataCallBack){ - ws.aiMouseSendCmdDataCallBack(data); - } - }; - - self.hid.aiMouseSendDeviceInfoDataCallBack = ^(NSData * _Nonnull data) { - if (ws.aiMouseSendDeviceInfoDataCallBack) { - // 将NSData转换为Base64编码的字符串 - NSString *base64String = [data base64EncodedStringWithOptions:0]; - ws.aiMouseSendDeviceInfoDataCallBack(base64String); - } - }; - self.hid.begainRecoredCallBack = ^{ - if (ws.begainRecoredCallBack) { - ws.begainRecoredCallBack(); - } + }; - - self.hid.recordingCallBack = ^(NSData *data) { - if (ws.recordingCallBack) { - // 将NSData转换为Base64编码的字符串 - NSString *base64String = [data base64EncodedStringWithOptions:0]; - ws.recordingCallBack(base64String); - } + self.hid.receiveInfoDataCallBack = ^(NSData *data) { + [[TlwMouse shared] sendDeviceDataToSdk:data]; }; - - self.hid.finishRecoredCallBack = ^(NSData * _Nonnull data) { - if (ws.finishRecoredCallBack) { - // 将NSData转换为Base64编码的字符串 - NSString *base64String = [data base64EncodedStringWithOptions:0]; - ws.finishRecoredCallBack(base64String); - } + self.hid.receiveVoiceDataCallBack = ^(NSData *data) { + [[TlwMouse shared] sendAiDataToSdk:data]; }; - self.hid.aiMouseAddLogCallBack = ^(NSString * _Nonnull log) { + self.hid.logCallBack = ^(NSString * _Nonnull log) { + [ws showLog:log]; if (ws.aiMouseAddLogCallBack) { ws.aiMouseAddLogCallBack(log); } @@ -132,61 +83,23 @@ self.ble = [BleManager shared]; __weak typeof(self) ws = self; - self.ble.authCallBack = ^(BOOL isSuccess) { - if(ws.authCallBack)ws.authCallBack(isSuccess); - }; - - self.ble.aiMouseConnectStateDidChangeCallBack = ^(BOOL connected) { + self.ble.connectStateCallBack = ^(BOOL connected) { + [[TlwMouse shared] switchConnect:AiMouseConnectType_bluetooth isConnected:connected]; + + if(ws.authCallBack && connected)ws.authCallBack(true); if (ws.aiMouseConnectStateDidChangeCallBack) { ws.aiMouseConnectStateDidChangeCallBack(AiMouseConnectType_bluetooth,connected); } - - //蓝牙连接失败,重新初始化USB监听 - if (!connected) { - [ws.hid close]; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [ws.hid open]; - }); - } - }; - - self.ble.aiMouseSendCmdDataCallBack = ^(NSString * _Nonnull data) { - if(ws.aiMouseSendCmdDataCallBack){ - ws.aiMouseSendCmdDataCallBack(data); - } }; - - self.ble.aiMouseSendDeviceInfoDataCallBack = ^(NSData * _Nonnull data) { - if (ws.aiMouseSendDeviceInfoDataCallBack) { - // 将NSData转换为Base64编码的字符串 - NSString *base64String = [data base64EncodedStringWithOptions:0]; - ws.aiMouseSendDeviceInfoDataCallBack(base64String); - } - }; - - self.ble.begainRecoredCallBack = ^{ - if (ws.begainRecoredCallBack) { - ws.begainRecoredCallBack(); - } + self.ble.receiveInfoDataCallBack = ^(NSData *data) { + [[TlwMouse shared] sendDeviceDataToSdk:data]; }; - - self.ble.recordingCallBack = ^(NSData *data) { - if (ws.recordingCallBack) { - // 将NSData转换为Base64编码的字符串 - NSString *base64String = [data base64EncodedStringWithOptions:0]; - ws.recordingCallBack(base64String); - } + self.ble.receiveVoiceDataCallBack = ^(NSData *data) { + [[TlwMouse shared] sendAiDataToSdk:data]; }; - self.ble.finishRecoredCallBack = ^(NSData * _Nonnull data) { - if (ws.finishRecoredCallBack) { - // 将NSData转换为Base64编码的字符串 - NSString *base64String = [data base64EncodedStringWithOptions:0]; - ws.finishRecoredCallBack(base64String); - } - }; - - self.ble.aiMouseAddLogCallBack = ^(NSString * _Nonnull log) { + self.ble.logCallBack = ^(NSString * _Nonnull log) { + [ws showLog:log]; if (ws.aiMouseAddLogCallBack) { ws.aiMouseAddLogCallBack(log); } @@ -195,6 +108,31 @@ #pragma mark ------ 设备相关接口 +- (NSString *)getCurrentConnectType { + if ([TlwMouse shared].connectType == AiMouseConnectType_bluetooth) { + return @"0"; + } + else { + return @"1"; + } +} + +- (void)begainMonitorAiMouseConnectStateDidChange:(NSString *)mouseName callBack:(void(^)(int connectType, BOOL connected))callBack{ + self.aiMouseConnectStateDidChangeCallBack = callBack; + [self.ble startScanWithName:mouseName]; + + [TimerManager shared].timerCallBack = ^{ +// [self showLog:@"定时器。。。"]; + if([TlwMouse shared].connected){ + [self.ble stopScan]; + [self.hid close]; + } + else{ + [self.ble startScanWithName:mouseName]; + [self.hid open]; + } + }; +} ///获取设备信息 - (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))completation{ [[TlwMouse shared] getDeviceInfo:^(TlwDeviceInfo *deviceInfo, NSError *error) { @@ -204,8 +142,8 @@ info.CPI_list = @"1,2,3,4"; info.version = [NSString stringWithFormat:@"%d",deviceInfo.version]; info.brand = @"NNMouse"; - info.sn = @""; - info.mac = @""; + info.sn = @"MSCL1BKZ12105000042371"; + info.mac = @"C0310000A583"; completation(info,nil); }]; } @@ -286,4 +224,133 @@ - (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished{ [[TlwMouse shared] closeRecord:finished]; } + + + +#pragma mark - TlwMouseDelegate +/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备 +/// - Parameter data: 数据 +-(void)tlwMouseSendDeviceInfoData:(NSData *)data{ + [self.ble writeToDevice:data]; + if (self.aiMouseSendDeviceInfoDataCallBack) { + // 将NSData转换为Base64编码的字符串 + NSString *base64String = [data base64EncodedStringWithOptions:0]; + self.aiMouseSendDeviceInfoDataCallBack(base64String); + } +} + +/// 鼠标按键指令回调 +/// - Parameter data: 数据。 +/// 前 单击0x06, 按下0x13(开始录音)抬起0x14(结束录音) +/// 中 单击0x03, 按下0x11(开始录音)抬起0x12(结束录音) +/// 后 第一次单击0x01, 第二次单击0x02(结束录音) , 按下0x09(开始录音)抬起0x10(结束录音) +/// 其他未定义 +/// +/// /// 鼠标按键指令回调 富瑞坤 +/// - Parameter data: 数据。 +/// 前 单击43,按下27(开始录音)抬起28(结束录音) +/// 中 单击42, 按下25(开始录音)抬起26(结束录音) +/// 后 第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音) +/// +/// 其他未定义 +- (void)tlwMouseSendCmdData:(NSData *)data{ + uint8 cmd; + [data getBytes:&cmd length:1]; + if( cmd == 0x01){ + cmd = 0x31; + }else if( cmd == 0x02){ + cmd = 0x32; + } + else if( cmd == 0x09){ + cmd = 0x21; + } + else if( cmd == 0x10){ + cmd = 0x22; + } + else if( cmd == 0x03){ + cmd = 0x42; + } + else if( cmd == 0x11){ + cmd = 0x25; + } + else if( cmd == 0x12){ + cmd = 0x26; + } + else if( cmd == 0x06){ + cmd = 0x43; + } + else if( cmd == 0x13){ + cmd = 0x27; + } + else if( cmd == 0x14){ + cmd = 0x28; + } + + if (self.aiMouseSendCmdDataCallBack) { + self.aiMouseSendCmdDataCallBack([NSString stringWithFormat:@"%X",cmd]); + } + + if(cmd == 0x31 || cmd == 0x21 || cmd == 0x25 ||cmd == 0x27){ + [self showLog:@"(BleManager) aiMouseSendCmdData:开始录音"]; + self.recordData = [[NSMutableData alloc] init]; + if (self.begainRecoredCallBack) { + self.begainRecoredCallBack(); + } + } + else if(cmd == 0x32 || cmd == 0x22 || cmd == 0x26 ||cmd == 0x28){ + [self showLog:@"(BleManager) aiMouseSendCmdData:结束录音"]; + [self finishRecored:self.recordData]; + if (self.finishRecoredCallBack) { + // 将NSData转换为Base64编码的字符串 + NSString *base64String = [self.recordData base64EncodedStringWithOptions:0]; + self.finishRecoredCallBack(base64String); + } + } +} + +/// 录音回调 +/// - Parameter data: pcm格式语音数据 +- (void)tlwMouseSendRecordData:(NSData *)data{ + [self.recordData appendData:data]; + if (self.recordingCallBack) { + // 将NSData转换为Base64编码的字符串 + NSString *base64String = [data base64EncodedStringWithOptions:0]; + self.recordingCallBack(base64String); + } +} +/// 输出日志 +- (void)aiMouseAddLog:(NSString *)log { + if (self.aiMouseAddLogCallBack) { + self.aiMouseAddLogCallBack(log); + } +} + +// 连接状态改变 +- (void)tlwMouseConnectStateDidChange:(BOOL)connected{ + [self showLog:[NSString stringWithFormat:@"(BleManager) aiMouseConnectStateDidChange - 设备连接状态返回: %hhd",connected]]; + + if (self.aiMouseConnectStateDidChangeCallBack) { + self.aiMouseConnectStateDidChangeCallBack(self.getCurrentConnectType,connected); + } + if (connected == true) { + self.authCallBack(true); + } +} + +- (void)showLog:(NSString *)log{ + NSLog(@"%@",log); +} +//将录音数据保存 +- (void)finishRecored:(NSData *)data{ + NSString *doc = NSTemporaryDirectory(); + NSString *fullPath = [NSString stringWithFormat:@"%@1.pcm",doc]; + NSError *err; + [data writeToFile:fullPath options:NSDataWritingAtomic error:&err]; + if (err) { + [self showLog:[NSString stringWithFormat:@"录音保存失败 %@",err.description]]; + } + else{ + [self showLog:[NSString stringWithFormat:@"录音保存成功 path = %@",fullPath]]; + } +} @end diff --git a/MouseSdk/MouseSdk/Ble/HidManager.h b/MouseSdk/MouseSdk/Ble/HidManager.h index 3ac2c64..2defd05 100644 --- a/MouseSdk/MouseSdk/Ble/HidManager.h +++ b/MouseSdk/MouseSdk/Ble/HidManager.h @@ -6,33 +6,24 @@ // #import -#import "TlwMouseSdk.h" -#import "AiMouseSdk.h" -NS_ASSUME_NONNULL_BEGIN - -@interface HidManager : NSObject -@property (nonatomic,copy)void (^authCallBack)(BOOL isSuccess);/// 鉴权回调 -@property (nonatomic, copy)void (^aiMouseConnectStateDidChangeCallBack)(BOOL connected);/// 设备连接状态回调 -@property (nonatomic, copy)void (^aiMouseSendDeviceInfoDataCallBack)(NSData *data);/// 设备信息数据回调 -@property (nonatomic, copy)void (^aiMouseSendCmdDataCallBack)(NSString *data);/// 鼠标按键指令回调 -@property (nonatomic, copy)void (^begainRecoredCallBack)(void);/// 录音开始回调 -@property (nonatomic, copy)void (^recordingCallBack)(NSData *data);/// 录音进行中回调 -@property (nonatomic, copy)void (^finishRecoredCallBack)(NSData *data);/// 录音结束回调 +NS_ASSUME_NONNULL_BEGIN -@property (nonatomic, copy)void (^aiMouseAddLogCallBack)(NSString *log);//输出日志 +@interface HidManager : NSObject +@property (nonatomic, copy)void (^connectStateCallBack)(BOOL connected);/// 设备连接状态回调 +@property (nonatomic, copy)void (^receiveVoiceDataCallBack)(NSData *data);/// 语音数据回调 +@property (nonatomic, copy)void (^receiveInfoDataCallBack)(NSData *data);/// 设备信息数据回调 +@property (nonatomic, copy)void (^logCallBack)(NSString *log);//输出日志 +(HidManager *)shared; - (void)open; -- (void)close; -/// 获取设备信息 -- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))completation; -/// 获取信号强度 -- (void)getRSSI:(void (^)(NSString *value,NSError *error))complete; +- (void)close; +//写入数据 +-(void)writeToDevice:(NSData *)data; @end NS_ASSUME_NONNULL_END diff --git a/MouseSdk/MouseSdk/Ble/HidManager.m b/MouseSdk/MouseSdk/Ble/HidManager.m index d2b9c2c..09572e1 100644 --- a/MouseSdk/MouseSdk/Ble/HidManager.m +++ b/MouseSdk/MouseSdk/Ble/HidManager.m @@ -8,16 +8,11 @@ #import "HidManager.h" #include #include -#import "BleManager.h" @interface HidManager () -{ - -} @property(nonatomic, assign) IOHIDManagerRef hidManager;///hid管理 @property(nonatomic, assign) IOHIDDeviceRef deviceInfoCha;//设备信息通道 -@property (nonatomic,strong) NSMutableData *recordData;//录音的数据 @end @implementation HidManager @@ -26,7 +21,6 @@ static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ manager = [[HidManager alloc]init]; - [manager open]; }); return manager; } @@ -39,89 +33,22 @@ return self; } -- (void)open{ - //初始化 - self.deviceInfoCha = nil; - - [self showLog:@"(HidManager)open:打开设备"]; - self.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - IOHIDManagerScheduleWithRunLoop(self.hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode); - IOReturn ret = IOHIDManagerOpen(self.hidManager, 0L); - if (ret != kIOReturnSuccess) { - [self showLog:(@"(HidManager)open:打开hid失败!")]; - }else{ - [self showLog:(@"(HidManager)open:打开hid成功!")]; - } - //设置匹配设备 - ////供应商id - //const long vendorID = 0x6675; - ////产品id - //const long productID = 0x8601; - //供应商id - const long vendorID = 0x10D6; - //产品id - const long productID = 0xB008; - NSMutableDictionary* dict= [NSMutableDictionary dictionary]; - [dict setValue:[NSNumber numberWithLong:productID] forKey:[NSString stringWithCString:kIOHIDProductIDKey encoding:NSUTF8StringEncoding]]; - [dict setValue:[NSNumber numberWithLong:vendorID] forKey:[NSString stringWithCString:kIOHIDVendorIDKey encoding:NSUTF8StringEncoding]]; - IOHIDManagerSetDeviceMatching(self.hidManager, (__bridge CFMutableDictionaryRef)dict); - //设置匹配到设备回调 - IOHIDManagerRegisterDeviceMatchingCallback(self.hidManager, &hidAppearDevice, NULL); - //设置移除设备回调 - IOHIDManagerRegisterDeviceRemovalCallback(self.hidManager, &hidDisAppearDevice, NULL); -} - -- (void)close{ - if (self.hidManager == nil) { - [self showLog:@"(HidManager)close:设备已关闭"]; - return; - } - [self showLog:@"(HidManager)close:关闭设备"]; - IOReturn ret = IOHIDManagerClose(self.hidManager, 0); - self.hidManager = nil; - - if (ret != kIOReturnSuccess) { - [self showLog:(@"(HidManager)close:关闭设备失败!")]; - }else{ - [self showLog:(@"(HidManager)close:关闭设备成功!")]; - } - - self.deviceInfoCha = nil; -} - #pragma mark - Hid CallBack /// 匹配到设备回调 static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) { - if ([[BleManager shared] isDidConnectBleDevice]) { - [[HidManager shared] showLog:(@"(HidManager)hidAppearDevice:当前处于蓝牙连接状态,对监听到有USB 插入 的事件不做处理")]; - return; - } - - - - //设备信息 [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; - [TlwMouse shared].delegate = [HidManager shared]; - //切换当前连接类型 - [[TlwMouse shared] switchConnect:AiMouseConnectType_hid]; - [[HidManager shared] showLog:(@"(HidManager)hidAppearDevice:回调连接成功 ")]; //注册消息回调 unsigned char InputBuffer[64]; IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL); - - [[HidManager shared] openDiveceAction]; - -} -- (void)openDiveceAction{ IOReturn result = IOHIDDeviceOpen([HidManager shared].deviceInfoCha, kIOHIDOptionsTypeNone); if (result != kIOReturnSuccess) { - NSLog([NSString stringWithFormat:@"打开hid失败! %d",result]); - [self performSelector:@selector(openDiveceAction) withObject:nil afterDelay:2]; + NSLog([NSString stringWithFormat:@"打开设备失败! %d",result]); }else{ - NSLog(@"打开hid成功!"); + NSLog(@"打开设备成功!"); + [HidManager shared].connectStateCallBack(true) ; } CFRetain([HidManager shared].deviceInfoCha); IOHIDDeviceScheduleWithRunLoop([HidManager shared].deviceInfoCha, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); @@ -129,10 +56,6 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH /// 设备移除回调 static void hidDisAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) { - if ([[BleManager shared] isDidConnectBleDevice]) { - [[HidManager shared] showLog:(@"(HidManager)hidDisAppearDevice:当前处于蓝牙连接状态,对监听到有USB 拔出 的事件不做处理")]; - return; - } [[HidManager shared] showLog:[NSString stringWithFormat:@"(HidManager)hidDisAppearDevice:拔出设备 %@ ",inIOHIDDeviceRef]]; //取消执行超时操作 @@ -140,8 +63,7 @@ static void hidDisAppearDevice(void *inContext,IOReturn inResult,void *inSender, [HidManager shared].deviceInfoCha = nil; - [[HidManager shared] tlwMouseConnectStateDidChange:false]; - [[TlwMouse shared] didDisconnect]; + [HidManager shared].connectStateCallBack(false) ; } @@ -155,180 +77,79 @@ static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDRe NSData *data = [[NSData alloc] initWithBytes:report length:len]; [[HidManager shared] showLog:@"(HidManager)hidReceiveData:device数据"]; - [[TlwMouse shared] sendDeviceDataToSdk:data]; - - + [HidManager shared].receiveInfoDataCallBack(data); } -#pragma mark - TlwMouseDelegate -/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备 -/// - Parameter data: 数据 --(void)tlwMouseSendDeviceInfoData:(NSData *)data{ - [self showLog:[NSString stringWithFormat:@"(HidManager)aiMouseSendDeviceInfoData:[send] %@",data]]; - [self sendData:data toDevice:self.deviceInfoCha]; - if (self.aiMouseSendDeviceInfoDataCallBack) { - self.aiMouseSendDeviceInfoDataCallBack(data); - } -} -/// 鼠标按键指令回调 -/// - Parameter data: 数据。 -/// 前 单击0x06, 按下0x13(开始录音)抬起0x14(结束录音) -/// 中 单击0x03, 按下0x11(开始录音)抬起0x12(结束录音) -/// 后 第一次单击0x01, 第二次单击0x02(结束录音) , 按下0x09(开始录音)抬起0x10(结束录音) -/// 其他未定义 -/// -/// /// 鼠标按键指令回调 富瑞坤 -/// - Parameter data: 数据。 -/// 前 单击43,按下27(开始录音)抬起28(结束录音) -/// 中 单击42, 按下25(开始录音)抬起26(结束录音) -/// 后 第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音) -/// -/// 其他未定义 -- (void)tlwMouseSendCmdData:(NSData *)data{ - uint8 cmd; - [data getBytes:&cmd length:1]; - if( cmd == 0x01){ - cmd = 0x31; - }else if( cmd == 0x02){ - cmd = 0x32; - } - else if( cmd == 0x09){ - cmd = 0x21; - } - else if( cmd == 0x10){ - cmd = 0x22; - } - else if( cmd == 0x03){ - cmd = 0x42; - } - else if( cmd == 0x11){ - cmd = 0x25; - } - else if( cmd == 0x12){ - cmd = 0x26; - } - else if( cmd == 0x06){ - cmd = 0x43; - } - else if( cmd == 0x13){ - cmd = 0x27; - } - else if( cmd == 0x14){ - cmd = 0x28; - } - - [self showLog:[NSString stringWithFormat:@"(HidManager) aiMouseSendCmdData:收到指令 = %X",cmd]]; - - if (self.aiMouseSendCmdDataCallBack) { - self.aiMouseSendCmdDataCallBack([NSString stringWithFormat:@"%X",cmd]); - } - - - if(cmd == 0x31 || cmd == 0x21 || cmd == 0x25 ||cmd == 0x27){ - [self showLog:@"(HidManager)aiMouseSendCmdData:开始录音"]; - self.recordData = [[NSMutableData alloc] init]; - - if (self.begainRecoredCallBack) { - self.begainRecoredCallBack(); - } - } - else if(cmd == 0x32 || cmd == 0x22 || cmd == 0x26 ||cmd == 0x28){ - [self showLog:@"(HidManager)aiMouseSendCmdData:结束录音"]; - [self finishRecored:self.recordData]; - - if (self.finishRecoredCallBack) { - self.finishRecoredCallBack(self.recordData); - } - } -} +///// hid数据异常,需要重新开启监听usb设备 +//- (void)hidDataError { +// //收到数据异常,需要关闭后重新打开 +// [self close]; +// [self open]; +//} -/// 录音回调 -/// - Parameter data: pcm格式语音数据 -- (void)tlwMouseSendRecordData:(NSData *)data{ - [self showLog:[NSString stringWithFormat:@"(HidManager)aiMouseSendRecordData: %@",data]]; - [self.recordData appendData:data]; - if (self.recordingCallBack) { - self.recordingCallBack(data); - } -} -/// 输出日志 -- (void)aiMouseAddLog:(NSString *)log { - if (self.aiMouseAddLogCallBack) { - self.aiMouseAddLogCallBack(log); +#pragma mark - public +- (void)open{ + //初始化 + self.deviceInfoCha = nil; + self.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + IOHIDManagerScheduleWithRunLoop(self.hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode); + IOReturn ret = IOHIDManagerOpen(self.hidManager, 0L); + if (ret != kIOReturnSuccess) { + [self showLog:(@"(HidManager)open:打开hid失败!")]; + }else{ + [self showLog:(@"(HidManager)open:打开hid成功!")]; } + //设置匹配设备 + ////供应商id + //const long vendorID = 0x6675; + ////产品id + //const long productID = 0x8601; + //供应商id + const long vendorID = 0x10D6; + //产品id + const long productID = 0xB008; + NSMutableDictionary* dict= [NSMutableDictionary dictionary]; + [dict setValue:[NSNumber numberWithLong:productID] forKey:[NSString stringWithCString:kIOHIDProductIDKey encoding:NSUTF8StringEncoding]]; + [dict setValue:[NSNumber numberWithLong:vendorID] forKey:[NSString stringWithCString:kIOHIDVendorIDKey encoding:NSUTF8StringEncoding]]; + IOHIDManagerSetDeviceMatching(self.hidManager, (__bridge CFMutableDictionaryRef)dict); + //设置匹配到设备回调 + IOHIDManagerRegisterDeviceMatchingCallback(self.hidManager, &hidAppearDevice, NULL); + //设置移除设备回调 + IOHIDManagerRegisterDeviceRemovalCallback(self.hidManager, &hidDisAppearDevice, NULL); } -// 连接状态改变 -- (void)tlwMouseConnectStateDidChange:(BOOL)connected{ - [self showLog:[NSString stringWithFormat:@"(HidManager) aiMouseConnectStateDidChange - 设备连接状态返回: %hhd",connected]]; - - if (self.aiMouseConnectStateDidChangeCallBack) { - self.aiMouseConnectStateDidChangeCallBack(connected); +- (void)close{ + if (self.hidManager == nil) { + [self showLog:@"(HidManager)close:设备已关闭"]; + return; } - //没有连接 - if (!connected) { - [HidManager shared].deviceInfoCha = nil; + [self showLog:@"(HidManager)close:关闭设备"]; + IOReturn ret = IOHIDManagerClose(self.hidManager, 0); + self.hidManager = nil; + + if (ret != kIOReturnSuccess) { + [self showLog:(@"(HidManager)close:关闭设备失败!")]; + }else{ + [self showLog:(@"(HidManager)close:关闭设备成功!")]; } + self.deviceInfoCha = nil; } - -/// hid数据异常,需要重新开启监听usb设备 -- (void)hidDataError { - //收到数据异常,需要关闭后重新打开 - [self close]; - [self open]; -} - -#pragma mark - public -/// 获取设备信息 -- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo * _Nonnull, NSError * _Nonnull))completation{ - [self showLog:@"(HidManager)getDeviceInfo: 获取设备信息"]; - [[TlwMouse shared] getDeviceInfo:^(TlwDeviceInfo *deviceInfo, NSError *error) { - AiMouseDeviceInfo *info = [[AiMouseDeviceInfo alloc] init]; - info.battery_power = [NSString stringWithFormat:@"%d",deviceInfo.batteryValue] ; - info.CPI = [NSString stringWithFormat:@"%d",deviceInfo.DPI]; - info.CPI_list = @"1,2,3,4"; - info.version = [NSString stringWithFormat:@"%d",deviceInfo.version]; - info.brand = @"NNMouse"; - info.sn = @""; - info.mac = @""; - completation(info,nil); - }]; -} - -/// 获取信号强度 -- (void)getRSSI:(void (^)(NSString *value,NSError *error))finished { - [self showLog:[NSString stringWithFormat:@"(HidManager) getRSSI:获取信号强度"]]; - finished(0,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]); -} - /// 发送数据给设备 --(void)sendData:(NSData *)data toDevice:(IOHIDDeviceRef)device{ - if(device == nil){ +-(void)writeToDevice:(NSData *)data{ + if(self.deviceInfoCha == nil){ [self showLog:@"(HidManager)sendData: 请先连上设备"]; return; } - IOReturn ret = IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, 0, data.bytes, data.length); + IOReturn ret = IOHIDDeviceSetReport(self.deviceInfoCha, kIOHIDReportTypeOutput, 0, data.bytes, data.length); if (ret != kIOReturnSuccess) { [self showLog:[NSString stringWithFormat:@"(HidManager)sendData: 发送失败! code = %d",ret]]; }else{ [self showLog:@"(HidManager)sendData: 发送成功!"]; } } -//将录音数据保存 -- (void)finishRecored:(NSData *)data{ -// NSString *doc = NSTemporaryDirectory(); -// NSString *fullPath = [NSString stringWithFormat:@"%@1.pcm",doc]; -// NSError *err; -// [data writeToFile:fullPath options:NSDataWritingAtomic error:&err]; -// if (err) { -// [self showLog:[NSString stringWithFormat:@"录音保存失败 %@",err.description]]; -// } -// else{ -// [self showLog:[NSString stringWithFormat:@"录音保存成功 path = %@",fullPath]]; -// } -} + - (void)showLog:(NSString *)log{ NSLog(@"%@",log); diff --git a/MouseSdk/MouseSdk/Ble/TimerManager.h b/MouseSdk/MouseSdk/Ble/TimerManager.h new file mode 100644 index 0000000..738950f --- /dev/null +++ b/MouseSdk/MouseSdk/Ble/TimerManager.h @@ -0,0 +1,18 @@ +// +// TimerManager.h +// MouseSdk +// +// Created by incar on 2024/8/24. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TimerManager : NSObject +@property (nonatomic, copy)void (^timerCallBack)(void); +///单例 ++(TimerManager *)shared; +@end + +NS_ASSUME_NONNULL_END diff --git a/MouseSdk/MouseSdk/Ble/TimerManager.m b/MouseSdk/MouseSdk/Ble/TimerManager.m new file mode 100644 index 0000000..9401170 --- /dev/null +++ b/MouseSdk/MouseSdk/Ble/TimerManager.m @@ -0,0 +1,42 @@ +// +// TimerManager.m +// MouseSdk +// +// Created by incar on 2024/8/24. +// + +#import "TimerManager.h" + +@interface TimerManager() + +@property (nonatomic, strong) NSTimer *timer; + +@end + +@implementation TimerManager + ++(TimerManager *)shared{ + static TimerManager *manager = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + manager = [[TimerManager alloc]init]; + [manager addSendTimer]; + }); + return manager; +} + +#pragma mark - timer +- (void)addSendTimer{ + dispatch_async(dispatch_queue_create("timeoutQueue", DISPATCH_QUEUE_SERIAL), ^{ + self.timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(timerAction) userInfo:nil repeats:true]; + [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; + [[NSRunLoop currentRunLoop] run]; + }); +} + +- (void)timerAction{ + if(self.timerCallBack) self.timerCallBack(); +} + + +@end diff --git a/MouseSdk/MouseSdk/ScanVC.m b/MouseSdk/MouseSdk/ScanVC.m index 783160b..f06526a 100644 --- a/MouseSdk/MouseSdk/ScanVC.m +++ b/MouseSdk/MouseSdk/ScanVC.m @@ -71,28 +71,28 @@ BleManager *manager = [BleManager shared]; __weak typeof(self) weakSelf= self; __weak typeof(BleManager) *weakManager = manager; - manager.discoverDevice = ^(CBPeripheral *peripheral){ - if ([weakSelf.scanArray containsObject:peripheral]){ - return; - } - if(peripheral.name.length == 0){ - return; - } - [weakSelf.scanArray addObject:peripheral]; - [weakSelf.tableView reloadData]; - }; - manager.didConnectDevice = ^(CBPeripheral * _Nonnull peripheral) { - [weakSelf connectSuccess]; - }; - [manager startScanDevice]; +// manager.discoverDevice = ^(CBPeripheral *peripheral){ +// if ([weakSelf.scanArray containsObject:peripheral]){ +// return; +// } +// if(peripheral.name.length == 0){ +// return; +// } +// [weakSelf.scanArray addObject:peripheral]; +// [weakSelf.tableView reloadData]; +// }; +// manager.didConnectDevice = ^(CBPeripheral * _Nonnull peripheral) { +// [weakSelf connectSuccess]; +// }; +// [manager startScanDevice]; } - (void)tapDevice:(CBPeripheral *)peripheral{ - [[BleManager shared] connectPeripheral:peripheral]; +// [[BleManager shared] connectPeripheral:peripheral]; } - (void)connectSuccess{ - [[BleManager shared] stopScanDevice]; +// [[BleManager shared] stopScanDevice]; dispatch_async(dispatch_get_main_queue(), ^{ NSAlert *alert = [NSAlert new]; [alert addButtonWithTitle:@"确定"]; diff --git a/MouseSdk/MouseSdk/Tlw/TlwBleManager.m b/MouseSdk/MouseSdk/Tlw/TlwBleManager.m index f480817..e795926 100644 --- a/MouseSdk/MouseSdk/Tlw/TlwBleManager.m +++ b/MouseSdk/MouseSdk/Tlw/TlwBleManager.m @@ -121,7 +121,7 @@ //切换代理 [TlwMouse shared].delegate = self; //切换当前连接类型 - [[TlwMouse shared] switchConnect:AiMouseConnectType_bluetooth]; +// [[TlwMouse shared] switchConnect:AiMouseConnectType_bluetooth]; } } } diff --git a/MouseSdk/MouseSdk/Tlw/TlwDeviceManger.m b/MouseSdk/MouseSdk/Tlw/TlwDeviceManger.m index 78118ee..68168cc 100644 --- a/MouseSdk/MouseSdk/Tlw/TlwDeviceManger.m +++ b/MouseSdk/MouseSdk/Tlw/TlwDeviceManger.m @@ -40,7 +40,7 @@ } - (void)switchConnect:(AiMouseConnectType)type{ - [[TlwMouse shared] switchConnect:type]; + [[TlwMouse shared] switchConnect:type isConnected:true]; if ([TlwMouse shared].connectType == AiMouseConnectType_bluetooth) { [self setupBle]; @@ -115,11 +115,12 @@ - (void)bleDidConnect:(NSNotification *)notification{ if(self.connectStateCallBack)self.connectStateCallBack(AiMouseConnectType_bluetooth,true); + [[TlwMouse shared] switchConnect:AiMouseConnectType_bluetooth isConnected:true]; } - (void)bleDidDisconnect:(NSNotification *)notification{ if(self.connectStateCallBack)self.connectStateCallBack(AiMouseConnectType_bluetooth,false); - [[TlwMouse shared] switchConnect:AiMouseConnectType_hid]; + [[TlwMouse shared] switchConnect:AiMouseConnectType_bluetooth isConnected:false]; } @end diff --git a/MouseSdk/MouseSdk/Tlw/TlwHidManager.m b/MouseSdk/MouseSdk/Tlw/TlwHidManager.m index d3ff2b7..e7a916f 100644 --- a/MouseSdk/MouseSdk/Tlw/TlwHidManager.m +++ b/MouseSdk/MouseSdk/Tlw/TlwHidManager.m @@ -186,7 +186,7 @@ static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDRe //设置代理 [TlwMouse shared].delegate = self; //切换当前连接类型 - [[TlwMouse shared] switchConnect:AiMouseConnectType_hid]; +// [[TlwMouse shared] switchConnect:AiMouseConnectType_hid]; } /// 发送数据给设备