From: liangzhenying <867174124@qq.com> Date: Tue, 27 May 2025 09:41:57 +0000 (+0800) Subject: 卡顿优化,hid只初始化一次 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=64ba2e40ec301247efa62da38f60d150e71a4420;p=mirrors%2FMouseSdk-MacOS.git 卡顿优化,hid只初始化一次 --- diff --git a/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.m b/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.m index 758273b..1df5a3f 100644 --- a/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.m +++ b/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.m @@ -249,9 +249,9 @@ else{ complete(deviceInfo,error); } - if (error != nil) { - [ws switchConnect:ws.connectType isConnected:false]; - } +// if (error != nil) { +// [ws switchConnect:ws.connectType isConnected:false]; +// } }]; } - (void)getRSSI:(void (^)(NSString *value,NSError *error))complete{ diff --git a/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.h b/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.h index 06751c6..daff93b 100644 --- a/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.h +++ b/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.h @@ -52,6 +52,9 @@ /// - Parameter log: 日志 - (void)keyboardAddLog:(NSString *)log; + +/// hid数据异常,需要重新开启监听usb设备 +- (void)keyboardHidDataError; @end @@ -74,4 +77,5 @@ /// 获取设备信息 /// - Parameter completation: 如果获取成功,则deviceInfo有值,否则为nil - (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished; + @end diff --git a/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.m b/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.m index 9f05824..b1fcfcb 100644 --- a/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.m +++ b/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.m @@ -12,10 +12,10 @@ @property (nonatomic,strong)void (^getDeviceInfoCallBack)(AiMouseDeviceInfo *deviceInfo,NSError *error); -@property (nonatomic,strong)void (^getUsbSateCallBack)(int bind,NSError *error); @property (nonatomic,strong)void (^getKeyboardStateCallBack)(NSString *version,uint8_t battery,NSError *error); @property (nonatomic,strong)void (^getInfoCallBack)(TlwSnInfo *info,NSError *error); +@property (nonatomic,strong)void (^dongleStateCallBack)(BOOL success); @property (nonatomic,assign)NSInteger dongleTimes; @property (nonatomic,strong)AiMouseDeviceInfo *deviceInfo; @end @@ -30,11 +30,7 @@ [self showLog:type == AiMouseConnectType_bluetooth?@"sdk切换到蓝牙模式":@"sdk切换到usb模式"]; if (type == AiMouseConnectType_hid ) { - [self getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) { - - }]; -// [self sendCmd:0x0D]; - [self startCheckConnectState]; + [self checkDongleState]; } else{ [self TlwConnectManager:nil connectStateDidChange:true]; @@ -104,7 +100,7 @@ [[data subdataWithRange:NSMakeRange(2, 1)] getBytes:&bind length:1]; NSString *log = [NSString stringWithFormat:@"version = %@,bind = %d",version,bind]; [self showLog:log]; - if(self.getUsbSateCallBack)self.getUsbSateCallBack(bind, nil); + if(self.dongleStateCallBack)self.dongleStateCallBack(bind == 1); } else if(cmd == 0x9f){ //接收器状态查询 @@ -161,39 +157,53 @@ } //usb接收器状态查询 -- (void)getUsbReceiverState:(void (^)(int bind,NSError *error))finished{ - self.getUsbSateCallBack = finished; +- (void)getUsbReceiverState:(void (^)(BOOL success))finished{ + self.dongleStateCallBack = finished; [self sendCmd:0x0D]; } //读取键盘序列号 - (void)getSn:(void (^)(TlwSnInfo *info,NSError *error))finished{ self.getInfoCallBack = finished; - [self getUsbReceiverState:^(int bind, NSError *error) { - if (bind == 1) { + [self getUsbReceiverState:^(BOOL success) { + if (success) { [self sendCmd:0x12]; } }]; } -#pragma mark - check connect -- (void)startCheckConnectState{ + +#pragma mark - check dongle +- (void)checkDongleState{ self.dongleTimes = 0; - [self checkAction]; + __weak typeof(self) ws = self; + [self checkDongleStateAction:^(BOOL success) { + ws.dongleStateCallBack = nil; + if (success) { + [ws TlwConnectManager:nil connectStateDidChange:true]; + } + else{ + [ws TlwConnectManager:nil connectStateDidChange:false]; + } + }]; +} +- (void)checkDongleStateAction:(void (^)(BOOL success))finished{ + self.dongleStateCallBack = finished; + [self performSelector:@selector(sendDongleCmd) withObject:nil afterDelay:1]; } -- (void)checkAction{ - if (self.deviceInfo.sn && self.deviceInfo.sn.length > 0) { - [self TlwConnectManager:nil connectStateDidChange:true]; + +- (void)sendDongleCmd{ + self.dongleTimes++; + if ( self.dongleStateCallBack == nil) { return; } - self.dongleTimes++; if (self.dongleTimes > 3) { [self TlwConnectManager:nil connectStateDidChange:false]; return; } - [self performSelector:@selector(checkAction) withObject:nil afterDelay:1]; + [self getUsbReceiverState:self.dongleStateCallBack]; + [self performSelector:@selector(sendDongleCmd) withObject:nil afterDelay:1]; } - #pragma mark - other -(void)TlwConnectManager:(NSString *)manager connectStateDidChange:(BOOL)connected{ _connected = connected; @@ -211,9 +221,7 @@ uint8_t head1 = 0xf1;//头分区 uint8_t head2 = 0xfe;//头信息 uint8_t type = 0x00;//0x00 app发往键盘,0xc0键盘回复 -// uint8_t cmd = 0x00;//类型 uint8_t len = 0x00;//数据负载长度 -// uint8_t data = uint8_t tail = 0xef; NSMutableData *mData = NSMutableData.data; @@ -235,7 +243,7 @@ } - [self showLog:[NSString stringWithFormat:@"[send][info] %@",[TlwTools dataToHexString:mData]]]; +// [self showLog:[NSString stringWithFormat:@"[send][info] %@",[TlwTools dataToHexString:mData]]]; [self.delegate keyboardSendDeviceInfoData:mData]; } diff --git a/MouseSdk/AiMouseSdk/Manager/DeviceManger.h b/MouseSdk/AiMouseSdk/Manager/DeviceManger.h index 5ddd69c..673ae67 100644 --- a/MouseSdk/AiMouseSdk/Manager/DeviceManger.h +++ b/MouseSdk/AiMouseSdk/Manager/DeviceManger.h @@ -122,6 +122,8 @@ NS_ASSUME_NONNULL_BEGIN /// - finished: 执行结果回调 - (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished; +//- (void)startConnect; + @end NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/Manager/DeviceManger.m b/MouseSdk/AiMouseSdk/Manager/DeviceManger.m index 05dff21..a3058f5 100644 --- a/MouseSdk/AiMouseSdk/Manager/DeviceManger.m +++ b/MouseSdk/AiMouseSdk/Manager/DeviceManger.m @@ -32,7 +32,8 @@ @property (nonatomic,strong) M8MouseSdk *m8Sdk; @property (nonatomic,assign) AiMouseProductType productType; @property (nonatomic,strong)void (^authCallBack)(BOOL isSuccess);/// 鉴权回调 -@property (nonatomic, assign)NSInteger retryTimes;//重试次数 + +@property (nonatomic, strong)AiMouseDeviceInfo *deviceInfo;///设备信息 //connectType 返回为0代表蓝牙,为1代表usb @property (nonatomic, copy)void (^aiMouseConnectStateDidChangeCallBack)(int connectType, BOOL connected);/// 设备连接状态回调 @@ -52,7 +53,7 @@ - (instancetype)init{ self = [super init]; if (self) { - self.version = @"MouseSdk_v2025052601"; + self.version = @"MouseSdk_v2025052701"; } return self; } @@ -97,44 +98,17 @@ // [self.hid close]; } else{ - [self.ble open]; - if (self.retryTimes < 5) { - [self.hid open]; - } - else{ - if (self.hid.isOpen) { - if (self.hid.productType == AiMouseProductType_n) { - [self.nSdk switchConnect:AiMouseConnectType_hid isConnected:true]; - } - else if (self.hid.productType == AiMouseProductType_tlw) { - [self.tlwSdk switchConnect:AiMouseConnectType_hid isConnected:true]; - } - else if (self.hid.productType == AiMouseProductType_frk){ - [self.frkSdk switchConnect:AiMouseConnectType_hid isConnected:true]; - } - else if (self.hid.productType == AiMouseProductType_keyboard){ - [self.kbSdk switchConnect:AiMouseConnectType_hid isConnected:true]; - } - else if (self.hid.productType == AiMouseProductType_m8){ - [self.m8Sdk switchConnect:AiMouseConnectType_hid isConnected:true]; - } - } - else{ - [self.hid open]; - } - } } }; } - (void)startConnect{ if(self.kbSdk.connected || self.nSdk.connected || self.tlwSdk.connected || self.frkSdk.connected|| self.m8Sdk.connected){ - // [self.hid close]; } else{ [self.ble open]; - [self.hid open]; + [self.hid openHid]; } } @@ -162,6 +136,7 @@ } } else{ + ws.deviceInfo = nil; if (ws.hid.productType == AiMouseProductType_n) { [ws.nSdk switchConnect:AiMouseConnectType_hid isConnected:false]; [ws.nSdk didDisconnect]; @@ -185,6 +160,11 @@ } }; self.hid.receiveInfoDataCallBack = ^(NSData *data) { + if (ws.isConneted == false) { + [ws.hid closeHid]; + [ws.hid openHid]; + return; + } if (ws.productType == AiMouseProductType_n) { [ws.nSdk sendDeviceDataToSdk:data]; } @@ -204,7 +184,6 @@ self.hid.logCallBack = ^(NSString * _Nonnull log) { [ws showLog:log]; }; - [self.hid open]; } - (void)setupBle{ @@ -366,7 +345,7 @@ - (void)begainMonitorAiMouseConnectStateDidChange:(NSString *)mouseName callBack:(void(^)(int connectType, BOOL connected))callBack{ self.aiMouseConnectStateDidChangeCallBack = callBack; [self.ble open]; - [self.hid open]; + [self.hid openHid]; } ///获取设备信息 - (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{ @@ -374,29 +353,34 @@ __weak typeof(self) ws = self; if(self.productType == AiMouseProductType_keyboard){ [self.kbSdk getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) { + if(deviceInfo != nil)ws.deviceInfo = deviceInfo; finished(deviceInfo,error); [ws checkedDisconect:error]; }]; } else if(self.productType == AiMouseProductType_n){ [self.nSdk getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) { + if(deviceInfo != nil)ws.deviceInfo = deviceInfo; finished(deviceInfo,error); [ws checkedDisconect:error]; }]; }else if (self.productType == AiMouseProductType_tlw) { [self.tlwSdk getFullDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) { + if(deviceInfo != nil)ws.deviceInfo = deviceInfo; finished(deviceInfo,error); [ws checkedDisconect:error]; }]; } else if (self.productType == AiMouseProductType_m8) { [self.m8Sdk getFullDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) { + if(deviceInfo != nil)ws.deviceInfo = deviceInfo; finished(deviceInfo,error); [ws checkedDisconect:error]; }]; } else{ [self.frkSdk getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) { + if(deviceInfo != nil)ws.deviceInfo = deviceInfo; finished(deviceInfo,error); [ws checkedDisconect:error]; }]; @@ -404,10 +388,7 @@ } - (void)checkedDisconect:(NSError *)error{ - if (error == nil) { - self.retryTimes = 0; - } - self.retryTimes++; + } /// 获取信号强度 @@ -911,6 +892,11 @@ - (void)keyboardAddLog:(NSString *)log{ [self showLog:log]; } + +-(void)keyboardHidDataError{ + [self showLog:@"[keyboard]hid重启"]; +// [self.hid openHid]; +} #pragma mark - AiMouseDelegate /// 设备连接状态 /// - Parameter connected: 是否连接 @@ -982,7 +968,7 @@ /// hid数据异常,需要重新开启监听usb设备 - (void)aiMouseHidDataError{ - [self.hid open]; +// [self.hid openHid]; } #pragma mark - M8MouseSdkDelegate /// 设备连接状态 @@ -1118,7 +1104,7 @@ /// hid数据异常,需要重新开启监听usb设备 - (void)m8HidDataError{ - [self.hid open]; +// [self.hid openHid]; } /// 输出sdk日志 diff --git a/MouseSdk/AiMouseSdk/Manager/HidManager.h b/MouseSdk/AiMouseSdk/Manager/HidManager.h index 9ef0872..62e0c29 100644 --- a/MouseSdk/AiMouseSdk/Manager/HidManager.h +++ b/MouseSdk/AiMouseSdk/Manager/HidManager.h @@ -16,13 +16,12 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy)void (^logCallBack)(NSString *log);//输出日志 @property (nonatomic, assign)AiMouseProductType productType; -@property (nonatomic, assign)BOOL isOpen; +(HidManager *)shared; -- (void)open; +- (void)openHid; -//- (void)close; +- (BOOL)closeHid; //写入数据 -(void)writeToDevice:(NSData *)data; diff --git a/MouseSdk/AiMouseSdk/Manager/HidManager.m b/MouseSdk/AiMouseSdk/Manager/HidManager.m index 48f951a..3935125 100644 --- a/MouseSdk/AiMouseSdk/Manager/HidManager.m +++ b/MouseSdk/AiMouseSdk/Manager/HidManager.m @@ -1,4 +1,3 @@ -// // HidManager.m // MouseSdk // @@ -14,11 +13,15 @@ #import "AiDeviceAuthManager.h" #import "TlwTools.h" #import "Tlw2ReceiveManager.h" + @interface HidManager () @property(nonatomic, assign) IOHIDManagerRef hidManager;///hid管理 @property(nonatomic, assign) IOHIDDeviceRef deviceInfoCha;//设备信息通道 -@property(nonatomic, assign) IOHIDDeviceRef voiceCha;//语音通道 +@property(nonatomic, assign) IOHIDDeviceRef voiceRef;//声音事件 +@property(nonatomic, assign) IOHIDDeviceRef moveRef;//鼠标或键盘的基本事件 + @property(nonatomic, strong) Tlw2ReceiveManager *tlw2Receiver; +@property(nonatomic, strong) NSMutableDictionary *deviceBuffers; // 设备缓冲区映射 (key: NSValue(pointer), value: IOHIDDeviceRef) @end @implementation HidManager @@ -27,6 +30,7 @@ static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ manager = [[HidManager alloc]init]; + manager.deviceBuffers = [NSMutableDictionary dictionary]; }); return manager; } @@ -41,67 +45,62 @@ #pragma mark - Hid CallBack /// 匹配到设备回调 -static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) { +static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef deviceRef) { if ([DeviceManger shared].isConneted) { -// [[HidManager shared] showLog:(@"当前处于连接状态,对监听到有USB 插入 的事件不做处理")]; + // [[HidManager shared] showLog:(@"当前处于连接状态,对监听到有USB 插入 的事件不做处理")]; return; } - uint32_t pid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey)); - uint32_t vid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey)); - uint32_t page = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey)); - uint32_t usage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey)); -// [[HidManager shared] showLog: [NSString stringWithFormat:@"发现设备 %@",inIOHIDDeviceRef]]; - if(vid == 3468 && pid == 786){ - if (page == 65282 && usage == 2) { - [HidManager shared].productType = AiMouseProductType_m8; - [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; - unsigned char InputBuffer[64]; - IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), &hidReceiveData, NULL); - - IOReturn result = IOHIDDeviceOpen(inIOHIDDeviceRef, kIOHIDOptionsTypeNone); - if (result != kIOReturnSuccess) { - [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]]; - [[AiDeviceAuthManager shared] showHidAlert]; - return; - }else{ - [[HidManager shared] showLog:@"打开设备成功!"]; - [HidManager shared].isOpen = true; - [HidManager shared].connectStateCallBack(true) ; - } - } -// else if (page == 1 && usage == 2){ -// [HidManager shared].productType = AiMouseProductType_m8; -// [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; -// unsigned char InputBuffer[64]; -// IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), &hidReceiveData, NULL); -// -// IOReturn result = IOHIDDeviceOpen(inIOHIDDeviceRef, kIOHIDOptionsTypeNone); -// if (result != kIOReturnSuccess) { -// [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]]; -// [[AiDeviceAuthManager shared] showHidAlert]; -// return; -// }else{ -// [[HidManager shared] showLog:@"打开设备成功!"]; -// // [HidManager shared].connectStateCallBack(true) ; -// } -// } - return; + + uint32_t pid = IOHIDDevGetUInt32Property(deviceRef, CFSTR(kIOHIDProductIDKey)); + uint32_t vid = IOHIDDevGetUInt32Property(deviceRef, CFSTR(kIOHIDVendorIDKey)); + uint32_t page = IOHIDDevGetUInt32Property(deviceRef, CFSTR(kIOHIDPrimaryUsagePageKey)); + uint32_t usage = IOHIDDevGetUInt32Property(deviceRef, CFSTR(kIOHIDPrimaryUsageKey)); + [[HidManager shared] showLog: [NSString stringWithFormat:@"发现设备 %@",deviceRef]]; + + // 为设备创建专用缓冲区 + unsigned char *inputBuffer = (unsigned char *)malloc(64); + NSValue *bufferKey = [NSValue valueWithPointer:inputBuffer]; + [[HidManager shared].deviceBuffers setObject:(__bridge id)deviceRef forKey:bufferKey]; + + if(vid == 3468 && pid == 786){ + if (page == 65282 && usage == 2) { + [HidManager shared].productType = AiMouseProductType_m8; + [HidManager shared].deviceInfoCha = deviceRef; + IOHIDDeviceRegisterInputReportCallback(deviceRef, inputBuffer, 64, &hidReceiveData, NULL); + + IOReturn result = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); + if (result != kIOReturnSuccess) { + [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]]; + [[AiDeviceAuthManager shared] showHidAlert]; + free(inputBuffer); // 释放未使用的缓冲区 + return; + }else{ + [[HidManager shared] showLog:@"打开设备成功!"]; + [HidManager shared].connectStateCallBack(true) ; + } + } + return; } if((vid == 0x248a && pid == 0x6092)){ + if ([HidManager shared].deviceInfoCha) { + return; + } + [HidManager shared].deviceInfoCha = deviceRef; [HidManager shared].productType = AiMouseProductType_keyboard; - [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; - unsigned char InputBuffer[64]; - IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), &hidReceiveData, NULL); + IOHIDDeviceRegisterInputReportCallback(deviceRef, inputBuffer, 64, &hidReceiveData, NULL); IOReturn result = IOHIDDeviceOpen([HidManager shared].deviceInfoCha, kIOHIDOptionsTypeNone); if (result != kIOReturnSuccess) { [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]]; [[AiDeviceAuthManager shared] showHidAlert]; + free(inputBuffer); // 释放未使用的缓冲区 return; }else{ [[HidManager shared] showLog:@"打开设备成功!"]; - [HidManager shared].isOpen = true; - [HidManager shared].connectStateCallBack(true) ; +// dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC); +// dispatch_after(delayTime, dispatch_get_main_queue(), ^{ + [HidManager shared].connectStateCallBack(true); +// }); } return; } @@ -110,98 +109,126 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH || (vid == 0x32c2 && pid == 0x0066) ){ [HidManager shared].productType = AiMouseProductType_n; - [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; - unsigned char InputBuffer[64]; - IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), &hidReceiveData, NULL); + [HidManager shared].deviceInfoCha = deviceRef; + IOHIDDeviceRegisterInputReportCallback(deviceRef, inputBuffer, 64, &hidReceiveData, NULL); IOReturn result = IOHIDDeviceOpen([HidManager shared].deviceInfoCha, kIOHIDOptionsTypeNone); if (result != kIOReturnSuccess) { [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]]; [[AiDeviceAuthManager shared] showHidAlert]; + free(inputBuffer); // 释放未使用的缓冲区 return; }else{ [[HidManager shared] showLog:@"打开设备成功!"]; - [HidManager shared].isOpen = true; [HidManager shared].connectStateCallBack(true) ; } } else if(vid == 0x10D6 && pid == 0xB008){ + //泰凌微只有一个通道 [HidManager shared].productType = AiMouseProductType_tlw; - [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; - unsigned char InputBuffer[64]; - IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), &hidReceiveData, NULL); + [HidManager shared].deviceInfoCha = deviceRef; + IOHIDDeviceRegisterInputReportCallback(deviceRef, inputBuffer, 64, &hidReceiveData, NULL); IOReturn result = IOHIDDeviceOpen([HidManager shared].deviceInfoCha, kIOHIDOptionsTypeNone); if (result != kIOReturnSuccess) { [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]]; [[AiDeviceAuthManager shared] showHidAlert]; + free(inputBuffer); // 释放未使用的缓冲区 return; }else{ [[HidManager shared] showLog:@"打开设备成功!"]; - [HidManager shared].isOpen = true; [HidManager shared].connectStateCallBack(true) ; } } - else if(vid == 0x6675 && pid == 0x8601){ + else if(vid == 26229 && pid == 34305){ [HidManager shared].productType = AiMouseProductType_frk; AiMouse.shared.tlw2 = false; if(page == 1 && usage == 0){ - unsigned char InputBuffer[128]; - IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL); - IOReturn result = IOHIDDeviceOpen(inIOHIDDeviceRef, kIOHIDOptionsTypeNone); + IOHIDDeviceRegisterInputReportCallback(deviceRef, inputBuffer, 64, hidReceiveData, NULL); + IOReturn result = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); if (result != kIOReturnSuccess) { - [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备信息失败! %d",result]]; + [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备通道失败! %d",result]]; [[AiDeviceAuthManager shared] showHidAlert]; - return; + free(inputBuffer); // 释放未使用的缓冲区 }else{ - [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; - - [[HidManager shared] showLog:@"打开设备信息成功!"]; - if([HidManager shared].voiceCha != nil){ - [HidManager shared].isOpen = true; + [HidManager shared].deviceInfoCha = deviceRef; + [[HidManager shared] showLog:@"打开设备通道成功!"]; + if (([HidManager shared].deviceInfoCha != nil) && + ([HidManager shared].voiceRef != nil) && + ([HidManager shared].moveRef != nil)) { [HidManager shared].connectStateCallBack(true); } } } else if(page == 65283 && usage == 0){ - unsigned char InputBuffer[128]; - IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL); - - IOReturn result = IOHIDDeviceOpen(inIOHIDDeviceRef, kIOHIDOptionsTypeNone); + IOHIDDeviceRegisterInputReportCallback(deviceRef, inputBuffer, 64, hidReceiveData, NULL); + IOReturn result = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); if (result != kIOReturnSuccess) { [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备voice失败! %d",result]]; [[AiDeviceAuthManager shared] showHidAlert]; - return; - }else{ - [HidManager shared].voiceCha = inIOHIDDeviceRef; - - [[HidManager shared] showLog:@"打开设备voice成功!"]; - if([HidManager shared].deviceInfoCha != nil){ - [HidManager shared].isOpen = true; + free(inputBuffer); // 释放未使用的缓冲区 + } + else{ + [HidManager shared].voiceRef = deviceRef; + if (([HidManager shared].deviceInfoCha != nil) && + ([HidManager shared].voiceRef != nil) && + ([HidManager shared].moveRef != nil)) { + [HidManager shared].connectStateCallBack(true); + } + } + } + else if(page == 1 && usage == 6){ + //鼠标坐标移动 + IOHIDDeviceRegisterInputReportCallback(deviceRef, inputBuffer, 64, mouseData, NULL); + IOReturn result = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); + if (result != kIOReturnSuccess) { + [[HidManager shared] showLog:[NSString stringWithFormat:@"鼠标监听失败! %d",result]]; + free(inputBuffer); // 释放未使用的缓冲区 + } + else{ + [HidManager shared].moveRef = deviceRef; + if (([HidManager shared].deviceInfoCha != nil) && + ([HidManager shared].voiceRef != nil) && + ([HidManager shared].moveRef != nil)) { [HidManager shared].connectStateCallBack(true); } } } } - else if(vid == 0x6675 && pid == 0x8602){ + else if(vid == 26229 && pid == 34306){ [HidManager shared].productType = AiMouseProductType_frk; AiMouse.shared.tlw2 = true; [HidManager shared].tlw2Receiver = [[Tlw2ReceiveManager alloc] init]; - if(page == 65519 && usage == 0){ - unsigned char InputBuffer[128]; - IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL); + if(page == 65519 && usage == 0){ + IOHIDDeviceRegisterInputReportCallback(deviceRef, inputBuffer, 64, hidReceiveData, NULL); - IOReturn result = IOHIDDeviceOpen(inIOHIDDeviceRef, kIOHIDOptionsTypeNone); + IOReturn result = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); if (result != kIOReturnSuccess) { [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备voice失败! %d",result]]; [[AiDeviceAuthManager shared] showHidAlert]; + free(inputBuffer); // 释放未使用的缓冲区 return; }else{ - [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; - + [HidManager shared].deviceInfoCha = deviceRef; [[HidManager shared] showLog:@"打开设备voice成功!"]; - if([HidManager shared].deviceInfoCha != nil){ - [HidManager shared].isOpen = true; + if (([HidManager shared].deviceInfoCha != nil) && + ([HidManager shared].moveRef != nil)) { + [HidManager shared].connectStateCallBack(true); + } + } + } + else if(page == 1 && usage == 2){ + //鼠标坐标移动 + IOHIDDeviceRegisterInputReportCallback(deviceRef, inputBuffer, 64, mouseData, NULL); + IOReturn result = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); + if (result != kIOReturnSuccess) { + [[HidManager shared] showLog:[NSString stringWithFormat:@"鼠标监听失败! %d",result]]; + free(inputBuffer); // 释放未使用的缓冲区 + } + else{ + [HidManager shared].moveRef = deviceRef; + if (([HidManager shared].deviceInfoCha != nil) && + ([HidManager shared].moveRef != nil)) { [HidManager shared].connectStateCallBack(true); } } @@ -209,25 +236,70 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH } } +/// 关闭特定设备 +- (void)closeDevice:(IOHIDDeviceRef)deviceRef { + if (deviceRef) { + // 查找设备对应的缓冲区并释放 + NSValue *bufferKeyToRemove = nil; + for (NSValue *key in self.deviceBuffers) { + IOHIDDeviceRef bufferDevice = (__bridge IOHIDDeviceRef)[self.deviceBuffers objectForKey:key]; + if (bufferDevice == deviceRef) { + unsigned char *buffer = (unsigned char *)[key pointerValue]; + free(buffer); + bufferKeyToRemove = key; + break; + } + } + + if (bufferKeyToRemove) { + [self.deviceBuffers removeObjectForKey:bufferKeyToRemove]; + } + + // 取消注册回调 + IOHIDDeviceRegisterInputReportCallback(deviceRef, NULL, 0, NULL, NULL); + + // 关闭设备 + IOReturn ret = IOHIDDeviceClose(deviceRef, kIOHIDOptionsTypeNone); + if (ret != kIOReturnSuccess) { + [self showLog:(@"关闭device失败!")]; + } + + // 清除引用 + if (self.deviceInfoCha == deviceRef) { + self.deviceInfoCha = nil; + } else if (self.voiceRef == deviceRef) { + self.voiceRef = nil; + } else if (self.moveRef == deviceRef) { + self.moveRef = nil; + } + } +} + /// 设备移除回调 -static void hidDisAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) { - [[HidManager shared] showLog:[NSString stringWithFormat:@"拔出设备 %@ ",inIOHIDDeviceRef]]; - if([HidManager shared].deviceInfoCha == inIOHIDDeviceRef){ - [HidManager shared].deviceInfoCha = nil; - [HidManager shared].voiceCha = nil; -// [HidManager shared].hidManager = nil; - [HidManager shared].isOpen = false; +static void hidDisAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef deviceRef) { + [[HidManager shared] showLog:[NSString stringWithFormat:@"拔出设备 %@ ",deviceRef]]; + [[HidManager shared] closeDevice:deviceRef]; + + // 检查是否所有设备都已断开 + if ([HidManager shared].deviceInfoCha == nil) { [HidManager shared].connectStateCallBack(false) ; } } +static void mouseData(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report,CFIndex reportLength){ + // NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; + // [[HidManager shared] showLog:[NSString stringWithFormat:@"[鼠标事件]%@",@""]]; + [[HidManager shared] checkedConected]; +} + static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report,CFIndex reportLength){ - NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; - if (data.length <= 4) { - return; - } -// [[HidManager shared] showLog:[NSString stringWithFormat:@"[reciv] %@",data]]; - // return; + [[HidManager shared] checkedConected]; + // NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; + // if (data.length <= 4) { + // return; + // } + // [[HidManager shared] showLog:[NSString stringWithFormat:@"[reciv] reportID = %ul %@",reportID,data]]; + // return; if([HidManager shared].productType == AiMouseProductType_keyboard){ NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; [HidManager shared].receiveInfoDataCallBack(data); @@ -239,18 +311,17 @@ static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDRe else if([HidManager shared].productType == AiMouseProductType_tlw){ if (report[0] == 0x01 || report[0] == 0x02) { //鼠标键盘活动事件 + [[HidManager shared] checkedConected]; return; } uint32_t page = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsagePageKey)); uint32_t usage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsageKey)); -// [[HidManager shared] showLog:[NSString stringWithFormat:@"[reciv]page = %d,usage = %d, %@",page,usage,data]]; if(page == 1 && usage == 2){ NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; [HidManager shared].receiveInfoDataCallBack(data); } } else if([HidManager shared].productType == AiMouseProductType_frk){ - NSInteger len = get_data_len(report, (int)reportLength); NSData *data = [[NSData alloc] initWithBytes:report length:len]; uint32_t page = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsagePageKey)); @@ -269,75 +340,85 @@ static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDRe } } +//检查是否已连接 +- (void)checkedConected{ + if (![DeviceManger shared].isConneted) { + [HidManager shared].connectStateCallBack(true); + } +} + #pragma mark - public -- (void)open{ - [self close]; - //初始化 - self.deviceInfoCha = nil; - self.voiceCha = nil; - self.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - IOHIDManagerScheduleWithRunLoop(self.hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode); - IOReturn ret = IOHIDManagerOpen(self.hidManager, 0L); - if (ret != kIOReturnSuccess) { - [self showLog:(@"打开hid失败!")]; - }else{ - [self showLog:(@"打开hid成功!")]; + +- (void)openHid{ + // [self close]; + if (self.hidManager == nil) { + self.deviceInfoCha = nil; + self.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + IOHIDManagerScheduleWithRunLoop(self.hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode); + IOReturn ret = IOHIDManagerOpen(self.hidManager, 0L); + if (ret != kIOReturnSuccess) { + [self showLog:(@"打开hid失败!")]; + }else{ + [self showLog:(@"打开hid成功!")]; + } + //设置匹配设备 + NSMutableDictionary* dict= [NSMutableDictionary dictionary]; + IOHIDManagerSetDeviceMatching(self.hidManager, (__bridge CFMutableDictionaryRef)dict); + //设置匹配到设备回调 + IOHIDManagerRegisterDeviceMatchingCallback(self.hidManager, &hidAppearDevice, NULL); + //设置移除设备回调 + IOHIDManagerRegisterDeviceRemovalCallback(self.hidManager, &hidDisAppearDevice, NULL); } - //设置匹配设备 - 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); } -- (BOOL)close{ +- (BOOL)closeHid{ + [self showLog:@"关闭hid"]; + // 关闭所有已连接的设备 + if (self.deviceInfoCha) { + [self closeDevice:self.deviceInfoCha]; + } + + if (self.voiceRef) { + [self closeDevice:self.voiceRef]; + } + + if (self.moveRef) { + [self closeDevice:self.moveRef]; + } + + // 清空缓冲区字典 + for (NSValue *key in self.deviceBuffers) { + unsigned char *buffer = (unsigned char *)[key pointerValue]; + free(buffer); + } + [self.deviceBuffers removeAllObjects]; + + // 关闭HID管理器 if (self.hidManager != nil) { - if (self.deviceInfoCha != nil) { - // 取消所有报告回调 - IOReturn ret = IOHIDDeviceClose(self.deviceInfoCha, kIOHIDOptionsTypeNone); - if (ret != kIOReturnSuccess) { - [self showLog:(@"关闭device失败!")]; - return false; - } - } - if (self.voiceCha != nil) { - IOReturn ret = IOHIDDeviceClose(self.voiceCha, kIOHIDOptionsTypeNone); - if (ret != kIOReturnSuccess) { - [self showLog:(@"关闭voice失败!")]; - return false; - } - } + // 取消注册回调 + IOHIDManagerRegisterDeviceMatchingCallback(self.hidManager, NULL, NULL); + IOHIDManagerRegisterDeviceRemovalCallback(self.hidManager, NULL, NULL); IOReturn ret = IOHIDManagerClose(self.hidManager, 0); if (ret != kIOReturnSuccess) { - [self showLog:(@"关闭hid失败!")]; - return false; + [self showLog:[NSString stringWithFormat:@"关闭hid失败! 错误码:%d", ret]]; } - self.deviceInfoCha = nil; - self.voiceCha = nil; - self.hidManager = nil; + [self showLog:@"IOHIDManager已关闭"]; + self.hidManager = nil; } + return true; } + /// 发送数据给设备 -(void)writeToDevice:(NSData *)data{ if(self.deviceInfoCha == nil){ [self showLog:@"sendData: 请先连上设备"]; return; } -// data = [self addFullData:data]; - [self showLog:[NSString stringWithFormat:@"[send] %@ %@",self.deviceInfoCha,data]]; - IOReturn ret = IOHIDDeviceSetReport(self.deviceInfoCha, kIOHIDReportTypeOutput, 0x05, data.bytes, data.length); - if (ret != kIOReturnSuccess) { - [self showLog:[NSString stringWithFormat:@"发送失败! code = %d",ret]]; - }else{ - // [self showLog:@"发送成功!"]; - } + [self showLog:[NSString stringWithFormat:@"[send]%@",[TlwTools dataToHexString:data]]]; + IOHIDDeviceSetReport(self.deviceInfoCha, kIOHIDReportTypeOutput, 0x05, data.bytes, data.length); } - (NSData *)addFullData:(NSData *)data{ @@ -368,10 +449,10 @@ static inline int get_data_len(uint8_t *buf, int len) { } /// 获取对应属性值 -static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey) { +static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef deviceRef, CFStringRef inKey) { uint32_t outValue = 0; - if (inIOHIDDeviceRef != NULL) { - CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, inKey); + if (deviceRef != NULL) { + CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(deviceRef, inKey); if (tCFTypeRef != NULL && (CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef)) ) { Boolean result = CFNumberGetValue((CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, &outValue); if (!result) { diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m index 5259e61..cb1b4f1 100644 --- a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m @@ -52,7 +52,6 @@ -(instancetype)init{ if (self = [super init]) { _connectType = AiMouseConnectType_bluetooth; -// NSLog(@"[TlwMouseSdk]%@",[NSString stringWithFormat:@"AiMouseSdk_v%@",self.version]); [self.recordManager checkPermissions]; } return self; @@ -97,15 +96,11 @@ if (type == AiMouseConnectType_hid ) { [self.recordManager checkPermissions]; -// [self sendOpenCmd]; [self checkDongleState]; } else{ [self TlwConnectManager:nil connectStateDidChange:true]; } -// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ -// [HidManager shared].connectStateCallBack(true); -// }); } else{ [self stopRecord]; @@ -331,67 +326,11 @@ } else{ if(ws.getFullInfoCallBack)ws.getFullInfoCallBack(nil,error); - [ws TlwConnectManager:nil connectStateDidChange:false]; +// [ws TlwConnectManager:nil connectStateDidChange:false]; } }]; } -//- (void)getFullDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{ -// self.getFullInfoCallBack = finished; -// __weak typeof(self) ws = self; -// [self getDeviceInfo:^(TlwDeviceInfo *deviceInfo, NSError *error) { -// if(deviceInfo != nil){ -// NSDictionary *dict = @{ -// @"1200":@"1", -// @"1600":@"2", -// @"2400":@"3", -// @"4800":@"4", -// }; -// -// NSString *CPI_list = [[dict allKeys] componentsJoinedByString:@","]; -// NSString *level = [NSString stringWithFormat:@"%d",deviceInfo.DPI]; -// NSString *dpiValue = @"1200"; -// -// for (NSString *key in dict) { -// if ([dict[key] isEqualToString:level]) { -// dpiValue = key; -// break;; -// } -// } -// -// AiMouseDeviceInfo *info = [[AiMouseDeviceInfo alloc] init]; -// info.type = 0; -// info.battery_power = [NSString stringWithFormat:@"%d",deviceInfo.batteryValue] ; -// info.version = [NSString stringWithFormat:@"%@",deviceInfo.version]; -// info.CPI_list = CPI_list; -// info.CPI = dpiValue; -// ws.fullInfo = info; -// -// [ws getSnInfo:^(TlwSnInfo *snInfo, NSError *error) { -// if( info != nil){ -// info.brand = snInfo.brand; -// info.sn = snInfo.sn; -// info.mac = snInfo.mac; -// if ([[info.brand uppercaseString] isEqualTo:@"D3"]) { -// info.type = 1;//D3是键盘 -// } -// [ws showLog:info.description]; -// if(ws.getFullInfoCallBack)ws.getFullInfoCallBack(info, nil); -// } -// else{ -// if(ws.getFullInfoCallBack)ws.getFullInfoCallBack(nil,error); -// [ws TlwConnectManager:nil connectStateDidChange:false]; -// } -// }]; -// } -// else{ -// if(ws.getFullInfoCallBack) ws.getFullInfoCallBack(nil,error); -// [ws TlwConnectManager:nil connectStateDidChange:false]; -// } -// }]; -//} - - /// 设置长按滚轮弹出网页开关 /// - Parameters: /// - state: 0关闭,1打开 @@ -810,7 +749,7 @@ [data appendBytes:&d length:1]; } } - [self showLog:[NSString stringWithFormat:@"[send][info] %@",[TlwTools dataToHexString:data]]]; +// [self showLog:[NSString stringWithFormat:@"[send][info] %@",[TlwTools dataToHexString:data]]]; [self.delegate tlwMouseSendDeviceInfoData:data]; } #pragma mark - deviceInfo diff --git a/MouseSdk/MouseSdk.xcodeproj/xcshareddata/xcschemes/MouseSdk.xcscheme b/MouseSdk/MouseSdk.xcodeproj/xcshareddata/xcschemes/MouseSdk.xcscheme index 7bf9e69..5299a22 100644 --- a/MouseSdk/MouseSdk.xcodeproj/xcshareddata/xcschemes/MouseSdk.xcscheme +++ b/MouseSdk/MouseSdk.xcodeproj/xcshareddata/xcschemes/MouseSdk.xcscheme @@ -54,7 +54,7 @@