18EF7B032C7603E800AC5223 /* TlwMouseSdk.h in Headers */ = {isa = PBXBuildFile; fileRef = 18EF7AF42C7603E800AC5223 /* TlwMouseSdk.h */; settings = {ATTRIBUTES = (Public, ); }; };
18EF7B042C7603E800AC5223 /* TlwAudioManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 18EF7AF52C7603E800AC5223 /* TlwAudioManager.m */; };
18EF7B052C7603E800AC5223 /* TlwConnectManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 18EF7AF62C7603E800AC5223 /* TlwConnectManager.h */; };
+ 18FCA3972C7F2AD100C44A37 /* AiMouseAuth.h in Headers */ = {isa = PBXBuildFile; fileRef = 18FCA3952C7F2AD100C44A37 /* AiMouseAuth.h */; };
+ 18FCA3982C7F2AD100C44A37 /* AiMouseAuth.m in Sources */ = {isa = PBXBuildFile; fileRef = 18FCA3962C7F2AD100C44A37 /* AiMouseAuth.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
18EF7AF42C7603E800AC5223 /* TlwMouseSdk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TlwMouseSdk.h; sourceTree = "<group>"; };
18EF7AF52C7603E800AC5223 /* TlwAudioManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TlwAudioManager.m; sourceTree = "<group>"; };
18EF7AF62C7603E800AC5223 /* TlwConnectManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TlwConnectManager.h; sourceTree = "<group>"; };
+ 18FCA3952C7F2AD100C44A37 /* AiMouseAuth.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiMouseAuth.h; sourceTree = "<group>"; };
+ 18FCA3962C7F2AD100C44A37 /* AiMouseAuth.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiMouseAuth.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
180E7BF62BD8FC4E008558E8 /* ffmpeg */,
180E7AA92BD7BB12008558E8 /* AiMouseSdk.h */,
180E7AAB2BD7BB12008558E8 /* AiMouseSdk.m */,
+ 18FCA3952C7F2AD100C44A37 /* AiMouseAuth.h */,
+ 18FCA3962C7F2AD100C44A37 /* AiMouseAuth.m */,
18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */,
18AD83242BFAE8B9009BDE3B /* AiDeviceInfoManager.m */,
189C15842C05726600676A80 /* AiConnectManager.h */,
18EF7AFD2C7603E800AC5223 /* TlwAudioManager.h in Headers */,
180E7C892BD8FC4E008558E8 /* time.h in Headers */,
180E7CD32BD8FC4E008558E8 /* bprint.h in Headers */,
+ 18FCA3972C7F2AD100C44A37 /* AiMouseAuth.h in Headers */,
180E7CB02BD8FC4E008558E8 /* timecode.h in Headers */,
180E7CA42BD8FC4E008558E8 /* md5.h in Headers */,
180E7CE32BD8FC4E008558E8 /* avio.h in Headers */,
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 18FCA3982C7F2AD100C44A37 /* AiMouseAuth.m in Sources */,
180E7BE52BD7BD84008558E8 /* AiMouseTools2.m in Sources */,
184A71252BDE2DA60025A332 /* AiSecretModel.m in Sources */,
18AD832A2BFB22DE009BDE3B /* AiSender.m in Sources */,
#pragma mark - timer
- (void)addSendTimer{
dispatch_async(dispatch_queue_create("timeoutQueue", DISPATCH_QUEUE_SERIAL), ^{
- self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:true];
+ self.timer = [NSTimer timerWithTimeInterval:10000000 target:self selector:@selector(timerAction) userInfo:nil repeats:true];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
});
--- /dev/null
+////
+//// AiMouseSdk.h
+//// AiMouseSdk
+////
+//// Created by incar on 2024/4/23.
+////
+//
+//#import <Foundation/Foundation.h>
+//
+//@interface AiMouseDeviceInfo : NSObject
+//@property (nonatomic, strong) NSString *battery_power;/// 电池百分百电量,0-100
+//@property (nonatomic, strong) NSString *CPI;/// CPI值
+//@property (nonatomic, strong) NSString *CPI_list;/// 可设置的CPI参数列表
+//@property (nonatomic, strong) NSString *version;///软件版本
+//@property (nonatomic, strong) NSString *brand;/// 品牌名称
+//@property (nonatomic, strong) NSString *sn;/// 设备序列号
+//@property (nonatomic, strong) NSString *mac;///设备MAC地址
+//@end
+//
+//typedef NS_ENUM(NSInteger,AiMouseErrorCode) {
+// AiMouseErrorCode_timeOut = 1001,///请求超时
+// AiMouseErrorCode_busy = 1002,/// 繁忙,有命令未执行完
+// AiMouseErrorCode_unknown = 1003,/// 未知错误
+//};
+//
+///// 日志等级
+//typedef NS_ENUM(NSInteger,AiMouseLogLevel) {
+// AiMouseLogLevel_none = 0,
+// AiMouseLogLevel_error,
+// AiMouseLogLevel_info,
+//};
+//
+//typedef NS_ENUM(NSInteger,AiMouseConnectType) {
+// AiMouseConnectType_bluetooth = 0,///蓝牙
+// AiMouseConnectType_hid = 1,///hid
+//};
+//
+//typedef NS_ENUM(NSInteger,AiMouseAuthState) {
+// AiMouseAuthState_Unknow = 0,///未知
+// AiMouseAuthState_Success,///鉴权成功
+// AiMouseAuthState_Failure///鉴权失败
+//};
+//
+//@protocol AiMouseDelegate <NSObject>
+//
+///// 设备连接状态
+///// - Parameter connected: 是否连接
+//- (void)aiMouseConnectStateDidChange:(BOOL)connected;
+//
+///// 鉴权结果返回
+///// - Parameter authState: 鉴权状态
+//- (void)aiMouseAuthenticationResult:(AiMouseAuthState)authState;
+//
+///// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备
+///// - Parameter data: 数据
+//- (void)aiMouseSendDeviceInfoData:(NSData *)data;
+//
+///// 鼠标按键指令回调
+///// - Parameter data: 数据。
+///// 前 第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音)
+///// 中 单击42, 按下25(开始录音)抬起26(结束录音)
+///// 后 单击43,按下27(开始录音)抬起28(结束录音)
+///// 其他未定义
+//- (void)aiMouseSendCmdData:(NSData *)data;
+//
+///// 录音回调
+///// - Parameter data: pcm格式语音数据
+//- (void)aiMouseSendRecordData:(NSData *)data;
+//
+//@optional
+///// 输出sdk日志
+///// - Parameter log: 日志
+//- (void)aiMouseAddLog:(NSString *)log;
+//
+///// hid数据异常,需要重新开启监听usb设备
+//- (void)hidDataError;
+//@end
+//
+//@interface AiMouse : NSObject
+//@property (nonatomic, readonly) NSString *version;/// 版本号
+//@property (nonatomic, weak) id<AiMouseDelegate> delegate;/// 代理
+//@property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型
+//@property (nonatomic, readonly) BOOL connected;//是否已连接
+//@property (nonatomic, readonly) AiMouseAuthState authState;/// 鉴权状态,默认是Unknow。所以必须在连上蓝牙设备找到鉴权特征后,需要主动调用startAuthentication方法去鉴权。(只有鉴权成功,AI功能才可用)
+//
+///// 单利
+//+(AiMouse *)shared;
+//
+///// 设置日志等级
+///// - Parameter level: 等级
+//- (void)setLogLevel:(AiMouseLogLevel)level;
+//
+//
+///// 断开连接
+//- (void)didDisconnect;
+//
+///// 切换连接类型
+///// - Parameter type: 连接类型
+//- (void)switchConnect:(AiMouseConnectType)type;
+//
+/////// 开始鉴权
+/////// - Parameter finished: 鉴权结果回调
+////- (void)startAuthentication:(void (^)(AiMouseAuthState state))complete;
+//
+///// 传输业务数据给sdk
+///// - Parameter data:ai特征传过来的数据
+//- (void)sendAiDataToSdk:(NSData *)data;
+//
+///// 传输设备信息数据给sdk
+///// - Parameter data:设备信息特征传过来的数据
+//- (void)sendDeviceDataToSdk:(NSData *)data;
+//
+///// 获取设备信息
+///// - Parameter completation: 如果获取成功,则deviceInfo有值,否则为nil
+//- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))complete;
+//
+///// 获取信号强度
+///// - Parameter completation: 信号强度回调,如果获取成功,则value有值,否则为nil
+//- (void)getRSSI:(void (^)(NSString *value,NSError *error))complete;
+//
+///// 设置品牌名称
+///// - Parameters:
+///// - value: 品牌名称
+///// - finished: 设置结果回调
+//- (void)setBrand:(NSString *)brand completation:(void (^)(BOOL isSuccess,NSError *error))finished;
+//
+///// 设置CPI
+///// - Parameters:
+///// - value: AiMouseDeviceInfo 中可以设置的值CPI_list
+///// - finished: 设置结果回调
+//- (void)setCPI:(NSInteger)value completation:(void (^)(BOOL isSuccess,NSError *error))finished;
+//
+///// 设置录音模式
+///// - Parameters:
+///// - value: 0:常规模式,按按键打开关闭录音 1:命令模式,发命令打开关闭录音
+///// - finished: 设置结果回调
+//- (void)setRecordMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished;
+//
+///// 设置长按滚轮弹出的网页地址
+///// - Parameters:
+///// - url: 最大长度:49字节
+///// - finished: 设置结果回调
+//- (void)setUrl:(NSString *)url completation:(void (^)(BOOL isSuccess,NSError *error))finished;
+//
+///// 设置长按滚轮弹出网页开关
+///// - Parameters:
+///// - state: 0关闭,1打开
+///// - finished: 设置结果回调
+//- (void)setUrlState:(int)state completation:(void (^)(BOOL isSuccess,NSError *error))finished;
+//
+///// 设置鼠标连接模式
+///// - Parameters:
+///// - mode: 0:2.4G模式,1:蓝牙1模式,2:蓝牙2模式
+///// - finished: 设置结果回调
+//- (void)setMouseMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished;
+//
+///// 获取录音模式
+///// - Parameter complete: mode 0:常规模式,按按键打开关闭录音 1:命令模式,发命令打开关闭录音 。error为nil才代表获取成功
+//- (void)getRecordMode:(void (^)(int mode,NSError *error))complete;
+//
+///// 获取长按滚轮弹出的网页地址
+///// - Parameter complete: url地址 。error为nil才代表获取成功
+//- (void)getUrl:(void (^)(NSString *url,NSError *error))complete;
+//
+///// 获取长按滚轮弹出的网页地址开关状态
+///// - Parameter complete: state 0关闭,1打开。 error为nil才代表获取成功
+//- (void)getUrlState:(void (^)(int state,NSError *error))complete;
+//
+///// 获取鼠标连接模式
+///// - Parameter complete: mode 0:2.4G模式,1:蓝牙1模式,2:蓝牙2模式 。error为nil才代表获取成功
+//- (void)getMouseModel:(void (^)(int mode,NSError *error))complete;
+//
+///// 打开录音
+///// - finished: 执行结果回调
+//- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
+//
+///// 关闭录音
+///// - finished: 执行结果回调
+//- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
+//@end
--- /dev/null
+////
+//// AiMouseSdk.m
+//// AiMouseSdk
+////
+//// Created by incar on 2024/4/23.
+////
+//
+//#import "AiMouseSdk.h"
+//#import "AiDeviceInfoManager.h"
+//#import "AiAuthManager.h"
+//#import "AiAliAuthManager.h"
+//#import "AiAudioManager.h"
+//#import "AiMouseTools.h"
+//#import "AiMouseTools2.h"
+//#import "AiMouseConfig.h"
+//#import "AiRecordManager.h"
+//#import "AiConnectManager.h"
+//
+//#define kIsAliChannal true
+//
+//@interface AiMouseDeviceInfo()
+//@property (nonatomic, strong) NSString *productKey;/// 品牌key
+//@property (nonatomic, strong) NSString *secretKey;/// 品牌Secret
+//@property (nonatomic, strong) NSString *deviceSecret;///设备Secret
+//@end
+//@implementation AiMouseDeviceInfo
+//-(NSString *)description{
+//// NSString *info = [NSString stringWithFormat:@"\n battery_power = %@\n CPI = %@\n CPI_list = %@\n version = %@\n brand = %@\n sn = %@\n mac = %@\n productKey = %@\n secretKey = %@\n deviceSecret = %@ \n record_mode = %@ \n mouse_mode = %@ \n url = %@ \n urlActive = %@ ",self.battery_power,self.CPI,self.CPI_list,self.version,self.brand,self.sn,self.mac,self.productKey,self.secretKey,self.deviceSecret,self.record_mode,self.mouse_mode,self.url,self.urlActive];
+//
+// NSString *info = [NSString stringWithFormat:@"\n battery_power = %@\n CPI = %@\n CPI_list = %@\n version = %@\n brand = %@\n sn = %@\n mac = %@\n productKey = %@\n secretKey = %@\n deviceSecret = %@ ",self.battery_power,self.CPI,self.CPI_list,self.version,self.brand,self.sn,self.mac,self.productKey,self.secretKey,self.deviceSecret];
+// return info;
+//}
+//@end
+//
+//@interface AiMouse()<AiConnectManagerDelegate>
+//@property (nonatomic, assign) AiMouseLogLevel logLevel;
+//@property (nonatomic, strong) AiAuthManager *authManager;
+//@property (nonatomic, strong) AiAliAuthManager *aliAuthManager;
+//@property (nonatomic, strong) AiAudioManager *audioManager;
+//@property (nonatomic, strong) AiRecordManager *recordManager;
+//@property (nonatomic, strong) void (^authBlock)(AiMouseAuthState state);
+//@property (nonatomic, strong) AiDeviceInfoManager *deviceInfoManager;
+//@property (nonatomic, strong) NSString *updateDeviceSecret;//更新的deviceSecret
+//
+//@property (nonatomic, strong) AiConnectManager *connectManager;
+//@property (nonatomic, assign) BOOL isAuthing;
+//@end
+//
+//@implementation AiMouse
+//+(AiMouse *)shared{
+// static AiMouse *manager = nil;
+// static dispatch_once_t oncePredicate;
+// dispatch_once(&oncePredicate, ^{
+// manager = [[AiMouse alloc]init];
+// });
+// return manager;
+//}
+//
+//-(instancetype)init{
+// if (self = [super init]) {
+// _logLevel = AiMouseLogLevel_none;
+// _authState = AiMouseAuthState_Unknow;
+// _connectType = AiMouseConnectType_bluetooth;
+// [self.connectManager start];
+// NSLog(@"[AiMouseSdk]%@",[NSString stringWithFormat:@"AiMouseSdk_v%@",self.version]);
+// }
+// return self;
+//}
+//
+//-(NSString *)version{
+// return @"1.0.32";
+//}
+//
+//-(AiDeviceInfoManager *)deviceInfoManager{
+// if (!_deviceInfoManager) {
+// _deviceInfoManager = [[AiDeviceInfoManager alloc] init];
+// __weak typeof(self) ws = self;
+// _deviceInfoManager.sendToBleBlock = ^(NSData * _Nonnull data) {
+// if (ws.delegate) {
+// [ws showLog:[NSString stringWithFormat:@"[send][info] %@",data]];
+// [ws.delegate aiMouseSendDeviceInfoData:data];
+// }
+// };
+// _deviceInfoManager.outputLogBlock = ^(NSString * _Nonnull log) {
+// [ws showLog:log];
+// };
+// }
+// return _deviceInfoManager;;
+//}
+//
+//-(AiAuthManager *)authManager{
+// if (!_authManager) {
+// _authManager = [[AiAuthManager alloc] init];
+// __weak typeof(self) ws = self;
+// _authManager.outputLog = ^(NSString * _Nonnull log) {
+// [ws showLog:log];
+// };
+// _authManager.setDeviceSecret = ^(NSString * _Nonnull value, AiCmdFinishBlock _Nonnull finished) {
+// [ws setDeviceSecret:value completation:finished];
+// };
+// _authManager.authCallBack = ^(BOOL isSuccess) {
+// [ws authResult:isSuccess];
+//// [ws setDeviceSecret:@"" completation:nil];
+// };
+// }
+// return _authManager;
+//}
+//
+//-(AiAliAuthManager *)aliAuthManager{
+// if (!_aliAuthManager) {
+// _aliAuthManager = [[AiAliAuthManager alloc] init];
+// __weak typeof(self) ws = self;
+// _aliAuthManager.outputLog = ^(NSString * _Nonnull log) {
+// [ws showLog:log];
+// };
+// _aliAuthManager.setDeviceSecret = ^(NSString * _Nonnull value, AiAliCmdFinishBlock _Nonnull finished) {
+// [ws setDeviceSecret:value completation:finished];
+// };
+// _aliAuthManager.authCallBack = ^(BOOL isSuccess) {
+// [ws authResult:isSuccess];
+//// [ws setDeviceSecret:@"" completation:nil];
+// };
+// }
+// return _aliAuthManager;
+//}
+//
+//-(AiAudioManager *)audioManager{
+// if (!_audioManager) {
+// _audioManager = [[AiAudioManager 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;
+//}
+//
+//-(AiConnectManager *)connectManager{
+// if (!_connectManager) {
+// _connectManager = [[AiConnectManager alloc] init];
+// _connectManager.delegate = self;
+// }
+// return _connectManager;
+//}
+//#pragma mark - pub Api
+//- (void)setLogLevel:(AiMouseLogLevel)level{
+// _logLevel = level;
+//}
+//- (void)didDisconnect{
+// [self showLog:@"系统断开连接"];
+// [self stopRecord:true];
+// [self.connectManager disConnected];
+//
+//}
+//- (void)switchConnect:(AiMouseConnectType)type{
+// if(type != _connectType && self.connected){
+// [self.connectManager disConnected];
+// }
+// _connectType = type;
+// [self showLog:type == AiMouseConnectType_bluetooth?@"sdk切换到蓝牙模式":@"sdk切换到usb模式"];
+//
+//
+// if (type == AiMouseConnectType_hid) {
+// [self.recordManager checkPermissions];
+// }
+//}
+////开始鉴权
+//- (void)startAuthentication:(void (^)(AiMouseAuthState))complete{
+//// [self showLog:@"获取设备信息"];
+//// _authState = AiMouseAuthState_Unknow;
+// [self showLog:@"开始鉴权"];
+// self.authBlock = complete;
+// __block typeof(self) ws = self;
+// [self getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) {
+// if (error ) {
+// ws.authBlock(AiMouseAuthState_Failure);
+// }
+// else{
+// if(kIsAliChannal){
+// [ws.aliAuthManager loginWith:deviceInfo];
+// }
+// else{
+// [ws.authManager loginWith:deviceInfo];
+// }
+// }
+// }];
+//}
+//
+//- (void)sendAiDataToSdk:(NSData *)data{
+// [self.connectManager resetTimeOut];
+//
+// [self showLog:[NSString stringWithFormat:@"[receive][Ai] %@",data]];
+//
+// if (self.authState != AiMouseAuthState_Success){
+// [self showLog:@"设备还未鉴权!!!"];
+// [self checkAuthState];
+// return;
+// }
+// if(self.connectType == AiMouseConnectType_hid){
+//// 0AFFFF12BC32
+// if(data.length == 6){
+// NSData *subData = [data subdataWithRange:NSMakeRange(5, 1)];
+// [self sendCmdData:subData];
+// uint8 cmd;
+// [subData getBytes:&cmd length:1];
+//// [self showLog:[NSString stringWithFormat:@"cmd = %X",cmdInt]];
+// if(cmd == 0x31 || cmd == 0x21 || cmd == 0x25 ||cmd == 0x27){
+// self.recordManager.startCmd = subData;
+// [self startRecord];
+// }
+// else if(cmd == 0x32 || cmd == 0x22 || cmd == 0x26 ||cmd == 0x28){
+// [self stopRecord:false];
+// }
+// }
+// else{
+// [self showLog:@"未实现指令"];
+// }
+// }
+// else if (self.connectType == AiMouseConnectType_bluetooth){
+// if(data.length == 16){
+// //0A65004E003200010101C0C10000A5A5
+// NSData *cmd = [data subdataWithRange:NSMakeRange(5, 1)];
+// [self sendCmdData:cmd];
+// return;
+// }
+// NSString *cmd = [[AiMouseTools dataToHexString:data] lowercaseString];
+// if([cmd hasPrefix:@"9c31"]){
+// //声音
+// [self.audioManager receiveData:data];
+// }
+// else{
+// [self showLog:@"未实现指令"];
+// }
+// }
+//}
+//
+//#pragma mark - deviceInfoManager
+//-(void)sendDeviceDataToSdk:(NSData *)data{
+// [self showLog:[NSString stringWithFormat:@"[receive][info] %@",data]];
+// if (self.connected == false) {
+// if([AiMouseTools dataToHexString:data].length < 10){
+// if (self.delegate && [self.delegate respondsToSelector:@selector(hidDataError)]) [self.delegate hidDataError];
+// return;
+// }
+// }
+//
+// [self.connectManager resetTimeOut];
+// [self.deviceInfoManager receiveData:data];
+// [self checkAuthState];
+//}
+//- (void)setDeviceSecret:(NSString *)value completation:(AiCmdFinishBlock)complete{
+// self.updateDeviceSecret = value;
+// __weak typeof(self) ws = self;
+// [self.deviceInfoManager setDeviceSecret:value completation:^(BOOL isSuccess) {
+// if (isSuccess) {
+// [ws showLog:@"写入deviceSecret成功,查询是否获读取成功..."];
+// //更新成功,检查是否读取到
+// [ws.deviceInfoManager getDeviceInfo:^(AiMouseDeviceInfo * _Nonnull deviceInfo, NSError * _Nonnull error) {
+// if ([deviceInfo.deviceSecret isEqualToString:value]) {
+// [ws showLog:@"写入deviceSecret成功,读取成功!"];
+// complete(true);
+// }
+// else{
+// //查不到,继续写入
+// [ws showLog:@"查询不到deviceSecret,继续写入!!!"];
+// [ws setDeviceSecret:ws.updateDeviceSecret completation:complete];
+// }
+// }];
+// }
+// else{
+// [ws showLog:@"写入deviceSecret失败!"];
+// [ws setDeviceSecret:ws.updateDeviceSecret completation:complete];
+// }
+// }];
+//}
+//- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))complete{
+// [self.deviceInfoManager getDeviceInfo:complete];
+//}
+//- (void)getRSSI:(void (^)(NSString *value,NSError *error))complete{
+// [self.deviceInfoManager getRSSI:complete];
+//}
+//- (void)setBrand:(NSString *)brand completation:(void (^)(BOOL isSuccess,NSError *error))finished{
+// [self.deviceInfoManager setBrand:brand completation:finished];
+//}
+//- (void)setCPI:(NSInteger)value completation:(void (^)(BOOL isSuccess,NSError *error))finished{
+// [self.deviceInfoManager setCPI:value completation:finished];
+//}
+///// 设置录音模式
+//- (void)setRecordMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished{
+// [self.deviceInfoManager setRecordMode:mode completation:finished];
+//}
+///// 设置长按滚轮弹出的网页地址
+//- (void)setUrl:(NSString *)url completation:(void (^)(BOOL isSuccess,NSError *error))finished{
+// [self.deviceInfoManager setUrl:url completation:finished];
+//}
+///// 设置长按滚轮弹出网页开关
+//- (void)setUrlState:(int)state completation:(void (^)(BOOL, NSError *))finished{
+// [self.deviceInfoManager setUrlState:state completation:finished];
+//}
+///// 设置鼠标连接模式
+//- (void)setMouseMode:(int)mode completation:(void (^)(BOOL, NSError *))finished{
+// [self.deviceInfoManager setMouseMode: mode completation:finished];
+//}
+///// 获取录音模式
+//- (void)getRecordMode:(void (^)(int mode,NSError *error))complete{
+// [self.deviceInfoManager getRecordMode:complete];
+//}
+///// 获取长按滚轮弹出的网页地址
+//- (void)getUrl:(void (^)(NSString *url,NSError *error))complete{
+// [self.deviceInfoManager getUrl:complete];
+//}
+///// 获取长按滚轮弹出的网页地址开关状态
+//- (void)getUrlState:(void (^)(int state,NSError *error))complete{
+// [self.deviceInfoManager getUrlState:complete];
+//}
+///// 获取鼠标连接模式
+//- (void)getMouseModel:(void (^)(int mode,NSError *error))complete{
+// [self.deviceInfoManager getMouseModel:complete];
+//}
+///// 开始录音
+//- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
+// __weak typeof(self) ws = self;
+// [self.deviceInfoManager openRecord:^(BOOL isSuccess, NSError * _Nonnull error) {
+// finished(isSuccess,error);
+// if (isSuccess) {
+// uint8 value = 0x31;
+// NSData *cmd = [NSData dataWithBytes:&value length:1];
+// [ws sendCmdData:cmd];
+//
+// if(self.connectType == AiMouseConnectType_hid){
+// [ws startRecord];
+// }
+// }
+// }];
+//}
+///// 结束录音
+//- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
+// __weak typeof(self) ws = self;
+// [self.deviceInfoManager closeRecord:^(BOOL isSuccess, NSError * _Nonnull error) {
+// finished(isSuccess,error);
+//
+// if (isSuccess) {
+// uint8 value = 0x32;
+// NSData *cmd = [NSData dataWithBytes:&value length:1];
+// [ws sendCmdData:cmd];
+//
+// if(self.connectType == AiMouseConnectType_hid){
+// [ws stopRecord:false];
+// }
+// }
+// }];
+//}
+//#pragma mark - other
+//- (void)sendRecordData:(NSData *)data{
+//// if (self.authState != AiMouseAuthState_Success){
+//// [self showLog:@"设备还未鉴权!!!"];
+//// return;
+//// };
+//// [self showLog:[NSString stringWithFormat:@"[audio] %@",data]];
+// if (self.delegate) [self.delegate aiMouseSendRecordData:data];
+//}
+//- (void)sendCmdData:(NSData *)data{
+//// if (self.authState != AiMouseAuthState_Success){
+//// [self showLog:@"设备还未鉴权!!!"];
+//// return;
+//// }
+// [self showLog:[NSString stringWithFormat:@"[send] %@",data]];
+// if (self.delegate) [self.delegate aiMouseSendCmdData:data];
+//}
+//
+//- (void)authResult:(BOOL)isSuccess{
+// _authState = isSuccess ? AiMouseAuthState_Success:AiMouseAuthState_Failure;
+// [self.deviceInfoManager setAuthStateToDevice:isSuccess];
+//
+// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+// if(self.authBlock) self.authBlock(self->_authState);
+// });
+//}
+//- (void)showLog:(NSString *)log{
+// if (self.delegate && [self.delegate respondsToSelector:@selector(aiMouseAddLog:)]) {
+// [self.delegate aiMouseAddLog:log];
+// }
+// if(self.logLevel == AiMouseLogLevel_info){
+// NSLog(@"[AiMouseSdk]%@",log);
+// }
+//}
+//
+//- (void)checkAuthState{
+// if (self.authState != AiMouseAuthState_Success) {
+// if (self.isAuthing) {
+// return;
+// }
+// self.isAuthing = true;
+// __weak typeof(self) ws = self;
+// [self startAuthentication:^(AiMouseAuthState state) {
+// ws.isAuthing = false;
+// [ws showLog:state == AiMouseAuthState_Success? @"鉴权成功":@"鉴权失败"];
+// if(ws.delegate) [ws.delegate aiMouseAuthenticationResult:state];
+// }];
+// }
+//}
+//#pragma mark - deviceInfo
+//- (void)startRecord{
+//// [self showLog:@"开始录音"];
+// [self.recordManager start];
+//}
+//
+//- (void)stopRecord:(BOOL)sendCmd{
+// if (self.recordManager.recording ) {
+// [self.recordManager stop];
+// }
+// if (sendCmd) {
+// [self sendCmdData:self.recordManager.stopCmd];
+// }
+//// [self showLog:@"结束录音"];
+//}
+//
+//#pragma mark - AiConnectManagerDelegate
+//-(void)aiConnectManager:(AiConnectManager *)manager connectStateDidChange:(BOOL)connected{
+// if (connected == false) {
+// _authState = AiMouseAuthState_Unknow;
+// }
+// _connected = connected;
+// if([self.delegate respondsToSelector:@selector(aiMouseConnectStateDidChange:)]) [self.delegate aiMouseConnectStateDidChange:connected];
+//}
+//-(void)aiConnectManagerReSendData:(AiConnectManager *)manager{
+// __weak typeof(self) ws = self;
+// [self.deviceInfoManager getVersion:^(NSString * _Nonnull version, NSError * _Nonnull error) {
+// if (error.code == AiMouseErrorCode_timeOut) {
+// [ws.connectManager addTimeOut];
+// }
+// }];
+//}
+//-(void)aiConnectManager:(AiConnectManager *)manager outputLog:(NSString *)log{
+// [self showLog:log];
+//}
+//@end
+//
@property (nonatomic, readonly) NSString *version;/// 版本号
@property (nonatomic, weak) id<AiMouseDelegate> delegate;/// 代理
@property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型
-@property (nonatomic, readonly) BOOL connected;//是否已连接
+@property (nonatomic, assign) BOOL connected;//是否已连接
@property (nonatomic, readonly) AiMouseAuthState authState;/// 鉴权状态,默认是Unknow。所以必须在连上蓝牙设备找到鉴权特征后,需要主动调用startAuthentication方法去鉴权。(只有鉴权成功,AI功能才可用)
/// 单利
/// 切换连接类型
/// - Parameter type: 连接类型
-- (void)switchConnect:(AiMouseConnectType)type;
+- (void)switchConnect:(AiMouseConnectType)type isConnected:(BOOL)isConneted;
///// 开始鉴权
///// - Parameter finished: 鉴权结果回调
#define kIsAliChannal true
+#define kIsNeedAuth false
+
@interface AiMouseDeviceInfo()
@property (nonatomic, strong) NSString *productKey;/// 品牌key
@property (nonatomic, strong) NSString *secretKey;/// 品牌Secret
-(instancetype)init{
if (self = [super init]) {
_logLevel = AiMouseLogLevel_none;
- _authState = AiMouseAuthState_Unknow;
- _connectType = AiMouseConnectType_bluetooth;
+ _authState = kIsNeedAuth ? AiMouseAuthState_Unknow:AiMouseAuthState_Success;
+ _connectType = AiMouseConnectType_bluetooth;
[self.connectManager start];
NSLog(@"[AiMouseSdk]%@",[NSString stringWithFormat:@"AiMouseSdk_v%@",self.version]);
}
[self.connectManager disConnected];
}
-- (void)switchConnect:(AiMouseConnectType)type{
- if(type != _connectType && self.connected){
- [self.connectManager disConnected];
+- (void)switchConnect:(AiMouseConnectType)type isConnected:(BOOL)isConneted{
+ _connected = isConneted;
+ if (isConneted) {
+ _connectType = type;
+ [self showLog:type == AiMouseConnectType_bluetooth?@"sdk切换到蓝牙模式":@"sdk切换到usb模式"];
}
- _connectType = type;
- [self showLog:type == AiMouseConnectType_bluetooth?@"sdk切换到蓝牙模式":@"sdk切换到usb模式"];
-
+ [self aiConnectManager:self.connectManager connectStateDidChange:isConneted];
- if (type == AiMouseConnectType_hid) {
+ if (type == AiMouseConnectType_hid && isConneted) {
[self.recordManager checkPermissions];
}
}
landmarkType = "0">
</BreakpointContent>
</BreakpointProxy>
- <BreakpointProxy
- BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
- <BreakpointContent
- uuid = "C13039FF-9A3F-41DA-BFBF-DB7E074186A0"
- shouldBeEnabled = "Yes"
- ignoreCount = "0"
- continueAfterRunningActions = "No"
- filePath = "MouseSdk/Ble/DeviceManger.m"
- startingColumnNumber = "9223372036854775807"
- endingColumnNumber = "9223372036854775807"
- startingLineNumber = "266"
- endingLineNumber = "266"
- landmarkName = "-tlwMouseSendDeviceInfoData:"
- landmarkType = "7">
- </BreakpointContent>
- </BreakpointProxy>
</Breakpoints>
</Bucket>
@interface BleManager : NSObject
-@property (nonatomic, copy)void (^connectStateCallBack)(BOOL connected);/// 设备连接状态回调
+@property (nonatomic, copy)void (^connectStateCallBack)(NSString *name,BOOL connected);/// 设备连接状态回调
@property (nonatomic, copy)void (^receiveVoiceDataCallBack)(NSData *data);/// 语音数据回调
@property (nonatomic, copy)void (^receiveInfoDataCallBack)(NSData *data);/// 设备信息数据回调
@property (nonatomic, copy)void (^logCallBack)(NSString *log);//输出日志
#import "BleManager.h"
-//// 服务id
-//#define kServiceUUID @"FFF1"
-////ai特征
-//#define kAiUUID @"0783B03E-8535-B5A0-7140-A304D2194CB8"
-////设备信息特征
-//#define kDeviceInfoUUID @"0783B63E-8535-B5A0-7140-A304D2495CB6"
-
// 服务id
-#define kServiceUUID @"FFF0"
+#define kFrkServiceUUID @"FFF1"
//ai特征
-#define kAiUUID @"00010203-0405-0607-0809-0A0B0C0D2B18"
+#define kFrkVoiceUUID @"0783B03E-8535-B5A0-7140-A304D2194CB8"
+//设备信息特征
+#define kFrkDeviceInfoUUID @"0783B63E-8535-B5A0-7140-A304D2495CB6"
+
+// 服务id
+#define kTlwServiceUUID @"FFF0"
+//voice特征
+#define kTlwVoiceUUID @"00010203-0405-0607-0809-0A0B0C0D2B18"
//写设备信息特征
-#define kSetDeviceInfoUUID @"FFF1"
+#define kTlwSetDeviceInfoUUID @"FFF1"
//通知设备信息特征
-#define kNotifyDeviceInfoUUID @"FFF2"
+#define kTlwNotifyDeviceInfoUUID @"FFF2"
@interface BleManager ()<CBCentralManagerDelegate,CBPeripheralDelegate>
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
- [self showLog:[NSString stringWithFormat:@"连接成功 name = %@",peripheral.name]];
+// [self showLog:[NSString stringWithFormat:@"连接成功 name = %@",peripheral.name]];
peripheral.delegate = self;
[peripheral discoverServices:nil];
self.crrentPeripheral = peripheral;
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
[self showLog:[NSString stringWithFormat:@"断开连接。。。%@",error.description]];
+ self.connectStateCallBack(self.crrentPeripheral.name,false);
self.crrentPeripheral = nil;
- self.connectStateCallBack(false);
+
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
[self showLog:[NSString stringWithFormat:@"连接失败。。。%@",error.description]];
+ self.connectStateCallBack(self.crrentPeripheral.name,false);
self.crrentPeripheral = nil;
- self.connectStateCallBack(false);
}
#pragma mark - CBPeripheralDelegate
//发现服务
// 发现特征
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
- for (CBCharacteristic *characteristic in service.characteristics){
- if ([characteristic.UUID.UUIDString isEqualToString:kAiUUID]) {
- //语音特征
- [peripheral setNotifyValue:YES forCharacteristic:characteristic];
- }
- else if ([characteristic.UUID.UUIDString isEqualToString:kNotifyDeviceInfoUUID]) {
- //通知设备信息特征
- [peripheral setNotifyValue:YES forCharacteristic:characteristic];
+ if([peripheral.name isEqualToString:@"VMouse"]){
+ for (CBCharacteristic *characteristic in service.characteristics){
+ if ([characteristic.UUID.UUIDString isEqualToString:kFrkVoiceUUID]) {
+ //语音特征
+ [peripheral setNotifyValue:YES forCharacteristic:characteristic];
+ }
+ else if ([characteristic.UUID.UUIDString isEqualToString:kFrkDeviceInfoUUID]) {
+ //通知设备信息特征
+ [peripheral setNotifyValue:YES forCharacteristic:characteristic];
+ self.deviceInfoCha = characteristic;
+ [self showLog:[NSString stringWithFormat:@"连接成功 = %@",peripheral.name]];
+ self.connectStateCallBack(self.crrentPeripheral.name,true);
+ }
+
}
- else if ([characteristic.UUID.UUIDString isEqualToString:kSetDeviceInfoUUID]) {
- //设备信息特征
- self.deviceInfoCha = characteristic;
- [self showLog:(@"回调连接成功 ")];
- self.connectStateCallBack(true);
+ }
+ else{
+ for (CBCharacteristic *characteristic in service.characteristics){
+ if ([characteristic.UUID.UUIDString isEqualToString:kTlwVoiceUUID]) {
+ //语音特征
+ [peripheral setNotifyValue:YES forCharacteristic:characteristic];
+ }
+ else if ([characteristic.UUID.UUIDString isEqualToString:kTlwNotifyDeviceInfoUUID]) {
+ //通知设备信息特征
+ [peripheral setNotifyValue:YES forCharacteristic:characteristic];
+ }
+ else if ([characteristic.UUID.UUIDString isEqualToString:kTlwSetDeviceInfoUUID]) {
+ //设备信息特征
+ self.deviceInfoCha = characteristic;
+ [self showLog:[NSString stringWithFormat:@"连接成功 = %@",peripheral.name]];
+ self.connectStateCallBack(self.crrentPeripheral.name,true);
+ }
}
}
}
//收到蓝牙数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
- NSData *data = characteristic.value;
- if([characteristic.UUID.UUIDString isEqualToString:kAiUUID]){
- //AI数据
- self.receiveVoiceDataCallBack(data);
+ if ([peripheral.name isEqualToString:@"VMouse"]) {
+ NSData *data = characteristic.value;
+ if([characteristic.UUID.UUIDString isEqualToString:kFrkVoiceUUID]){
+ self.receiveVoiceDataCallBack(data);
+ }
+ else if([characteristic.UUID.UUIDString isEqualToString:kFrkDeviceInfoUUID]){
+ self.receiveInfoDataCallBack(data);
+ }
}
- else if([characteristic.UUID.UUIDString isEqualToString:kNotifyDeviceInfoUUID]){
- //设备信息数据
- self.receiveInfoDataCallBack(data);
+ else{
+ NSData *data = characteristic.value;
+ if([characteristic.UUID.UUIDString isEqualToString:kTlwVoiceUUID]){
+ //AI数据
+ self.receiveVoiceDataCallBack(data);
+ }
+ else if([characteristic.UUID.UUIDString isEqualToString:kTlwNotifyDeviceInfoUUID]){
+ //设备信息数据
+ self.receiveInfoDataCallBack(data);
+ }
}
}
//
// self.bleName = bleName;
- NSArray<CBPeripheral *> *devices = [self.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]]];
+ NSArray<CBPeripheral *> *devices = [self.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:kFrkServiceUUID],[CBUUID UUIDWithString:kTlwServiceUUID]]];
if (devices.count > 0 && [self isContainInSearchList: devices[0].name]) {
[self showLog:[NSString stringWithFormat:@"匹配过的设备%@",devices[0].name]];
[self connectPeripheral:devices[0]];
/// 连接设备
- (void)connectPeripheral:(CBPeripheral *)peripheral{
+ if(self.crrentPeripheral != nil && self.crrentPeripheral.state == CBPeripheralStateConnected){
+ [self showLog:@"当前蓝牙已处理连接状态,不会重连!!!"];
+ return;
+ }
+
[self showLog:[NSString stringWithFormat:@"连接设备 %@",peripheral.description]];
self.crrentPeripheral = peripheral;
[self.centralManager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey : [NSNumber numberWithBool:YES]}];
return;
}
[self showLog:[NSString stringWithFormat:@"向蓝牙设备发送数据 %@",data]];
- [self.crrentPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithResponse];
+
+ if ([self.crrentPeripheral.name isEqualToString:@"VMouse"]) {
+ [self.crrentPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithoutResponse];
+ }
+ else{
+ [self.crrentPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithResponse];
+ }
}
- (void)showLog:(NSString *)log{
#import <Foundation/Foundation.h>
#import "AiMouseSdk.h"
+/// 产品类型
+typedef NS_ENUM(NSInteger,AiMouseProductType) {
+ AiMouseProductType_frk = 1,///富瑞坤
+ AiMouseProductType_tlw = 2,///泰凌微
+};
+
NS_ASSUME_NONNULL_BEGIN
@interface DeviceManger : NSObject
+@property (nonatomic, readonly)BOOL isConneted;//是否连接
@property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型
#pragma mark ------- 鼠标的回调
#import "TlwMouseSdk.h"
#import "TimerManager.h"
+
+
@interface DeviceManger()<TlwMouseDelegate,AiMouseDelegate>
@property (nonatomic, strong) AiMouseDeviceInfo *deviceInfo;
@property (nonatomic,strong) TlwMouse *tlwSdk;
@property (nonatomic,strong) AiMouse *frkSdk;
+@property (nonatomic,assign) AiMouseProductType productType;
//connectType 返回为0代表蓝牙,为1代表usb
@property (nonatomic, copy)void (^aiMouseConnectStateDidChangeCallBack)(int connectType, BOOL connected);/// 设备连接状态回调
- (instancetype)init{
self = [super init];
if (self) {
- self.tlwSdk = [[TlwMouse alloc] init];
- [self.tlwSdk setDelegate:self];
- [self.tlwSdk setLogLevel:(TlwMouseLogLevel_info)];
-
-
-
[self setupBle];
[self setupHid];
[self setupTimer];
- (void)setupTimer{
[TimerManager shared].timerCallBack = ^{
[self showLog:@"timer action。。。"];
- if(self.tlwSdk.connected){
+ if(self.tlwSdk.connected || self.frkSdk.connected){
[self.ble stopScan];
// [self.hid close];
}
if (connected) {
[ws.ble stopScan];
}
- [ws.tlwSdk switchConnect:AiMouseConnectType_hid isConnected:connected];
+// if ([name isEqualToString:@"NNMouse"]) {
+// ws.productType = AiMouseProductType_tlw;
+// ws.tlwSdk = [[TlwMouse alloc] init];
+// [ws.tlwSdk setDelegate:ws];
+// [ws.tlwSdk setLogLevel:(TlwMouseLogLevel_info)];
+// [ws.tlwSdk switchConnect:AiMouseConnectType_hid isConnected:connected];
+// }
+// else{
+ ws.productType = AiMouseProductType_frk;
+ ws.frkSdk = [AiMouse shared];
+ [ws.frkSdk setDelegate:ws];
+ [ws.frkSdk setLogLevel:AiMouseLogLevel_info];
+ [ws.frkSdk switchConnect:AiMouseConnectType_hid isConnected:connected];
+// }
};
self.hid.receiveInfoDataCallBack = ^(NSData *data) {
- [ws.tlwSdk sendDeviceDataToSdk:data];
- };
- self.hid.receiveVoiceDataCallBack = ^(NSData *data) {
- [ws.tlwSdk sendAiDataToSdk:data];
+ if (ws.productType == AiMouseProductType_tlw) {
+ [ws.tlwSdk sendDeviceDataToSdk:data];
+ }
+ else{
+ [ws.frkSdk sendDeviceDataToSdk:data];
+ }
};
-
self.hid.logCallBack = ^(NSString * _Nonnull log) {
[ws showLog:log];
};
self.ble = [[BleManager alloc] init];
__weak typeof(self) ws = self;
- self.ble.connectStateCallBack = ^(BOOL connected) {
+ self.ble.connectStateCallBack = ^(NSString *name,BOOL connected) {
if (connected) {
[ws.hid close];
}
- [ws.tlwSdk switchConnect:AiMouseConnectType_bluetooth isConnected:connected];
+ if ([name isEqualToString:@"NMMouse"]) {
+ ws.productType = AiMouseProductType_tlw;
+ ws.tlwSdk = [[TlwMouse alloc] init];
+ [ws.tlwSdk setDelegate:ws];
+ [ws.tlwSdk setLogLevel:(TlwMouseLogLevel_info)];
+ [ws.tlwSdk switchConnect:AiMouseConnectType_bluetooth isConnected:connected];
+ }
+ else{
+ ws.productType = AiMouseProductType_frk;
+ ws.frkSdk = [AiMouse shared];
+ [ws.frkSdk setDelegate:ws];
+ [ws.frkSdk setLogLevel:AiMouseLogLevel_info];
+ [ws.frkSdk switchConnect:AiMouseConnectType_bluetooth isConnected:connected];
+ }
};
self.ble.receiveInfoDataCallBack = ^(NSData *data) {
- [ws.tlwSdk sendDeviceDataToSdk:data];
+ if (ws.productType == AiMouseProductType_tlw) {
+ [ws.tlwSdk sendDeviceDataToSdk:data];
+ }
+ else{
+ [ws.frkSdk sendDeviceDataToSdk:data];
+ }
};
self.ble.receiveVoiceDataCallBack = ^(NSData *data) {
- [ws.tlwSdk sendAiDataToSdk:data];
+ if (ws.productType == AiMouseProductType_tlw) {
+ [ws.tlwSdk sendAiDataToSdk:data];
+ }
+ else{
+ [ws.frkSdk sendDeviceDataToSdk:data];
+ }
};
self.ble.logCallBack = ^(NSString * _Nonnull log) {
#pragma mark ------ 设备相关接口
+-(BOOL)isConneted{
+ if (self.tlwSdk != nil && self.tlwSdk.connected) {
+ return true;
+ }
+ if (self.frkSdk != nil && self.frkSdk.connected) {
+ return true;
+ }
+ return false;
+}
- (NSString *)getCurrentConnectType {
- if (self.tlwSdk.connectType == AiMouseConnectType_bluetooth) {
- return @"0";
+ if (self.productType == AiMouseProductType_tlw) {
+ if (self.tlwSdk.connectType == AiMouseConnectType_bluetooth) {
+ return @"0";
+ }
+ else {
+ return @"1";
+ }
}
- else {
- return @"1";
+ else{
+ if (self.frkSdk.connectType == AiMouseConnectType_bluetooth) {
+ return @"0";
+ }
+ else {
+ return @"1";
+ }
}
}
-(AiMouseConnectType)connectType{
- return self.tlwSdk.connectType;
+ if (self.productType == AiMouseProductType_tlw) {
+ return self.tlwSdk.connectType;
+ }
+ else{
+ return self.frkSdk.connectType;
+ }
}
-
- (void)begainMonitorAiMouseConnectStateDidChange:(NSString *)mouseName callBack:(void(^)(int connectType, BOOL connected))callBack{
self.aiMouseConnectStateDidChangeCallBack = callBack;
- self.mouseNames = @[mouseName];
+ self.mouseNames = @[mouseName,@"VMouse"];
}
///获取设备信息
-- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))completation{
+- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{
[self showLog:@"getDeviceInfo request"];
- [self.tlwSdk getDeviceInfo:^(TlwDeviceInfo *deviceInfo, NSError *error) {
-
- NSString *CPI_list = @"800,1200,1800,2400";// 1-4,800 1200 1800 2400
- NSString *cpi = [[CPI_list componentsSeparatedByString:@","] objectAtIndex:deviceInfo.DPI - 1];
-
- AiMouseDeviceInfo *info = [[AiMouseDeviceInfo alloc] init];
- info.battery_power = [NSString stringWithFormat:@"%d",deviceInfo.batteryValue] ;
- info.version = [NSString stringWithFormat:@"%d",deviceInfo.version];
- info.CPI_list = CPI_list;// 1-4,800 1200 1800 2400
- info.CPI = cpi;
-// info.CPI_list = @"1,2,3,4";// 1-4,800 1200 1800 2400
-// info.CPI = [NSString stringWithFormat:@"%d",deviceInfo.DPI];
- info.brand = @"NNMouse";
- info.sn = @"MSCL1BKZ12105000042371";
- info.mac = @"C0310000A583";
- self.deviceInfo = info;
-
- [self showLog:info.description];
- completation(info,nil);
- }];
+ if (self.productType == AiMouseProductType_tlw) {
+ [self.tlwSdk getDeviceInfo:^(TlwDeviceInfo *deviceInfo, NSError *error) {
+ NSString *CPI_list = @"800,1200,1800,2400";// 1-4,800 1200 1800 2400
+ NSString *cpi = [[CPI_list componentsSeparatedByString:@","] objectAtIndex:deviceInfo.DPI - 1];
+
+ AiMouseDeviceInfo *info = [[AiMouseDeviceInfo alloc] init];
+ info.battery_power = [NSString stringWithFormat:@"%d",deviceInfo.batteryValue] ;
+ info.version = [NSString stringWithFormat:@"%d",deviceInfo.version];
+ info.CPI_list = CPI_list;// 1-4,800 1200 1800 2400
+ info.CPI = cpi;
+ // info.CPI_list = @"1,2,3,4";// 1-4,800 1200 1800 2400
+ // info.CPI = [NSString stringWithFormat:@"%d",deviceInfo.DPI];
+ info.brand = @"NNMouse";
+ info.sn = @"MSCL1BKZ12105000042371";
+ info.mac = @"C0310000A583";
+ self.deviceInfo = info;
+
+ [self showLog:info.description];
+ finished(info,nil);
+ }];
+ }
+ else{
+ [self.frkSdk getDeviceInfo:finished];
+ }
}
/// 获取信号强度
-- (void)getRSSI:(void (^)(NSString *value,NSError *error))completation{
- completation(nil,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+- (void)getRSSI:(void (^)(NSString *value,NSError *error))finished{
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(nil,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk getRSSI:finished];
+ }
}
/// 设置CPI
- (void)setCPI:(NSInteger)value completation:(void (^)(BOOL isSuccess,NSError *error))finished{
- NSDictionary *dict = @{
- @"800":@"1",
- @"1200":@"2",
- @"1800":@"3",
- @"2400":@"4"
- };
-
- if (dict[[NSString stringWithFormat:@"%ld",value]]) {
- int num = [dict[[NSString stringWithFormat:@"%ld",value]] intValue];
- [self.tlwSdk setDPI:num completation:finished];
+ if (self.productType == AiMouseProductType_tlw) {
+ NSDictionary *dict = @{
+ @"800":@"1",
+ @"1200":@"2",
+ @"1800":@"3",
+ @"2400":@"4"
+ };
+
+ if (dict[[NSString stringWithFormat:@"%ld",value]]) {
+ int num = [dict[[NSString stringWithFormat:@"%ld",value]] intValue];
+ [self.tlwSdk setDPI:num completation:finished];
+ }
+ else{
+ [self showLog:[NSString stringWithFormat:@"CPI值设置错误 %ld",value]];
+ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"CPI值设置错误"}]);
+ }
}
else{
- [self showLog:[NSString stringWithFormat:@"CPI值设置错误 %ld",value]];
- finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"CPI值设置错误"}]);
+ [self.frkSdk setCPI:value completation:finished];
}
}
/// - value: 品牌名称
/// - finished: 设置结果回调
- (void)setBrand:(NSString *)brand completation:(void (^)(BOOL isSuccess,NSError *error))finished {
-// [self.tlwSdk setBrand:brand completation:finished];
- finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk setBrand:brand completation:finished];
+ }
}
/// 设置录音模式
- (void)setRecordMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished{
-// [self.tlwSdk setRecordMode:mode completation:finished];
- finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk setRecordMode:mode completation:finished];
+ }
}
/// 设置长按滚轮弹出的网页地址
- (void)setUrl:(NSString *)url completation:(void (^)(BOOL isSuccess,NSError *error))finished{
-// [self.tlwSdk setUrl:url completation:finished];
- finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk setUrl:url completation:finished];
+ }
}
/// 设置长按滚轮弹出网页开关
- (void)setUrlState:(int)state completation:(void (^)(BOOL isSuccess,NSError *error))finished{
-// [self.tlwSdk setUrlState:state completation:finished];
- finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk setUrlState:state completation:finished];
+ }
}
/// 设置鼠标连接模式
- (void)setMouseMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished{
-// [self.tlwSdk setMouseMode:mode completation:finished];
- finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk setMouseMode:mode completation:finished];
+ }
}
/// 获取录音模式
- (void)getRecordMode:(void (^)(int mode,NSError *error))finished{
-// [self.tlwSdk getRecordMode:complete];
- finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk getRecordMode:finished];
+ }
}
/// 获取长按滚轮弹出的网页地址
- (void)getUrl:(void (^)(NSString *url,NSError *error))finished{
-// [self.tlwSdk getUrl:complete];
- finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk getUrl:finished];
+ }
}
/// 获取长按滚轮弹出的网页地址开关状态
- (void)getUrlState:(void (^)(int state,NSError *error))finished{
-// [self.tlwSdk getUrlState:complete];
- finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(false,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk getUrlState:finished];
+ }
}
/// 获取鼠标连接模式
- (void)getMouseModel:(void (^)(int mode,NSError *error))finished{
-// [self.tlwSdk getMouseModel:complete];
- finished(0,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}]);
+ if (self.productType == AiMouseProductType_tlw) {
+ finished(0,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"当前鼠标不支持该接口"}]);
+ }
+ else{
+ [self.frkSdk getMouseModel:finished];
+ }
}
/// 打开录音
- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
- [self.tlwSdk openRecord:finished];
+ if (self.productType == AiMouseProductType_tlw) {
+ [self.tlwSdk openRecord:finished];
+ }
+ else{
+ [self.frkSdk openRecord:finished];
+ }
}
/// 关闭录音
- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
- [self.tlwSdk closeRecord:finished];
+ if (self.productType == AiMouseProductType_tlw) {
+ [self.tlwSdk closeRecord:finished];
+ }
+ else{
+ [self.frkSdk closeRecord:finished];
+ }
}
//
#import <Foundation/Foundation.h>
-
+#import "DeviceManger.h"
NS_ASSUME_NONNULL_BEGIN
@interface HidManager : NSObject
@property (nonatomic, copy)void (^connectStateCallBack)(BOOL connected);/// 设备连接状态回调
-@property (nonatomic, copy)void (^receiveVoiceDataCallBack)(NSData *data);/// 语音数据回调
@property (nonatomic, copy)void (^receiveInfoDataCallBack)(NSData *data);/// 设备信息数据回调
@property (nonatomic, copy)void (^logCallBack)(NSString *log);//输出日志
+@property (nonatomic, assign)AiMouseProductType productType;//
+
+(HidManager *)shared;
- (void)open;
@interface HidManager ()
@property(nonatomic, assign) IOHIDManagerRef hidManager;///hid管理
@property(nonatomic, assign) IOHIDDeviceRef deviceInfoCha;//设备信息通道
+@property(nonatomic, assign) IOHIDDeviceRef voiceCha;//语音通道
@end
@implementation HidManager
#pragma mark - Hid CallBack
/// 匹配到设备回调
static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOHIDDeviceRef inIOHIDDeviceRef) {
- [HidManager shared].deviceInfoCha = inIOHIDDeviceRef;
- [[HidManager shared] showLog:([NSString stringWithFormat:@"发现设备 %@",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]];
- }else{
- [[HidManager shared] showLog:@"打开设备成功!"];
- [HidManager shared].connectStateCallBack(true) ;
+ if ([DeviceManger shared].isConneted) {
+ [[HidManager shared] showLog:(@"当前处于连接状态,对监听到有USB 插入 的事件不做处理")];
+ return;
+ }
+ if([HidManager shared].productType == AiMouseProductType_tlw){
+ [HidManager shared].deviceInfoCha = inIOHIDDeviceRef;
+ [[HidManager shared] showLog:([NSString stringWithFormat:@"发现设备 %@",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]];
+ }else{
+ [[HidManager shared] showLog:@"打开设备成功!"];
+ [HidManager shared].connectStateCallBack(true) ;
+ }
+ CFRetain([HidManager shared].deviceInfoCha);
+ IOHIDDeviceScheduleWithRunLoop([HidManager shared].deviceInfoCha, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ }
+ else{
+ uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey));
+ uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey));
+ NSString *tmpPrimaryUsagePage = [NSString stringWithFormat:@"%u",PrimaryUsagePage];
+ NSString *tmpPrimaryUsage = [NSString stringWithFormat:@"%u",PrimaryUsage];
+ if([tmpPrimaryUsagePage isEqualToString:@"1"] && [tmpPrimaryUsage isEqualToString:@"0"]){
+ //设备信息
+ [HidManager shared].deviceInfoCha = inIOHIDDeviceRef;
+ if ([HidManager shared].connectStateCallBack != nil) {
+ [HidManager shared].connectStateCallBack(true);
+ }
+ unsigned char InputBuffer[128];
+ IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL);
+ }
+ else if([tmpPrimaryUsagePage isEqualToString:@"65283"] && [tmpPrimaryUsage isEqualToString:@"0"]){
+ [HidManager shared].voiceCha = inIOHIDDeviceRef;
+ unsigned char InputBuffer[128];
+ IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL);
+ }
}
- CFRetain([HidManager shared].deviceInfoCha);
- IOHIDDeviceScheduleWithRunLoop([HidManager shared].deviceInfoCha, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
}
/// 设备移除回调
static void hidReceiveData(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report,CFIndex reportLength){
- if (report[0] == 0x01 || report[0] == 0x02) {
- //鼠标键盘活动事件
- return;
+ if([HidManager shared].productType == AiMouseProductType_tlw){
+ if (report[0] == 0x01 || report[0] == 0x02) {
+ //鼠标键盘活动事件
+ return;
+ }
+ NSData *data = [[NSData alloc] initWithBytes:report length:reportLength];
+ [HidManager shared].receiveInfoDataCallBack(data);
+ }
+ else{
+ NSInteger len = get_data_len(report, reportLength);
+ NSData *data = [[NSData alloc] initWithBytes:report length:len];
+ uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsagePageKey));
+ uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsageKey));
+
+ if(PrimaryUsagePage == 1 && PrimaryUsage == 0){
+ [[AiMouse shared] sendDeviceDataToSdk:data];
+ }
+ else if(PrimaryUsagePage == 65283 && PrimaryUsage == 0){
+ [[AiMouse shared] sendAiDataToSdk:data];
+ }
}
-// NSInteger len = get_data_len(report, reportLength);
-// NSData *data = [[NSData alloc] initWithBytes:report length:len];
-
-// NSInteger len = get_data_len(report, reportLength);
- NSData *data = [[NSData alloc] initWithBytes:report length:reportLength];
-
- [HidManager shared].receiveInfoDataCallBack(data);
}
#pragma mark - public
}
//设置匹配设备
////供应商id
- //const long vendorID = 0x6675;
- ////产品id
- //const long productID = 0x8601;
- //供应商id
- const long vendorID = 0x10D6;
+ const long vendorID = 0x6675;
//产品id
- const long productID = 0xB008;
+ 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]];
}
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) {
+ [[HidManager shared] showLog:[NSString stringWithFormat:@"(HidManager)IOHIDDevGetUInt32Property:get %@ failed.", inKey]];
+ }
+ }
+ }
+ return outValue;
+}
@end