USB鉴权通讯调试
authorliangzhenying <867174124@qq.com>
Mon, 1 Apr 2024 09:56:47 +0000 (17:56 +0800)
committerliangzhenying <867174124@qq.com>
Mon, 1 Apr 2024 09:56:47 +0000 (17:56 +0800)
13 files changed:
Document/AiMouseSdk接口文档.md
MouseSdk/AiMouseSdk/AiAuthManager.m
MouseSdk/AiMouseSdk/AiFrameManager.m
MouseSdk/AiMouseSdk/AiMouse.h
MouseSdk/AiMouseSdk/AiMouse.m
MouseSdk/AiMouseSdk/AiRecordManager.m
MouseSdk/AliIotConnectKitSDK/AliIotConnectKit/Mqtt/IotMqtt/IotMqttManager_C.swift
MouseSdk/MouseSdk.xcodeproj/project.pbxproj
MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate
MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
MouseSdk/MouseSdk/HidManager.h
MouseSdk/MouseSdk/HidManager.m
MouseSdk/MouseSdk/Info.plist [new file with mode: 0644]

index ca77af9..f70e522 100644 (file)
@@ -9,6 +9,7 @@
 | 1.0.0 | 初始版本                                            | 梁振营 | 2024-03-8  |\r
 | 1.0.1 | 鼠标按键指令修改                                    | 梁振营 | 2024-03-18 |\r
 | 1.0.2 | 鉴权流程修改,只有鉴权成功了,SDK相关功能才可以使用 | 梁振营 | 2024-03-19 |\r
+| 1.0.3 | 支持USB通讯                                         | 梁振营 | 2024-04-01 |\r
 \r
 \r
 \r
 \r
 ## 相关权限配置\r
 \r
-因为sdk用到蓝牙权限,所以需要在info.plist进行相关配置\r
+因为sdk用到蓝牙权限、网络、语音等功能,info.plist和沙盒需要进行相关权限设置\r
 \r
 ```xml\r
   <!-- 蓝牙 -->   \r
 <key>NSBluetoothAlwaysUsageDescription</key>   \r
-<string>App需要您的同意,才能访问蓝牙</string> \r
-```\r
+<string>要打开蓝牙才能使用AI功能哦</string> \r
+\r
+<key>Privacy - Microphone Usage Description</key>  \r
+<string>要打开麦克风才能使用AI功能哦</string> \r
 \r
+```\r
 \r
+![image-20240401162536522](/Users/apple/Library/Application Support/typora-user-images/image-20240401162536522.png)\r
 \r
 ## SDK相关接口\r
 \r
 ```objective-c\r
+/// 单利\r
++(AiMouse *)shared;\r
+\r
+/// 切换连接类型\r
+/// - Parameter type: 连接类型\r
+- (void)switchConnect:(AiMouseConnectType)type;\r
+\r
 /// 开始鉴权\r
 /// - Parameter finished: 鉴权结果回调\r
 - (void)startAuthentication:(void (^)(AiMouseAuthState state))finished;\r
@@ -77,9 +89,9 @@
 \r
 /// 鼠标按键指令回调\r
 /// - Parameter data: 数据。\r
-/// M 键    短按0x42;长按按下(开始录音)0x25,  长按抬起(结束录音) 0x26;\r
-/// AI键  短按0x43  ,长按按下(开始录音)0x27,  长按抬起(结束录音) 0x28;\r
-/// 语音键 按下(开始录音) 0x31,弹起(结束录音)0x32;\r
+/// 前  第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音)\r
+/// 中  单击42, 按下25(开始录音)抬起26(结束录音)\r
+/// 后  单击43,按下27(开始录音)抬起28(结束录音)\r
 /// 其他未定义\r
 - (void)aiMouseSendCmdData:(NSData *)data;\r
 \r
 - (void)aiMouseSendRecordData:(NSData *)data;\r
 ```\r
 \r
-## 示例\r
-\r
-- 蓝牙服务特征\r
-\r
-  ```objective-c\r
-  // 服务id\r
-  #define kServiceUUID @"FFF1"\r
-  //ai特征\r
-  #define kAiUUID @"0783B03E-8535-B5A0-7140-A304D2194CB8"\r
-  //鉴权特征\r
-  #define kAuthUUID @"0783B73E-8535-B5A0-7140-A304D2194CB7"\r
-  //设备信息特征\r
-  #define kDeviceInfoUUID @"0783B63E-8535-B5A0-7140-A304D2495CB6"\r
-  ```\r
-  \r
-  \r
-\r
-\r
-\r
-1. 设置代理\r
-\r
-  ```objective-c\r
-  [AiMouse shared].delegate = self;\r
-  ```\r
-\r
-2. 查找对应特征,订阅\r
-\r
-  ```\r
-  // 发现特征\r
-  - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {\r
-      for (CBCharacteristic *characteristic in service.characteristics){\r
-          if ([characteristic.UUID.UUIDString isEqualToString:kAuthUUID]) {\r
-              //鉴权特征\r
-              self.authCha = characteristic;\r
-              [peripheral setNotifyValue:YES forCharacteristic:characteristic];\r
-              //找到鉴权特征后,一定要调用鉴权接口开始鉴权。只有鉴权通过了,sdk相关功能才可以使用\r
-              [[AiMouse shared] startAuthentication:^(AiMouseAuthState state) {\r
-                  [self showLog:[NSString stringWithFormat:@"鉴权结果 = %@",@(state)]];\r
-                  if(self.authCallBack){\r
-                      self.authCallBack(state == AiMouseAuthState_Success);\r
-                  }\r
-              }];\r
-          }\r
-          else if ([characteristic.UUID.UUIDString isEqualToString:kAiUUID]) {\r
-              //AI特征\r
-              self.aiCha = characteristic;\r
-              [peripheral setNotifyValue:YES forCharacteristic:characteristic];\r
-          }\r
-          else if ([characteristic.UUID.UUIDString isEqualToString:kDeviceInfoUUID]) {\r
-              //设备信息特征\r
-              self.deviceInfoCha = characteristic;\r
-              [peripheral setNotifyValue:YES forCharacteristic:characteristic];\r
-          }\r
-      }\r
-  }\r
-  ```\r
-\r
-  \r
-\r
-3. 收到设备传输过来的数据,传给sdk处理\r
-\r
-  ```objective-c\r
-  //收到蓝牙数据\r
-  - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {\r
-      NSData *data = characteristic.value;\r
-      [self showLog:[NSString stringWithFormat:@"[receive] %@",[AiMouseTools dataToHexString:data]]];\r
-      if([characteristic.UUID.UUIDString isEqualToString:kAuthUUID]){\r
-          //鉴权数据\r
-          [[AiMouse shared] sendAuthDataToSdk:data];\r
-      }\r
-      else if([characteristic.UUID.UUIDString isEqualToString:kAiUUID]){\r
-          //AI数据\r
-          [[AiMouse shared] sendAiDataToSdk:data];\r
-      }\r
-      else if([characteristic.UUID.UUIDString isEqualToString:kDeviceInfoUUID]){\r
-          //设备信息数据\r
-          [[AiMouse shared] sendDeviceDataToSdk:data];\r
-      }\r
-  }\r
-  \r
-  ```\r
-\r
-  sdk代理回调\r
-\r
-  ```objective-c\r
-  /// 鉴权数据回调,需要将此数据转发给蓝牙设备\r
-  /// - Parameter data: 数据\r
-  - (void)aiMouseSendAuthData:(NSData *)data{\r
-      [self showLog:[NSString stringWithFormat:@"[send] %@",[AiMouseTools dataToHexString:data]]];\r
-      [self.connectPeripheral writeValue:data forCharacteristic:self.authCha type:CBCharacteristicWriteWithoutResponse];\r
-  }\r
-  \r
-  \r
-  /// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备\r
-  /// - Parameter data: 数据\r
-  -(void)aiMouseSendDeviceInfoData:(NSData *)data{\r
-      [self showLog:[NSString stringWithFormat:@"[send] %@",[AiMouseTools dataToHexString:data]]];\r
-      [self.connectPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithoutResponse];\r
-  }\r
-  \r
-  /// 鼠标按键指令回调\r
-  /// - Parameter data: 数据。\r
-  /// M 键    短按0x42;长按按下(开始录音)0x25,  长按抬起(结束录音) 0x26;\r
-  /// AI键  短按0x43  ,长按按下(开始录音)0x27,  长按抬起(结束录音) 0x28;\r
-  /// 语音键 按下(开始录音) 0x31,弹起(结束录音)0x32;\r
-  /// 其他未定义\r
-  - (void)aiMouseSendCmdData:(NSData *)data{\r
-      uint8 cmd;\r
-      [data getBytes:&cmd length:1];\r
-      if(cmd == 0x25){\r
-          [self showLog:@"M键开始录音"];\r
-          self.recordData = [[NSMutableData alloc] init];\r
-      }\r
-      else if(cmd == 0x26){\r
-          [self showLog:@"M键结束录音"];\r
-          [self finishRecored:self.recordData];\r
-      }\r
-      else if(cmd == 0x27){\r
-          [self showLog:@"AI键开始录音"];\r
-          self.recordData = [[NSMutableData alloc] init];\r
-      }\r
-      else if(cmd == 0x28){\r
-          [self showLog:@"AI键结束录音"];\r
-          [self finishRecored:self.recordData];\r
-      }\r
-      else if(cmd == 0x31){\r
-          [self showLog:@"语音键开始录音"];\r
-          self.recordData = [[NSMutableData alloc] init];\r
-      }\r
-      else if(cmd == 0x32){\r
-          [self showLog:@"语音键结束录音"];\r
-          [self finishRecored:self.recordData];\r
-      }\r
-      else{\r
-          [self showLog:@"未定义指令!!!!!!!!"];\r
-      }\r
-  }\r
-  /// 录音回调\r
-  /// - Parameter data: pcm格式语音数据\r
-  - (void)aiMouseSendRecordData:(NSData *)data{\r
-      [self.recordData appendData:data];\r
-  }\r
-  ```\r
-\r
-  获取设备信息\r
-\r
-- 获取设备信息\r
-\r
-  ```\r
-      [[AiMouse shared] getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) {\r
-  \r
-      }];\r
-  ```\r
-\r
-  \r
-\r
-- 设置PCI\r
-\r
-  ```\r
-      [[AiMouse shared] setCPI:1000 completation:^(BOOL isSuccess, NSError *error) {\r
-          \r
-      }];\r
-  ```\r
-\r
-  \r
+\r
+\r
+## 蓝牙示例\r
+\r
+```objective-c\r
+       //\r
+//  BleManager.m\r
+//  AliIotSdkDemo\r
+//\r
+//  Created by incar on 2024/1/30.\r
+//\r
+\r
+#import "BleManager.h"\r
+#import <AiMouseSdk/AiMouseSdk.h>\r
+#import "Config.h"\r
+\r
+// 服务id\r
+#define kServiceUUID @"FFF1"\r
+//ai特征\r
+#define kAiUUID @"0783B03E-8535-B5A0-7140-A304D2194CB8"\r
+//鉴权特征\r
+#define kAuthUUID @"0783B73E-8535-B5A0-7140-A304D2194CB7"\r
+//设备信息特征\r
+#define kDeviceInfoUUID @"0783B63E-8535-B5A0-7140-A304D2495CB6"\r
+\r
+@interface BleManager ()<CBCentralManagerDelegate,CBPeripheralDelegate,AiMouseDelegate>\r
+@property(nonatomic, strong) CBCentralManager *centralManager;///蓝牙管理\r
+@property(nonatomic, strong) CBPeripheral *connectPeripheral;//连接的设备\r
+@property(nonatomic, strong) CBCharacteristic *authCha;//鉴权特征\r
+@property(nonatomic, strong) CBCharacteristic *aiCha;//ai特征\r
+@property(nonatomic, strong) CBCharacteristic *deviceInfoCha;//设备信息特征\r
+@property (nonatomic,strong) NSMutableData *recordData;//录音的数据\r
+@end\r
+\r
+@implementation BleManager\r
++(BleManager *)shared{\r
+    static BleManager *manager = nil;\r
+    static dispatch_once_t oncePredicate;\r
+    dispatch_once(&oncePredicate, ^{\r
+        manager = [[BleManager alloc]init];\r
+    });\r
+    return manager;\r
+}\r
+\r
+- (instancetype)init{\r
+    self = [super init];\r
+    if (self) {\r
+        self.centralManager = [[CBCentralManager alloc]initWithDelegate:self queue:nil];\r
+    }\r
+    return self;\r
+}\r
+\r
+#pragma mark - CBCentralManagerDelegate\r
+- (void)centralManagerDidUpdateState:(nonnull CBCentralManager *)central {\r
+    [self showLog:[NSString stringWithFormat:@"蓝牙状态 = %@",@(central.state)]];\r
+    switch (central.state) {\r
+        case CBManagerStateUnknown:\r
+            \r
+            break;\r
+        case CBManagerStateResetting:\r
+            \r
+            break;\r
+        case CBManagerStateUnsupported:\r
+            \r
+            break;\r
+        case CBManagerStateUnauthorized:\r
+            \r
+            break;\r
+        case CBManagerStatePoweredOff:\r
+            \r
+            break;\r
+        case CBManagerStatePoweredOn:\r
+            [self autoConnectDevice];\r
+            break;\r
+    }\r
+}\r
+\r
+- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{\r
+//    [self showLog:[NSString stringWithFormat:@"扫描到设备 = %@, data = %@",peripheral,advertisementData]];\r
+    if(self.discoverDevice){\r
+        self.discoverDevice(peripheral);\r
+    }\r
+}\r
+\r
+- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{\r
+    [self showLog:[NSString stringWithFormat:@"连接成功 name = %@",peripheral.name]];\r
+    if(self.didConnectDevice){\r
+        self.didConnectDevice(peripheral);\r
+    }\r
+    peripheral.delegate = self;\r
+    [peripheral discoverServices:nil];\r
+    \r
+    [[NSNotificationCenter defaultCenter] postNotificationName:kDidConnectBleNotification object:nil];\r
+}\r
+-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{\r
+    [self showLog:[NSString stringWithFormat:@"断开连接。。。%@",error.description]];\r
+    [[NSNotificationCenter defaultCenter] postNotificationName:kDidDisconnectBleNotification object:nil];\r
+    if(self.didDisConnectDevice){\r
+        self.didDisConnectDevice(peripheral);\r
+    }\r
+    [self autoConnectDevice];\r
+}\r
+- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{\r
+    [self showLog:[NSString stringWithFormat:@"连接失败。。。%@",error.description]];\r
+}\r
+#pragma mark - CBPeripheralDelegate\r
+//发现服务\r
+- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {\r
+    for (CBService *service in peripheral.services){\r
+        [peripheral discoverCharacteristics:nil forService:service];\r
+    }\r
+}\r
+\r
+// 发现特征\r
+- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {\r
+    for (CBCharacteristic *characteristic in service.characteristics){\r
+        if ([characteristic.UUID.UUIDString isEqualToString:kAuthUUID]) {\r
+            //鉴权特征\r
+            self.authCha = characteristic;\r
+            [peripheral setNotifyValue:YES forCharacteristic:characteristic];\r
+            //切换代理\r
+            [AiMouse shared].delegate = self;\r
+            //切换当前连接类型\r
+            [[AiMouse shared] switchConnect:AiMouseConnectType_bluetooth];\r
+            //找到鉴权特征后,一定要调用鉴权接口开始鉴权。只有鉴权通过了,sdk相关功能才可以使用\r
+            [[AiMouse shared] startAuthentication:^(AiMouseAuthState state) {\r
+                [self showLog:[NSString stringWithFormat:@"鉴权结果 = %@",@(state)]];\r
+                if(self.authCallBack){\r
+                    self.authCallBack(state == AiMouseAuthState_Success);\r
+                }\r
+            }];\r
+        }\r
+        else if ([characteristic.UUID.UUIDString isEqualToString:kAiUUID]) {\r
+            //AI特征\r
+            self.aiCha = characteristic;\r
+            [peripheral setNotifyValue:YES forCharacteristic:characteristic];\r
+        }\r
+        else if ([characteristic.UUID.UUIDString isEqualToString:kDeviceInfoUUID]) {\r
+            //设备信息特征\r
+            self.deviceInfoCha = characteristic;\r
+            [peripheral setNotifyValue:YES forCharacteristic:characteristic];\r
+        }\r
+    }\r
+}\r
+//收到蓝牙数据\r
+- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {\r
+    NSData *data = characteristic.value;\r
+    [self showLog:[NSString stringWithFormat:@"[receive] %@",[AiMouseTools dataToHexString:data]]];\r
+    if([characteristic.UUID.UUIDString isEqualToString:kAuthUUID]){\r
+        //鉴权数据\r
+        [[AiMouse shared] sendAuthDataToSdk:data];\r
+    }\r
+    else if([characteristic.UUID.UUIDString isEqualToString:kAiUUID]){\r
+        //AI数据\r
+        [[AiMouse shared] sendAiDataToSdk:data];\r
+    }\r
+    else if([characteristic.UUID.UUIDString isEqualToString:kDeviceInfoUUID]){\r
+        //设备信息数据\r
+        [[AiMouse shared] sendDeviceDataToSdk:data];\r
+    }\r
+}\r
+\r
+#pragma mark - AiDelegate\r
+/// 鉴权数据回调,需要将此数据转发给蓝牙设备\r
+/// - Parameter data: 数据\r
+- (void)aiMouseSendAuthData:(NSData *)data{\r
+    [self showLog:[NSString stringWithFormat:@"[send] %@",[AiMouseTools dataToHexString:data]]];\r
+    [self.connectPeripheral writeValue:data forCharacteristic:self.authCha type:CBCharacteristicWriteWithoutResponse];\r
+}\r
+\r
+\r
+/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备\r
+/// - Parameter data: 数据\r
+-(void)aiMouseSendDeviceInfoData:(NSData *)data{\r
+    [self showLog:[NSString stringWithFormat:@"[send] %@",[AiMouseTools dataToHexString:data]]];\r
+    [self.connectPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithoutResponse];\r
+}\r
+\r
+/// 鼠标按键指令回调\r
+/// - Parameter data: 数据。\r
+/// 前  第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音)\r
+/// 中  单击42, 按下25(开始录音)抬起26(结束录音)\r
+/// 后  单击43,按下27(开始录音)抬起28(结束录音)\r
+/// 其他未定义\r
+- (void)aiMouseSendCmdData:(NSData *)data{\r
+    uint8 cmd;\r
+    [data getBytes:&cmd length:1];\r
+    [self showLog:[NSString stringWithFormat:@"收到指令 = %X",cmd]];\r
+    \r
+    if(cmd == 0x31 || cmd == 0x21 || cmd == 0x25 ||cmd == 0x27){\r
+        [self showLog:@"开始录音"];\r
+        self.recordData = [[NSMutableData alloc] init];\r
+    }\r
+    else if(cmd == 0x32 || cmd == 0x22 || cmd == 0x26 ||cmd == 0x28){\r
+        [self showLog:@"结束录音"];\r
+        [self finishRecored:self.recordData];\r
+    }\r
+}\r
+\r
+/// 录音回调\r
+/// - Parameter data: pcm格式语音数据\r
+- (void)aiMouseSendRecordData:(NSData *)data{\r
+    [self.recordData appendData:data];\r
+}\r
+\r
+#pragma mark - public\r
+/// 连接设备\r
+- (void)startScanDevice{\r
+    [self.centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : [NSNumber numberWithBool:NO]}];\r
+}\r
+\r
+/// 扫描设备\r
+- (void)stopScanDevice{\r
+    [self.centralManager stopScan];\r
+}\r
+\r
+/// 连接设备\r
+- (void)connectPeripheral:(CBPeripheral *)peripheral{\r
+    self.connectPeripheral = peripheral;\r
+    [self.centralManager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey : [NSNumber numberWithBool:YES]}];\r
+}\r
+\r
+/// 获取设备信息\r
+- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo * _Nonnull, NSError * _Nonnull))completation{\r
+    [[AiMouse shared] getDeviceInfo:completation];\r
+}\r
+#pragma mark - other\r
+//自动连接,获取已配对的蓝牙,取第一个连接\r
+- (void)autoConnectDevice{\r
+    //如果是已连接或者正在连接,则不再重连\r
+    if (self.connectPeripheral && (self.connectPeripheral.state == CBPeripheralStateConnected || self.connectPeripheral.state == CBPeripheralStateConnecting)) {\r
+        return;\r
+    }\r
+    NSArray<CBPeripheral *> *devices = [self.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]]];\r
+    if (devices.count > 0) {\r
+        CBPeripheral *peripheral = devices[0];\r
+        [self showLog:[NSString stringWithFormat:@"匹配过的设备%@",peripheral.name]];\r
+        [self connectPeripheral:peripheral];\r
+    }\r
+    // 10s自动重连\r
+    [self performSelector:@selector(autoConnectDevice) withObject:nil afterDelay:10];\r
+}\r
+- (void)showLog:(NSString *)log{\r
+    NSLog(@"%@",log);\r
+}\r
+\r
+//将录音数据保存\r
+- (void)finishRecored:(NSData *)data{\r
+    NSString *doc = NSTemporaryDirectory();\r
+    NSString *fullPath = [NSString stringWithFormat:@"%@1.pcm",doc];\r
+    NSError *err;\r
+    [data writeToFile:fullPath options:NSDataWritingAtomic error:&err];\r
+    if (err) {\r
+        [self showLog:[NSString stringWithFormat:@"录音保存失败 %@",err.description]];\r
+    }\r
+    else{\r
+        [self showLog:[NSString stringWithFormat:@"录音保存成功 path = %@",fullPath]];\r
+    }\r
+}\r
+@end\r
+\r
+```\r
+\r
+\r
+\r
+## USB示例\r
+\r
+​    \r
+\r
+```objective-c\r
+//\r
+//  HidManager.m\r
+//  MouseSdk\r
+//\r
+//  Created by incar on 2024/3/26.\r
+//\r
+\r
+#import "HidManager.h"\r
+#include <IOKit/hid/IOHIDLib.h>\r
+#include <IOKit/hid/IOHIDKeys.h>\r
+#import <AiMouseSdk/AiMouseSdk.h>\r
+#import "Config.h"\r
+\r
+//供应商id\r
+const long vendorID = 0x248a;\r
+//产品id\r
+const long productID = 0xca08;\r
+\r
+@interface HidManager ()<AiMouseDelegate>\r
+\r
+@property(nonatomic, assign) IOHIDManagerRef hidManager;///hid管理\r
+@property(nonatomic, assign) IOHIDDeviceRef authCha;//鉴权通道\r
+@property(nonatomic, assign) IOHIDDeviceRef aiCha;//ai通道\r
+@property(nonatomic, assign) IOHIDDeviceRef deviceInfoCha;//设备信息通道\r
+@property (nonatomic,strong) NSMutableData *recordData;//录音的数据\r
+@end\r
+\r
+@implementation HidManager\r
++(HidManager *)shared{\r
+    static HidManager *manager = nil;\r
+    static dispatch_once_t oncePredicate;\r
+    dispatch_once(&oncePredicate, ^{\r
+        manager = [[HidManager alloc]init];\r
+    });\r
+    return manager;\r
+}\r
+\r
+- (instancetype)init{\r
+    self = [super init];\r
+    if (self) {\r
+        [self initHid];\r
+        [self open];\r
+    }\r
+    return self;\r
+}\r
+\r
+- (void)initHid{\r
+\r
+}\r
+\r
+- (void)open{\r
+    self.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);\r
+    IOHIDManagerScheduleWithRunLoop(self.hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);\r
+    IOReturn ret = IOHIDManagerOpen(self.hidManager, 0L);\r
+    if (ret != kIOReturnSuccess) {\r
+        NSLog(@"打开设备失败!");\r
+    }else{\r
+        NSLog(@"打开设备成功!");\r
+    }\r
+    //设置匹配设备\r
+    NSMutableDictionary* dict= [NSMutableDictionary dictionary];\r
+    [dict setValue:[NSNumber numberWithLong:productID] forKey:[NSString stringWithCString:kIOHIDProductIDKey encoding:NSUTF8StringEncoding]];\r
+    [dict setValue:[NSNumber numberWithLong:vendorID] forKey:[NSString stringWithCString:kIOHIDVendorIDKey encoding:NSUTF8StringEncoding]];\r
+    IOHIDManagerSetDeviceMatching(self.hidManager, (__bridge CFMutableDictionaryRef)dict);\r
+    //设置匹配到设备回调\r
+    IOHIDManagerRegisterDeviceMatchingCallback(self.hidManager, &hidAppearDevice, NULL);\r
+    //设置移除设备回调\r
+    IOHIDManagerRegisterDeviceRemovalCallback(self.hidManager, &hidDisAppearDevice, NULL);\r
+}\r
+\r
+- (void)close{\r
+    IOReturn ret = IOHIDManagerClose(self.hidManager, 0);\r
+    if (ret != kIOReturnSuccess) {\r
+        NSLog(@"关闭设备失败!");\r
+    }else{\r
+        NSLog(@"关闭设备成功!");\r
+    }\r
+}\r
+\r
+#pragma mark - Hid CallBack\r
+/// 匹配到设备回调\r
+static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) {\r
+    uint32_t vid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey));\r
+    uint32_t pid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey));\r
+    uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey));\r
+    uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey));\r
+    NSLog(@"vid = %u, pid = %u, PrimaryUsagePage = %u, PrimaryUsage = %u,",vid,pid,PrimaryUsagePage,PrimaryUsage);\r
+    NSLog(@"发现设备 %@\n ",inIOHIDDeviceRef);\r
+    \r
+    //    PrimaryUsagePage=1 PrimaryUsage=0,设备信息\r
+    //    PrimaryUsagePage=1 PrimaryUsage=6,鉴权\r
+    //    PrimaryUsagePage=65283 PrimaryUsage=0,ai\r
+    if(PrimaryUsagePage == 1 && PrimaryUsage == 0){\r
+        //设备信息\r
+        [HidManager shared].deviceInfoCha = inIOHIDDeviceRef;\r
+        //鉴权\r
+        [HidManager shared].authCha = inIOHIDDeviceRef;\r
+        //开始鉴权\r
+        [[HidManager shared] startAuthentication];\r
+    }\r
+    else if(PrimaryUsagePage == 65283 && PrimaryUsage == 0){\r
+        //ai\r
+        [HidManager shared].aiCha = inIOHIDDeviceRef;\r
+    }\r
+    //注册消息回调\r
+    unsigned char InputBuffer[128];\r
+    IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL);\r
+}\r
+\r
+/// 设备移除回调\r
+static void hidDisAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) {\r
+    NSLog(@"拔出设备 %@ ",inIOHIDDeviceRef);\r
+    uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey));\r
+    uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey));\r
+\r
+    if(PrimaryUsagePage == 1 && PrimaryUsage == 0){\r
+        [HidManager shared].connectStateCallBack(false);\r
+    }\r
+}\r
+\r
+static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report,CFIndex reportLength){\r
+    \r
+    [[HidManager shared] showLog:[NSString stringWithFormat:@"[receive] 处理前 %@",[AiMouseTools dataToHexString:[[NSData alloc] initWithBytes:report length:reportLength]]]];\r
+    \r
+    NSInteger len = get_data_len(report, reportLength);\r
+    NSData *data = [[NSData alloc] initWithBytes:report length:len];\r
+    [[HidManager shared] showLog:[NSString stringWithFormat:@"[receive] 处理后 %@",[AiMouseTools dataToHexString:data]]];\r
+    \r
+    uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsagePageKey));\r
+    uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsageKey));\r
+\r
+    if(PrimaryUsagePage == 1 && PrimaryUsage == 0){\r
+        [[HidManager shared] showLog:@"device数据"];\r
+        [[AiMouse shared] sendDeviceDataToSdk:data];\r
+    }\r
+    else if(PrimaryUsagePage == 65283 && PrimaryUsage == 0){\r
+        [[HidManager shared] showLog:@"AI数据"];\r
+        [[AiMouse shared] sendAiDataToSdk:data];\r
+    }\r
+}\r
+#pragma mark - AiDelegate\r
+/// 鉴权数据回调,需要将此数据转发给蓝牙设备\r
+/// - Parameter data: 数据\r
+- (void)aiMouseSendAuthData:(NSData *)data{\r
+    [self sendData:data toDevice:self.authCha];\r
+}\r
+\r
+/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备\r
+/// - Parameter data: 数据\r
+-(void)aiMouseSendDeviceInfoData:(NSData *)data{\r
+    [self sendData:data toDevice:self.deviceInfoCha];\r
+}\r
+\r
+/// 鼠标按键指令回调\r
+/// - Parameter data: 数据。\r
+/// 前  第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音)\r
+/// 中  单击42, 按下25(开始录音)抬起26(结束录音)\r
+/// 后  单击43,按下27(开始录音)抬起28(结束录音)\r
+/// 其他未定义\r
+- (void)aiMouseSendCmdData:(NSData *)data{\r
+    uint8 cmd;\r
+    [data getBytes:&cmd length:1];\r
+    [self showLog:[NSString stringWithFormat:@"收到指令 = %X",cmd]];\r
+    \r
+    if(cmd == 0x31 || cmd == 0x21 || cmd == 0x25 ||cmd == 0x27){\r
+        [self showLog:@"开始录音"];\r
+        self.recordData = [[NSMutableData alloc] init];\r
+    }\r
+    else if(cmd == 0x32 || cmd == 0x22 || cmd == 0x26 ||cmd == 0x28){\r
+        [self showLog:@"结束录音"];\r
+        [self finishRecored:self.recordData];\r
+    }\r
+}\r
+/// 录音回调\r
+/// - Parameter data: pcm格式语音数据\r
+- (void)aiMouseSendRecordData:(NSData *)data{\r
+    [self.recordData appendData:data];\r
+}\r
+\r
+#pragma mark - public\r
+-(void)startAuthentication{\r
+    //连上设备\r
+    [HidManager shared].connectStateCallBack(true);\r
+    //设置代理\r
+    [AiMouse shared].delegate = self;\r
+    //切换当前连接类型\r
+    [[AiMouse shared] switchConnect:AiMouseConnectType_hid];\r
+    //找到鉴权特征后,一定要调用鉴权接口开始鉴权。只有鉴权通过了,sdk相关功能才可以使用\r
+    [self showLog:@"开始鉴权"];\r
+    [[AiMouse shared] startAuthentication:^(AiMouseAuthState state) {\r
+        [self showLog:[NSString stringWithFormat:@"鉴权结果 = %@",@(state)]];\r
+        if(self.authCallBack){\r
+            self.authCallBack(state == AiMouseAuthState_Success);\r
+        }\r
+    }];\r
+}\r
+/// 获取设备信息\r
+- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo * _Nonnull, NSError * _Nonnull))completation{\r
+    [[AiMouse shared] getDeviceInfo:completation];\r
+}\r
+\r
+/// 发送数据给设备\r
+-(void)sendData:(NSData *)data toDevice:(IOHIDDeviceRef)device{\r
+    if(device == nil){\r
+        [self showLog:@"请先连上设备"];\r
+        return;\r
+    }\r
+    [self showLog:[NSString stringWithFormat:@"开始发送[send] %@\n%@",[AiMouseTools dataToHexString:data],[AiMouseTools dataToUtf8String:data]]];\r
+    \r
+    IOReturn ret = IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, 0, data.bytes, data.length);\r
+    if (ret != kIOReturnSuccess) {\r
+        [self showLog:[NSString stringWithFormat:@"发送失败! code = %d",ret]];\r
+    }else{\r
+        [self showLog:@"发送成功!"];\r
+    }\r
+}\r
+//将录音数据保存\r
+- (void)finishRecored:(NSData *)data{\r
+    NSString *doc = NSTemporaryDirectory();\r
+    NSString *fullPath = [NSString stringWithFormat:@"%@1.pcm",doc];\r
+    NSError *err;\r
+    [data writeToFile:fullPath options:NSDataWritingAtomic error:&err];\r
+    if (err) {\r
+        [self showLog:[NSString stringWithFormat:@"录音保存失败 %@",err.description]];\r
+    }\r
+    else{\r
+        [self showLog:[NSString stringWithFormat:@"录音保存成功 path = %@",fullPath]];\r
+    }\r
+}\r
+- (void)showLog:(NSString *)log{\r
+    NSLog(@"%@",log);\r
+}\r
+\r
+/// 实际到数据长度\r
+static inline int get_data_len(uint8_t *buf, u_long len) {\r
+    if (len <= 0 ) return 0;\r
+    int url_len = 0;\r
+    while (buf[url_len] != 0x00) url_len++;\r
+    return url_len;\r
+}\r
+\r
+/// 获取对应属性值\r
+static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey) {\r
+    uint32_t outValue = 0;\r
+    if (inIOHIDDeviceRef != NULL) {\r
+        CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, inKey);\r
+        if (tCFTypeRef != NULL && (CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef))  ) {\r
+            Boolean result = CFNumberGetValue((CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, &outValue);\r
+            if (!result) {\r
+                NSLog(@"get %@ failed.", inKey);\r
+            }\r
+        }\r
+    }\r
+    return outValue;\r
+}\r
+@end\r
+\r
+```\r
 \r
 \r
 \r
 ## 注意事项\r
 \r
-- 鉴权数据使用的是鉴权特征,走鉴权接口;设备信息数据使用的是设备信息特征,走设备信息接口;AI数据使用的是AI特征,走AI接口。\r
-- 只有鉴权成功了以后,AI相关功能才可用。authState鉴权状态,默认是Unknow。所以必须在连上蓝牙设备找到鉴权特征后,需要主动调用startAuthentication方法去鉴权。(只有鉴权成功,AI键,语音键、M键才可用)\r
+- 鉴权数据使用的是鉴权,走鉴权接口;设备信息数据使用的是设备信息通道,走设备信息接口;AI数据使用的是AI通道,走AI接口。\r
+- 只有鉴权成功了以后,AI相关功能才可用。authState鉴权状态,默认是Unknow。所以必须在连上蓝牙设备找到鉴权特征后,需要主动调用startAuthentication方法去鉴权。(只有鉴权成功,AI功能才可用)\r
 - SDK只封装了蓝牙相关数据处理,APP自己维护蓝牙设备的扫描连接。蓝牙设备一段时间没有任何操作的话,会自动断开连接。APP可以在检测到断开后重连。\r
+- 当切换蓝牙或者USB,需要调用switchConnect切换连接类型。\r
 \r
index 64b4276..0a9b99a 100644 (file)
@@ -24,7 +24,7 @@
         _bizbusManager.bleSendDataDelegate = self;
         _bizbusManager.appVersion = @"--";
         _bizbus_connect_queue = dispatch_queue_create("bizbus_connect_queue", DISPATCH_QUEUE_SERIAL);
-        [self enableBizbusLog:true];
+        [self enableBizbusLog:false];
     }
     return self;
 }
index 056c7f8..db7dd64 100644 (file)
@@ -7,6 +7,7 @@
 
 #import "AiFrameManager.h"
 #import "AiMouseTools.h"
+#import "AiMouseConfig.h"
 @interface AiFrameManager()
 
 @property (nonatomic,strong)NSMutableData *recvData;
 
 @implementation AiFrameManager
 - (void)didReceiveFrameData:(NSData *)data{
-    NSString *str = [AiMouseTools dataToUtf8String:data];
-    if ([str isEqualTo:@"-$$"]) {
+    NSString *str = [[AiMouseTools dataToHexString:data] uppercaseString];
+    [self showLog:[NSString stringWithFormat:@"分段 = %@ 内容 = %@",str,[AiMouseTools dataToUtf8String:data]]];
+    if ([str hasPrefix:@"2D242400"]) {
         //开始
         self.recvData = [[NSMutableData alloc] init];
     }
-    else if([str isEqualTo:@"$$-\n"]){
+    else if([str hasSuffix:@"24242D0A00"]){
         NSString *str1 = [AiMouseTools dataToHexString:self.recvData];
-        NSLog(@"收到完整数据 = %@",str1);
+        [self showLog:[NSString stringWithFormat:@"完整数据 = %@",str1]];
         //结束
         if(self.didReceiveFullData){
             self.didReceiveFullData(self.recvData);
     }
     else{
         //数据
-        [self.recvData appendData:data];
+        NSData *subData;
+        if([str hasSuffix:@"00"]){
+            subData = [data subdataWithRange:NSMakeRange(0, data.length - 1)];
+        }
+        else{
+            subData = data;
+        }
+        [self showLog:[NSString stringWithFormat:@"拼接数据 = %@",[AiMouseTools dataToHexString:subData]]];
+        [self.recvData appendData:subData];
     }
 }
 
 - (void)didReceiveHidAuthData:(NSData *)data{
-    NSString *str = [AiMouseTools dataToHexString:data];
-    NSLog(@"收到数据 = %@",str);
+    NSString *str = [[AiMouseTools dataToHexString:data] uppercaseString];
+    [self showLog:[NSString stringWithFormat:@"分段 = %@ 内容 = %@",str,[AiMouseTools dataToUtf8String:data]]];
     if ([str hasPrefix:@"2D2424"]) {
+        self.recvData = [[NSMutableData alloc] init];
         //开始
-        NSData *subData = [data subdataWithRange:NSMakeRange(3, data.length - 4)];
-        NSString *str1 = [AiMouseTools dataToHexString:subData];
-        NSLog(@"实收数据 = %@",str1);
-        self.recvData = [[NSMutableData alloc] initWithData:subData];
+        NSData *subData = [data subdataWithRange:NSMakeRange(3, data.length - 3)];
+        if(subData.length > 0){
+            [self showLog:[NSString stringWithFormat:@"拼接数据 = %@",[AiMouseTools dataToHexString:subData]]];
+            [self.recvData appendData:subData];
+        }
+        
     }
     else if([str hasSuffix:@"24242D0A"]){
-        NSData *subData = [data subdataWithRange:NSMakeRange(0, data.length - 5)];
-        NSString *str1 = [AiMouseTools dataToHexString:subData];
-        NSLog(@"实收数据 = %@",str1);
-        [self.recvData appendData:subData];
-        NSString *all = [AiMouseTools dataToUtf8String:self.recvData];
-        NSLog(@"完整数据 %@\n %@",[AiMouseTools dataToHexString:self.recvData],all);
+        NSData *subData = [data subdataWithRange:NSMakeRange(0, data.length - 4)];
+        if(subData.length > 0){
+            [self showLog:[NSString stringWithFormat:@"拼接数据 = %@",[AiMouseTools dataToHexString:subData]]];
+            [self.recvData appendData:subData];
+        }
+        NSString *str1 = [AiMouseTools dataToHexString:self.recvData];
+        [self showLog:[NSString stringWithFormat:@"完整数据 = %@",str1]];
         //结束
         if(self.didReceiveFullData){
             self.didReceiveFullData(self.recvData);
     }
     else{
         //数据
-        NSData *subData = [data subdataWithRange:NSMakeRange(0, data.length - 1)];
-        NSString *str1 = [AiMouseTools dataToHexString:subData];
-        NSLog(@"实收数据 = %@",str1);
-        [self.recvData appendData:data];
+        NSData *subData;
+        if([str hasSuffix:@"00"]){
+            subData = [data subdataWithRange:NSMakeRange(0, data.length - 1)];
+        }
+        else{
+            subData = data;
+        }
+        [self showLog:[NSString stringWithFormat:@"拼接数据 = %@",[AiMouseTools dataToHexString:subData]]];
+        [self.recvData appendData:subData];
     }
 }
+
+- (void)showLog:(NSString *)log{
+    NSLog(@"%@",log);
+}
 @end
index a5e4b9b..c8f174b 100644 (file)
@@ -47,7 +47,7 @@ typedef NS_ENUM(NSInteger,AiMouseAuthState) {
 @property (nonatomic, readonly) NSString *version;/// 版本号
 @property (nonatomic, weak) id<AiMouseDelegate> delegate;/// 代理
 @property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型
-@property (nonatomic, readonly) AiMouseAuthState authState;/// 鉴权状态,默认是Unknow。所以必须在连上蓝牙设备找到鉴权特征后,需要主动调用startAuthentication方法去鉴权。(只有鉴权成功,AI键,语音键、M键才可用)
+@property (nonatomic, readonly) AiMouseAuthState authState;/// 鉴权状态,默认是Unknow。所以必须在连上蓝牙设备找到鉴权特征后,需要主动调用startAuthentication方法去鉴权。(只有鉴权成功,AI功能才可用)
 
 /// 单利
 +(AiMouse *)shared;
index 9a3f06b..0a98cb6 100644 (file)
@@ -47,7 +47,7 @@
 }
 
 -(NSString *)version{
-    return @"1.0.3";
+    return @"1.0.4";
 }
 -(AiFrameManager *)frameManager{
     if (!_frameManager) {
     }
 }
 - (void)sendDeviceInfoData:(NSData *)data{
+    NSString *str = [AiMouseTools dataToUtf8String:data];
+    NSMutableString *str1 = [NSMutableString stringWithString:str];
+    NSString *sendStr = [NSString stringWithFormat:@"-$$%@$$-\n",str1];
+    NSData *sendData = [sendStr dataUsingEncoding:NSUTF8StringEncoding];
+    [self showLog:[NSString stringWithFormat:@"发送的设备信息数据 = %@",sendStr]];
     if (self.delegate) {
-        [self.delegate aiMouseSendDeviceInfoData:data];
+        [self.delegate aiMouseSendDeviceInfoData:sendData];
     }
 }
 
index 5a6b216..b0c9e5f 100644 (file)
 }
 
 - (void)openSettings{
-    NSURL *url = [NSURL URLWithString:@""];
+//    NSURL *url = [NSURL URLWithString:@""];
 }
 
 - (void)showLog:(NSString *)log{
index ad8f245..d652003 100755 (executable)
@@ -161,6 +161,7 @@ class IotMqttManager_C: NSObject, SdkMqttService_C {
         }\r
         \r
         let legacyConfig = IotMqttLegacyConfig_C.init(productKey: config.productKey, deviceName: config.deviceName, password: config.password, timestamp: config.timestamp)\r
+//        print("开始请求: clientId =\(legacyConfig.clientId) userName = \(legacyConfig.username) passWord = \(legacyConfig.password) url = \(config.server) port = \(config.port)")\r
         \r
         let initSdk:() -> () = { [self] in\r
             let result = mqttShared.mqttLegacyInit(legacyConfig.clientId, userName: legacyConfig.username, passWord: legacyConfig.password, hostUrl: config.server, port: config.port)\r
index 2dc25fc..05904bf 100644 (file)
                18BF1E892B8362D300B8D90F /* AiMouseSdk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiMouseSdk.h; sourceTree = "<group>"; };
                18BF8F4C2BA9A7A4008F6933 /* AiMouseDeviceInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiMouseDeviceInfo.h; sourceTree = "<group>"; };
                18BF8F4D2BA9A7A4008F6933 /* AiMouseDeviceInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiMouseDeviceInfo.m; sourceTree = "<group>"; };
+               18C31D6F2BBAA6CC0089D656 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
                18CB080B2BA401D0005F5854 /* liblzma.5.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = liblzma.5.tbd; path = usr/lib/liblzma.5.tbd; sourceTree = SDKROOT; };
                18CB08102BA40282005F5854 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
                18CB08112BA40282005F5854 /* buffersrc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffersrc.h; sourceTree = "<group>"; };
                18BF1DCC2B81AB7C00B8D90F /* MouseSdk */ = {
                        isa = PBXGroup;
                        children = (
+                               18C31D6F2BBAA6CC0089D656 /* Info.plist */,
                                18BF1E202B83066200B8D90F /* BleManager.h */,
                                18BF1E212B83066200B8D90F /* BleManager.m */,
                                1867E5A72BB2706F008FC5FB /* HidManager.h */,
                                        "$(PROJECT_DIR)/framework",
                                );
                                GENERATE_INFOPLIST_FILE = YES;
-                               INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "要打开蓝牙才能继续使用APP哦";
+                               INFOPLIST_FILE = MouseSdk/Info.plist;
+                               INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "要打开蓝牙才能使用AI功能哦";
                                INFOPLIST_KEY_NSHumanReadableCopyright = "";
                                INFOPLIST_KEY_NSMainStoryboardFile = Main;
-                               INFOPLIST_KEY_NSMicrophoneUsageDescription = "要打开麦克风才能继续使用APP哦";
+                               INFOPLIST_KEY_NSMicrophoneUsageDescription = "要打开麦克风才能使用AI功能哦";
                                INFOPLIST_KEY_NSPrincipalClass = NSApplication;
                                LD_RUNPATH_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/framework",
                                );
                                GENERATE_INFOPLIST_FILE = YES;
-                               INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "要打开蓝牙才能继续使用APP哦";
+                               INFOPLIST_FILE = MouseSdk/Info.plist;
+                               INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "要打开蓝牙才能使用AI功能哦";
                                INFOPLIST_KEY_NSHumanReadableCopyright = "";
                                INFOPLIST_KEY_NSMainStoryboardFile = Main;
-                               INFOPLIST_KEY_NSMicrophoneUsageDescription = "要打开麦克风才能继续使用APP哦";
+                               INFOPLIST_KEY_NSMicrophoneUsageDescription = "要打开麦克风才能使用AI功能哦";
                                INFOPLIST_KEY_NSPrincipalClass = NSApplication;
                                LD_RUNPATH_SEARCH_PATHS = (
                                        "$(inherited)",
index 1b585d5..ae341d2 100644 (file)
Binary files a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate and b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate differ
index 8cf9284..b9bdb28 100644 (file)
             stopOnStyle = "0">
          </BreakpointContent>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "049FE207-4E22-4DF6-9ABE-D8D05DE11A83"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "AliIotConnectKitSDK/AliIotConnectKit/Mqtt/IotMqtt/IotMqttManager_C.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "166"
+            endingLineNumber = "166"
+            landmarkName = "startQulianConnect()"
+            landmarkType = "7">
+            <Locations>
+               <Location
+                  uuid = "049FE207-4E22-4DF6-9ABE-D8D05DE11A83 - f59a5d25c341706d"
+                  shouldBeEnabled = "Yes"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "AliIotConnectKit.IotMqttManager_C.startQulianConnect() throws -&gt; ()"
+                  moduleName = "AliIotConnectKit"
+                  usesParentBreakpointCondition = "Yes"
+                  urlString = "file:///Users/apple/Desktop/code/MouseSdk-iOS/MouseSdk/AliIotConnectKitSDK/AliIotConnectKit/Mqtt/IotMqtt/IotMqttManager_C.swift"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "166"
+                  endingLineNumber = "166"
+                  offsetFromSymbolStart = "2048">
+               </Location>
+               <Location
+                  uuid = "049FE207-4E22-4DF6-9ABE-D8D05DE11A83 - 8550d5cd9362e6d1"
+                  shouldBeEnabled = "Yes"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "closure #1 () -&gt; () in AliIotConnectKit.IotMqttManager_C.startQulianConnect() throws -&gt; ()"
+                  moduleName = "AliIotConnectKit"
+                  usesParentBreakpointCondition = "Yes"
+                  urlString = "file:///Users/apple/Desktop/code/MouseSdk-iOS/MouseSdk/AliIotConnectKitSDK/AliIotConnectKit/Mqtt/IotMqtt/IotMqttManager_C.swift"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "166"
+                  endingLineNumber = "166"
+                  offsetFromSymbolStart = "127">
+               </Location>
+               <Location
+                  uuid = "049FE207-4E22-4DF6-9ABE-D8D05DE11A83 - f59a5d25c341706d"
+                  shouldBeEnabled = "Yes"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "AliIotConnectKit.IotMqttManager_C.startQulianConnect() throws -&gt; ()"
+                  moduleName = "AliIotConnectKit"
+                  usesParentBreakpointCondition = "Yes"
+                  urlString = "file:///Users/apple/Desktop/code/MouseSdk-iOS/MouseSdk/AliIotConnectKitSDK/AliIotConnectKit/Mqtt/IotMqtt/IotMqttManager_C.swift"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "166"
+                  endingLineNumber = "166"
+                  offsetFromSymbolStart = "2590">
+               </Location>
+            </Locations>
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
 </Bucket>
index c1e4e62..147e693 100644 (file)
@@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
 - (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))completation;
 
 
+/// 鉴权
 -(void)startAuthentication;
 @end
 
index 838d5d1..c164014 100644 (file)
@@ -8,16 +8,20 @@
 #import "HidManager.h"
 #include <IOKit/hid/IOHIDLib.h>
 #include <IOKit/hid/IOHIDKeys.h>
-
 #import <AiMouseSdk/AiMouseSdk.h>
 #import "Config.h"
 
+//供应商id
+const long vendorID = 0x248a;
+//产品id
+const long productID = 0xca08;
+
 @interface HidManager ()<AiMouseDelegate>
 
 @property(nonatomic, assign) IOHIDManagerRef hidManager;///hid管理
-@property(nonatomic, assign) IOHIDDeviceRef authCha;//鉴权特征
-@property(nonatomic, assign) IOHIDDeviceRef aiCha;//ai特征
-@property(nonatomic, assign) IOHIDDeviceRef deviceInfoCha;//设备信息特征
+@property(nonatomic, assign) IOHIDDeviceRef authCha;//鉴权通道
+@property(nonatomic, assign) IOHIDDeviceRef aiCha;//ai通道
+@property(nonatomic, assign) IOHIDDeviceRef deviceInfoCha;//设备信息通道
 @property (nonatomic,strong) NSMutableData *recordData;//录音的数据
 @end
 
     }else{
         NSLog(@"打开设备成功!");
     }
-    
-    const long vendorID = 0x248a;
-    const long productID = 0xca08;
+    //设置匹配设备
     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);
 }
 
@@ -75,6 +78,7 @@
 }
 
 #pragma mark - Hid CallBack
+/// 匹配到设备回调
 static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) {
     uint32_t vid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey));
     uint32_t pid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey));
@@ -91,22 +95,19 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH
         [HidManager shared].deviceInfoCha = inIOHIDDeviceRef;
         //鉴权
         [HidManager shared].authCha = inIOHIDDeviceRef;
+        //开始鉴权
         [[HidManager shared] startAuthentication];
     }
-    else if(PrimaryUsagePage == 1 && PrimaryUsage == 6){
-//        //鉴权
-//        [HidManager shared].authCha = inIOHIDDeviceRef;
-//        [[HidManager shared] startAuthentication];
-    }
     else if(PrimaryUsagePage == 65283 && PrimaryUsage == 0){
         //ai
         [HidManager shared].aiCha = inIOHIDDeviceRef;
     }
-    
+    //注册消息回调
     unsigned char InputBuffer[128];
     IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL);
 }
 
+/// 设备移除回调
 static void hidDisAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) {
     NSLog(@"拔出设备 %@ ",inIOHIDDeviceRef);
     uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey));
@@ -118,9 +119,12 @@ static void hidDisAppearDevice(void *inContext,IOReturn inResult,void *inSender,
 }
 
 static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report,CFIndex reportLength){
+    
+    [[HidManager shared] showLog:[NSString stringWithFormat:@"[receive] 处理前 %@",[AiMouseTools dataToHexString:[[NSData alloc] initWithBytes:report length:reportLength]]]];
+    
     NSInteger len = get_data_len(report, reportLength);
     NSData *data = [[NSData alloc] initWithBytes:report length:len];
-    [[HidManager shared] showLog:[NSString stringWithFormat:@"[receive]  = %@",[AiMouseTools dataToHexString:data]]];
+    [[HidManager shared] showLog:[NSString stringWithFormat:@"[receive] 处理后 %@",[AiMouseTools dataToHexString:data]]];
     
     uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsagePageKey));
     uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsageKey));
@@ -134,21 +138,6 @@ static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDRe
         [[AiMouse shared] sendAiDataToSdk:data];
     }
 }
-
-static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey) {
-    uint32_t outValue = 0;
-    if (inIOHIDDeviceRef != NULL) {
-        CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, inKey);
-        if (tCFTypeRef != NULL && (CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef))  ) {
-            Boolean result = CFNumberGetValue((CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, &outValue);
-            if (!result) {
-                NSLog(@"get %@ failed.", inKey);
-            }
-        }
-    }
-    
-    return outValue;
-}
 #pragma mark - AiDelegate
 /// 鉴权数据回调,需要将此数据转发给蓝牙设备
 /// - Parameter data: 数据
@@ -156,7 +145,6 @@ static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStr
     [self sendData:data toDevice:self.authCha];
 }
 
-
 /// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备
 /// - Parameter data: 数据
 -(void)aiMouseSendDeviceInfoData:(NSData *)data{
@@ -191,7 +179,9 @@ static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStr
 
 #pragma mark - public
 -(void)startAuthentication{
+    //连上设备
     [HidManager shared].connectStateCallBack(true);
+    //设置代理
     [AiMouse shared].delegate = self;
     //切换当前连接类型
     [[AiMouse shared] switchConnect:AiMouseConnectType_hid];
@@ -209,6 +199,7 @@ static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStr
     [[AiMouse shared] getDeviceInfo:completation];
 }
 
+/// 发送数据给设备
 -(void)sendData:(NSData *)data toDevice:(IOHIDDeviceRef)device{
     if(device == nil){
         [self showLog:@"请先连上设备"];
@@ -240,6 +231,7 @@ static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStr
     NSLog(@"%@",log);
 }
 
+/// 实际到数据长度
 static inline int get_data_len(uint8_t *buf, u_long len) {
     if (len <= 0 ) return 0;
     int url_len = 0;
@@ -247,4 +239,18 @@ static inline int get_data_len(uint8_t *buf, u_long len) {
     return url_len;
 }
 
+/// 获取对应属性值
+static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey) {
+    uint32_t outValue = 0;
+    if (inIOHIDDeviceRef != NULL) {
+        CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, inKey);
+        if (tCFTypeRef != NULL && (CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef))  ) {
+            Boolean result = CFNumberGetValue((CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, &outValue);
+            if (!result) {
+                NSLog(@"get %@ failed.", inKey);
+            }
+        }
+    }
+    return outValue;
+}
 @end
diff --git a/MouseSdk/MouseSdk/Info.plist b/MouseSdk/MouseSdk/Info.plist
new file mode 100644 (file)
index 0000000..0c67376
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict/>
+</plist>