From: liangzhenying <867174124@qq.com> Date: Tue, 19 Nov 2024 09:33:14 +0000 (+0800) Subject: 新增支持泰凌微键盘 X-Git-Tag: 威鼠泰凌微电池电量版本优化~8 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=ed34aba611b99d0b465fc070f471500cc311626f;p=mirrors%2FMouseSdk-MacOS.git 新增支持泰凌微键盘 --- diff --git a/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj index dc8b476..d26c6d8 100644 --- a/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj +++ b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj @@ -397,6 +397,12 @@ 188814C32C85C2BB009299A9 /* AESCBCHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 188814C02C85C2BA009299A9 /* AESCBCHelper.h */; }; 188814C42C85C2BB009299A9 /* AESCBCHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 188814C12C85C2BA009299A9 /* AESCBCHelper.m */; }; 188814C52C85C2BB009299A9 /* AESCBCHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 188814C12C85C2BA009299A9 /* AESCBCHelper.m */; }; + 189365542CEB115200023B62 /* KeyboardHidManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 189365522CEB115200023B62 /* KeyboardHidManager.h */; }; + 189365552CEB115200023B62 /* KeyboardHidManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 189365532CEB115200023B62 /* KeyboardHidManager.m */; }; + 189365582CEB153000023B62 /* MSUtilis.h in Headers */ = {isa = PBXBuildFile; fileRef = 189365562CEB153000023B62 /* MSUtilis.h */; }; + 189365592CEB153000023B62 /* MSUtilis.m in Sources */ = {isa = PBXBuildFile; fileRef = 189365572CEB153000023B62 /* MSUtilis.m */; }; + 189960102CEAD7B50042505F /* KeyboardSdk.h in Headers */ = {isa = PBXBuildFile; fileRef = 1899600E2CEAD7B50042505F /* KeyboardSdk.h */; }; + 189960112CEAD7B50042505F /* KeyboardSdk.m in Sources */ = {isa = PBXBuildFile; fileRef = 1899600F2CEAD7B50042505F /* KeyboardSdk.m */; }; 18AD83252BFAE8B9009BDE3B /* AiDeviceInfoManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */; }; 18AD83262BFAE8B9009BDE3B /* AiDeviceInfoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AD83242BFAE8B9009BDE3B /* AiDeviceInfoManager.m */; }; 18AD83292BFB22DE009BDE3B /* AiSender.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD83272BFB22DE009BDE3B /* AiSender.h */; }; @@ -418,7 +424,6 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 18068CFA2CDC8E2F006B6EF5 /* libAiMouseSdk copy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libAiMouseSdk copy.a"; path = "/Users/apple/Desktop/code/MouseSdk-MacOS/MouseSdk/AiMouseSdk/build/Debug/libAiMouseSdk copy.a"; sourceTree = ""; }; 180E7AA62BD7BB12008558E8 /* libAiMouseManager.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAiMouseManager.a; sourceTree = BUILT_PRODUCTS_DIR; }; 180E7AA92BD7BB12008558E8 /* AiMouseSdk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiMouseSdk.h; sourceTree = ""; }; 180E7AAB2BD7BB12008558E8 /* AiMouseSdk.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiMouseSdk.m; sourceTree = ""; }; @@ -608,6 +613,13 @@ 188814BC2C85BB76009299A9 /* AiBkzhAuthManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiBkzhAuthManager.m; sourceTree = ""; }; 188814C02C85C2BA009299A9 /* AESCBCHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AESCBCHelper.h; sourceTree = ""; }; 188814C12C85C2BA009299A9 /* AESCBCHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AESCBCHelper.m; sourceTree = ""; }; + 189365512CEB0C3700023B62 /* libAiMouseSdk copy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libAiMouseSdk copy.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 189365522CEB115200023B62 /* KeyboardHidManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyboardHidManager.h; sourceTree = ""; }; + 189365532CEB115200023B62 /* KeyboardHidManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeyboardHidManager.m; sourceTree = ""; }; + 189365562CEB153000023B62 /* MSUtilis.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSUtilis.h; sourceTree = ""; }; + 189365572CEB153000023B62 /* MSUtilis.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSUtilis.m; sourceTree = ""; }; + 1899600E2CEAD7B50042505F /* KeyboardSdk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyboardSdk.h; sourceTree = ""; }; + 1899600F2CEAD7B50042505F /* KeyboardSdk.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeyboardSdk.m; sourceTree = ""; }; 18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiDeviceInfoManager.h; sourceTree = ""; }; 18AD83242BFAE8B9009BDE3B /* AiDeviceInfoManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiDeviceInfoManager.m; sourceTree = ""; }; 18AD83272BFB22DE009BDE3B /* AiSender.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiSender.h; sourceTree = ""; }; @@ -675,12 +687,14 @@ 180E7A9D2BD7BB12008558E8 = { isa = PBXGroup; children = ( + 1899600D2CEAD78B0042505F /* Keyboard */, 18D579FF2C91733E003D5714 /* NMouseSdk */, 18862A172C8064E300D3564D /* Manager */, 18EF7AE72C7603E800AC5223 /* TlwMouseSdk */, 180E7AA82BD7BB12008558E8 /* AiMouseSdk */, 180E7AA72BD7BB12008558E8 /* Products */, 180E7D092BD8FEB2008558E8 /* Frameworks */, + 189365512CEB0C3700023B62 /* libAiMouseSdk copy.a */, ); sourceTree = ""; }; @@ -991,10 +1005,23 @@ 18862A202C8064E300D3564D /* TimerManager.m */, 1888148C2C85766B009299A9 /* AiDeviceAuthManager.h */, 1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */, + 189365562CEB153000023B62 /* MSUtilis.h */, + 189365572CEB153000023B62 /* MSUtilis.m */, ); path = Manager; sourceTree = ""; }; + 1899600D2CEAD78B0042505F /* Keyboard */ = { + isa = PBXGroup; + children = ( + 1899600E2CEAD7B50042505F /* KeyboardSdk.h */, + 1899600F2CEAD7B50042505F /* KeyboardSdk.m */, + 189365522CEB115200023B62 /* KeyboardHidManager.h */, + 189365532CEB115200023B62 /* KeyboardHidManager.m */, + ); + path = Keyboard; + sourceTree = ""; + }; 18D579FF2C91733E003D5714 /* NMouseSdk */ = { isa = PBXGroup; children = ( @@ -1052,6 +1079,7 @@ 180E7CE02BD8FC4E008558E8 /* version.h in Headers */, 180E7C972BD8FC4E008558E8 /* base64.h in Headers */, 180E7CC02BD8FC4E008558E8 /* mastering_display_metadata.h in Headers */, + 189960102CEAD7B50042505F /* KeyboardSdk.h in Headers */, 180E7CA02BD8FC4E008558E8 /* crc.h in Headers */, 180E7C8A2BD8FC4E008558E8 /* hwcontext_cuda.h in Headers */, 18D57A022C917385003D5714 /* NMouseSdk.h in Headers */, @@ -1127,6 +1155,7 @@ 180E7CB22BD8FC4E008558E8 /* tx.h in Headers */, 180E7C842BD8FC4E008558E8 /* version.h in Headers */, 180E7CEE2BD8FC4F008558E8 /* codec_desc.h in Headers */, + 189365582CEB153000023B62 /* MSUtilis.h in Headers */, 184A711F2BDD11C70025A332 /* AiTrippleModel.h in Headers */, 180E7CDC2BD8FC4E008558E8 /* mathematics.h in Headers */, 180E7CCD2BD8FC4E008558E8 /* imgutils.h in Headers */, @@ -1178,6 +1207,7 @@ 180E7C8E2BD8FC4E008558E8 /* fifo.h in Headers */, 180E7CC72BD8FC4E008558E8 /* cpu.h in Headers */, 180E7CF22BD8FC4F008558E8 /* d3d11va.h in Headers */, + 189365542CEB115200023B62 /* KeyboardHidManager.h in Headers */, 180E7CBC2BD8FC4E008558E8 /* eval.h in Headers */, 180E7CF72BD8FC4F008558E8 /* bsf.h in Headers */, 188814C22C85C2BB009299A9 /* AESCBCHelper.h in Headers */, @@ -1390,7 +1420,7 @@ ); name = "AiMouseSdk copy"; productName = AiMouseSdk; - productReference = 18068CFA2CDC8E2F006B6EF5 /* libAiMouseSdk copy.a */; + productReference = 189365512CEB0C3700023B62 /* libAiMouseSdk copy.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ @@ -1432,6 +1462,7 @@ buildActionMask = 2147483647; files = ( 18FCA3982C7F2AD100C44A37 /* AiMouseAuth.m in Sources */, + 189365552CEB115200023B62 /* KeyboardHidManager.m in Sources */, 18862A2A2C8064E300D3564D /* TimerManager.m in Sources */, 18862A232C8064E300D3564D /* HidManager.m in Sources */, 180E7BE52BD7BD84008558E8 /* AiMouseTools2.m in Sources */, @@ -1448,6 +1479,7 @@ 184A710C2BDA4C050025A332 /* AFNetworkReachabilityManager.m in Sources */, 180E7BE42BD7BD84008558E8 /* AiRecordManager.m in Sources */, 18EF7B042C7603E800AC5223 /* TlwAudioManager.m in Sources */, + 189960112CEAD7B50042505F /* KeyboardSdk.m in Sources */, 180E7BE72BD7BD84008558E8 /* AiAudioManager.m in Sources */, 18EF7AFB2C7603E800AC5223 /* TlwTools.m in Sources */, 18EF7AFA2C7603E800AC5223 /* TlwMouseSdk.m in Sources */, @@ -1460,6 +1492,7 @@ 184A710D2BDA4C050025A332 /* AFSecurityPolicy.m in Sources */, 18862A272C8064E300D3564D /* DeviceManger.m in Sources */, 180E7B552BD7BD83008558E8 /* AiAudioDecoder.m in Sources */, + 189365592CEB153000023B62 /* MSUtilis.m in Sources */, 18AD83262BFAE8B9009BDE3B /* AiDeviceInfoManager.m in Sources */, 18EF7B012C7603E800AC5223 /* adpcm.c in Sources */, 184A71092BDA4C050025A332 /* AFURLSessionManager.m in Sources */, diff --git a/MouseSdk/AiMouseSdk/Keyboard/KeyboardHidManager.h b/MouseSdk/AiMouseSdk/Keyboard/KeyboardHidManager.h new file mode 100644 index 0000000..7e5e0c1 --- /dev/null +++ b/MouseSdk/AiMouseSdk/Keyboard/KeyboardHidManager.h @@ -0,0 +1,31 @@ +// +// KeyboardHidManager.h +// AiMouseManager +// +// Created by incar on 2024/11/18. +// + +#import +#import "DeviceManger.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface KeyboardHidManager : NSObject +@property (nonatomic, copy)void (^connectStateCallBack)(BOOL connected);/// 设备连接状态回调 +@property (nonatomic, copy)void (^receiveInfoDataCallBack)(NSData *data);/// 设备信息数据回调 +@property (nonatomic, copy)void (^logCallBack)(NSString *log);//输出日志 + +@property (nonatomic, assign)AiMouseProductType productType;// + ++(KeyboardHidManager *)shared; + +- (void)open; + +//- (void)close; + +//写入数据 +-(void)writeToDevice:(NSData *)data; +@end + +NS_ASSUME_NONNULL_END + diff --git a/MouseSdk/AiMouseSdk/Keyboard/KeyboardHidManager.m b/MouseSdk/AiMouseSdk/Keyboard/KeyboardHidManager.m new file mode 100644 index 0000000..fcf8578 --- /dev/null +++ b/MouseSdk/AiMouseSdk/Keyboard/KeyboardHidManager.m @@ -0,0 +1,204 @@ +// +// KeyboardHidManager.m +// AiMouseManager +// +// Created by incar on 2024/11/18. +// + +#import "KeyboardHidManager.h" + +#include +#include +#import +#import +#import +#import "AiDeviceAuthManager.h" + +@interface KeyboardHidManager () +@property(nonatomic, assign) IOHIDManagerRef hidManager;///hid管理 +@property(nonatomic, assign) IOHIDDeviceRef deviceInfoCha;//设备信息通道 +@end + +@implementation KeyboardHidManager ++(KeyboardHidManager *)shared{ + static KeyboardHidManager *manager = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + manager = [[KeyboardHidManager alloc]init]; + }); + return manager; +} + +- (instancetype)init{ + self = [super init]; + if (self) { + + } + return self; +} + +#pragma mark - Hid CallBack +/// 匹配到设备回调 +static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) { + if ([DeviceManger shared].isConneted) { +// [[KeyboardHidManager shared] showLog:(@"当前处于连接状态,对监听到有USB 插入 的事件不做处理")]; + return; + } +// 1ea7 0064 + uint32_t pid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey)); + uint32_t vid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey)); + uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey)); + uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey)); +// [[KeyboardHidManager shared] showLog:([NSString stringWithFormat:@"keyboard 发现设备%@,pid = %d,vid = %d ,page = %d, usage = %d",inIOHIDDeviceRef,pid,vid,PrimaryUsagePage,PrimaryUsage])]; + + + if((vid == 0x248a && pid == 0x6092)){ + [[KeyboardHidManager shared] showLog:([NSString stringWithFormat:@"发现键盘%@,pid = %d,vid = %d ,page = %d, usage = %d",inIOHIDDeviceRef,pid,vid,PrimaryUsagePage,PrimaryUsage])]; + [KeyboardHidManager shared].productType = AiMouseProductType_n; + [KeyboardHidManager shared].deviceInfoCha = inIOHIDDeviceRef; + //注册消息回调 + unsigned char InputBuffer[64]; + IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), &hidReceiveData, NULL); + + IOReturn result = IOHIDDeviceOpen([KeyboardHidManager shared].deviceInfoCha, kIOHIDOptionsTypeNone); + if (result != kIOReturnSuccess) { + [[KeyboardHidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]]; + [[AiDeviceAuthManager shared] showHidAlert]; + return; + }else{ + [[KeyboardHidManager shared] showLog:@"打开设备成功!"]; + [KeyboardHidManager shared].connectStateCallBack(true) ; + } + } + +} + +/// 设备移除回调 +static void hidDisAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) { + [[KeyboardHidManager shared] showLog:[NSString stringWithFormat:@"拔出设备 %@ ",inIOHIDDeviceRef]]; + + if([KeyboardHidManager shared].deviceInfoCha){ + [KeyboardHidManager shared].deviceInfoCha = nil; + [KeyboardHidManager shared].hidManager = nil; + [KeyboardHidManager shared].connectStateCallBack(false) ; + } +} + + +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]; + [[KeyboardHidManager shared] showLog:[NSString stringWithFormat:@"receive = %@",data]]; + if([KeyboardHidManager shared].productType == AiMouseProductType_n){ + uint32_t primaryUsagePage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsagePageKey)); + uint32_t primaryUsage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsageKey)); + NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; + [KeyboardHidManager shared].receiveInfoDataCallBack(data); + } + +} + +#pragma mark - public +- (void)open{ + [self close]; + //初始化 + 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成功!")]; + } + //设置匹配设备 + // ////供应商id + // const long vendorID = 0x6675; + // //产品id + // const long productID = 0x8601; + // //供应商id + // const long vendorID = 0x10D6; + // //产品id + // const long productID = 0xB008; + NSMutableDictionary* dict= [NSMutableDictionary dictionary]; + // [dict setValue:[NSNumber numberWithLong:productID] forKey:[NSString stringWithCString:kIOHIDProductIDKey encoding:NSUTF8StringEncoding]]; + // [dict setValue:[NSNumber numberWithLong:vendorID] forKey:[NSString stringWithCString:kIOHIDVendorIDKey encoding:NSUTF8StringEncoding]]; + IOHIDManagerSetDeviceMatching(self.hidManager, (__bridge CFMutableDictionaryRef)dict); + //设置匹配到设备回调 + IOHIDManagerRegisterDeviceMatchingCallback(self.hidManager, &hidAppearDevice, NULL); + //设置移除设备回调 + IOHIDManagerRegisterDeviceRemovalCallback(self.hidManager, &hidDisAppearDevice, NULL); +} + +- (void)close{ + if (self.hidManager == nil) { + return; + } + [self showLog:@"关闭hid"]; + + IOReturn ret = IOHIDManagerClose(self.hidManager, 0); + self.hidManager = nil; + + if (ret != kIOReturnSuccess) { + [self showLog:(@"关闭hid失败!")]; + }else{ + [self showLog:(@"关闭hid成功!")]; + self.deviceInfoCha = nil; + self.hidManager = nil; + } +} +/// 发送数据给设备 +-(void)writeToDevice:(NSData *)data{ + if(self.deviceInfoCha == nil){ + [self showLog:@"sendData: 请先连上设备"]; + return; + } + + [self showLog:[NSString stringWithFormat:@"向usb设备发送数据 %@",data]]; + IOReturn ret = IOHIDDeviceSetReport(self.deviceInfoCha, kIOHIDReportTypeOutput, 0, data.bytes, data.length); + if (ret != kIOReturnSuccess) { + [self showLog:[NSString stringWithFormat:@"发送失败! code = %d",ret]]; + }else{ +// [self showLog:@"发送成功!"]; + } +} + + +- (void)showLog:(NSString *)log{ + NSString *text = [NSString stringWithFormat:@"[KeyboardHidManager] %@",log]; + if(self.logCallBack) self.logCallBack(text); +} + +/// 实际到数据长度 +static inline int get_data_len(uint8_t *buf, u_long len) { + if (len <= 0 ) return 0; + int url_len = 0; + while (buf[url_len] != 0x00) url_len++; + return url_len; +} + +- (NSString *)dataToHexString:(NSData *)data { + NSUInteger length = data.length; + NSMutableString *result = [NSMutableString stringWithCapacity:length * 2]; + const unsigned char *byte = data.bytes; + for (int i = 0; i < length; i++, byte++) { + [result appendFormat:@"%02X", *byte]; + } + return result; +} + + +/// 获取对应属性值 +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) { + [[KeyboardHidManager shared] showLog:[NSString stringWithFormat:@"(HidManager)IOHIDDevGetUInt32Property:get %@ failed.", inKey]]; + } + } + } + return outValue; +} +@end diff --git a/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.h b/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.h new file mode 100644 index 0000000..06751c6 --- /dev/null +++ b/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.h @@ -0,0 +1,77 @@ +// +// KeyboardSdk.h +// AiMouseManager +// +// Created by incar on 2024/11/18. +// + + +#import +#import "AiMouseSdk.h" +@interface KeyboardInfo : NSObject +@property (nonatomic, assign) int DPI;/// DPI值 数值1 ~ 4 (分别对应1200,1600,2400,4800) +@property (nonatomic, assign) int version;///软件版本 +@property (nonatomic, assign) int batteryState;/// 电池状态 +@property (nonatomic, assign) int batteryValue;/// 电池百分百电量,0-100 +@end + + +@protocol KeyboardSdkDelegate + +/// 设备连接状态 +/// - Parameter connected: 是否连接 +- (void)keyboardConnectStateDidChange:(BOOL)connected; + + +/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备 +/// - Parameter data: 数据 +- (void)keyboardSendDeviceInfoData:(NSData *)data; + +/// 鼠标按键指令回调 +//0x81: 截屏 (fn + a) +//0x82: AI问答 (fn + s) +//0x83: AI写作 (fn + d) +//0x84: AI PPT (fn + f) +//0x85: 智能阅读 (fn + g) +//0x86: 长文写作 (fn +h) +//0x87: 文稿校对 (fn + j) +//0x88: AI绘画 (fn + k) +//0x89: AI 翻译 (fn + l) +//0x8a: 模版下载 (fn + ;) +//0x8b: 思维导图 (fn + ‘) +//0x8c: 工作总结 (fn + n) +//0x8d: 日报/周报 (fn + m) +//0x8e: AI 教案 (fn + ,) +//0x8f: AI 律师 (fn + .) +//0x90: AI 电商 (fn + /) +//0x91: AI上网 (fn + PgUp) +//0x92: AI办公 (fn + PgDn) +- (void)keyboardSendCmdData:(NSData *)data; + +/// 输出sdk日志 +/// - Parameter log: 日志 +- (void)keyboardAddLog:(NSString *)log; + +@end + + +@interface KeyboardSdk : NSObject +@property (nonatomic, weak) id delegate;/// 代理 +@property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型 +@property (nonatomic, readonly) BOOL connected;//是否已连接 + +/// 切换连接类型 +/// - Parameter type: 连接类型 +- (void)switchConnect:(AiMouseConnectType)type isConnected:(BOOL)isConneted; + +/// 断开连接 +- (void)didDisconnect; + +/// 传输设备信息数据给sdk +/// - Parameter data:设备信息特征传过来的数据 +- (void)sendDeviceDataToSdk:(NSData *)data; + +/// 获取设备信息 +/// - Parameter completation: 如果获取成功,则deviceInfo有值,否则为nil +- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished; +@end diff --git a/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.m b/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.m new file mode 100644 index 0000000..a5c96ca --- /dev/null +++ b/MouseSdk/AiMouseSdk/Keyboard/KeyboardSdk.m @@ -0,0 +1,256 @@ +// +// KeyboardSdk.m +// AiMouseManager +// +// Created by incar on 2024/11/18. +// + +#import "KeyboardSdk.h" +#import "TlwTools.h" +#import "TlwMouseSdk.h" +@interface KeyboardSdk() + +@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,assign)NSInteger dongleTimes; +@property (nonatomic,strong)AiMouseDeviceInfo *deviceInfo; +@end + +@implementation KeyboardSdk +/// 切换连接类型 +/// - Parameter type: 连接类型 +- (void)switchConnect:(AiMouseConnectType)type isConnected:(BOOL)isConneted{ + if(isConneted ){ + _connected = true; + _connectType = type; + [self showLog:type == AiMouseConnectType_bluetooth?@"sdk切换到蓝牙模式":@"sdk切换到usb模式"]; + + if (type == AiMouseConnectType_hid ) { + [self getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) { + + }]; +// [self sendCmd:0x0D]; + [self startCheckConnectState]; + } + else{ + [self TlwConnectManager:nil connectStateDidChange:true]; + } + } + else{ + if (self.connected) { + _connected = false; + [self TlwConnectManager:nil connectStateDidChange:false]; + } + } +} + +- (void)didDisconnect{ + _connected = false; +} + + +- (void)sendDeviceDataToSdk:(NSData *)data{ + NSString *text = [TlwTools dataToHexString:data]; + [self showLog:[NSString stringWithFormat:@"[receive][usb][info] %@",text]]; + + if (data.length < 6) { + return; + } + uint8_t cmd; + [data getBytes:&cmd range:NSMakeRange(5, 1)]; + + if (cmd == 0x22) { + //序列号回复 + data = [data subdataWithRange:NSMakeRange(7, data.length - 8)]; + NSString *code = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 2)] encoding:NSUTF8StringEncoding]; + NSString *brand = [self getBrand:[data subdataWithRange:NSMakeRange(2, 6)]]; + NSString *batch = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(8, 2)] encoding:NSUTF8StringEncoding]; + NSString *mac = [[TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(10, 6)]] lowercaseString]; + + NSString *fullBrand = [self getFullBrand:[data subdataWithRange:NSMakeRange(2, 6)]]; + NSString *sn = [NSString stringWithFormat:@"%@%@%@%@",code,fullBrand,batch,mac] ; + TlwSnInfo *info = [[TlwSnInfo alloc] init]; + info.code = code; + info.brand = brand; + info.batch = batch; + info.mac = mac; + info.sn = sn; + [self showLog:info.description]; + if(self.getInfoCallBack)self.getInfoCallBack(info, nil); + } + else if (cmd == 0x9c) { + //键盘状态查询 + data = [data subdataWithRange:NSMakeRange(7, data.length - 8)]; + NSString *version = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 2)] encoding:NSUTF8StringEncoding]; + uint8_t batteryState;// 0. 未充电 , 1 充电 + [[data subdataWithRange:NSMakeRange(4, 1)] getBytes:&batteryState length:1]; + uint8_t battery; + [[data subdataWithRange:NSMakeRange(5, 1)] getBytes:&battery length:1]; + + NSString *log = [NSString stringWithFormat:@"version = %@,batteryState = %d,battery = %d",version,batteryState,battery]; + [self showLog:log]; + + if(self.getKeyboardStateCallBack)self.getKeyboardStateCallBack(version,battery, nil); + } + else if(cmd == 0x9d){ + //接收器状态查询 + data = [data subdataWithRange:NSMakeRange(7, data.length - 8)]; + NSString *version = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 2)] encoding:NSUTF8StringEncoding]; + uint8_t bind; + [[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); + } + else if(cmd == 0x9f){ + //接收器状态查询 + data = [data subdataWithRange:NSMakeRange(7, 1)]; + uint8_t type; + [[data subdataWithRange:NSMakeRange(0, 1)] getBytes:&type length:1]; + NSString *log = [NSString stringWithFormat:@"type = %d",type]; + [self showLog:log]; + if([self.delegate respondsToSelector:@selector(keyboardSendCmdData:)])[self.delegate keyboardSendCmdData:data]; + } +} +- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{ + [NSObject cancelPreviousPerformRequestsWithTarget:self]; + self.getDeviceInfoCallBack = finished; + + self.deviceInfo = [[AiMouseDeviceInfo alloc] init]; + self.deviceInfo.battery_power = @"0"; + self.deviceInfo.CPI = @"1200"; + self.deviceInfo.CPI_list = @"1200,1600,2400,4800"; + self.deviceInfo.version = @"1"; + self.deviceInfo.sn = @""; + self.deviceInfo.mac = @""; + + __weak typeof(self) ws = self; + [ws getSn:^(TlwSnInfo *info, NSError *error) { + if (info) { + ws.deviceInfo.brand = info.brand; + ws.deviceInfo.sn = info.sn; + ws.deviceInfo.mac = info.mac; + [ws showLog:info.description]; + + [ws getKeyboardState:^(NSString *version, uint8_t battery, NSError *error) { + if(error == nil){ + ws.deviceInfo.version = version; + ws.deviceInfo.battery_power = [NSString stringWithFormat:@"%d",battery]; + ws.getDeviceInfoCallBack(ws.deviceInfo, nil); + } + else{ + ws.getDeviceInfoCallBack(nil, error); + } + }]; + } + else{ + ws.getDeviceInfoCallBack(nil, error); + } + }]; +} + +//键盘状态查询 +- (void)getKeyboardState:(void (^)(NSString *version,uint8_t battery,NSError *error))finished{ + self.getKeyboardStateCallBack = finished; + [self sendCmd:0x0c]; +} + +//usb接收器状态查询 +- (void)getUsbReceiverState:(void (^)(int bind,NSError *error))finished{ + self.getUsbSateCallBack = 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 sendCmd:0x12]; + } + }]; + +} +#pragma mark - check connect +- (void)startCheckConnectState{ + self.dongleTimes = 0; + [self checkAction]; +} +- (void)checkAction{ + if (self.deviceInfo.sn && self.deviceInfo.sn.length > 0) { + [self TlwConnectManager:nil connectStateDidChange:true]; + return; + } + self.dongleTimes++; + if (self.dongleTimes > 3) { + [self TlwConnectManager:nil connectStateDidChange:false]; + return; + } + [self performSelector:@selector(checkAction) withObject:nil afterDelay:1]; +} + +#pragma mark - other +-(void)TlwConnectManager:(NSString *)manager connectStateDidChange:(BOOL)connected{ + _connected = connected; + if([self.delegate respondsToSelector:@selector(keyboardConnectStateDidChange:)]) [self.delegate keyboardConnectStateDidChange:connected]; +} +- (void)showLog:(NSString *)log{ + if (self.delegate && [self.delegate respondsToSelector:@selector(keyboardAddLog:)]) { + [self.delegate keyboardAddLog:[NSString stringWithFormat:@"[keyboard]%@",log]]; + } +} + +- (void)sendCmd:(uint8_t)cmd{ + uint8_t reportId = 0x04;//开头 + uint8_t head0 = 0xff;//头分区 + 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; + [mData appendBytes:&reportId length:1]; + [mData appendBytes:&head0 length:1]; + [mData appendBytes:&head1 length:1]; + [mData appendBytes:&head2 length:1]; + [mData appendBytes:&type length:1]; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&len length:1]; + [mData appendBytes:&tail length:1]; + + if (mData.length < 64) { + NSInteger len = 64 - mData.length; + for (NSInteger i = 0; i < len; i++) { + uint8_t d = 0x00; + [mData appendBytes:&d length:1]; + } + } + + + [self showLog:[NSString stringWithFormat:@"[send][info] %@",[TlwTools dataToHexString:mData]]]; + [self.delegate keyboardSendDeviceInfoData:mData]; +} + +- (NSString *)getBrand:(NSData *)data{ + NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + for (NSInteger i = 0; i < text.length;i++) { + if ([[text substringWithRange:NSMakeRange(i, 1)] isEqual:@"\0"]) { + return [text substringWithRange:NSMakeRange(0, i)]; + } + } + return text; +} +- (NSString *)getFullBrand:(NSData *)data{ + NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSString *replacedString = [text stringByReplacingOccurrencesOfString:@"\0" withString:@"0"]; + return replacedString; +} +@end + diff --git a/MouseSdk/AiMouseSdk/Manager/DeviceManger.h b/MouseSdk/AiMouseSdk/Manager/DeviceManger.h index baced2c..215acec 100644 --- a/MouseSdk/AiMouseSdk/Manager/DeviceManger.h +++ b/MouseSdk/AiMouseSdk/Manager/DeviceManger.h @@ -13,6 +13,7 @@ typedef NS_ENUM(NSInteger,AiMouseProductType) { AiMouseProductType_frk = 1,///富瑞坤 AiMouseProductType_tlw = 2,///泰凌微 AiMouseProductType_n = 3,///一键上网 + AiMouseProductType_keyboard = 4,///键盘 }; NS_ASSUME_NONNULL_BEGIN diff --git a/MouseSdk/AiMouseSdk/Manager/DeviceManger.m b/MouseSdk/AiMouseSdk/Manager/DeviceManger.m index 073975d..d888abe 100644 --- a/MouseSdk/AiMouseSdk/Manager/DeviceManger.m +++ b/MouseSdk/AiMouseSdk/Manager/DeviceManger.m @@ -12,8 +12,10 @@ #import "NMouseSdk.h" #import "TimerManager.h" #import "AiMouseConfig.h" +#import "KeyboardHidManager.h" +#import "KeyboardSdk.h" -@interface DeviceManger() +@interface DeviceManger() @property (nonatomic,strong) NSMutableData *recordData;//录音的数据 @property (nonatomic,strong) BleManager *ble; @@ -22,6 +24,7 @@ @property (nonatomic,strong) TlwMouse *tlwSdk; @property (nonatomic,strong) AiMouse *frkSdk; @property (nonatomic,strong) NMouseSdk *nSdk; +@property (nonatomic,strong) KeyboardSdk *kbSdk; @property (nonatomic,assign) AiMouseProductType productType; //connectType 返回为0代表蓝牙,为1代表usb @@ -42,18 +45,22 @@ - (instancetype)init{ self = [super init]; if (self) { - NSString *version = @"MouseSdk_v2024110802"; + NSString *version = @"MouseSdk_v2024111901"; NSLog(@"[AiMouseSdk] %@",version); - [self showLog:version]; + [self showLog:version];; [self setupSDK]; [self setupBle]; [self setupHid]; [self setupTimer]; +// [self setupKeyboard]; } return self; } #pragma mark ------ 设备初始化 - (void)setupSDK{ + self.kbSdk = [[KeyboardSdk alloc] init]; + [self.kbSdk setDelegate:self]; + self.nSdk = [[NMouseSdk alloc] init]; [self.nSdk setDelegate:self]; @@ -66,11 +73,22 @@ [self.frkSdk setLogLevel:AiMouseLogLevel_none]; } - +- (void)setupKeyboard{ + [KeyboardHidManager shared].receiveInfoDataCallBack = ^(NSData * _Nonnull data) { + + }; + [KeyboardHidManager shared].connectStateCallBack = ^(BOOL connected) { + [self.kbSdk switchConnect:AiMouseConnectType_hid isConnected:true]; + }; + [KeyboardHidManager shared].logCallBack = ^(NSString * _Nonnull log) { + [self showLog:log]; + }; + [[KeyboardHidManager shared] open]; +} - (void)setupTimer{ [TimerManager shared].timerCallBack = ^{ // [self showLog:@"timer action。。。"]; - if(self.nSdk.connected || self.tlwSdk.connected || self.frkSdk.connected){ + if(self.kbSdk.connected || self.nSdk.connected || self.tlwSdk.connected || self.frkSdk.connected){ // [self.hid close]; } else{ @@ -78,7 +96,10 @@ } }; } + + - (void)setupHid{ + self.hid = [HidManager shared]; __weak typeof(self) ws = self; @@ -91,9 +112,12 @@ else if (ws.hid.productType == AiMouseProductType_tlw) { [ws.tlwSdk switchConnect:AiMouseConnectType_hid isConnected:true]; } - else{ + else if (ws.hid.productType == AiMouseProductType_frk){ [ws.frkSdk switchConnect:AiMouseConnectType_hid isConnected:true]; } + else if (ws.hid.productType == AiMouseProductType_keyboard){ + [ws.kbSdk switchConnect:AiMouseConnectType_hid isConnected:true]; + } } else{ if (ws.hid.productType == AiMouseProductType_n) { @@ -104,10 +128,14 @@ [ws.tlwSdk switchConnect:AiMouseConnectType_hid isConnected:false]; [ws.tlwSdk didDisconnect]; } - else{ + else if (ws.hid.productType == AiMouseProductType_frk) { [ws.frkSdk switchConnect:AiMouseConnectType_hid isConnected:false]; [ws.frkSdk didDisconnect]; } + else if (ws.hid.productType == AiMouseProductType_keyboard) { + [ws.kbSdk switchConnect:AiMouseConnectType_hid isConnected:false]; + [ws.kbSdk didDisconnect]; + } } }; self.hid.receiveInfoDataCallBack = ^(NSData *data) { @@ -117,9 +145,12 @@ else if (ws.productType == AiMouseProductType_tlw) { [ws.tlwSdk sendDeviceDataToSdk:data]; } - else{ + else if (ws.hid.productType == AiMouseProductType_frk){ [ws.frkSdk sendDeviceDataToSdk:data]; } + else if (ws.hid.productType == AiMouseProductType_keyboard) { + [ws.kbSdk sendDeviceDataToSdk:data]; + } }; self.hid.logCallBack = ^(NSString * _Nonnull log) { [ws showLog:log]; @@ -147,7 +178,10 @@ } } else{ - if (ws.ble.productType == AiMouseProductType_n) { + if (ws.ble.productType == AiMouseProductType_keyboard) { + [ws.kbSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; + } + else if (ws.ble.productType == AiMouseProductType_n) { [ws.nSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; } else if (ws.ble.productType == AiMouseProductType_tlw) { @@ -159,7 +193,10 @@ } }; self.ble.receiveInfoDataCallBack = ^(NSData *data) { - if (ws.productType == AiMouseProductType_n) { + if (ws.productType == AiMouseProductType_keyboard) { + [ws.kbSdk sendDeviceDataToSdk:data]; + } + else if (ws.productType == AiMouseProductType_n) { [ws.nSdk sendDeviceDataToSdk:data]; } else if (ws.productType == AiMouseProductType_tlw) { @@ -186,6 +223,9 @@ #pragma mark ------ 设备相关接口 -(BOOL)isConneted{ + if (self.kbSdk != nil && self.kbSdk.connected) { + return true; + } if (self.nSdk != nil && self.nSdk.connected) { return true; } @@ -198,6 +238,14 @@ return false; } - (NSString *)getCurrentConnectType { + if (self.productType == AiMouseProductType_keyboard) { + if (self.kbSdk.connectType == AiMouseConnectType_bluetooth) { + return @"0"; + } + else { + return @"1"; + } + } if (self.productType == AiMouseProductType_n) { if (self.nSdk.connectType == AiMouseConnectType_bluetooth) { return @"0"; @@ -224,15 +272,19 @@ } } -(AiMouseConnectType)connectType{ - if (self.productType == AiMouseProductType_n) { + if (self.productType == AiMouseProductType_keyboard) { + return self.kbSdk.connectType; + } + else if (self.productType == AiMouseProductType_n) { return self.nSdk.connectType; } else if (self.productType == AiMouseProductType_tlw) { return self.tlwSdk.connectType; } - else{ + else { return self.frkSdk.connectType; } + } - (void)begainMonitorAiMouseConnectStateDidChange:(NSString *)mouseName callBack:(void(^)(int connectType, BOOL connected))callBack{ @@ -242,7 +294,10 @@ } ///获取设备信息 - (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{ - if(self.productType == AiMouseProductType_n){ + if(self.productType == AiMouseProductType_keyboard){ + [self.kbSdk getDeviceInfo:finished]; + } + else if(self.productType == AiMouseProductType_n){ [self.nSdk getDeviceInfo:finished]; }else if (self.productType == AiMouseProductType_tlw) { [self.tlwSdk getFullDeviceInfo:finished]; @@ -254,6 +309,10 @@ /// 获取信号强度 - (void)getRSSI:(void (^)(NSString *value,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -268,6 +327,10 @@ /// 设置CPI - (void)setCPI:(NSInteger)value completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -286,6 +349,10 @@ /// - value: 品牌名称 /// - finished: 设置结果回调 - (void)setBrand:(NSString *)brand completation:(void (^)(BOOL isSuccess,NSError *error))finished { + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -300,6 +367,10 @@ /// 设置录音模式 - (void)setRecordMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -314,6 +385,10 @@ /// 设置长按滚轮弹出的网页地址 - (void)setUrl:(NSString *)url completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -328,6 +403,10 @@ /// 设置长按滚轮弹出网页开关 - (void)setUrlState:(int)state completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -342,6 +421,10 @@ /// 设置鼠标连接模式 - (void)setMouseMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -356,6 +439,10 @@ /// 获取录音模式 - (void)getRecordMode:(void (^)(int mode,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -370,6 +457,10 @@ /// 获取长按滚轮弹出的网页地址 - (void)getUrl:(void (^)(NSString *url,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -384,6 +475,10 @@ /// 获取长按滚轮弹出的网页地址开关状态 - (void)getUrlState:(void (^)(int state,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -398,6 +493,10 @@ /// 获取鼠标连接模式 - (void)getMouseModel:(void (^)(int mode,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -412,6 +511,10 @@ /// 打开录音 - (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -426,6 +529,10 @@ /// 关闭录音 - (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_n) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -620,6 +727,40 @@ - (void)nMouseAddLog:(NSString *)log{ [self showLog:log]; } +#pragma mark - keyboardDelegate +/// 设备连接状态 +/// - Parameter connected: 是否连接 +- (void)keyboardConnectStateDidChange:(BOOL)connected{ + [self showLog:[NSString stringWithFormat:@"%@设备连接状态返回: %@",self.kbSdk.connectType == AiMouseConnectType_bluetooth ? @"键盘 蓝牙 ":@"键盘 USB",connected ? @"true":@"false"]]; + + if (self.aiMouseConnectStateDidChangeCallBack) { + self.aiMouseConnectStateDidChangeCallBack(self.kbSdk.connectType == AiMouseConnectType_bluetooth ? 0:1,connected); + } + if(self.authCallBack && connected)self.authCallBack(connected); +} + + +/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备 +/// - Parameter data: 数据 +- (void)keyboardSendDeviceInfoData:(NSData *)data{ + if (self.kbSdk.connectType == AiMouseConnectType_bluetooth) { + [self.ble writeToDevice:data]; + } + else if (self.kbSdk.connectType == AiMouseConnectType_hid){ + [self.hid writeToDevice:data]; + } +} + +/// 鼠标按键指令回调 +- (void)keyboardSendCmdData:(NSData *)data{ + [self showLog:[NSString stringWithFormat:@"键盘按下 : %@",data]]; +} + +/// 输出sdk日志 +/// - Parameter log: 日志 +- (void)keyboardAddLog:(NSString *)log{ + [self showLog:log]; +} #pragma mark - AiMouseDelegate /// 设备连接状态 /// - Parameter connected: 是否连接 @@ -723,4 +864,6 @@ [self showLog:[NSString stringWithFormat:@"录音保存成功 path = %@",fullPath]]; } } + + @end diff --git a/MouseSdk/AiMouseSdk/Manager/HidManager.m b/MouseSdk/AiMouseSdk/Manager/HidManager.m index b022262..e60be39 100644 --- a/MouseSdk/AiMouseSdk/Manager/HidManager.m +++ b/MouseSdk/AiMouseSdk/Manager/HidManager.m @@ -40,26 +40,45 @@ #pragma mark - Hid CallBack /// 匹配到设备回调 static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) { - if ([DeviceManger shared].isConneted) { -// [[HidManager shared] showLog:(@"当前处于连接状态,对监听到有USB 插入 的事件不做处理")]; - return; - } -// 1ea7 0064 +// if ([DeviceManger shared].isConneted) { +// // [[HidManager shared] showLog:(@"当前处于连接状态,对监听到有USB 插入 的事件不做处理")]; +// return; +// } + // 1ea7 0064 uint32_t pid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey)); uint32_t vid = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey)); uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey)); uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey)); -// [[HidManager shared] showLog: inIOHIDDeviceRef]; - + // [[HidManager shared] showLog: inIOHIDDeviceRef]; - if((vid == 0x1ea7 && pid == 0x0064) - || (vid == 0x1ea7 && pid == 0x0066) - || (vid == 0x32c2 && pid == 0x0066) + if((vid == 0x248a && pid == 0x6092) ){ -// 现在确认是这三款: -// VID 0x1EA7 PID 0x0064 -// VID 0x1EA7 PID 0x0066 -// VID 0x32C2 PID 0x0066 + [[HidManager shared] showLog:([NSString stringWithFormat:@"发现键盘%@,pid = %d,vid = %d ,page = %d, usage = %d",inIOHIDDeviceRef,pid,vid,PrimaryUsagePage,PrimaryUsage])]; + [HidManager shared].productType = AiMouseProductType_keyboard; + [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; + //注册消息回调 + unsigned char InputBuffer[64]; + IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), &hidReceiveData, NULL); + + IOReturn result = IOHIDDeviceOpen([HidManager shared].deviceInfoCha, kIOHIDOptionsTypeNone); + if (result != kIOReturnSuccess) { + [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]]; + [[AiDeviceAuthManager shared] showHidAlert]; + return; + }else{ + [[HidManager shared] showLog:@"打开设备成功!"]; + [HidManager shared].connectStateCallBack(true) ; + } + return; + } + else if((vid == 0x1ea7 && pid == 0x0064) + || (vid == 0x1ea7 && pid == 0x0066) + || (vid == 0x32c2 && pid == 0x0066) + ){ + // 现在确认是这三款:sdsdsdsffg` + // VID 0x1EA7 PID 0x0064 + // VID 0x1EA7 PID 0x0066 + // VID 0x32C2 PID 0x0066 [[HidManager shared] showLog:([NSString stringWithFormat:@"发现设备%@,pid = %d,vid = %d ,page = %d, usage = %d",inIOHIDDeviceRef,pid,vid,PrimaryUsagePage,PrimaryUsage])]; [HidManager shared].productType = AiMouseProductType_n; @@ -95,8 +114,8 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH [[HidManager shared] showLog:@"打开设备成功!"]; [HidManager shared].connectStateCallBack(true) ; } -// CFRetain([HidManager shared].deviceInfoCha); -// IOHIDDeviceScheduleWithRunLoop([HidManager shared].deviceInfoCha, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + // CFRetain([HidManager shared].deviceInfoCha); + // IOHIDDeviceScheduleWithRunLoop([HidManager shared].deviceInfoCha, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); } else if(vid == 0x6675 && pid == 0x8601){ [HidManager shared].productType = AiMouseProductType_frk; @@ -112,8 +131,8 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH [[AiDeviceAuthManager shared] showHidAlert]; return; }else{ -// CFRetain(inIOHIDDeviceRef); -// IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + // CFRetain(inIOHIDDeviceRef); + // IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); [HidManager shared].deviceInfoCha = inIOHIDDeviceRef; [[HidManager shared] showLog:@"打开设备信息成功!"]; @@ -133,8 +152,8 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH return; return; }else{ -// CFRetain(inIOHIDDeviceRef); -// IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + // CFRetain(inIOHIDDeviceRef); + // IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); [HidManager shared].voiceCha = inIOHIDDeviceRef; [[HidManager shared] showLog:@"打开设备voice成功!"]; @@ -161,20 +180,18 @@ 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){ NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; -// [[HidManager shared] showLog:[NSString stringWithFormat:@"receive = %@",data]]; - if([HidManager shared].productType == AiMouseProductType_n){ -// if (report[0] == 0x01 || report[0] == 0x02) { -// //鼠标键盘活动事件 -// return; -// } + [[HidManager shared] showLog:[NSString stringWithFormat:@"receive = %@",data]]; + if([HidManager shared].productType == AiMouseProductType_keyboard){ uint32_t primaryUsagePage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsagePageKey)); uint32_t primaryUsage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsageKey)); - -// if(primaryUsagePage == 65461 && primaryUsage == 1){ -// if(primaryUsage == 1){ - NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; - [HidManager shared].receiveInfoDataCallBack(data); -// } + NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; + [HidManager shared].receiveInfoDataCallBack(data); + } + else if([HidManager shared].productType == AiMouseProductType_n){ + uint32_t primaryUsagePage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsagePageKey)); + uint32_t primaryUsage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsageKey)); + NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; + [HidManager shared].receiveInfoDataCallBack(data); } else if([HidManager shared].productType == AiMouseProductType_tlw){ if (report[0] == 0x01 || report[0] == 0x02) { @@ -186,13 +203,13 @@ static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDRe if(primaryUsagePage == 1 && primaryUsage == 2){ NSData *data = [[NSData alloc] initWithBytes:report length:reportLength]; -// [[HidManager shared] showLog:[NSString stringWithFormat:@"receive = %@",data]]; + // [[HidManager shared] showLog:[NSString stringWithFormat:@"receive = %@",data]]; [HidManager shared].receiveInfoDataCallBack(data); } } else{ NSData *data1 = [[NSData alloc] initWithBytes:report length:reportLength]; -// [[HidManager shared] showLog:[NSString stringWithFormat:@"receive = %@",data1]]; + // [[HidManager shared] showLog:[NSString stringWithFormat:@"receive = %@",data1]]; NSInteger len = get_data_len(report, reportLength); NSData *data = [[NSData alloc] initWithBytes:report length:len]; @@ -248,20 +265,20 @@ static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDRe [self showLog:@"关闭hid"]; -// if (self.deviceInfoCha ) { -// IOReturn result = IOHIDDeviceSetReport(self.deviceInfoCha, kIOHIDReportTypeInput, 0, NULL, 0); -// if (result!= kIOReturnSuccess) { -// [self showLog:(@"关闭deviceInfoCha 失败!")]; -// return; -// } -// } -// if (self.voiceCha ) { -// IOReturn result = IOHIDDeviceSetReport(self.voiceCha, kIOHIDReportTypeInput, 0, NULL, 0); -// if (result!= kIOReturnSuccess) { -// [self showLog:(@"关闭 voiceCha 失败!")]; -// return; -// } -// } + // if (self.deviceInfoCha ) { + // IOReturn result = IOHIDDeviceSetReport(self.deviceInfoCha, kIOHIDReportTypeInput, 0, NULL, 0); + // if (result!= kIOReturnSuccess) { + // [self showLog:(@"关闭deviceInfoCha 失败!")]; + // return; + // } + // } + // if (self.voiceCha ) { + // IOReturn result = IOHIDDeviceSetReport(self.voiceCha, kIOHIDReportTypeInput, 0, NULL, 0); + // if (result!= kIOReturnSuccess) { + // [self showLog:(@"关闭 voiceCha 失败!")]; + // return; + // } + // } IOReturn ret = IOHIDManagerClose(self.hidManager, 0); self.hidManager = nil; @@ -287,7 +304,7 @@ static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDRe if (ret != kIOReturnSuccess) { [self showLog:[NSString stringWithFormat:@"发送失败! code = %d",ret]]; }else{ -// [self showLog:@"发送成功!"]; + // [self showLog:@"发送成功!"]; } } diff --git a/MouseSdk/AiMouseSdk/Manager/MSUtilis.h b/MouseSdk/AiMouseSdk/Manager/MSUtilis.h new file mode 100644 index 0000000..4ec53eb --- /dev/null +++ b/MouseSdk/AiMouseSdk/Manager/MSUtilis.h @@ -0,0 +1,16 @@ +// +// MSUtilis.h +// AiMouseManager +// +// Created by incar on 2024/11/18. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MSUtilis : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/Manager/MSUtilis.m b/MouseSdk/AiMouseSdk/Manager/MSUtilis.m new file mode 100644 index 0000000..4c46077 --- /dev/null +++ b/MouseSdk/AiMouseSdk/Manager/MSUtilis.m @@ -0,0 +1,12 @@ +// +// MSUtilis.m +// AiMouseManager +// +// Created by incar on 2024/11/18. +// + +#import "MSUtilis.h" + +@implementation MSUtilis + +@end diff --git a/MouseSdk/AiMouseSdk/Manager/TimerManager.m b/MouseSdk/AiMouseSdk/Manager/TimerManager.m index 331ff84..87d4517 100644 --- a/MouseSdk/AiMouseSdk/Manager/TimerManager.m +++ b/MouseSdk/AiMouseSdk/Manager/TimerManager.m @@ -32,7 +32,7 @@ // [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; // [[NSRunLoop currentRunLoop] run]; // }); - self.timer = [NSTimer scheduledTimerWithTimeInterval:8 target:self selector:@selector(timerAction) userInfo:nil repeats:true]; + self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:true]; } - (void)timerAction{ diff --git a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate index de7d8c9..a6412bf 100644 Binary files a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate and b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index c3ddbcd..64ee367 100644 --- a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -40,5 +40,21 @@ + + + + diff --git a/MouseSdk/MouseSdk/ViewController.m b/MouseSdk/MouseSdk/ViewController.m index f7ea11e..85ecaf6 100644 --- a/MouseSdk/MouseSdk/ViewController.m +++ b/MouseSdk/MouseSdk/ViewController.m @@ -102,7 +102,7 @@ dispatch_async(dispatch_get_main_queue(), ^{ ws.authLabel.stringValue = isSuccess?@"鉴权状态:鉴权成功":@"鉴权状态:鉴权失败"; if(isSuccess){ - [ws geviceInfoAction]; + [ws geviceInfoAction]; } }); }; @@ -161,7 +161,7 @@ } - (void)setUrlState:(NSMenuItem*)sender{ - [[DeviceManger shared] setUrlState:1 completation:^(BOOL isSuccess, NSError * _Nonnull error) { + [[DeviceManger shared] setUrlState:0 completation:^(BOOL isSuccess, NSError * _Nonnull error) { NSLog(isSuccess? @"设置滚轮开关成功":@"设置滚轮开关失败"); }]; }