卡顿优化,hid只初始化一次
authorliangzhenying <867174124@qq.com>
Tue, 27 May 2025 09:41:57 +0000 (17:41 +0800)
committerliangzhenying <867174124@qq.com>
Tue, 27 May 2025 09:41:57 +0000 (17:41 +0800)
MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.m
MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.h
MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.m
MouseSdk/AiMouseSdk/Manager/DeviceManger.h
MouseSdk/AiMouseSdk/Manager/DeviceManger.m
MouseSdk/AiMouseSdk/Manager/HidManager.h
MouseSdk/AiMouseSdk/Manager/HidManager.m
MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m
MouseSdk/MouseSdk.xcodeproj/xcshareddata/xcschemes/MouseSdk.xcscheme
MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate
MouseSdk/MouseSdk/ViewController.m

index 758273b..1df5a3f 100644 (file)
         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{
index 06751c6..daff93b 100644 (file)
@@ -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
index 9f05824..b1fcfcb 100644 (file)
 
 @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
         [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];
         [[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){
         //接收器状态查询
 }
 
 //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;
     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;
     }
 
     
-    [self showLog:[NSString stringWithFormat:@"[send][info] %@",[TlwTools dataToHexString:mData]]];
+//    [self showLog:[NSString stringWithFormat:@"[send][info] %@",[TlwTools dataToHexString:mData]]];
     [self.delegate keyboardSendDeviceInfoData:mData];
 }
 
index 5ddd69c..673ae67 100644 (file)
@@ -122,6 +122,8 @@ NS_ASSUME_NONNULL_BEGIN
 /// - finished: 执行结果回调
 - (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
 
+//- (void)startConnect;
+
 @end
 
 NS_ASSUME_NONNULL_END
index 05dff21..a3058f5 100644 (file)
@@ -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;
 }
 //            [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];
     }
 }
 
             }
         }
         else{
+            ws.deviceInfo = nil;
             if (ws.hid.productType == AiMouseProductType_n) {
                 [ws.nSdk switchConnect:AiMouseConnectType_hid isConnected:false];
                 [ws.nSdk didDisconnect];
         }
     };
     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];
         }
     self.hid.logCallBack = ^(NSString * _Nonnull log) {
         [ws showLog:log];
     };
-    [self.hid open];
 }
 
 - (void)setupBle{
 - (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{
     __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];
         }];
 }
 
 - (void)checkedDisconect:(NSError *)error{
-    if (error == nil) {
-        self.retryTimes = 0;
-    }
-    self.retryTimes++;
+
 }
 
 /// 获取信号强度
 - (void)keyboardAddLog:(NSString *)log{
     [self showLog:log];
 }
+
+-(void)keyboardHidDataError{
+    [self showLog:@"[keyboard]hid重启"];
+//    [self.hid openHid];
+}
 #pragma mark - AiMouseDelegate
 /// 设备连接状态
 /// - Parameter connected: 是否连接
 
 /// hid数据异常,需要重新开启监听usb设备
 - (void)aiMouseHidDataError{
-    [self.hid open];
+//    [self.hid openHid];
 }
 #pragma mark - M8MouseSdkDelegate
 /// 设备连接状态
 
 /// hid数据异常,需要重新开启监听usb设备
 - (void)m8HidDataError{
-    [self.hid open];
+//    [self.hid openHid];
 }
 
 /// 输出sdk日志
index 9ef0872..62e0c29 100644 (file)
@@ -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;
index 48f951a..3935125 100644 (file)
@@ -1,4 +1,3 @@
-//
 //  HidManager.m
 //  MouseSdk
 //
 #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;
 }
 
 #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) {
index 5259e61..cb1b4f1 100644 (file)
@@ -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;
         
         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];
         }
         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打开
             [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
index 7bf9e69..5299a22 100644 (file)
@@ -54,7 +54,7 @@
       </Testables>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Release"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"
index 6f65429..bb65899 100644 (file)
Binary files a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate and b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate differ
index 8b1c6fd..af195d8 100644 (file)
@@ -82,7 +82,7 @@
 #pragma mark - action
 - (void)setupDeviceManger{
     DeviceManger *manager = [DeviceManger shared];
-    [manager initSdk:1];
+    [manager initSdk:2];
     manager.debugLevel = 2;
     
     __weak typeof(self) ws = self;
     NSMenuItem *item4 = [[NSMenuItem alloc] initWithTitle:@"鼠标状态查询" action:@selector(searchState:) keyEquivalent:@"4"];
     NSMenuItem *item5 = [[NSMenuItem alloc] initWithTitle:@"设置滚轮开关" action:@selector(setUrlState:) keyEquivalent:@"5"];
     NSMenuItem *item6 = [[NSMenuItem alloc] initWithTitle:@"获取滚轮开关" action:@selector(getUrlState:) keyEquivalent:@"6"];
+    NSMenuItem *item7 = [[NSMenuItem alloc] initWithTitle:@"查询连接状态" action:@selector(getConnectState:) keyEquivalent:@"7"];
 
     [popupMenu addItem:item1];
     [popupMenu addItem:item2];
     [popupMenu addItem:item4];
     [popupMenu addItem:item5];
     [popupMenu addItem:item6];
+    [popupMenu addItem:item7];
 
     NSPoint buttonLocation = [sender convertPoint:NSZeroPoint toView:self.view];
     [popupMenu popUpMenuPositioningItem:nil atLocation:buttonLocation inView:self.view];
     [self geviceInfoAction];
 }
 
+- (void)getConnectState:(NSMenuItem*)sender{
+//    [[DeviceManger shared] startConnect];
+}
+
 - (void)setUrlState:(NSMenuItem*)sender{
     [[DeviceManger shared] setUrlState:0 completation:^(BOOL isSuccess, NSError * _Nonnull error) {
         NSLog(isSuccess? @"设置滚轮开关成功":@"设置滚轮开关失败");