\r
\r
\r
-## 文档修改记录\r
+## 介绍\r
\r
-| 版本 | 修改内容 | 修改人 | 修改时间 |\r
-| ------ | --------------------------------------------------- | ------ | ---------- |\r
-| 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 | 按键指令修改 | 梁振营 | 2024-03-20 |\r
-| 1.0.4 | 支持USB通讯 | 梁振营 | 2024-04-01 |\r
-| 1.0.5 | 支持静态库.a | 梁振营 | 2024-04-22 |\r
-| 1.0.6 | 增加鉴权 | 梁振营 | 2024-04-30 |\r
-| 1.0.13 | 鉴权流程优化 | 梁振营 | 2024-05-20 |\r
-| 1.0.17 | 增加命令控制录音功能 | 梁振营 | 2024-05-28 |\r
-| 1.0.19 | 新增连接状态回调 | 梁振营 | 2024-05-29 |\r
-| 1.0.21 | 鉴权逻辑优化,隐藏鉴权接口 | 梁振营 | 2024-05-31 |\r
-| 1.0.21 | 新增设置品牌接口、USB数据异常接口回调 | 梁振营 | 2024-06-06 |\r
+当前版本:v1.0.31\r
\r
+更新内容20240816:\r
\r
+1. 支持阿里鉴权\r
+\r
+## 环境要求\r
+\r
+MacOS 13.0\r
\r
\r
\r
## SDK相关接口\r
\r
```objective-c\r
-\r
/// 单利\r
+(AiMouse *)shared;\r
\r
\r
```\r
\r
+## 其他类型数据\r
+\r
+```objective-c\r
+\r
+@interface AiMouseDeviceInfo : NSObject\r
+@property (nonatomic, strong) NSString *battery_power;/// 电池百分百电量,0-100\r
+@property (nonatomic, strong) NSString *CPI;/// CPI值\r
+@property (nonatomic, strong) NSString *CPI_list;/// 可设置的CPI参数列表\r
+@property (nonatomic, strong) NSString *version;///软件版本\r
+@property (nonatomic, strong) NSString *brand;/// 品牌名称\r
+@property (nonatomic, strong) NSString *sn;/// 设备序列号\r
+@property (nonatomic, strong) NSString *mac;///设备MAC地址\r
+@end\r
+\r
+typedef NS_ENUM(NSInteger,AiMouseErrorCode) {\r
+ AiMouseErrorCode_timeOut = 1001,///请求超时\r
+ AiMouseErrorCode_busy = 1002,/// 繁忙,有命令未执行完\r
+ AiMouseErrorCode_unknown = 1003,/// 未知错误\r
+};\r
+\r
+/// 日志等级\r
+typedef NS_ENUM(NSInteger,AiMouseLogLevel) {\r
+ AiMouseLogLevel_none = 0,\r
+ AiMouseLogLevel_error,\r
+ AiMouseLogLevel_info,\r
+};\r
+\r
+typedef NS_ENUM(NSInteger,AiMouseConnectType) {\r
+ AiMouseConnectType_bluetooth = 0,///蓝牙\r
+ AiMouseConnectType_hid,///hid\r
+};\r
+\r
+typedef NS_ENUM(NSInteger,AiMouseAuthState) {\r
+ AiMouseAuthState_Unknow = 0,///未知\r
+ AiMouseAuthState_Success,///鉴权成功\r
+ AiMouseAuthState_Failure///鉴权失败\r
+};\r
+\r
+```\r
+\r
\r
\r
## 蓝牙示例\r
if(self.didDisConnectDevice){\r
self.didDisConnectDevice(peripheral);\r
}\r
- [self autoConnectDevice];\r
+// [self aiMouseConnectStateDidChange:false];\r
+ [[AiMouse shared] didDisconnect];\r
}\r
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{\r
[self showLog:[NSString stringWithFormat:@"连接失败。。。%@",error.description]];\r
[AiMouse shared].delegate = self;\r
//切换当前连接类型\r
[[AiMouse shared] switchConnect:AiMouseConnectType_bluetooth];\r
- //找到鉴权特征后,一定要调用鉴权接口开始鉴权。只有鉴权通过了,sdk相关功能才可以使用\r
- [self startAuthentication];\r
+\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] %@",data]];\r
if([characteristic.UUID.UUIDString isEqualToString:kAiUUID]){\r
//AI数据\r
[[AiMouse shared] sendAiDataToSdk:data];\r
}\r
\r
#pragma mark - AiDelegate\r
-\r
+/// 设备鉴权结果返回\r
+/// - Parameter authState: 鉴权状态\r
+-(void)aiMouseAuthenticationResult:(AiMouseAuthState)authState{\r
+ [self showLog:[NSString stringWithFormat:@"鉴权结果 = %@",@(authState)]];\r
+ if(self.authCallBack){\r
+ self.authCallBack(authState == AiMouseAuthState_Success);\r
+ }\r
+}\r
/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备\r
/// - Parameter data: 数据\r
-(void)aiMouseSendDeviceInfoData:(NSData *)data{\r
- [self showLog:[NSString stringWithFormat:@"[send] %@",data]];\r
+// [self showLog:[NSString stringWithFormat:@"[send] %@",data]];\r
[self.connectPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithoutResponse];\r
}\r
\r
- (void)aiMouseSendRecordData:(NSData *)data{\r
[self.recordData appendData:data];\r
}\r
+/// 输出日志\r
+- (void)aiMouseAddLog:(NSString *)log { \r
+// [self showLog:log];\r
+}\r
\r
+// 连接状态改变\r
+- (void)aiMouseConnectStateDidChange:(BOOL)connected{\r
+ if (connected) {\r
+ [[NSNotificationCenter defaultCenter] postNotificationName:kDidConnectBleNotification object:nil];\r
+ }\r
+ else{\r
+ [[NSNotificationCenter defaultCenter] postNotificationName:kDidDisconnectBleNotification object:nil];\r
+ }\r
+}\r
#pragma mark - public\r
/// 连接设备\r
- (void)startScanDevice{\r
- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo * _Nonnull, NSError * _Nonnull))completation{\r
[[AiMouse shared] getDeviceInfo:completation];\r
}\r
-/// 鉴权\r
--(void)startAuthentication{\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
#pragma mark - other\r
//自动连接,获取已配对的蓝牙,取第一个连接\r
- (void)autoConnectDevice{\r
\r
- (void)open{\r
self.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);\r
- IOHIDManagerScheduleWithRunLoop(self.hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);\r
+ IOHIDManagerScheduleWithRunLoop(self.hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);\r
IOReturn ret = IOHIDManagerOpen(self.hidManager, 0L);\r
if (ret != kIOReturnSuccess) {\r
NSLog(@"打开设备失败!");\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
+ [[HidManager shared] showLog:[NSString stringWithFormat:@"发现设备 %@\n ",inIOHIDDeviceRef]];\r
uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey));\r
uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey));\r
- [[HidManager shared] showLog:[NSString stringWithFormat:@"vid = %u, pid = %u, PrimaryUsagePage = %u, PrimaryUsage = %u,",vid,pid,PrimaryUsagePage,PrimaryUsage]];\r
- [[HidManager shared] showLog:[NSString stringWithFormat:@"发现设备 %@\n ",inIOHIDDeviceRef]];\r
- \r
- // PrimaryUsagePage=1 PrimaryUsage=0,设备信息\r
- // PrimaryUsagePage=65283 PrimaryUsage=0,ai\r
if(PrimaryUsagePage == 1 && PrimaryUsage == 0){\r
//设备信息\r
[HidManager shared].deviceInfoCha = inIOHIDDeviceRef;\r
- //开始鉴权\r
- [[HidManager shared] startAuthentication];\r
+ [[HidManager shared] connectDevice];\r
+ //注册消息回调\r
+ unsigned char InputBuffer[128];\r
+ IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL);\r
+ IOReturn ret = IOHIDDeviceOpen(inIOHIDDeviceRef, 0);\r
+ if (ret != kIOReturnSuccess) {\r
+ NSLog(@"打开设备信息失败!");\r
+ }else{\r
+ NSLog(@"打开设备信息成功!");\r
+ }\r
+ CFRetain(inIOHIDDeviceRef);\r
+ IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);\r
}\r
else if(PrimaryUsagePage == 65283 && PrimaryUsage == 0){\r
//ai\r
[HidManager shared].aiCha = inIOHIDDeviceRef;\r
+ //注册消息回调\r
+ unsigned char InputBuffer[128];\r
+ IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL);\r
+ IOReturn ret = IOHIDDeviceOpen(inIOHIDDeviceRef, 0);\r
+ if (ret != kIOReturnSuccess) {\r
+ NSLog(@"打开AI失败!");\r
+ }else{\r
+ NSLog(@"打开AI成功!");\r
+ }\r
+ CFRetain(inIOHIDDeviceRef);\r
+ IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);\r
}\r
- //注册消息回调\r
- unsigned char InputBuffer[128];\r
- IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL);\r
}\r
\r
/// 设备移除回调\r
uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey));\r
\r
if(PrimaryUsagePage == 1 && PrimaryUsage == 0){\r
- [HidManager shared].connectStateCallBack(false);\r
+ [HidManager shared].deviceInfoCha = nil;\r
+ [HidManager shared].aiCha = nil;\r
+ [[AiMouse shared] didDisconnect];\r
}\r
}\r
\r
uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsageKey));\r
\r
if(PrimaryUsagePage == 1 && PrimaryUsage == 0){\r
- [[HidManager shared] showLog:[NSString stringWithFormat:@"收到device数据 %@",data]];\r
[[AiMouse shared] sendDeviceDataToSdk:data];\r
+ \r
}\r
else if(PrimaryUsagePage == 65283 && PrimaryUsage == 0){\r
- [[HidManager shared] showLog:[NSString stringWithFormat:@"收到AI数据 %@",data]];\r
[[AiMouse shared] sendAiDataToSdk:data];\r
}\r
}\r
[self sendData:data toDevice:self.deviceInfoCha];\r
}\r
\r
+/// 设备鉴权结果返回\r
+/// - Parameter authState: 鉴权状态\r
+-(void)aiMouseAuthenticationResult:(AiMouseAuthState)authState{\r
+ [self showLog:[NSString stringWithFormat:@"鉴权结果 = %@",@(authState)]];\r
+ if(self.authCallBack){\r
+ self.authCallBack(authState == AiMouseAuthState_Success);\r
+ }\r
+}\r
/// 鼠标按键指令回调\r
/// - Parameter data: 数据。\r
/// 前 第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音)\r
- (void)aiMouseSendRecordData:(NSData *)data{\r
[self.recordData appendData:data];\r
}\r
+/// 输出日志\r
+- (void)aiMouseAddLog:(NSString *)log {\r
+// [self showLog:log];\r
+}\r
\r
+-(void)hidDataError{\r
+ [self close];\r
+ [self open];\r
+}\r
+\r
+// 连接状态改变\r
+- (void)aiMouseConnectStateDidChange:(BOOL)connected{\r
+ [HidManager shared].connectStateCallBack(connected);\r
+}\r
#pragma mark - public\r
--(void)startAuthentication{\r
- //连上设备\r
- [HidManager shared].connectStateCallBack(true);\r
+-(void)connectDevice{\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
[self showLog:@"请先连上设备"];\r
return;\r
}\r
- [self showLog:[NSString stringWithFormat:@"开始发送[send] %@",data]];\r
\r
IOReturn ret = IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, 0, data.bytes, data.length);\r
if (ret != kIOReturnSuccess) {\r