From: liangzhenying <867174124@qq.com> Date: Thu, 17 Apr 2025 09:46:14 +0000 (+0800) Subject: M8蓝牙调试 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=aa079e83aa4f45faf5bed65bd50829f04a79a5c1;p=mirrors%2FMouseSdk-MacOS.git M8蓝牙调试 --- diff --git "a/Document/\346\226\260/21744613056_.pic.jpg" "b/Document/\346\226\260/21744613056_.pic.jpg" new file mode 100644 index 0000000..087f622 Binary files /dev/null and "b/Document/\346\226\260/21744613056_.pic.jpg" differ diff --git "a/Document/\346\226\260/Mouse_Dongle\351\200\232\344\277\241\345\215\217\350\256\256_v1.3.pdf" "b/Document/\346\226\260/Mouse_Dongle\351\200\232\344\277\241\345\215\217\350\256\256_v1.3.pdf" new file mode 100644 index 0000000..3ce7cd7 Binary files /dev/null and "b/Document/\346\226\260/Mouse_Dongle\351\200\232\344\277\241\345\215\217\350\256\256_v1.3.pdf" differ diff --git "a/Document/\346\226\260/WX20250416-114056.png" "b/Document/\346\226\260/WX20250416-114056.png" new file mode 100644 index 0000000..74da006 Binary files /dev/null and "b/Document/\346\226\260/WX20250416-114056.png" differ diff --git "a/Document/\346\226\260/m8_log.txt" "b/Document/\346\226\260/m8_log.txt" new file mode 100644 index 0000000..9d7b0ff --- /dev/null +++ "b/Document/\346\226\260/m8_log.txt" @@ -0,0 +1,45 @@ +12:04:56.2000: connected in underlying BLE layer. +12:05:02.2080: discovered services: ( + "Device Information", + "Human Interface Device", + AE00, + AE40, + Battery, + FF00 +) +12:05:02.3330: discovered characteristics for service 180A: ( + "Manufacturer Name String", + "Model Number String", + "Serial Number String", + "Hardware Revision String", + "Firmware Revision String", + "Software Revision String", + "System ID", + "IEEE Regulatory Certification", + "PnP ID" +) +12:05:02.4490: discovered characteristics for service 180F: ( + "Battery Level" +) +12:05:02.5110: discovered characteristics for service AE40: ( + AE41, + AE42 +) +12:05:02.5690: discovered characteristics for service FF00: ( + FF01, + FF02, + FF03 +) +12:05:02.6300: discovered characteristics for service AE00: ( + AE01, + AE02 +) +12:05:02.6300: state changed to 'Connected'. +12:05:03.0050: updated subscription state for characteristic 2A19___180F: subscribed +12:05:03.0340: received update from characteristic 2A19___180F: <3c> +12:05:03.0640: received update from characteristic 2A25___180A: <5342544a 30313445 31453030 30303030 4136> +12:05:03.3290: received update from characteristic 2A23___180A: <00000000 00000000> +12:05:03.4490: received update from characteristic 2A27___180A: <312e302e 30> +12:05:03.5610: received update from characteristic 2A28___180A: <4d38> +12:05:03.6340: received update from characteristic 2A29___180A: <4a594420 5368656e 5a68656e> +12:05:03.6640: received update from characteristic 2A24___180A: <42542d30 574d4f2d 74623732 2d323430 34313830 315458> \ No newline at end of file diff --git "a/Document/\346\226\260/\346\234\261\345\233\275\345\267\247\351\274\240\346\240\207.docx" "b/Document/\346\226\260/\346\234\261\345\233\275\345\267\247\351\274\240\346\240\207.docx" new file mode 100644 index 0000000..bf28c09 Binary files /dev/null and "b/Document/\346\226\260/\346\234\261\345\233\275\345\267\247\351\274\240\346\240\207.docx" differ diff --git "a/Document/\346\226\260/\350\257\255\351\237\263\351\274\240\346\240\207\350\223\235\347\211\231\351\200\232\344\277\241\346\216\245\345\217\243v2.0.3.docx" "b/Document/\346\226\260/\350\257\255\351\237\263\351\274\240\346\240\207\350\223\235\347\211\231\351\200\232\344\277\241\346\216\245\345\217\243v2.0.3.docx" new file mode 100644 index 0000000..cfd9653 Binary files /dev/null and "b/Document/\346\226\260/\350\257\255\351\237\263\351\274\240\346\240\207\350\223\235\347\211\231\351\200\232\344\277\241\346\216\245\345\217\243v2.0.3.docx" differ diff --git a/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj index 78fe40c..8b758b5 100644 --- a/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj +++ b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj @@ -429,6 +429,14 @@ 3FCF53502D1A5C97007EC52F /* LogManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FCF534D2D1A5C97007EC52F /* LogManager.h */; }; 3FCF53512D1A5C97007EC52F /* LogManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FCF534D2D1A5C97007EC52F /* LogManager.h */; }; 3FCF53522D1A5C97007EC52F /* LogManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FCF534E2D1A5C97007EC52F /* LogManager.m */; }; + 3FF3D7372DAE442C008EBA5D /* M8MouseSdk.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FF3D7352DAE442C008EBA5D /* M8MouseSdk.h */; }; + 3FF3D7382DAE442C008EBA5D /* M8MouseSdk.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FF3D7362DAE442C008EBA5D /* M8MouseSdk.m */; }; + 3FF3D7392DAE442C008EBA5D /* M8MouseSdk.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FF3D7352DAE442C008EBA5D /* M8MouseSdk.h */; }; + 3FF3D73A2DAE442C008EBA5D /* M8MouseSdk.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FF3D7362DAE442C008EBA5D /* M8MouseSdk.m */; }; + 3FF3D75C2DAFA0BC008EBA5D /* M8MouseInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FF3D75B2DAFA0BC008EBA5D /* M8MouseInfo.m */; }; + 3FF3D75D2DAFA0BC008EBA5D /* M8MouseInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FF3D75A2DAFA0BC008EBA5D /* M8MouseInfo.h */; }; + 3FF3D75E2DAFA0BC008EBA5D /* M8MouseInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FF3D75A2DAFA0BC008EBA5D /* M8MouseInfo.h */; }; + 3FF3D75F2DAFA0BC008EBA5D /* M8MouseInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FF3D75B2DAFA0BC008EBA5D /* M8MouseInfo.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -654,6 +662,10 @@ 3F5CE3E62D1E7BCA00A5628A /* libAiMouseSdk copy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libAiMouseSdk copy.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 3FCF534D2D1A5C97007EC52F /* LogManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogManager.h; sourceTree = ""; }; 3FCF534E2D1A5C97007EC52F /* LogManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LogManager.m; sourceTree = ""; }; + 3FF3D7352DAE442C008EBA5D /* M8MouseSdk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = M8MouseSdk.h; sourceTree = ""; }; + 3FF3D7362DAE442C008EBA5D /* M8MouseSdk.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = M8MouseSdk.m; sourceTree = ""; }; + 3FF3D75A2DAFA0BC008EBA5D /* M8MouseInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = M8MouseInfo.h; sourceTree = ""; }; + 3FF3D75B2DAFA0BC008EBA5D /* M8MouseInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = M8MouseInfo.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -707,6 +719,7 @@ 180E7A9D2BD7BB12008558E8 = { isa = PBXGroup; children = ( + 3FF3D7562DAFA058008EBA5D /* M8 */, 18E0C5842D0FF84A0093BA8F /* ByteDance */, 1899600D2CEAD78B0042505F /* Keyboard */, 18D579FF2C91733E003D5714 /* NMouseSdk */, @@ -1116,6 +1129,17 @@ path = TlwMouseSdk; sourceTree = ""; }; + 3FF3D7562DAFA058008EBA5D /* M8 */ = { + isa = PBXGroup; + children = ( + 3FF3D7352DAE442C008EBA5D /* M8MouseSdk.h */, + 3FF3D7362DAE442C008EBA5D /* M8MouseSdk.m */, + 3FF3D75A2DAFA0BC008EBA5D /* M8MouseInfo.h */, + 3FF3D75B2DAFA0BC008EBA5D /* M8MouseInfo.m */, + ); + path = M8; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -1200,6 +1224,7 @@ 180E7C982BD8FC4E008558E8 /* rational.h in Headers */, 18EF7B022C7603E800AC5223 /* TlwTools.h in Headers */, 180E7CF82BD8FC4F008558E8 /* codec_id.h in Headers */, + 3FF3D75E2DAFA0BC008EBA5D /* M8MouseInfo.h in Headers */, 180E7C9B2BD8FC4E008558E8 /* avconfig.h in Headers */, 180E7CDA2BD8FC4E008558E8 /* avassert.h in Headers */, 180E7CCA2BD8FC4E008558E8 /* channel_layout.h in Headers */, @@ -1247,6 +1272,7 @@ 180E7CDB2BD8FC4E008558E8 /* hash.h in Headers */, 180E7B562BD7BD83008558E8 /* AiMouseConfig.h in Headers */, 180E7CF42BD8FC4F008558E8 /* codec.h in Headers */, + 3FF3D7392DAE442C008EBA5D /* M8MouseSdk.h in Headers */, 180E7C8D2BD8FC4E008558E8 /* detection_bbox.h in Headers */, 180E7CEF2BD8FC4F008558E8 /* videotoolbox.h in Headers */, 180E7CFF2BD8FC4F008558E8 /* version.h in Headers */, @@ -1357,6 +1383,7 @@ 18862B452C806BD900D3564D /* version.h in Headers */, 18862B462C806BD900D3564D /* ffversion.h in Headers */, 18862B472C806BD900D3564D /* intreadwrite.h in Headers */, + 3FF3D75D2DAFA0BC008EBA5D /* M8MouseInfo.h in Headers */, 18862B482C806BD900D3564D /* AFURLRequestSerialization.h in Headers */, 18862B492C806BD900D3564D /* buffer.h in Headers */, 18862B4A2C806BD900D3564D /* twofish.h in Headers */, @@ -1427,6 +1454,7 @@ 18862B8E2C806BD900D3564D /* AiMouseSdk.h in Headers */, 18862B8F2C806BD900D3564D /* qsv.h in Headers */, 18862B902C806BD900D3564D /* hmac.h in Headers */, + 3FF3D7372DAE442C008EBA5D /* M8MouseSdk.h in Headers */, 18862B912C806BD900D3564D /* AFNetworking.h in Headers */, 18862B922C806BD900D3564D /* threadmessage.h in Headers */, 18862B932C806BD900D3564D /* adpcm.h in Headers */, @@ -1555,8 +1583,10 @@ 180E7BE72BD7BD84008558E8 /* AiAudioManager.m in Sources */, 18EF7AFB2C7603E800AC5223 /* TlwTools.m in Sources */, 18EF7AFA2C7603E800AC5223 /* TlwMouseSdk.m in Sources */, + 3FF3D73A2DAE442C008EBA5D /* M8MouseSdk.m in Sources */, 18862A282C8064E300D3564D /* BleManager.m in Sources */, 188814C42C85C2BB009299A9 /* AESCBCHelper.m in Sources */, + 3FF3D75F2DAFA0BC008EBA5D /* M8MouseInfo.m in Sources */, 180E7BDF2BD7BD84008558E8 /* AiMouseConfig.m in Sources */, 18EF7AFC2C7603E800AC5223 /* AiConnectManager.m in Sources */, 181CE5C22C6EED9900EF8D07 /* AiAliAuthManager.m in Sources */, @@ -1599,8 +1629,10 @@ 188814C52C85C2BB009299A9 /* AESCBCHelper.m in Sources */, 18862BC62C806BD900D3564D /* AiMouseConfig.m in Sources */, 18862BC72C806BD900D3564D /* AiConnectManager.m in Sources */, + 3FF3D7382DAE442C008EBA5D /* M8MouseSdk.m in Sources */, 18862BC82C806BD900D3564D /* AiAliAuthManager.m in Sources */, 18862BC92C806BD900D3564D /* AFSecurityPolicy.m in Sources */, + 3FF3D75C2DAFA0BC008EBA5D /* M8MouseInfo.m in Sources */, 18862BCA2C806BD900D3564D /* DeviceManger.m in Sources */, 18862BCB2C806BD900D3564D /* AiAudioDecoder.m in Sources */, 18862BCC2C806BD900D3564D /* AiDeviceInfoManager.m in Sources */, diff --git a/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist index 27157b9..64bd978 100644 --- a/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ AiMouseSdk copy.xcscheme_^#shared#^_ orderHint - 4 + 2 AiMouseSdk.xcscheme_^#shared#^_ diff --git a/MouseSdk/AiMouseSdk/M8/M8MouseInfo.h b/MouseSdk/AiMouseSdk/M8/M8MouseInfo.h new file mode 100644 index 0000000..2a7ab5d --- /dev/null +++ b/MouseSdk/AiMouseSdk/M8/M8MouseInfo.h @@ -0,0 +1,17 @@ +// +// M8MouseInfo.h +// AiMouseSdk +// +// Created by liangshi on 2025/4/16. +// + +#import + +@interface M8MouseInfo : NSObject +@property (nonatomic, strong) NSString *battery_power;/// 电池百分百电量,0-100 +@property (nonatomic, strong) NSString *version;///软件版本 +@property (nonatomic, strong) NSString *brand;/// 品牌名称 +@property (nonatomic, strong) NSString *sn;/// 设备序列号 +/// ++(M8MouseInfo *)shared; +@end diff --git a/MouseSdk/AiMouseSdk/M8/M8MouseInfo.m b/MouseSdk/AiMouseSdk/M8/M8MouseInfo.m new file mode 100644 index 0000000..34de1cc --- /dev/null +++ b/MouseSdk/AiMouseSdk/M8/M8MouseInfo.m @@ -0,0 +1,28 @@ +// +// M8MouseInfo.m +// AiMouseSdk +// +// Created by liangshi on 2025/4/16. +// + +#import "M8MouseInfo.h" + +@implementation M8MouseInfo + ++(M8MouseInfo *)shared{ + static M8MouseInfo *manager = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + manager = [[M8MouseInfo alloc]init]; + }); + return manager; +} + +- (instancetype)init{ + self = [super init]; + if (self) { + + } + return self; +} +@end diff --git a/MouseSdk/AiMouseSdk/M8/M8MouseSdk.h b/MouseSdk/AiMouseSdk/M8/M8MouseSdk.h new file mode 100644 index 0000000..12c289b --- /dev/null +++ b/MouseSdk/AiMouseSdk/M8/M8MouseSdk.h @@ -0,0 +1,81 @@ +// +// M8MouseSdk.h +// AiMouseSdk +// +// Created by liangshi on 2025/4/15. +// + +#import +#import "AiMouseSdk.h" +@protocol M8MouseSdkDelegate + +/// 设备连接状态 +/// - Parameter connected: 是否连接 +- (void)m8MouseConnectStateDidChange:(BOOL)connected; + + +/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备 +/// - Parameter data: 数据 +- (void)m8MouseSendDeviceInfoData:(NSData *)data; + +/// 鼠标按键指令回调 +/// - Parameter data: 数据。 +//EF AA 0B 00 02 E1 00 E3 语音键单击开始 +//EF AA 0C 00 02 E1 00 E3 语音键单击结束 +//EF AA 05 00 02 E1 00 E3 语音键长按 +//EF AA 06 00 02 E1 00 E3 语音键长按松开 +// +// +//EF AA 09 00 02 E1 00 E3 M键单击 +//EF AA 01 00 02 E1 00 E3 M键长按松开 +//EF AA 02 00 02 E1 00 E3 M键长按松开 +// +//EF AA 0A 00 02 E1 00 E3 AI键单击 +//EF AA 03 00 02 E1 00 E3 AI键长按松开 +//EF AA 04 00 02 E1 00 E3 AI键长按松开 +// +//EF AA 0D 00 02 E1 00 E3 翻译键单击开始 +//EF AA 0E 00 02 E1 00 E3 翻译键单击结束 +//EF AA 07 00 02 E1 00 E3 翻译键长按 +//EF AA 08 00 02 E1 00 E3 翻译键长按松开 +/// 其他未定义 +- (void)m8MouseSendCmdData:(NSData *)data; + +/// 录音回调 +/// - Parameter data: pcm格式语音数据 +- (void)m8MouseSendRecordData:(NSData *)data; + +/// hid数据异常,需要重新开启监听usb设备 +- (void)m8HidDataError; + +/// 输出sdk日志 +/// - Parameter log: 日志 +- (void)m8MouseAddLog:(NSString *)log; + +@end + +@interface M8MouseSdk : NSObject +@property (nonatomic, weak) id delegate;/// 代理 +@property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型 +@property (nonatomic, readonly) BOOL connected;//是否已连接 + +/// 断开连接 +- (void)didDisconnect; + +/// 切换连接类型 +/// - Parameter type: 连接类型 +- (void)switchConnect:(AiMouseConnectType)type isConnected:(BOOL)isConneted; + +/// 传输业务数据给sdk +/// - Parameter data:ai特征传过来的数据 +- (void)sendAiDataToSdk:(NSData *)data; + +/// 传输设备信息数据给sdk +/// - Parameter data:设备信息特征传过来的数据 +- (void)sendDeviceDataToSdk:(NSData *)data; + +/// 获取设备信息 +/// - Parameter completation: 如果获取成功,则deviceInfo有值,否则为nil +- (void)getFullDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished; + +@end diff --git a/MouseSdk/AiMouseSdk/M8/M8MouseSdk.m b/MouseSdk/AiMouseSdk/M8/M8MouseSdk.m new file mode 100644 index 0000000..8206b95 --- /dev/null +++ b/MouseSdk/AiMouseSdk/M8/M8MouseSdk.m @@ -0,0 +1,336 @@ +// +// M8MouseSdk.m +// AiMouseSdk +// +// Created by liangshi on 2025/4/15. +// + +#import "M8MouseSdk.h" +#import "TlwAudioManager.h" +#import "TlwTools.h" +#import "AiRecordManager.h" +#import "M8MouseInfo.h" +@interface M8MouseSdk() + +@property (nonatomic, strong) TlwAudioManager *audioManager; +@property (nonatomic, strong) AiRecordManager *recordManager; + +@property (nonatomic,strong)void (^dongleStateCallBack)(BOOL success); +@property (nonatomic,assign)NSInteger dongleTimes; + +@property (nonatomic,strong)AiMouseDeviceInfo *fullInfo; +@property (nonatomic,assign)NSInteger questTimes; +@end + +@implementation M8MouseSdk + +-(instancetype)init{ + if (self = [super init]) { + _connectType = AiMouseConnectType_bluetooth; + // NSLog(@"[TlwMouseSdk]%@",[NSString stringWithFormat:@"AiMouseSdk_v%@",self.version]); + [self.recordManager checkPermissions]; + } + return self; +} + +-(NSString *)version{ + return @"1.0.2"; +} + +-(TlwAudioManager *)audioManager{ + if (!_audioManager) { + _audioManager = [[TlwAudioManager alloc] init]; + __weak typeof(self) ws = self; + _audioManager.decodeCallBack = ^(NSData * _Nonnull data) { + [ws sendRecordData:data]; + }; + _audioManager.outputLog = ^(NSString * _Nonnull log) { + [ws showLog:log]; + }; + } + return _audioManager; +} + +- (AiRecordManager *)recordManager{ + if (!_recordManager) { + _recordManager = [[AiRecordManager alloc] init]; + __weak typeof(self) ws = self; + _recordManager.didRecordData = ^(NSData * _Nonnull data) { + [ws showLog:[NSString stringWithFormat:@"%@",data]]; + [ws sendRecordData:data]; + }; + } + return _recordManager; +} +- (void)sendOpenCmd{ + uint8_t cmd = 0x0D; + uint8_t len = 0x00; + uint8_t tail = 0xEF; + NSMutableData *mData = NSMutableData.data; + [mData appendData:[self getHidHeader]]; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&len length:1]; + [mData appendBytes:&tail length:1]; + [self sendToDevice:mData]; +} + +#pragma mark - pub Api +- (void)didDisconnect{ + _connected = false; + [self stopRecord]; +} + +- (void)switchConnect:(AiMouseConnectType)type isConnected:(BOOL)isConneted{ + [NSObject cancelPreviousPerformRequestsWithTarget:self]; + if(isConneted ){ + _connected = true; + _connectType = type; + [self showLog:type == AiMouseConnectType_bluetooth?@"sdk切换到蓝牙模式":@"sdk切换到usb模式"]; + +// if (type == AiMouseConnectType_hid ) { +// [self.recordManager checkPermissions]; +// // [self sendOpenCmd]; +// [self checkDongleState]; +// } +// else{ + [self TlwConnectManager:nil connectStateDidChange:true]; +// } + } + else{ + [self stopRecord]; + if (self.connected) { + _connected = false; + [self TlwConnectManager:nil connectStateDidChange:false]; + } + } +} + +- (void)sendAiDataToSdk:(NSData *)data{ + [self showLog:[NSString stringWithFormat:@"[receive][Voice] %@",data]]; + if(self.connectType == AiMouseConnectType_hid){ + } + else if (self.connectType == AiMouseConnectType_bluetooth){ + [self bleReceiveAiData:data]; + } +} + +-(void)sendDeviceDataToSdk:(NSData *)data{ + if(self.connectType == AiMouseConnectType_hid){ + [self showLog:[NSString stringWithFormat:@"[receive][usb][info] %@",[TlwTools dataToHexString:data]]]; + [self hidReceiveDeviceData:data]; + } + else if (self.connectType == AiMouseConnectType_bluetooth){ + [self showLog:[NSString stringWithFormat:@"[receive][ble][info] %@",[TlwTools dataToHexString:data]]]; + [self bleReceiveDeviceData:data]; + } +} + +- (void)getFullDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{ + AiMouseDeviceInfo *info = [[AiMouseDeviceInfo alloc] init]; + info.type = 0; + info.battery_power = M8MouseInfo.shared.battery_power; + info.version = M8MouseInfo.shared.version; + info.brand = M8MouseInfo.shared.brand; + info.sn = M8MouseInfo.shared.sn; + info.mac = info.sn; + info.CPI_list = @"2400"; + info.CPI = @"2400"; + self.fullInfo = info; + finished(info,nil); + +} + +#pragma mark - check dongle +- (void)checkDongleState{ + self.dongleTimes = 0; + __weak typeof(self) ws = self; + [self checkDongleStateAction:^(BOOL success) { + ws.dongleStateCallBack = nil; + if (success) { + [ws TlwConnectManager:nil connectStateDidChange:true]; + } + else{ + [ws TlwConnectManager:nil connectStateDidChange:false]; + } + }]; +} +- (void)checkDongleStateAction:(void (^)(BOOL success))finished{ + self.dongleStateCallBack = finished; + [self performSelector:@selector(sendDongleCmd) withObject:nil afterDelay:1]; +} +- (void)sendDongleCmd{ + self.dongleTimes++; + if ( self.dongleStateCallBack == nil) { + return; + } + if (self.dongleTimes > 2) { + [self TlwConnectManager:nil connectStateDidChange:false]; + return; + } + uint8_t cmd = 0x0D; + uint8_t len = 0x00; + uint8_t tail = 0xEF; + NSMutableData *mData = NSMutableData.data; + [mData appendData:[self getHidHeader]]; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&len length:1]; + [mData appendBytes:&tail length:1]; + [self sendToDevice:mData]; + [self performSelector:@selector(sendDongleCmd) withObject:nil afterDelay:1]; +} +#pragma mark - ble +- (void)bleReceiveAiData:(NSData *)data{ + [self.audioManager receiveData:data]; +} + +-(void)bleReceiveDeviceData:(NSData *)data{ + uint8 type; + [ [data subdataWithRange:NSMakeRange(0, 1)] getBytes:&type length:1]; + + uint8 len; + [[data subdataWithRange:NSMakeRange(1, 1)] getBytes:&len length:1]; + + switch (type) { + case 0xef: + { + //鼠标按键上报 + NSData *subData = [data subdataWithRange:NSMakeRange(2, 1)]; + [self sendCmdData:subData]; + break; + } + default: + break; + } +} + +#pragma mark - hid +- (void)hidReceiveDeviceData:(NSData *)data{ + // 0x05fff1fec09f0114ef + if(data.length < 7 ){ + [self showLog:@"收到异常数据"]; + return; + } + if(![[[TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(1, 2)]] lowercaseString] isEqualToString:@"fff1"]){ + [self showLog:@"收到异常数据"]; + return; + } + + uint8 type; + [[data subdataWithRange:NSMakeRange(5, 1)] getBytes:&type length:1]; + + NSData *lenData = [data subdataWithRange:NSMakeRange(6, 1)]; + uint8 len; + [lenData getBytes:&len length:1]; + + switch (type) { + + case 0x9d: + { + uint16_t version; + [[data subdataWithRange:NSMakeRange(7, 2)] getBytes:&version length:2]; + + uint8_t state; + [[data subdataWithRange:NSMakeRange(9, 1)] getBytes:&state length:1]; + + [self showLog:[NSString stringWithFormat:@"dongle version = %d,bind = %d",version,state]]; + if(self.dongleStateCallBack)self.dongleStateCallBack(state == 1); + break; + } + case 0x9f: + { + NSData *subData = [data subdataWithRange:NSMakeRange(7, 1)]; + [self sendCmdData:subData]; + + uint8 cmd; + [subData getBytes:&cmd length:1]; + + if(cmd == 0x04 || cmd == 0x07 || cmd == 0x13 || cmd == 0x11 || cmd == 0x01 ||cmd == 0x09){ + self.recordManager.startCmd = subData; + [self startRecord]; + } + else if(cmd == 0x05 || cmd == 0x08 || cmd == 0x14 || cmd == 0x12 || cmd == 0x02 ||cmd == 0x10){ + [self stopRecord]; + } + break; + } + + default: + break; + } +} +- (NSData *)getHidHeader{ + uint8_t head1 = 0x05; + uint16_t head2 = 0xF1FF; + uint8_t head3 = 0xfe; + uint8_t head4 = 0x00; + + NSMutableData *mData = NSMutableData.data; + [mData appendBytes:&head1 length:1]; + [mData appendBytes:&head2 length:2]; + [mData appendBytes:&head3 length:1]; + [mData appendBytes:&head4 length:1]; + + return mData; +} +#pragma mark - other +- (void)sendRecordData:(NSData *)data{ + [self showLog:[NSString stringWithFormat:@"[send][audio] %@",data]]; + if (self.delegate) [self.delegate m8MouseSendRecordData:data]; +} + +- (void)sendCmdData:(NSData *)data{ + [self showLog:[NSString stringWithFormat:@"[send] %@",data]]; + if (self.delegate) [self.delegate m8MouseSendCmdData:data]; +} + +- (void)showLog:(NSString *)log{ + if (self.delegate && [self.delegate respondsToSelector:@selector(m8MouseAddLog:)]) { + [self.delegate m8MouseAddLog:[NSString stringWithFormat:@"[m8]%@",log]]; + } +} + + +- (void)sendToDevice:(NSMutableData *)data{ + if (data.length < 64) { + NSInteger len = 64 - data.length; + for (NSInteger i = 0; i < len; i++) { + uint8_t d = 0x00; + [data appendBytes:&d length:1]; + } + } + [self showLog:[NSString stringWithFormat:@"[send][info] %@",[TlwTools dataToHexString:data]]]; + [self.delegate m8MouseSendDeviceInfoData:data]; +} +#pragma mark - deviceInfo +- (void)startRecord{ + [self.recordManager start]; +} + +- (void)stopRecord{ + if (self.recordManager.recording ) { + [self.recordManager stop]; + } +} + +#pragma mark - other +-(void)TlwConnectManager:(NSString *)manager connectStateDidChange:(BOOL)connected{ + _connected = connected; + [self showLog:[NSString stringWithFormat:@"连接状态 %@",connected ? @"true":@"false"]]; + if([self.delegate respondsToSelector:@selector(m8MouseConnectStateDidChange:)]) [self.delegate m8MouseConnectStateDidChange:connected]; +} + +- (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/BleManager.h b/MouseSdk/AiMouseSdk/Manager/BleManager.h index 07f3c3b..a704bfa 100644 --- a/MouseSdk/AiMouseSdk/Manager/BleManager.h +++ b/MouseSdk/AiMouseSdk/Manager/BleManager.h @@ -17,11 +17,6 @@ @property (nonatomic, copy)void (^logCallBack)(NSString *log);//输出日志 @property (nonatomic, assign)AiMouseProductType productType;// -//- (void)startScan; - -//- (void)stopScan; - -//- (void)start; - (void)open; diff --git a/MouseSdk/AiMouseSdk/Manager/BleManager.m b/MouseSdk/AiMouseSdk/Manager/BleManager.m index 6c7eb7f..7772f53 100644 --- a/MouseSdk/AiMouseSdk/Manager/BleManager.m +++ b/MouseSdk/AiMouseSdk/Manager/BleManager.m @@ -6,7 +6,8 @@ // #import "BleManager.h" - +#import "TlwTools.h" +#import "M8MouseInfo.h" // 服务id #define kFrkServiceUUID @"FFF1" //ai特征 @@ -23,12 +24,18 @@ //通知设备信息特征 #define kTlwNotifyDeviceInfoUUID @"FFF2" +// 服务id +#define kM8ServiceUUID @"FF00" +//voice特征 +#define kM8VoiceUUID @"AE42" +#define kM8ClickUUID @"FF03" + + @interface BleManager () @property(nonatomic, strong) CBCentralManager *centralManager;///蓝牙管理 @property(nonatomic, strong) CBPeripheral *curentPeripheral;//连接的设备 @property(nonatomic, strong) CBCharacteristic *deviceInfoCha;//设备信息特征 -@property (nonatomic,strong) NSMutableData *recordData;//录音的数据 @property (nonatomic, strong) NSTimer *timer; @property (nonatomic, strong) dispatch_queue_t mainQueue; @@ -106,7 +113,57 @@ // 发现特征 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { - + for (CBCharacteristic *characteristic in service.characteristics){ + [self showLog:characteristic.UUID.UUIDString]; + if ([characteristic.UUID.UUIDString isEqualToString:@"2A25"]) { + M8MouseInfo.shared.sn = [TlwTools dataToUtf8String:characteristic.value]; + } + else if ([characteristic.UUID.UUIDString isEqualToString:@"2A19"]) { + NSData *data = characteristic.value; + int result; + [data getBytes:&result length:1]; + M8MouseInfo.shared.battery_power = [NSString stringWithFormat:@"%d",result]; + } + else if ([characteristic.UUID.UUIDString isEqualToString:@"2A24"]) { + M8MouseInfo.shared.brand = [TlwTools dataToUtf8String:characteristic.value]; + } + else if ([characteristic.UUID.UUIDString isEqualToString:@"2A26"]) { + M8MouseInfo.shared.version = [TlwTools dataToUtf8String:characteristic.value]; + [self showLog:[NSString stringWithFormat:@"Firmware Revision = %@",[TlwTools dataToUtf8String:characteristic.value]]]; + } + else if ([characteristic.UUID.UUIDString isEqualToString:@"2A28"]) { + [self showLog:[NSString stringWithFormat:@"Software Revision = %@",[TlwTools dataToUtf8String:characteristic.value]]]; + } +// else if ([characteristic.UUID.UUIDString isEqualToString:@"2A27"]) { +// [self showLog:[NSString stringWithFormat:@"Hardware Revision = %@",[TlwTools dataToUtf8String:characteristic.value]]]; +// } +// + +// else if ([characteristic.UUID.UUIDString isEqualToString:@"2A23"]) { +// [self showLog:[NSString stringWithFormat:@"System ID = %@",[TlwTools dataToUtf8String:characteristic.value]]]; +// } +// else if ([characteristic.UUID.UUIDString isEqualToString:@"2A2A"]) { +// [self showLog:[NSString stringWithFormat:@"PnP ID = %@",[TlwTools dataToUtf8String:characteristic.value]]]; +// } +// else if ([characteristic.UUID.UUIDString isEqualToString:@"2A29"]) { +// [self showLog:[NSString stringWithFormat:@"Manufacturer Name = %@",[TlwTools dataToUtf8String:characteristic.value]]]; +// } + else if ([characteristic.UUID.UUIDString isEqualToString:kM8ClickUUID]) { + [peripheral setNotifyValue:YES forCharacteristic:characteristic]; + } + else if ([characteristic.UUID.UUIDString isEqualToString:kM8VoiceUUID]) { + //语音特征 + [peripheral setNotifyValue:YES forCharacteristic:characteristic]; + self.productType = AiMouseProductType_m8; +// dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC); +// dispatch_after(delayTime, dispatch_get_main_queue(), ^{ + [self showLog:[NSString stringWithFormat:@"连接成功 = %@",peripheral.name]]; + self.connectStateCallBack(self.curentPeripheral.name,true); +// }); + } + [self showLog:[NSString stringWithFormat:@"%@",characteristic]]; + } +// return; for (CBCharacteristic *characteristic in service.characteristics){ if ([characteristic.UUID.UUIDString isEqualToString:kFrkVoiceUUID]) { //语音特征 @@ -146,12 +203,45 @@ self.deviceInfoCha = characteristic; } } + + for (CBCharacteristic *characteristic in service.characteristics){ + if ([characteristic.UUID.UUIDString isEqualToString:kM8VoiceUUID]) { + //语音特征 + [peripheral setNotifyValue:YES forCharacteristic:characteristic]; + } + else if ([characteristic.UUID.UUIDString isEqualToString:kTlwNotifyDeviceInfoUUID]) { + //通知设备信息特征 + [peripheral setNotifyValue:YES forCharacteristic:characteristic]; + self.productType = AiMouseProductType_tlw; + // 使用dispatch_after来延迟执行任务 + dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC); + dispatch_after(delayTime, dispatch_get_main_queue(), ^{ + [self showLog:[NSString stringWithFormat:@"连接成功 = %@",peripheral.name]]; + self.connectStateCallBack(self.curentPeripheral.name,true); + }); + } + else if ([characteristic.UUID.UUIDString isEqualToString:kTlwSetDeviceInfoUUID]) { + //设备信息特征 + self.deviceInfoCha = characteristic; + } + } } //收到蓝牙数据 - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { - if (self.productType == AiMouseProductType_tlw) { + if (self.productType == AiMouseProductType_m8) { NSData *data = characteristic.value; - if([characteristic.UUID.UUIDString isEqualToString:kTlwVoiceUUID]){ + if( [characteristic.UUID.UUIDString isEqualToString:kM8ClickUUID]){ + self.receiveInfoDataCallBack(data); + } + else{ + if([characteristic.UUID.UUIDString isEqualToString:kM8VoiceUUID] ){ + self.receiveVoiceDataCallBack(data); + } + } + } + else if (self.productType == AiMouseProductType_tlw) { + NSData *data = characteristic.value; + if([characteristic.UUID.UUIDString isEqualToString:kTlwVoiceUUID] || [characteristic.UUID.UUIDString isEqualToString:kM8VoiceUUID] ){ self.receiveVoiceDataCallBack(data); } else if([characteristic.UUID.UUIDString isEqualToString:kTlwNotifyDeviceInfoUUID]){ @@ -172,7 +262,7 @@ - (void)checkRightDevice{ for (CBService *s in self.curentPeripheral.services) { for (CBCharacteristic *c in s.characteristics) { - if([c.UUID.UUIDString isEqualToString:kFrkVoiceUUID] ||[c.UUID.UUIDString isEqualToString:kTlwVoiceUUID] ){ + if([c.UUID.UUIDString isEqualToString:kFrkVoiceUUID] ||[c.UUID.UUIDString isEqualToString:kTlwVoiceUUID] ||[c.UUID.UUIDString isEqualToString:kM8VoiceUUID] ){ return; } } @@ -183,7 +273,11 @@ } #pragma mark - public - (void)startScan{ - NSArray *devices = [self.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:kFrkServiceUUID],[CBUUID UUIDWithString:kTlwServiceUUID]]]; + NSArray *devices = [self.centralManager retrieveConnectedPeripheralsWithServices: + @[[CBUUID UUIDWithString:kFrkServiceUUID], + [CBUUID UUIDWithString:kTlwServiceUUID], + [CBUUID UUIDWithString:kM8ServiceUUID], + ]]; // [self showLog:[NSString stringWithFormat:@"查询配对过的设备%@",devices]]; if (devices.count > 0) { @@ -191,8 +285,7 @@ [self connectPeripheral:devices[0]]; } else{ -// [self showLog:[NSString stringWithFormat:@"开始扫描%@",@""]]; -// [self.centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : [NSNumber numberWithBool:NO]}]; + } } @@ -237,20 +330,7 @@ NSString *text = [NSString stringWithFormat:@"[BleManager] %@",log]; if(self.logCallBack) self.logCallBack(text); } -#pragma mark - timer -- (void)start{ - if (self.timer && [self.timer isValid]) { - [self.timer invalidate]; - self.timer = nil; - } -// dispatch_async(dispatch_queue_create("timeoutQueue", DISPATCH_QUEUE_SERIAL), ^{ -// self.timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:true]; -// [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; -// [[NSRunLoop currentRunLoop] run]; -// }); -// self.timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:true]; - self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(checkConnected) userInfo:nil repeats:true]; -} + - (void)open{ if([DeviceManger shared].isConneted){ diff --git a/MouseSdk/AiMouseSdk/Manager/DeviceManger.h b/MouseSdk/AiMouseSdk/Manager/DeviceManger.h index 6912b81..e35bfd4 100644 --- a/MouseSdk/AiMouseSdk/Manager/DeviceManger.h +++ b/MouseSdk/AiMouseSdk/Manager/DeviceManger.h @@ -14,6 +14,7 @@ typedef NS_ENUM(NSInteger,AiMouseProductType) { AiMouseProductType_tlw = 2,///泰凌微 AiMouseProductType_n = 3,///一键上网 AiMouseProductType_keyboard = 4,///键盘 + AiMouseProductType_m8 = 5,///泰凌微m8 }; NS_ASSUME_NONNULL_BEGIN @@ -27,15 +28,13 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型 #pragma mark ------- 鼠标的回调 @property (nonatomic,strong)void (^authCallBack)(BOOL isSuccess);/// 鉴权回调 -@property (nonatomic, copy)void (^aiMouseSendDeviceInfoDataCallBack)(NSString *data);/// 设备信息数据回调 +//@property (nonatomic, copy)void (^aiMouseSendDeviceInfoDataCallBack)(NSString *data);/// 设备信息数据回调 @property (nonatomic, copy)void (^aiMouseSendCmdDataCallBack)(NSString *data);/// 鼠标按键指令回调 @property (nonatomic, copy)void (^begainRecoredCallBack)(void);/// 录音开始回调 @property (nonatomic, copy)void (^recordingCallBack)(NSString *data);/// 录音进行中回调 @property (nonatomic, copy)void (^finishRecoredCallBack)(NSString *data);/// 录音结束回调 -//@property (nonatomic, copy)void (^aiMouseAddLogCallBack)(NSString *log);///输出日志 - #pragma mark ------- 接口 ///单例 diff --git a/MouseSdk/AiMouseSdk/Manager/DeviceManger.m b/MouseSdk/AiMouseSdk/Manager/DeviceManger.m index c74161b..2c097ab 100644 --- a/MouseSdk/AiMouseSdk/Manager/DeviceManger.m +++ b/MouseSdk/AiMouseSdk/Manager/DeviceManger.m @@ -15,6 +15,7 @@ #import "KeyboardHidManager.h" #import "KeyboardSdk.h" #import "ByteDanceSdk.h" +#import "M8MouseSdk.h" #import "LogManager.h" @interface DeviceManger() @@ -27,6 +28,7 @@ @property (nonatomic,strong) AiMouse *frkSdk; @property (nonatomic,strong) NMouseSdk *nSdk; @property (nonatomic,strong) KeyboardSdk *kbSdk; +@property (nonatomic,strong) M8MouseSdk *m8Sdk; @property (nonatomic,assign) AiMouseProductType productType; //connectType 返回为0代表蓝牙,为1代表usb @@ -47,14 +49,7 @@ - (instancetype)init{ self = [super init]; if (self) { -// NSString *version = @"MouseSdk_v2024120303"; -// NSLog(@"[AiMouseSdk] %@",version); -// [self showLog:version];; -// [self setupSDK]; -// [self setupBle]; -// [self setupHid]; -// [self setupTimer]; - self.version = @"MouseSdk_v2025010303"; + self.version = @"MouseSdk_v2025041501"; } return self; } @@ -83,12 +78,15 @@ self.frkSdk = [AiMouse shared]; [self.frkSdk setDelegate:self]; + + self.m8Sdk = [[M8MouseSdk alloc] init]; + [self.m8Sdk setDelegate:self]; } - (void)setupTimer{ [TimerManager shared].timerCallBack = ^{ // [self showLog:@"timer action。。。"]; - if(self.kbSdk.connected || self.nSdk.connected || self.tlwSdk.connected || self.frkSdk.connected){ + if(self.kbSdk.connected || self.nSdk.connected || self.tlwSdk.connected || self.frkSdk.connected|| self.m8Sdk.connected){ // [self.hid close]; } else{ @@ -100,7 +98,6 @@ - (void)setupHid{ - self.hid = [HidManager shared]; __weak typeof(self) ws = self; @@ -119,6 +116,9 @@ else if (ws.hid.productType == AiMouseProductType_keyboard){ [ws.kbSdk switchConnect:AiMouseConnectType_hid isConnected:true]; } + else if (ws.hid.productType == AiMouseProductType_m8){ + [ws.m8Sdk switchConnect:AiMouseConnectType_hid isConnected:true]; + } } else{ if (ws.hid.productType == AiMouseProductType_n) { @@ -137,6 +137,10 @@ [ws.kbSdk switchConnect:AiMouseConnectType_hid isConnected:false]; [ws.kbSdk didDisconnect]; } + else if (ws.hid.productType == AiMouseProductType_keyboard) { + [ws.m8Sdk switchConnect:AiMouseConnectType_hid isConnected:false]; + [ws.m8Sdk didDisconnect]; + } } }; self.hid.receiveInfoDataCallBack = ^(NSData *data) { @@ -152,6 +156,9 @@ else if (ws.hid.productType == AiMouseProductType_keyboard) { [ws.kbSdk sendDeviceDataToSdk:data]; } + else if (ws.hid.productType == AiMouseProductType_keyboard) { + [ws.m8Sdk sendDeviceDataToSdk:data]; + } }; self.hid.logCallBack = ^(NSString * _Nonnull log) { [ws showLog:log]; @@ -174,6 +181,9 @@ else if (ws.ble.productType == AiMouseProductType_tlw) { [ws.tlwSdk switchConnect:AiMouseConnectType_bluetooth isConnected:true]; } + else if (ws.ble.productType == AiMouseProductType_m8) { + [ws.m8Sdk switchConnect:AiMouseConnectType_bluetooth isConnected:true]; + } else{ [ws.frkSdk switchConnect:AiMouseConnectType_bluetooth isConnected:true]; } @@ -188,6 +198,9 @@ else if (ws.ble.productType == AiMouseProductType_tlw) { [ws.tlwSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; } + else if (ws.ble.productType == AiMouseProductType_m8) { + [ws.m8Sdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; + } else{ [ws.frkSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; } @@ -203,6 +216,9 @@ else if (ws.productType == AiMouseProductType_tlw) { [ws.tlwSdk sendDeviceDataToSdk:data]; } + else if (ws.productType == AiMouseProductType_m8) { + [ws.m8Sdk sendDeviceDataToSdk:data]; + } else{ [ws.frkSdk sendDeviceDataToSdk:data]; } @@ -211,6 +227,9 @@ if (ws.productType == AiMouseProductType_tlw) { [ws.tlwSdk sendAiDataToSdk:data]; } + else if (ws.productType == AiMouseProductType_m8) { + [ws.m8Sdk sendAiDataToSdk:data]; + } else{ [ws.frkSdk sendAiDataToSdk:data]; } @@ -236,6 +255,9 @@ if (self.frkSdk != nil && self.frkSdk.connected) { return true; } + if (self.m8Sdk != nil && self.m8Sdk.connected) { + return true; + } return false; } @@ -264,6 +286,14 @@ return @"1"; } } + else if (self.productType == AiMouseProductType_m8) { + if (self.m8Sdk.connectType == AiMouseConnectType_bluetooth) { + return @"0"; + } + else { + return @"1"; + } + } else{ if (self.frkSdk.connectType == AiMouseConnectType_bluetooth) { return @"0"; @@ -283,6 +313,9 @@ else if (self.productType == AiMouseProductType_tlw) { return self.tlwSdk.connectType; } + else if (self.productType == AiMouseProductType_m8) { + return self.m8Sdk.connectType; + } else { return self.frkSdk.connectType; } @@ -305,6 +338,9 @@ }else if (self.productType == AiMouseProductType_tlw) { [self.tlwSdk getFullDeviceInfo:finished]; } + else if (self.productType == AiMouseProductType_m8) { + [self.m8Sdk getFullDeviceInfo:finished]; + } else{ [self.frkSdk getDeviceInfo:finished]; } @@ -320,6 +356,10 @@ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; } + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_frk ) { [self.frkSdk getRSSI:finished]; } @@ -330,7 +370,15 @@ /// 设置CPI - (void)setCPI:(NSInteger)value completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前键盘不支持该接口"}]); + return; + } + if (self.productType == AiMouseProductType_m8) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; } @@ -352,6 +400,10 @@ /// - value: 品牌名称 /// - finished: 设置结果回调 - (void)setBrand:(NSString *)brand completation:(void (^)(BOOL isSuccess,NSError *error))finished { + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -370,6 +422,10 @@ /// 设置录音模式 - (void)setRecordMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -388,6 +444,10 @@ /// 设置长按滚轮弹出的网页地址 - (void)setUrl:(NSString *)url completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -406,6 +466,10 @@ /// 设置长按滚轮弹出网页开关 - (void)setUrlState:(int)state completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -424,6 +488,10 @@ /// 设置鼠标连接模式 - (void)setMouseMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -442,6 +510,10 @@ /// 获取录音模式 - (void)getRecordMode:(void (^)(int mode,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -460,6 +532,10 @@ /// 获取长按滚轮弹出的网页地址 - (void)getUrl:(void (^)(NSString *url,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -478,6 +554,10 @@ /// 获取长按滚轮弹出的网页地址开关状态 - (void)getUrlState:(void (^)(int state,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -496,6 +576,10 @@ /// 获取鼠标连接模式 - (void)getMouseModel:(void (^)(int mode,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -514,6 +598,10 @@ /// 打开录音 - (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -532,6 +620,10 @@ /// 关闭录音 - (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished{ + if (self.productType == AiMouseProductType_m8) { + finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); + return; + } if (self.productType == AiMouseProductType_keyboard) { finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]); return; @@ -558,6 +650,7 @@ if (connected) { [self.frkSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; [self.nSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; + [self.m8Sdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; } if (self.aiMouseConnectStateDidChangeCallBack) { @@ -583,6 +676,7 @@ /// M 单击0x06, 按下0x13(开始录音)抬起0x14(结束录音) /// AI键 单击0x03, 按下0x11(开始录音)抬起0x12(结束录音) /// 语音键 第一次单击0x01, 第二次单击0x02(结束录音) , 按下0x09(开始录音)抬起0x10(结束录音) +/// 翻译键 第一次单击0x04(开始录音), 第二次单击0x05(结束录音), 按下0x07(开始录音) 抬起0x08(结束录音) /// 其他未定义 /// /// /// 鼠标按键指令回调 富瑞坤 @@ -690,6 +784,7 @@ if (connected) { [self.tlwSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; [self.frkSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; + [self.m8Sdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; } if (self.aiMouseConnectStateDidChangeCallBack) { @@ -778,6 +873,7 @@ if (connected) { [self.tlwSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; [self.nSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; + [self.m8Sdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; } if (self.aiMouseConnectStateDidChangeCallBack) { @@ -852,6 +948,159 @@ - (void)aiMouseHidDataError{ [self.hid open]; } +#pragma mark - M8MouseSdkDelegate +/// 设备连接状态 +/// - Parameter connected: 是否连接 +- (void)m8MouseConnectStateDidChange:(BOOL)connected{ + [self showLog:[NSString stringWithFormat:@"%@设备连接状态返回: %@",self.m8Sdk.connectType == AiMouseConnectType_bluetooth ? @"蓝牙 ":@"USB",connected ? @"true":@"false"]]; + + if (connected) { + [self.tlwSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; + [self.nSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; + [self.frkSdk switchConnect:AiMouseConnectType_bluetooth isConnected:false]; + } + + if (self.aiMouseConnectStateDidChangeCallBack) { + self.aiMouseConnectStateDidChangeCallBack(self.m8Sdk.connectType == AiMouseConnectType_bluetooth ? 0:1,connected); + } + if(self.authCallBack && connected)self.authCallBack(connected); +} + + +/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备 +/// - Parameter data: 数据 +- (void)m8MouseSendDeviceInfoData:(NSData *)data{ + if (self.m8Sdk.connectType == AiMouseConnectType_bluetooth) { + [self.ble writeToDevice:data]; + } + else if (self.frkSdk.connectType == AiMouseConnectType_hid){ + [self.hid writeToDevice:data]; + } +} + +/// 鼠标按键指令回调 +//EF AA 0B 00 02 E1 00 E3 语音键单击开始 +//EF AA 0C 00 02 E1 00 E3 语音键单击结束 +//EF AA 05 00 02 E1 00 E3 语音键长按 +//EF AA 06 00 02 E1 00 E3 语音键长按松开 +// +// +//EF AA 09 00 02 E1 00 E3 M键单击 +//EF AA 01 00 02 E1 00 E3 M键长按松开 +//EF AA 02 00 02 E1 00 E3 M键长按松开 +// +//EF AA 0A 00 02 E1 00 E3 AI键单击 +//EF AA 03 00 02 E1 00 E3 AI键长按松开 +//EF AA 04 00 02 E1 00 E3 AI键长按松开 +// +//EF AA 0D 00 02 E1 00 E3 翻译键单击开始 +//EF AA 0E 00 02 E1 00 E3 翻译键单击结束 +//EF AA 07 00 02 E1 00 E3 翻译键长按 +//EF AA 08 00 02 E1 00 E3 翻译键长按松开 +//@"09":@"43", +//@"01":@"27", +//@"02":@"28", +// +//@"0A":@"42", +//@"03":@"25", +//@"04":@"26", +// +//@"0B":@"31", +//@"0C":@"32", +//@"05":@"21", +//@"06":@"22", + +//@"0D":@"04", +//@"0E":@"05", +//@"07":@"07", +//@"08":@"08", +/// 其他未定义 +- (void)m8MouseSendCmdData:(NSData *)data{ + NSLog(@"%@",data); + uint8 cmd; + [data getBytes:&cmd length:1]; + if( cmd == 0x01){ + cmd = 0x27; + }else if( cmd == 0x02){ + cmd = 0x28; + } + else if( cmd == 0x09){ + cmd = 0x43; + } + else if( cmd == 0xa){ + cmd = 0x42; + } + else if( cmd == 0x03){ + cmd = 0x25; + } + else if( cmd == 0x4){ + cmd = 0x26; + } + else if( cmd == 0x0B){ + cmd = 0x31; + } + else if( cmd == 0x0C){ + cmd = 0x32; + } + else if( cmd == 0x05){ + cmd = 0x21; + } + else if( cmd == 0x06){ + cmd = 0x22; + } + else if( cmd == 0x0D){ + cmd = 0x04; + } + else if( cmd == 0x0E){ + cmd = 0x05; + } + else if( cmd == 0x07){ + cmd = 0x07; + } + else if( cmd == 0x08){ + cmd = 0x08; + } + if (self.aiMouseSendCmdDataCallBack) { + self.aiMouseSendCmdDataCallBack([NSString stringWithFormat:@"%X",cmd]); + } + + if(cmd == 0x04 || cmd == 0x07 || cmd == 0x31 || cmd == 0x21 || cmd == 0x25 ||cmd == 0x27){ + [self showLog:@"开始录音"]; + self.recordData = [[NSMutableData alloc] init]; + if (self.begainRecoredCallBack) { + self.begainRecoredCallBack(); + } + } + else if(cmd == 0x05 || cmd == 0x08 || cmd == 0x32 || cmd == 0x22 || cmd == 0x26 ||cmd == 0x28){ + [self showLog:@"结束录音"]; + [self finishRecored:self.recordData]; + if (self.finishRecoredCallBack) { + NSString *base64String = [self.recordData base64EncodedStringWithOptions:0]; + self.finishRecoredCallBack(base64String); + } + } +} + +/// 录音回调 +/// - Parameter data: pcm格式语音数据 +- (void)m8MouseSendRecordData:(NSData *)data{ + [self.recordData appendData:data]; + if (self.recordingCallBack) { + self.recordingCallBack( [data base64EncodedStringWithOptions:0]); + } +} + +/// hid数据异常,需要重新开启监听usb设备 +- (void)m8HidDataError{ + [self.hid open]; +} + +/// 输出sdk日志 +/// - Parameter log: 日志 +- (void)m8MouseAddLog:(NSString *)log{ + [self showLog:log]; +} + #pragma mark - other - (void)showLog:(NSString *)log{ // if (self.aiMouseAddLogCallBack) { diff --git a/MouseSdk/AiMouseSdk/Manager/HidManager.m b/MouseSdk/AiMouseSdk/Manager/HidManager.m index fde3c58..294da9e 100644 --- a/MouseSdk/AiMouseSdk/Manager/HidManager.m +++ b/MouseSdk/AiMouseSdk/Manager/HidManager.m @@ -288,14 +288,6 @@ static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDRe 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; -//} - /// 实际到数据长度 static inline int get_data_len(uint8_t *buf, int len) { if (len <= 0 ) return 0; diff --git a/MouseSdk/AiMouseSdk/Manager/TimerManager.m b/MouseSdk/AiMouseSdk/Manager/TimerManager.m index 556807b..a0267d1 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:5 target:self selector:@selector(timerAction) userInfo:nil repeats:true]; + self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(timerAction) userInfo:nil repeats:true]; } - (void)timerAction{ diff --git a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate index 7b99edf..bc0c02b 100644 Binary files a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate and b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 81258ac..51ba4e0 100644 --- a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -5,15 +5,35 @@ version = "2.0"> + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + filePath = "AiMouseSdk/M8/M8MouseSdk.m" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "59" + endingLineNumber = "59" + landmarkName = "-recordManager" + landmarkType = "7"> + + + + diff --git a/MouseSdk/MouseSdk/ViewController.m b/MouseSdk/MouseSdk/ViewController.m index 2dfccfa..decd0e0 100644 --- a/MouseSdk/MouseSdk/ViewController.m +++ b/MouseSdk/MouseSdk/ViewController.m @@ -120,6 +120,12 @@ } }); }]; + manager.aiMouseSendCmdDataCallBack = ^(NSString * _Nonnull data) { + NSLog(@"%@",[NSString stringWithFormat:@"按键指令 = %@",data]); + }; + manager.recordingCallBack = ^(NSString * _Nonnull data) { + NSLog(@"%@",[NSString stringWithFormat:@"语音数据 = %@",data]); + }; } diff --git a/MouseSdk/Pods/Pods.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist b/MouseSdk/Pods/Pods.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist index c230d1a..30f1cdd 100644 --- a/MouseSdk/Pods/Pods.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/MouseSdk/Pods/Pods.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,12 +7,12 @@ Masonry.xcscheme_^#shared#^_ orderHint - 2 + 3 Pods-MouseSdk.xcscheme_^#shared#^_ orderHint - 3 + 4