180E7B562BD7BD83008558E8 /* AiMouseConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 180E7AB62BD7BD7D008558E8 /* AiMouseConfig.h */; };
180E7B572BD7BD83008558E8 /* AiAudioConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 180E7AB72BD7BD7D008558E8 /* AiAudioConverter.h */; };
180E7B582BD7BD83008558E8 /* AiRecordManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 180E7AB82BD7BD7D008558E8 /* AiRecordManager.h */; };
- 180E7BDD2BD7BD84008558E8 /* AiAuthManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 180E7B472BD7BD7F008558E8 /* AiAuthManager.h */; };
180E7BDE2BD7BD84008558E8 /* AiMouseTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 180E7B482BD7BD7F008558E8 /* AiMouseTools.h */; };
180E7BDF2BD7BD84008558E8 /* AiMouseConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 180E7B492BD7BD80008558E8 /* AiMouseConfig.m */; };
180E7BE02BD7BD84008558E8 /* AiMouseTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 180E7B4A2BD7BD80008558E8 /* AiMouseTools.m */; };
180E7BE52BD7BD84008558E8 /* AiMouseTools2.m in Sources */ = {isa = PBXBuildFile; fileRef = 180E7B4F2BD7BD81008558E8 /* AiMouseTools2.m */; };
180E7BE62BD7BD84008558E8 /* AiAudioDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 180E7B502BD7BD82008558E8 /* AiAudioDecoder.h */; };
180E7BE72BD7BD84008558E8 /* AiAudioManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 180E7B512BD7BD82008558E8 /* AiAudioManager.m */; };
- 180E7BE82BD7BD84008558E8 /* AiAuthManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 180E7B522BD7BD82008558E8 /* AiAuthManager.m */; };
180E7BE92BD7BD84008558E8 /* AiMouseTools2.h in Headers */ = {isa = PBXBuildFile; fileRef = 180E7B532BD7BD82008558E8 /* AiMouseTools2.h */; };
180E7C842BD8FC4E008558E8 /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = 180E7BF92BD8FC4E008558E8 /* version.h */; };
180E7C852BD8FC4E008558E8 /* buffersrc.h in Headers */ = {isa = PBXBuildFile; fileRef = 180E7BFA2BD8FC4E008558E8 /* buffersrc.h */; };
180E7D112BD8FF11008558E8 /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 180E7D102BD8FF11008558E8 /* libbz2.tbd */; };
180E7D132BD8FF3A008558E8 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 180E7D122BD8FF3A008558E8 /* libiconv.tbd */; };
180E7D152BD8FF5C008558E8 /* liblzma.5.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 180E7D142BD8FF5C008558E8 /* liblzma.5.tbd */; };
- 181CE5C12C6EED9900EF8D07 /* AiAliAuthManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 181CE5BF2C6EED9900EF8D07 /* AiAliAuthManager.h */; };
- 181CE5C22C6EED9900EF8D07 /* AiAliAuthManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 181CE5C02C6EED9900EF8D07 /* AiAliAuthManager.m */; };
184A71022BDA4C050025A332 /* AFSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 184A70F42BDA4C040025A332 /* AFSecurityPolicy.h */; };
184A71032BDA4C050025A332 /* AFNetworkReachabilityManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 184A70F52BDA4C040025A332 /* AFNetworkReachabilityManager.h */; };
184A71042BDA4C050025A332 /* AFURLSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 184A70F62BDA4C040025A332 /* AFURLSessionManager.h */; };
184A71252BDE2DA60025A332 /* AiSecretModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 184A71232BDE2DA60025A332 /* AiSecretModel.m */; };
189C15862C05726600676A80 /* AiConnectManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 189C15842C05726600676A80 /* AiConnectManager.h */; };
189C15872C05726600676A80 /* AiConnectManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 189C15852C05726600676A80 /* AiConnectManager.m */; };
- 18AD83252BFAE8B9009BDE3B /* AiDeviceInfoManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */; };
- 18AD83262BFAE8B9009BDE3B /* AiDeviceInfoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AD83242BFAE8B9009BDE3B /* AiDeviceInfoManager.m */; };
18AD83292BFB22DE009BDE3B /* AiSender.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD83272BFB22DE009BDE3B /* AiSender.h */; };
18AD832A2BFB22DE009BDE3B /* AiSender.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AD83282BFB22DE009BDE3B /* AiSender.m */; };
/* End PBXBuildFile section */
180E7AB62BD7BD7D008558E8 /* AiMouseConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AiMouseConfig.h; sourceTree = "<group>"; };
180E7AB72BD7BD7D008558E8 /* AiAudioConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AiAudioConverter.h; sourceTree = "<group>"; };
180E7AB82BD7BD7D008558E8 /* AiRecordManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AiRecordManager.h; sourceTree = "<group>"; };
- 180E7B472BD7BD7F008558E8 /* AiAuthManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AiAuthManager.h; sourceTree = "<group>"; };
180E7B482BD7BD7F008558E8 /* AiMouseTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AiMouseTools.h; sourceTree = "<group>"; };
180E7B492BD7BD80008558E8 /* AiMouseConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AiMouseConfig.m; sourceTree = "<group>"; };
180E7B4A2BD7BD80008558E8 /* AiMouseTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AiMouseTools.m; sourceTree = "<group>"; };
180E7B4F2BD7BD81008558E8 /* AiMouseTools2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AiMouseTools2.m; sourceTree = "<group>"; };
180E7B502BD7BD82008558E8 /* AiAudioDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AiAudioDecoder.h; sourceTree = "<group>"; };
180E7B512BD7BD82008558E8 /* AiAudioManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AiAudioManager.m; sourceTree = "<group>"; };
- 180E7B522BD7BD82008558E8 /* AiAuthManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AiAuthManager.m; sourceTree = "<group>"; };
180E7B532BD7BD82008558E8 /* AiMouseTools2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AiMouseTools2.h; sourceTree = "<group>"; };
180E7BF92BD8FC4E008558E8 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
180E7BFA2BD8FC4E008558E8 /* buffersrc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffersrc.h; sourceTree = "<group>"; };
180E7D102BD8FF11008558E8 /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; };
180E7D122BD8FF3A008558E8 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; };
180E7D142BD8FF5C008558E8 /* liblzma.5.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = liblzma.5.tbd; path = usr/lib/liblzma.5.tbd; sourceTree = SDKROOT; };
- 181CE5BF2C6EED9900EF8D07 /* AiAliAuthManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AiAliAuthManager.h; sourceTree = "<group>"; };
- 181CE5C02C6EED9900EF8D07 /* AiAliAuthManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AiAliAuthManager.m; sourceTree = "<group>"; };
184A70F42BDA4C040025A332 /* AFSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSecurityPolicy.h; sourceTree = "<group>"; };
184A70F52BDA4C040025A332 /* AFNetworkReachabilityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworkReachabilityManager.h; sourceTree = "<group>"; };
184A70F62BDA4C040025A332 /* AFURLSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLSessionManager.h; sourceTree = "<group>"; };
184A71232BDE2DA60025A332 /* AiSecretModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiSecretModel.m; sourceTree = "<group>"; };
189C15842C05726600676A80 /* AiConnectManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiConnectManager.h; sourceTree = "<group>"; };
189C15852C05726600676A80 /* AiConnectManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiConnectManager.m; sourceTree = "<group>"; };
- 18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiDeviceInfoManager.h; sourceTree = "<group>"; };
- 18AD83242BFAE8B9009BDE3B /* AiDeviceInfoManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiDeviceInfoManager.m; sourceTree = "<group>"; };
18AD83272BFB22DE009BDE3B /* AiSender.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiSender.h; sourceTree = "<group>"; };
18AD83282BFB22DE009BDE3B /* AiSender.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiSender.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
180E7BF62BD8FC4E008558E8 /* ffmpeg */,
180E7AA92BD7BB12008558E8 /* AiMouseSdk.h */,
180E7AAB2BD7BB12008558E8 /* AiMouseSdk.m */,
- 18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */,
- 18AD83242BFAE8B9009BDE3B /* AiDeviceInfoManager.m */,
189C15842C05726600676A80 /* AiConnectManager.h */,
189C15852C05726600676A80 /* AiConnectManager.m */,
18AD83272BFB22DE009BDE3B /* AiSender.h */,
18AD83282BFB22DE009BDE3B /* AiSender.m */,
180E7AB42BD7BD7D008558E8 /* AiFrameManager.h */,
180E7B4D2BD7BD81008558E8 /* AiFrameManager.m */,
- 180E7B472BD7BD7F008558E8 /* AiAuthManager.h */,
- 180E7B522BD7BD82008558E8 /* AiAuthManager.m */,
- 181CE5BF2C6EED9900EF8D07 /* AiAliAuthManager.h */,
- 181CE5C02C6EED9900EF8D07 /* AiAliAuthManager.m */,
184A711D2BDD11C70025A332 /* AiTrippleModel.h */,
184A711E2BDD11C70025A332 /* AiTrippleModel.m */,
184A71222BDE2DA60025A332 /* AiSecretModel.h */,
buildActionMask = 2147483647;
files = (
180E7CFA2BD8FC4F008558E8 /* avdct.h in Headers */,
- 180E7BDD2BD7BD84008558E8 /* AiAuthManager.h in Headers */,
180E7CA52BD8FC4E008558E8 /* cast5.h in Headers */,
180E7CD82BD8FC4E008558E8 /* timestamp.h in Headers */,
180E7CEB2BD8FC4E008558E8 /* vdpau.h in Headers */,
184A710E2BDA4C050025A332 /* AFCompatibilityMacros.h in Headers */,
180E7B572BD7BD83008558E8 /* AiAudioConverter.h in Headers */,
180E7CAD2BD8FC4E008558E8 /* attributes.h in Headers */,
- 18AD83252BFAE8B9009BDE3B /* AiDeviceInfoManager.h in Headers */,
180E7C932BD8FC4E008558E8 /* murmur3.h in Headers */,
180E7CE52BD8FC4E008558E8 /* version.h in Headers */,
180E7CC62BD8FC4E008558E8 /* tea.h in Headers */,
180E7BE62BD7BD84008558E8 /* AiAudioDecoder.h in Headers */,
180E7CCB2BD8FC4E008558E8 /* encryption_info.h in Headers */,
180E7C8F2BD8FC4E008558E8 /* blowfish.h in Headers */,
- 181CE5C12C6EED9900EF8D07 /* AiAliAuthManager.h in Headers */,
180E7CF52BD8FC4F008558E8 /* jni.h in Headers */,
180E7CF62BD8FC4F008558E8 /* packet.h in Headers */,
180E7C882BD8FC4E008558E8 /* hwcontext.h in Headers */,
180E7BE72BD7BD84008558E8 /* AiAudioManager.m in Sources */,
189C15872C05726600676A80 /* AiConnectManager.m in Sources */,
180E7BDF2BD7BD84008558E8 /* AiMouseConfig.m in Sources */,
- 181CE5C22C6EED9900EF8D07 /* AiAliAuthManager.m in Sources */,
184A710D2BDA4C050025A332 /* AFSecurityPolicy.m in Sources */,
180E7B552BD7BD83008558E8 /* AiAudioDecoder.m in Sources */,
- 18AD83262BFAE8B9009BDE3B /* AiDeviceInfoManager.m in Sources */,
184A71092BDA4C050025A332 /* AFURLSessionManager.m in Sources */,
- 180E7BE82BD7BD84008558E8 /* AiAuthManager.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+++ /dev/null
-//
-// AiAliAuthManager.h
-// AiMouseSdk
-//
-// Created by incar on 2024/7/29.
-//
-
-#import <Foundation/Foundation.h>
-#import "AiMouseSdk.h"
-
-NS_ASSUME_NONNULL_BEGIN
-typedef void(^AiAliCmdFinishBlock)(BOOL isSuccess);
-
-@interface AiAliAuthManager : NSObject
-@property (nonatomic,strong)void (^outputLog)(NSString *log);
-@property (nonatomic,strong)void (^setDeviceSecret)(NSString *value,AiAliCmdFinishBlock finished);
-@property (nonatomic,strong)void (^authCallBack)(BOOL isSuccess);
-
-- (void)loginWith:(AiMouseDeviceInfo *)info;
-@end
-
-NS_ASSUME_NONNULL_END
+++ /dev/null
-//
-// AiAliAuthManager.m
-// AiMouseSdk
-//
-// Created by incar on 2024/7/29.
-//
-
-#import "AiAliAuthManager.h"
-#import "AiMouseTools.h"
-#import "AFNetworking.h"
-
-
-const NSString *regionId = @"cn-shenzhen";
-const NSString *accessKeyId = @"LTAI5t8xTtovaeJCHJyA91ou";
-const NSString *accessKeySecret = @"Yqbfke4QOX16b0rFYrCiknLsN9EZRe";
-const NSString *productKey = @"k1kijocAl8M";
-const NSString *productSecret = @"dCQesgqCwnLqybDJ";
-const NSString *instanceId = @"iot-040adh4x";
-
-@interface AiAliAuthManager ()
-@property (nonatomic,strong)AiMouseDeviceInfo *deviceInfo;
-@property (nonatomic,strong)NSString *token;
-@end
-
-@implementation AiAliAuthManager
-
-///将设备密钥密钥写到硬件
--(void)sendDeviceSecretCmd:(NSString *)deviceSecret{
- [self.deviceInfo setValue:deviceSecret forKey:@"deviceSecret"];
- if (self.setDeviceSecret) {
- self.setDeviceSecret(deviceSecret, ^(BOOL isSuccess) {
- [self loginRequest];
- });
- }
-}
-
-- (void)loginWith:(AiMouseDeviceInfo *)info{
- self.deviceInfo = info;
- if ([self.deviceInfo.mac isKindOfClass:[NSString class]] && self.deviceInfo.mac.length > 0 ) {
- if([[info valueForKey:@"deviceSecret"] isKindOfClass:[NSString class]] && ([(NSString *)[info valueForKey:@"deviceSecret"] length] > 2)){
- //已注册过,直接登录
- [self loginRequest];
- }
- else{
- //未注册
- [self registerReuest];
- }
- }
- else{
- [self showLog:@"获取设备信息错误,鉴权失败!"];
- }
-
-}
-
-- (void)showLog:(NSString *)log {
- if (self.outputLog) self.outputLog([NSString stringWithFormat:@"[auth]%@",log]);
-}
-
-#pragma mark - register
-- (NSString *)signText:(NSDictionary *)param{
- NSMutableArray<NSString *> *keys = [NSMutableArray arrayWithArray:param.allKeys];
- [keys sortUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
- return [obj1 compare:obj2];
- }];
-
- NSMutableArray *items = [[NSMutableArray alloc] init];
- for (NSString *key in keys) {
- NSString *value = [NSString stringWithFormat:@"%@=%@",key,param[key]];
- [items addObject:value];
- }
- NSString *text = [items componentsJoinedByString:@"&"];
- NSString *text1 = [self utf8Code:text];
- NSString *textToSign = [NSString stringWithFormat:@"GET&%@&%@",[self utf8Code:@"/"],text1];
- return textToSign;
-}
-
-- (NSString *)utf8Code:(NSString *)text{
- NSCharacterSet *allowedCharacters = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"];
- NSString *encode = [text stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
- if (encode.length) {
- return encode;
- }
- return text;
-}
-
-- (NSString *)getFullParams:(NSDictionary *)param{
- NSMutableArray<NSString *> *keys = [NSMutableArray arrayWithArray:param.allKeys];
- [keys sortUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
- return [obj1 compare:obj2];
- }];
-
- NSMutableArray *items = [[NSMutableArray alloc] init];
- for (NSString *key in keys) {
- NSString *value = [NSString stringWithFormat:@"%@=%@",key,param[key]];
- [items addObject:value];
- }
- NSString *text = [items componentsJoinedByString:@"&"];
- return text;
-}
-
-- (void)registerReuest{
-
- NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:@{
- @"Action":@"RegisterDevice",
- @"ProductKey":productKey,
- @"IotInstanceId":instanceId,
- @"DeviceName": self.deviceInfo.mac,
- }] ;
- params[@"Format"] = @"JSON";
- params[@"Version"] = @"2018-01-20";
- params[@"AccessKeyId"] = accessKeyId;//阿里云颁发给用户的访问服务所用的密钥ID。登录阿里云控制台,将鼠标指针移至账号头像上,然后单击AccessKey管理,跳转至AccessKey页面,即可创建和查看AccessKey。
- params[@"Timestamp"] = [AiMouseTools getCurrentTime];//例如,2016-01-04T12:00:00Z表示北京时间2016年01月04日20点0分0秒 @"2024-08-05T10:07:39Z"
- params[@"SignatureVersion"] = @"1.0";//签名算法版本。目前版本是1.0。
- params[@"SignatureNonce"] = [AiMouseTools randomString:14];//唯一随机数。用于防止网络重放攻击。用户在不同请求中要使用不同的随机数值。
- params[@"RegionId"] = regionId;//设备所在地域(与控制台上的地域对应)的ID,如cn-shanghai。
- params[@"SignatureMethod"] = @"HMAC-SHA1";//签名方式,目前支持HMAC-SHA1
-
- NSString *sginText = [self signText:params];
- sginText = [sginText stringByReplacingOccurrencesOfString:@"%3A" withString:@"%253A"];
-
- NSString *key = [NSString stringWithFormat:@"%@&",accessKeySecret];
- NSString *sign = [[AiMouseTools stringToHmacSha1:key text:sginText] lowercaseString];
- NSString *base64 = [AiMouseTools dataWithHexString:sign].base64Encoding;
-// NSLog(@"key = %@",key);
-// NSLog(@"sginText = %@",sginText);
-// NSLog(@"sign = %@",sign);
-// NSLog(@"base64 = %@",base64);
- params[@"Signature"] = base64;
-
- NSString *url = @"https://iot.cn-shenzhen.aliyuncs.com";
- [self showLog:[NSString stringWithFormat:@"%@ %@",url,params]];
-// [self showLog: [NSString stringWithFormat:@"%@?%@",url,[self getFullParams:params]]];
-
- AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
- manager.responseSerializer =[AFHTTPResponseSerializer serializer];
- manager.requestSerializer = [AFJSONRequestSerializer serializer];
- [manager GET:url parameters:params headers:@{} progress:^(NSProgress * _Nonnull downloadProgress) {
-
- } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
- NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
- [self showLog:[NSString stringWithFormat:@" %@",str]];
- NSDictionary *dict = [AiMouseTools dataToDictionary:responseObject];
- NSDictionary *data = dict[@"Data"];
- if([data isKindOfClass:[NSDictionary class]] ){
- NSString *deviceSecret = data[@"DeviceSecret"];
- if ([deviceSecret isKindOfClass:[NSString class]] && deviceSecret.length > 0) {
- [self sendDeviceSecretCmd:deviceSecret];
- [self showLog:@"激活成功"];
- }
- else{
- [self showLog:dict[@"ErrorMessage"]];
- if(self.authCallBack)self.authCallBack(false);
- }
- }
- else{
- [self showLog:dict[@"ErrorMessage"]];
- if(self.authCallBack)self.authCallBack(false);
- }
- } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
- [self showLog:[NSString stringWithFormat:@"error = %@",error]];
- if(self.authCallBack)self.authCallBack(false);
- }];
-}
-
-#pragma mark - login
-- (void)loginRequest{
-// NSString *bid = [self.deviceInfo valueForKey:@"productKey"];//品牌ID,管理中心获取
-// NSString *deviceId = self.deviceInfo.mac;//设备ID
-// NSString *deviceSecret = [self.deviceInfo valueForKey:@"deviceSecret"];//注册返回的密码
-
- NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:@{
- @"clientId": self.deviceInfo.mac,
- @"productKey": productKey,
- @"deviceName": self.deviceInfo.mac,
- @"timestamp": [NSString stringWithFormat:@"%ld",(NSInteger)([[NSDate date] timeIntervalSince1970]*1000 - 8*60*60)],
- }];
-
-
- NSString *sginText = [self loginSignText:params];
- NSString *deviceSecret = [self.deviceInfo valueForKey:@"deviceSecret"];//注册返回的密码
-
- [self showLog:[NSString stringWithFormat:@"text = %@",sginText]];
- [self showLog:[NSString stringWithFormat:@"deviceSecret = %@",deviceSecret]];
- NSString *sign = [[AiMouseTools stringToHmacSha1:deviceSecret text:sginText] lowercaseString];
- [self showLog:[NSString stringWithFormat:@"sign = %@",sign]];
- params[@"sign"] = sign;
- params[@"version"] = @"default";
- params[@"signmethod"] = @"hmacsha1";
-
- NSString *url = @"https://iot-040adh4x.http.iothub.aliyuncs.com/auth";
- [self showLog:[NSString stringWithFormat:@"阿里登录%@ %@",url,params]];
-
- AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
- manager.responseSerializer =[AFHTTPResponseSerializer serializer];
- manager.requestSerializer = [AFJSONRequestSerializer serializer];
-// AFSecurityPolicy *policy = [AFSecurityPolicy defaultPolicy];
-// policy.allowInvalidCertificates = YES;
-// policy.validatesDomainName = NO;
-// manager.securityPolicy = policy;
-
- [manager POST:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
- NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
- [self showLog:[NSString stringWithFormat:@"%@",str]];
- NSDictionary *dict = [AiMouseTools dataToDictionary:responseObject];
- NSString *code = dict[@"code"];
- NSString *token = [dict valueForKeyPath:@"info.token"];
- if(code.integerValue == 0){
- self.token = token;
- [self showLog:@"=====ali登录成功 ====="];
- if(self.authCallBack)self.authCallBack(true);
- }
-// else if(code.integerValue == 50021 ){
-// //密码错误,重置过
-// [self registerReuest];
-// }
- else{
- if(self.authCallBack)self.authCallBack(false);
- }
- } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
- [self showLog:[NSString stringWithFormat:@"error = %@",error]];
- if(self.authCallBack)self.authCallBack(false);
- }];
-}
-
-- (NSString *)loginSignText:(NSDictionary *)param{
- NSMutableArray<NSString *> *keys = [NSMutableArray arrayWithArray:param.allKeys];
- [keys sortUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
- return [obj1 compare:obj2];
- }];
-
- NSMutableArray *items = [[NSMutableArray alloc] init];
- for (NSString *key in keys) {
- NSString *value = [NSString stringWithFormat:@"%@%@",key,param[key]];
- [items addObject:value];
- }
- NSString *text = [items componentsJoinedByString:@""];
- return text;
-}
-
-@end
@property (nonatomic,strong)void (^decodeCallBack)(NSData *data);
@property (nonatomic,strong)void (^outputLog)(NSString *log);
-
- (void)receiveData:(NSData *)data;
@end
#import "AiAudioManager.h"
#import "AiMouseTools.h"
#import "AiAudioDecoder.h"
+#import <AVFoundation/AVFoundation.h>
+#import <AudioToolbox/AudioToolbox.h>
@interface AiAudioManager ()
@property (nonatomic,strong)AiAudioDecoder *audioDecoder;
}
- (void)receiveData:(NSData *)data{
- [self.audioDecoder decodeSBCData:data];
-// NSString *str = [[AiMouseTools dataToHexString:data] lowercaseString];
-// NSString *cmd = [str substringWithRange:NSMakeRange(0, 12)];
-// if([cmd hasPrefix:@"0a"] && [cmd hasSuffix:@"31"]){
-//// 0x0a6500002a3100020101c0c1a5a5a5a5
-// [self showLog:@"开始录音"];
-// }
-// if( [cmd hasPrefix:@"0a"] && [cmd hasSuffix:@"32"]){
-// [self showLog:@"结束录音"];
-//// [self showLog:[NSString stringWithFormat:@"完整声音数据 %@",self.recvData]];
-//// [self finishRecevice:self.recvData];
-//// self.recvData = nil;
-// }
-// else if([str hasPrefix:@"9c31"] && data.length >= 32){
-// [self.audioDecoder decodeSBCData:data];
-// }
-// else{
-// [self showLog:@"未实现指令"];
-// }
+// [self.audioDecoder decodeSBCData:data];
+ if(self.decodeCallBack)self.decodeCallBack(data);
}
- (void)setupAudioDecoder{
}
}
-
+//- (NSData *)convertADPCMData:(NSData *)adpcmData {
+// // 定义输入的 ADPCM 音频格式
+// AudioStreamBasicDescription adpcmInputFormat;
+// memset(&adpcmInputFormat, 0, sizeof(AudioStreamBasicDescription));
+// adpcmInputFormat.mFormatID = kAudioFormatADPCM;
+// adpcmInputFormat.mSampleRate = 44100.0;
+// adpcmInputFormat.mChannelsPerFrame = 1;
+// adpcmInputFormat.mBitsPerChannel = 4;
+// adpcmInputFormat.mBytesPerPacket = 4;
+// adpcmInputFormat.mFramesPerPacket = 1;
+// adpcmInputFormat.mBytesPerFrame = 4;
+// adpcmInputFormat.mReserved = 0;
+//
+// // 定义输出的 PCM 音频格式
+// AudioStreamBasicDescription pcmOutputFormat;
+// memset(&pcmOutputFormat, 0, sizeof(AudioStreamBasicDescription));
+// pcmOutputFormat.mFormatID = kAudioFormatLinearPCM;
+// pcmOutputFormat.mSampleRate = 44100.0;
+// pcmOutputFormat.mChannelsPerFrame = 1;
+// pcmOutputFormat.mBitsPerChannel = 16;
+// pcmOutputFormat.mBytesPerPacket = 2;
+// pcmOutputFormat.mFramesPerPacket = 1;
+// pcmOutputFormat.mBytesPerFrame = 2;
+// pcmOutputFormat.mReserved = 0;
+//
+// AudioConverterRef converter;
+// OSStatus status = AudioConverterNew(&adpcmInputFormat, &pcmOutputFormat, &converter);
+//
+// if (status!= noErr) {
+// NSLog(@"Failed to create audio converter. Error: %d", (int)status);
+// return nil;
+// }
+//
+// NSMutableData *outputData = [NSMutableData data];
+//
+// const UInt32 inputBufferSize = 1024;
+// UInt8 *inputBuffer = (UInt8 *)malloc(inputBufferSize);
+// UInt32 outputBufferSize = 2048;
+// UInt8 *outputBuffer = (UInt8 *)malloc(outputBufferSize);
+//
+// NSInteger offset = 0;
+// while (offset < [adpcmData length]) {
+// NSInteger dataToRead = MIN(inputBufferSize, [adpcmData length] - offset);
+// [adpcmData getBytes:inputBuffer range:NSMakeRange(offset, dataToRead)];
+//
+// UInt32 outputUsed = 0;
+// status = AudioConverterConvertBuffer(converter, dataToRead, inputBuffer, &outputUsed, outputBuffer);
+//
+// if (status!= noErr) {
+// NSLog(@"Conversion error. Error: %d", (int)status);
+// free(inputBuffer);
+// free(outputBuffer);
+// AudioConverterDispose(converter);
+// return nil;
+// }
+//
+// [outputData appendBytes:outputBuffer length:outputUsed];
+// offset += dataToRead;
+// }
+//
+// free(inputBuffer);
+// free(outputBuffer);
+// AudioConverterDispose(converter);
+//
+// return outputData;
+//}
@end
+++ /dev/null
-//
-// AiAuthManager.h
-// AiMouse
-//
-// Created by incar on 2024/2/28.
-//
-
-#import <Foundation/Foundation.h>
-#import "AiMouseSdk.h"
-
-
-NS_ASSUME_NONNULL_BEGIN
-typedef void(^AiCmdFinishBlock)(BOOL isSuccess);
-
-@interface AiAuthManager : NSObject
-@property (nonatomic,strong)void (^outputLog)(NSString *log);
-@property (nonatomic,strong)void (^setDeviceSecret)(NSString *value,AiCmdFinishBlock finished);
-@property (nonatomic,strong)void (^authCallBack)(BOOL isSuccess);
-
-- (void)loginWith:(AiMouseDeviceInfo *)info;
-@end
-
-NS_ASSUME_NONNULL_END
+++ /dev/null
-//
-// AiAuthManager.m
-// AiMouse
-//
-// Created by incar on 2024/2/28.
-//
-
-#import "AiAuthManager.h"
-#import "AiMouseTools.h"
-#import "AFNetworking.h"
-#import "AiTrippleModel.h"
-#import "AiSecretModel.h"
-
-//#define kBaseUrl @"https://iot.api.thisiot.com/da/auth"
-#define kBaseUrl @"https://app.api.thisiot.com/da/auth"
-#define kRegisterApi @"active"
-#define kLoginApi @"login"
-#define kTokenApi @"token"
-
-
-@interface AiAuthManager ()
-@property (nonatomic,strong)AiMouseDeviceInfo *deviceInfo;
-@property (nonatomic,strong)NSString *token;
-@end
-@implementation AiAuthManager
-- (instancetype)init{
- self = [super init];
- if (self) {
-
- }
- return self;
-}
-
-#pragma mark - pub api
-- (void)loginWith:(AiMouseDeviceInfo *)info{
-
- self.deviceInfo = info;
- if (![info valueForKey:@"productKey"] || ![info valueForKey:@"secretKey"] || !info.sn || !info.sn) {
- [self showLog:@"获取设备信息错误,鉴权失败!"];
- return;
- }
- if([[info valueForKey:@"deviceSecret"] isKindOfClass:[NSString class]] && ([(NSString *)[info valueForKey:@"deviceSecret"] length] > 2)){
- //已注册过,直接登录
- [self loginRequest];
- }
- else{
- //未注册
- [self registerReuest];
- }
-}
-
-#pragma mark -others
-///将设备密钥密钥写到硬件
--(void)sendDeviceSecretCmd:(NSString *)deviceSecret{
- [self.deviceInfo setValue:deviceSecret forKey:@"deviceSecret"];
- if (self.setDeviceSecret) {
- self.setDeviceSecret(deviceSecret, ^(BOOL isSuccess) {
- [self loginRequest];
- });
- }
-}
-- (void)showLog:(NSString *)log {
- if (self.outputLog) self.outputLog([NSString stringWithFormat:@"[auth]%@",log]);
-}
-
-- (void)registerReuest{
- NSString *deviceId = self.deviceInfo.mac;//设备ID
- NSString *sn = self.deviceInfo.sn;//SN号
- NSString *timeStamp = [NSString stringWithFormat:@"%ld",(NSInteger)([NSDate date].timeIntervalSince1970 * 1000)];//时间戳
- NSString *bid = [self.deviceInfo valueForKey:@"productKey"];//产品Key
- NSString *signMethod = @"HmacSHA1";//签名方法
-
- NSString *text = [NSString stringWithFormat:@"%@%@%@",deviceId,sn,timeStamp];
- NSString *key = [self.deviceInfo valueForKey:@"secretKey"];//产品秘钥
- NSString *sign = [AiMouseTools stringToHmacSha1:key text:text];
-
- NSDictionary *params = @{
- @"bid":bid,
- @"deviceId":deviceId,
- @"signMethod":signMethod,
- @"sign":sign,
- @"timeStamp":timeStamp,
- @"sn":sn
- };
-
- NSString *url = [NSString stringWithFormat:@"%@/%@",kBaseUrl,kRegisterApi];
- [self showLog:[NSString stringWithFormat:@"%@ %@",url,params]];
-
- AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
- manager.responseSerializer =[AFHTTPResponseSerializer serializer];
- manager.requestSerializer = [AFJSONRequestSerializer serializer];
-
- AFSecurityPolicy *policy = [AFSecurityPolicy defaultPolicy];
- policy.allowInvalidCertificates = YES;//客户端是否信任非法证书
- policy.validatesDomainName = NO;//是否在证书域字段中验证域名
- manager.securityPolicy = policy;
-
- [manager PUT:url parameters:params headers:@{} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
- NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
- [self showLog:[NSString stringWithFormat:@" %@",str]];
- NSDictionary *dict = [AiMouseTools dataToDictionary:responseObject];
- NSString *code = dict[@"code"];
- NSString *deviceSecret = [dict valueForKeyPath:@"data.deviceSecret"];
- if(code.integerValue == 20000 && deviceSecret){
- [self sendDeviceSecretCmd:deviceSecret];
-// [self showLog:@"激活成功"];
- }
- else{
- [self showLog:dict[@"msg"]];
- if(self.authCallBack)self.authCallBack(false);
- }
- } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
- [self showLog:[NSString stringWithFormat:@"error = %@",error]];
- if(self.authCallBack)self.authCallBack(false);
- }];
-}
-- (void)loginRequest{
- NSString *bid = [self.deviceInfo valueForKey:@"productKey"];//品牌ID,管理中心获取
- NSString *deviceId = self.deviceInfo.mac;//设备ID
- NSString *signMethod = @"HmacSHA1";//签名算法
- NSString *timeStamp = [NSString stringWithFormat:@"%ld",(NSInteger)([[NSDate date] timeIntervalSince1970] * 1000)];//时间戳
- NSString *deviceSecret = [self.deviceInfo valueForKey:@"deviceSecret"];//注册返回的密码
-
- NSString *text = [NSString stringWithFormat:@"%@%@%@",deviceId,deviceSecret,timeStamp];
- NSString *key = [self.deviceInfo valueForKey:@"secretKey"];//产品秘钥
- NSString *sign = [AiMouseTools stringToHmacSha1:key text:text];
-
- NSDictionary *params = @{
- @"bid":bid,
- @"deviceId":deviceId,
- @"deviceSecret":deviceSecret,
- @"timestamp":timeStamp,
- @"signMethod":signMethod,
- @"sign":sign
- };
- NSString *url = [NSString stringWithFormat:@"%@/%@",kBaseUrl,kLoginApi];
- [self showLog:[NSString stringWithFormat:@"%@ %@",url,params]];
-
- AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
- manager.responseSerializer =[AFHTTPResponseSerializer serializer];
- manager.requestSerializer = [AFJSONRequestSerializer serializer];
- AFSecurityPolicy *policy = [AFSecurityPolicy defaultPolicy];
- policy.allowInvalidCertificates = YES;
- policy.validatesDomainName = NO;
- manager.securityPolicy = policy;
-
- [manager POST:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
- NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
- [self showLog:[NSString stringWithFormat:@"%@",str]];
- NSDictionary *dict = [AiMouseTools dataToDictionary:responseObject];
- NSString *code = dict[@"code"];
- NSString *token = [dict valueForKeyPath:@"data.token"];
- if(code.integerValue == 20001){
- self.token = token;
- if(self.authCallBack)self.authCallBack(true);
- //[self tokenRequest];
- }
- else if(code.integerValue == 50021 || code.integerValue == 50003){
- //密码错误,重置过
- [self registerReuest];
- }
- else{
- if(self.authCallBack)self.authCallBack(false);
- }
- } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
- [self showLog:[NSString stringWithFormat:@"error = %@",error]];
- if(self.authCallBack)self.authCallBack(false);
- }];
-}
-- (void)tokenRequest{
- NSDictionary *params = @{
- @"token":self.token,
- };
- NSString *url = [NSString stringWithFormat:@"%@/%@",kBaseUrl,kTokenApi];
- [self showLog:[NSString stringWithFormat:@"%@ %@",url,params]];
-
- AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
- manager.responseSerializer =[AFHTTPResponseSerializer serializer];
- manager.requestSerializer = [AFJSONRequestSerializer serializer];
- AFSecurityPolicy *policy = [AFSecurityPolicy defaultPolicy];
- policy.allowInvalidCertificates = YES;
- policy.validatesDomainName = NO;
- manager.securityPolicy = policy;
-
- [manager GET:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
- NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
- [self showLog:[NSString stringWithFormat:@"%@",str]];
- NSDictionary *dict = [AiMouseTools dataToDictionary:responseObject];
- NSString *code = dict[@"code"];
- if(code.integerValue == 20000){
- [self showLog:@"账号已登录"];
- }
- } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
- [self showLog:[NSString stringWithFormat:@"error = %@",error]];
- }];
-}
-
-@end
#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:1000 target:self selector:@selector(timerAction) userInfo:nil repeats:true];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
});
+++ /dev/null
-//
-// AiDeviceInfoManager.h
-// AiMouseSdk
-//
-// Created by incar on 2024/5/20.
-//
-
-#import <Foundation/Foundation.h>
-#import "AiMouseSdk.h"
-#import "AiAuthManager.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface AiDeviceInfoManager : NSObject
-@property (nonatomic,strong)void (^sendToBleBlock)(NSData *data);
-@property (nonatomic,strong)void (^outputLogBlock)(NSString *log);
-
--(void)receiveData:(NSData *)data;
-
-/// 获取版本
-- (void)getVersion:(void (^)(NSString *version,NSError *error))finished;
-
-- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))complete;
-
-/// 获取信号强度
-/// - Parameter completation: 信号强度回调
-- (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:值
-/// - finished: 执行结果
-- (void)setCPI:(NSInteger)value completation:(void (^)(BOOL isSuccess,NSError *error))finished;
-
-
-/// 设置设备密钥
-/// - Parameters:
-/// - value: 密钥
-/// - complete: 设置结果
-- (void)setDeviceSecret:(NSString *)value completation:(AiCmdFinishBlock)complete;
-
-
-/// 设置鉴权
-/// - Parameter isSuccess: 是否已经鉴权
-- (void)setAuthStateToDevice:(BOOL)isSuccess;
-
-
-/// 设置录音模式
-/// - 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:命令模式,发命令打开关闭录音
-- (void)getRecordMode:(void (^)(int mode,NSError *error))complete;
-
-/// 获取长按滚轮弹出的网页地址
-/// - Parameter complete: url地址
-- (void)getUrl:(void (^)(NSString *url,NSError *error))complete;
-
-/// 获取长按滚轮弹出的网页地址开关状态
-/// - Parameter complete: 0关闭,1打开
-- (void)getUrlState:(void (^)(int state,NSError *error))complete;
-
-/// 获取鼠标连接模式
-/// - Parameter complete: mode
-- (void)getMouseModel:(void (^)(int mode,NSError *error))complete;
-
-/// 开始录音
-- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
-
-/// 结束录音
-- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
-@end
-
-NS_ASSUME_NONNULL_END
+++ /dev/null
-//
-// AiDeviceInfoManager.m
-// AiMouseSdk
-//
-// Created by incar on 2024/5/20.
-//
-
-#import "AiDeviceInfoManager.h"
-#import "AiMouseTools.h"
-#import "AiMouseTools2.h"
-#import "AiMouseConfig.h"
-#import "AiSender.h"
-
-#define kCmd_Key @"cmd"
-#define kSetCmd_Value @"set_config"
-
-
-#define kSetAuthState_Key @"set_activated_dtate"
-#define kSetDeviceSecret_Key @"set_deviceSecret"
-
-#define kSetBrand_Key @"set_brand"
-#define kSetCPI_Key @"set_CPI"
-#define kSetUrl_Key @"set_official_url"
-#define kSetUrlActive_Key @"set_official_url_switch"
-#define kSetRecordMode_Key @"set_record_mode"
-#define kSetMouseModel_Key @"set_mouse_mode"
-
-
-
-
-@interface AiDeviceInfoManager()<AiSenderDelegate>
-@property (nonatomic, strong) AiSender *sender;
-@property (nonatomic, strong) AiMouseDeviceInfo *deviceInfo;
-@property (nonatomic, strong) void (^deviceInfoBlock)(AiMouseDeviceInfo *deviceInfo,NSError *error);
-@property (nonatomic, strong) void (^getRSSIBlock)(NSString *value,NSError *error);
-@property (nonatomic, strong) void (^getVersionBlock)(NSString *version,NSError *error);
-@property (nonatomic, strong) void (^authBlock)(AiMouseAuthState state);
-@property (nonatomic, strong) AiCmdFinishBlock setDsBlock;
-
-@property (nonatomic, strong) void (^setBrandBlock)(BOOL isSuccess,NSError *error);
-@property (nonatomic, strong) void (^setCPIBlock)(BOOL isSuccess,NSError *error);
-@property (nonatomic, strong) void (^setUrlBlock)(BOOL isSuccess,NSError *error);
-@property (nonatomic, strong) void (^setUrlActiveBlock)(BOOL isSuccess,NSError *error);
-@property (nonatomic, strong) void (^setRecordModeBlock)(BOOL isSuccess,NSError *error);
-@property (nonatomic, strong) void (^setMouseModelBlock)(BOOL isSuccess,NSError *error);
-@property (nonatomic, strong) void (^setOpenRecordBlock)(BOOL isSuccess,NSError *error);
-@property (nonatomic, strong) void (^setCloseRecordBlock)(BOOL isSuccess,NSError *error);
-
-@property (nonatomic, strong) void (^getRecordModeBlock)(int mode,NSError *error);
-@property (nonatomic, strong) void (^getUrlBlock)(NSString *url,NSError *error);
-@property (nonatomic, strong) void (^getUrlStateBlock)(int state,NSError *error);
-@property (nonatomic, strong) void (^getMouseModelBlock)(int mode,NSError *error);
-
-@end
-
-
-@implementation AiDeviceInfoManager
-
--(void)receiveData:(NSData *)data{
- if(![self.sender isAnswer:data]){
- return;
- }
-
- AiSender *sender = self.sender;
- [self.sender remove];
- self.sender = nil;
-
- NSString *str = [AiMouseTools dataToUtf8String:data];
- NSString *str2 = [AiMouseTools2 fixDeviceData:str];
- NSDictionary *dict = [AiMouseTools stringToDictionary:str2];
-// [self showLog:[NSString stringWithFormat:@"总data = %@",[AiMouseTools dataToHexString:data]]];
-// [self showLog:[NSString stringWithFormat:@"fix前 = %@",str]];
-// [self showLog:[NSString stringWithFormat:@"receive %@",str2]];
- if (dict == nil) {
- if(data.length > 7 && [[AiMouseTools dataToHexString:[data subdataWithRange:NSMakeRange(0, 7)]] .lowercaseString isEqualToString:@"7b22534e223a22"] ){
- //SN异常
- [self showLog:@"SN未设置!!!"];
- self.deviceInfo.sn = @"";
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_MAC"}];
- }
- else if(data.length > 15 && [[AiMouseTools dataToHexString:[data subdataWithRange:NSMakeRange(0, 15)]] .lowercaseString isEqualToString:@"7b2264657669636553656372657422"] ){
- //deviceSecret异常
- [self showLog:@"deviceSecret未设置"];
- [self.deviceInfo setValue:nil forKey:@"deviceSecret"];
- if(self.deviceInfoBlock){
- [self showLog:self.deviceInfo.description];
- self.deviceInfoBlock(self.deviceInfo, nil);
- self.deviceInfoBlock= nil;
- }
- }
- //鼠标移动数据,不处理
- return;
- }
-
-// [self showLog:[NSString stringWithFormat:@"总data = %@",[AiMouseTools dataToHexString:data]]];
-// [self showLog:[NSString stringWithFormat:@"fix前 = %@",str]];
-// [self showLog:[NSString stringWithFormat:@"fix后 = %@",str2]];
- if(dict[kSetCmd_Value]){
- [self setCmdCallBack:dict sender:sender];
- }
- else{
- [self getCmdCallBack:dict];
- }
-}
-
-- (void)setCmdCallBack:(NSDictionary *)dict sender:(AiSender *)sender{
- if([dict[kSetCmd_Value] intValue] == 1){
- if ([sender.sendDict objectForKey:kSetCPI_Key]) {
- if(self.setCPIBlock)self.setCPIBlock(true, nil);
- return;
- }
- if ([sender.sendDict objectForKey:kSetBrand_Key]) {
- if(self.setBrandBlock)self.setBrandBlock(true, nil);
- return;
- }
- if([sender.sendDict objectForKey:kSetDeviceSecret_Key]){
- if(self.setDsBlock)self.setDsBlock(true);
- return;
- }
- if([sender.sendDict objectForKey:kSetRecordMode_Key]){
- if(self.setRecordModeBlock)self.setRecordModeBlock(true, nil);
- return;
- }
- if([sender.sendDict objectForKey:kSetUrl_Key]){
- if(self.setUrlBlock)self.setUrlBlock(true, nil);
- return;
- }
- if([sender.sendDict objectForKey:kSetUrlActive_Key]){
- if(self.setUrlActiveBlock)self.setUrlActiveBlock(true, nil);
- return;
- }
- if([sender.sendDict objectForKey:kSetMouseModel_Key]){
- if(self.setMouseModelBlock)self.setMouseModelBlock(true, nil);
- return;
- }
- if ([[sender.sendDict objectForKey:kCmd_Key] isKindOfClass:[NSString class]] && [[sender.sendDict objectForKey:kCmd_Key] isEqualTo:@"open_record"]){
- if(self.setOpenRecordBlock) self.setOpenRecordBlock(true, nil);
- return;
- }
- if ([[sender.sendDict objectForKey:kCmd_Key] isKindOfClass:[NSString class]] && [[sender.sendDict objectForKey:kCmd_Key] isEqualTo:@"close_record"]){
- if(self.setCloseRecordBlock) self.setCloseRecordBlock(true, nil);
- return;
- }
- }
- else{
- NSError *err = [NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_unknown userInfo:@{@"NSLocalizedDescriptionKey":@"请求失败"}];
- if ([sender.sendDict objectForKey:kSetCPI_Key]) {
- if(self.setCPIBlock)self.setCPIBlock(false, err);
- return;
- }
- if ([sender.sendDict objectForKey:kSetBrand_Key]) {
- if(self.setBrandBlock)self.setBrandBlock(false, err);
- return;
- }
- if ([sender.sendDict objectForKey:kSetDeviceSecret_Key]){
- if(self.setDsBlock)self.setDsBlock(false);
- return;
- }
- if([sender.sendDict objectForKey:kSetRecordMode_Key]){
- if(self.setRecordModeBlock)self.setRecordModeBlock(false, err);
- return;
- }
- if([sender.sendDict objectForKey:kSetUrl_Key]){
- if(self.setUrlBlock)self.setUrlBlock(false, err);
- return;
- }
- if([sender.sendDict objectForKey:kSetUrlActive_Key]){
- if(self.setUrlActiveBlock)self.setUrlActiveBlock(false, err);
- return;
- }
- if([sender.sendDict objectForKey:kSetMouseModel_Key]){
- if(self.setMouseModelBlock)self.setMouseModelBlock(false, err);
- return;
- }
- if ([[sender.sendDict objectForKey:kCmd_Key] isKindOfClass:[NSString class]] && [[sender.sendDict objectForKey:kCmd_Key] isEqualTo:@"open_record"]){
- if(self.setOpenRecordBlock) self.setOpenRecordBlock(false, err);
- return;
- }
- if ([[sender.sendDict objectForKey:kCmd_Key] isKindOfClass:[NSString class]] && [[sender.sendDict objectForKey:kCmd_Key] isEqualTo:@"close_record"]){
- if(self.setCloseRecordBlock) self.setCloseRecordBlock(false, err);
- return;
- }
- }
-}
-
-- (void)getCmdCallBack:(NSDictionary *)dict{
- if (dict[@"battery_power"]) {
- self.deviceInfo.battery_power = dict[@"battery_power"];
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_CPI"}];
- }
- else if(dict[@"CPI"]) {
- self.deviceInfo.CPI = dict[@"CPI"];
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_CPI_list"}];
- }
- else if(dict[@"CPI_list"]) {
- self.deviceInfo.CPI_list = dict[@"CPI_list"];
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_version"}];
- }
- else if(dict[@"version"]) {
- if(self.getVersionBlock && self.deviceInfoBlock == nil){
- self.getVersionBlock(dict[@"version"], nil);
- self.getVersionBlock = nil;
- return;
- }
- self.deviceInfo.version = dict[@"version"];
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_brand"}];
- }
- else if(dict[@"brand"]) {
- self.deviceInfo.brand = dict[@"brand"];
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_SN"}];
- }
- else if(dict[@"SN"]) {
- self.deviceInfo.sn = dict[@"SN"];
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_MAC"}];
- }
- else if(dict[@"MAC"]) {
- self.deviceInfo.mac = dict[@"MAC"];
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_productKey"}];
- }
- else if(dict[@"productKey"]) {
- [self.deviceInfo setValue:dict[@"productKey"] forKey:@"productKey"];
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_secretKey"}];
- }
- else if(dict[@"secretKey"]) {
- [self.deviceInfo setValue:dict[@"secretKey"] forKey:@"secretKey"];
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_deviceSecret"}];
- }
- else if(dict[@"deviceSecret"]) {
- [self.deviceInfo setValue:dict[@"deviceSecret"] forKey:@"deviceSecret"];
- if(self.deviceInfoBlock){
- [self showLog:self.deviceInfo.description];
- self.deviceInfoBlock(self.deviceInfo, nil);
- self.deviceInfoBlock= nil;
- }
- }
- else if(dict[@"rssi"]) {
- if(self.getRSSIBlock){
- self.getRSSIBlock(dict[@"rssi"],nil);
- }
- }
- else if(dict[@"official_url"]) {
- if(self.getUrlBlock)self.getUrlBlock(dict[@"official_url"],nil);
- }
- else if(dict[@"official_url_switch"]) {
- if(self.getUrlStateBlock)self.getUrlStateBlock([dict[@"official_url_switch"] intValue],nil);
- }
- else if(dict[@"mouse_mode"]) {
- if(self.getMouseModelBlock)self.getMouseModelBlock([dict[@"mouse_mode"] intValue],nil);
- }
- else if(dict[@"record_mode"]) {
- if(self.getRecordModeBlock)self.getRecordModeBlock([dict[@"record_mode"] intValue],nil);
- }
-}
-
-- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))complete{
- if(self.sender){
-// complete(nil,[NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_busy userInfo:@{@"NSLocalizedDescriptionKey":@"有命令正在执行中..."}]);
- [self showLog:@"有命令正在执行中..."];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [self getDeviceInfo:complete];
- });
- return;
- }
- self.deviceInfo = [[AiMouseDeviceInfo alloc] init];
- self.deviceInfoBlock = complete;
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_battery_power"}];
-}
-
-
-/// 获取信号强度
-- (void)getRSSI:(void (^)(NSString *value,NSError *error))complete{
- self.getRSSIBlock = complete;
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_rssi"}];
-}
-
-/// 获取版本
-- (void)getVersion:(void (^)(NSString *version,NSError *error))finished{
- if(self.deviceInfoBlock || self.sender){
- return;
- }
-
- self.getVersionBlock = finished;
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_version"}];
-}
-- (void)setBrand:(NSString *)brand completation:(void (^)(BOOL isSuccess,NSError *error))finished{
- self.setBrandBlock = finished;
- [self sendDeviceInfoCmd:@{kCmd_Key:kSetCmd_Value,kSetBrand_Key:brand}];
-}
-- (void)setCPI:(NSInteger)value completation:(void (^)(BOOL isSuccess,NSError *error))finished{
- self.setCPIBlock = finished;
- [self sendDeviceInfoCmd:@{kCmd_Key:kSetCmd_Value,kSetCPI_Key:[NSString stringWithFormat:@"%ld",value]}];
-}
-
-- (void)setDeviceSecret:(NSString *)value completation:(AiCmdFinishBlock)complete{
- self.setDsBlock = complete;
- [self sendDeviceInfoCmd:@{kCmd_Key:kSetCmd_Value,kSetDeviceSecret_Key:value}];
-}
-
--(void)setAuthStateToDevice:(BOOL)isSuccess {
-// NSData *data = [AiMouseTools dictionaryToData:@{kCmd_Value:kCmd_Value,kSetAuthState_Key:isSuccess?@"1":@"0"}];
-// [self sendDeviceInfoData:data];
- [self sendDeviceInfoCmd: @{kCmd_Key:kSetCmd_Value,kSetAuthState_Key:isSuccess?@"1":@"0"}];
-}
-
-#pragma mark - new
-/// 设置录音模式
-- (void)setRecordMode:(int)mode completation:(void (^)(BOOL isSuccess,NSError *error))finished{
- self.setRecordModeBlock = finished;
- NSDictionary *data = @{kCmd_Key:kSetCmd_Value,kSetRecordMode_Key:[NSString stringWithFormat:@"%d",mode]};
- [self sendDeviceInfoCmd:data];
-}
-
-/// 设置长按滚轮弹出的网页地址
-- (void)setUrl:(NSString *)url completation:(void (^)(BOOL isSuccess,NSError *error))finished{
- self.setUrlBlock = finished;
- NSDictionary *data = @{kCmd_Key:kSetCmd_Value,kSetUrl_Key:url};
- [self sendDeviceInfoCmd:data];
-}
-
-/// 设置长按滚轮弹出网页开关
-- (void)setUrlState:(int)state completation:(void (^)(BOOL, NSError * _Nonnull))finished{
- self.setUrlActiveBlock = finished;
- NSDictionary *data = @{kCmd_Key:kSetCmd_Value,kSetUrlActive_Key:[NSString stringWithFormat:@"%d",state]};
- [self sendDeviceInfoCmd:data];
-}
-
-/// 设置鼠标连接模式
-- (void)setMouseMode:(int)mode completation:(void (^)(BOOL, NSError * _Nonnull))finished{
- self.setMouseModelBlock = finished;
- NSDictionary *data = @{kCmd_Key:kSetCmd_Value,kSetMouseModel_Key:[NSString stringWithFormat:@"%d",mode]};
- [self sendDeviceInfoCmd:data];
-}
-/// 获取录音模式
-- (void)getRecordMode:(void (^)(int mode,NSError *error))complete{
- self.getRecordModeBlock = complete;
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_record_mode"}];
-}
-
-/// 获取长按滚轮弹出的网页地址
-- (void)getUrl:(void (^)(NSString *url,NSError *error))complete{
- self.getUrlBlock = complete;
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_official_url"}];
-}
-
-/// 获取长按滚轮弹出的网页地址开关状态
-/// - Parameter complete: 0关闭,1打开
-- (void)getUrlState:(void (^)(int state,NSError *error))complete{
- self.getUrlStateBlock = complete;
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_official_url_switch"}];
-}
-
-/// 获取鼠标连接模式
-/// - Parameter complete: mode
-- (void)getMouseModel:(void (^)(int mode,NSError *error))complete{
- self.getMouseModelBlock = complete;
- [self sendDeviceInfoCmd:@{kCmd_Key:@"get_mouse_mode"}];
-}
-/// 开始录音
-- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
- self.setOpenRecordBlock = finished;
- [self sendDeviceInfoCmd:@{kCmd_Key:@"open_record"}];
-}
-
-/// 结束录音
-- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
- self.setCloseRecordBlock = finished;
- [self sendDeviceInfoCmd:@{kCmd_Key:@"close_record"}];
-}
-#pragma mark - AiSenderDelegate
-- (void)aiSender:(AiSender *)sender reSendCmd:(NSDictionary *)dict{
- NSString *cmd = [sender.sendDict objectForKey:kCmd_Key];
-
- if ([cmd isKindOfClass:[NSString class]] && [cmd isEqualToString:@"get_version"] && self.getVersionBlock) {
- [self.sender remove];
- self.sender = nil;
- self.getVersionBlock(nil, [NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_timeOut userInfo:@{@"NSLocalizedDescriptionKey":@"请求超时"}]);
- self.getVersionBlock = nil;
- return;
- }
-
- [self sendCmdToBle:dict];
-}
-
--(void)aiSenderRecieveTimeOut:(AiSender *)sender{
- [self.sender remove];
- self.sender = nil;
-
- [self showLog:@"指令超时..."];
-
- NSString *cmd = [sender.sendDict objectForKey:kCmd_Key];
- if (![cmd isKindOfClass:[NSString class]] ) {
- return;
- }
-
- NSError *err = [NSError errorWithDomain:@"AiMouse SDK Error" code:AiMouseErrorCode_timeOut userInfo:@{@"NSLocalizedDescriptionKey":@"请求超时"}];
- if ([sender.sendDict objectForKey:kSetCPI_Key]) {
- if(self.setCPIBlock)self.setCPIBlock(false, err);
- return;
- }
- if ([sender.sendDict objectForKey:kSetBrand_Key]) {
- if(self.setBrandBlock)self.setBrandBlock(false, err);
- return;
- }
- if ([sender.sendDict objectForKey:kSetDeviceSecret_Key]){
- if(self.setDsBlock)self.setDsBlock(false);
- return;
- }
- if([sender.sendDict objectForKey:kSetRecordMode_Key]){
- if(self.setRecordModeBlock)self.setRecordModeBlock(false, err);
- return;
- }
- if([sender.sendDict objectForKey:kSetUrl_Key]){
- if(self.setUrlBlock)self.setUrlBlock(false, err);
- return;
- }
- if([sender.sendDict objectForKey:kSetUrlActive_Key]){
- if(self.setUrlActiveBlock)self.setUrlActiveBlock(false, err);
- return;
- }
- if([sender.sendDict objectForKey:kSetMouseModel_Key]){
- if(self.setMouseModelBlock)self.setMouseModelBlock(false, err);
- return;
- }
- if ([cmd isEqualTo:@"open_record"]){
- if(self.setOpenRecordBlock) self.setOpenRecordBlock(false, err);
- return;
- }
- if ([cmd isEqualTo:@"close_record"]){
- if(self.setCloseRecordBlock) self.setCloseRecordBlock(false, err);
- return;
- }
- if ([cmd isEqualTo:@"get_record_mode"]){
- if(self.getRecordModeBlock) self.getRecordModeBlock(0, err);
- return;
- }
- if ([cmd isEqualTo:@"get_official_url"]){
- if(self.getUrlBlock) self.getUrlBlock(nil, err);
- return;
- }
- if ([cmd isEqualTo:@"get_official_url_switch"]){
- if(self.getUrlStateBlock) self.getUrlStateBlock(0, err);
- return;
- }
- if ([cmd isEqualTo:@"get_mouse_mode"]){
- if(self.getMouseModelBlock) self.getMouseModelBlock(0, err);
- return;
- }
- if ([cmd isEqualTo:@"get_rssi"]){
- if(self.getRSSIBlock) self.getRSSIBlock(nil, err);
- return;
- }
- if ([cmd isEqualTo:@"get_version"]){
- if(self.getVersionBlock){
- self.getVersionBlock(nil, err);
- self.getVersionBlock = nil;
- }
- }
-
- if ([sender.sendDict objectForKey:kSetAuthState_Key]){
- //设置是否已鉴权
- return;
- }
-
- if(self.deviceInfoBlock) self.deviceInfoBlock(nil,err);
- self.deviceInfoBlock = nil;
-}
-
-- (void)aiSender:(AiSender *)sender outputLog:(NSString *)log{
- [self showLog:log];
-}
-#pragma mark - others
-- (void)sendDeviceInfoCmd:(NSDictionary *)dict{
- if(self.sender){
- [self showLog:@"有命令正在执行中.."];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [self sendDeviceInfoCmd:dict];
- });
- return;
- }
- self.sender = [[AiSender alloc] initWithCmd:dict];
- self.sender.delegate = self;
- [self sendCmdToBle:dict];
-}
-- (void)sendCmdToBle:(NSDictionary *)dict{
- NSData *data = [AiMouseTools dictionaryToData:dict];
- NSString *str = [AiMouseTools dataToUtf8String:data];
- NSArray *list = [self splitCMD:str];
-// [self showLog:[NSString stringWithFormat:@"send %@",str]];
- if(list.count > 1){
- {
- //开始标志
- NSString *cmd = @"-$$\0";
- [self sendToBle:cmd];
- }
- //指令
- for (NSInteger i = 0; i < list.count; i++) {
- NSString *cmd = [NSString stringWithFormat:@"%@\0",list[i]];
- [self sendToBle:cmd];
- }
- {
- //结束标志
- NSString *cmd = @"$$-\0";
- [self sendToBle:cmd];
- }
- }
- else{
- NSString *cmd = [NSString stringWithFormat:@"-$$%@$$-\n",str];
- [self sendToBle:cmd];
- }
-}
-- (void)sendToBle:(NSString *)cmd{
- NSData *data = [cmd dataUsingEncoding:NSUTF8StringEncoding];
- if (self.sendToBleBlock) {
- self.sendToBleBlock(data);
- }
-}
-//切割
-- (NSArray<NSString *> *)splitCMD:(NSString *)cmd{
- NSMutableArray *list = [[NSMutableArray alloc] init];
- NSString *str = cmd;
- NSInteger len = 30;
- while (str.length > 0) {
- if (str.length > len) {
- NSString *sub = [str substringToIndex:len];
- [list addObject:sub];
- str = [str substringFromIndex:len];
- }
- else{
- [list addObject:str];
- break;
- }
- }
- return list;
-}
-
-- (void)showLog:(NSString *)log{
- self.outputLogBlock(log);
-}
-
-@end
#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地址
+@property (nonatomic, assign) int DPI;/// DPI值
+@property (nonatomic, assign) int version;///软件版本
+@property (nonatomic, assign) int batteryState;/// 电池状态
+@property (nonatomic, assign) int batteryValue;/// 电池百分百电量,0-100
@end
typedef NS_ENUM(NSInteger,AiMouseErrorCode) {
AiMouseConnectType_hid,///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(结束录音)
+/// 前 单击0x06, 按下0x13(开始录音)抬起0x14(结束录音)
+/// 中 单击0x03, 按下0x11(开始录音)抬起0x12(结束录音)
+/// 后 第一次单击0x01, 第二次单击0x02(结束录音) , 按下0x09(开始录音)抬起0x10(结束录音)
/// 其他未定义
- (void)aiMouseSendCmdData:(NSData *)data;
@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特征传过来的数据
/// - 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;
-
-/// 设置鼠标连接模式
+/// 设置DPI
/// - Parameters:
-/// - mode: 0:2.4G模式,1:蓝牙1模式,2:蓝牙2模式
+/// - value: 数值(1-4)
/// - 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;
+- (void)setDPI:(int)value completation:(void (^)(BOOL isSuccess,NSError *error))finished;
/// 打开录音
/// - finished: 执行结果回调
//
#import "AiMouseSdk.h"
-#import "AiDeviceInfoManager.h"
-#import "AiAuthManager.h"
-#import "AiAliAuthManager.h"
#import "AiAudioManager.h"
#import "AiMouseTools.h"
#import "AiMouseTools2.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];
+ NSString *info = [NSString stringWithFormat:@"\n version = %d\n DPI = %d\n batteryState = %d\n batteryValue = %d\n",self.version,self.DPI,self.batteryState,self.batteryValue];
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;
+
+@property (nonatomic,strong)void (^openRecord)(BOOL isSuccess,NSError *error);
+@property (nonatomic,strong)void (^closeRecord)(BOOL isSuccess,NSError *error);
+@property (nonatomic,strong)void (^setDpi)(BOOL isSuccess,NSError *error);
+@property (nonatomic,strong)void (^getMouseInfo)(AiMouseDeviceInfo *deviceInfo,NSError *error);
@end
@implementation AiMouse
-(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 @"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) {
}
return _connectManager;
}
+
#pragma mark - pub Api
- (void)setLogLevel:(AiMouseLogLevel)level{
_logLevel = level;
[self showLog:@"系统断开连接"];
[self stopRecord:true];
[self.connectManager disConnected];
-
}
+
- (void)switchConnect:(AiMouseConnectType)type{
if(type != _connectType && self.connected){
[self.connectManager disConnected];
[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:@"未实现指令"];
- }
+//// 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:@"未实现指令"];
- }
+ //声音
+ [self.audioManager receiveData:data];
}
}
-#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];
- }
- }];
+ NSData *typeData = [data subdataWithRange:NSMakeRange(0, 1)];
+ uint8 type;
+ [typeData getBytes:&type length:1];
+
+ NSData *stateData = [data subdataWithRange:NSMakeRange(1, 1)];
+ uint8 state;
+ [stateData getBytes:&state length:1];
+ BOOL success = state == 0x02;
+
+ NSData *lenData = [data subdataWithRange:NSMakeRange(2, 1)];
+ uint8 len;
+ [lenData getBytes:&len length:1];
+
+ switch (type) {
+ case 0x6A:
+ //语音开启回复
+ [self showLog:[NSString stringWithFormat:@"语音开启回复 %@",@(success)]];
+ self.openRecord(success, nil);
+ break;
+ case 0x6B:
+ //语音停止回复
+ [self showLog:[NSString stringWithFormat:@"语音停止回复 %@",@(success)]];
+ self.closeRecord(success, nil);
+ break;
+ case 0x96:
+ //设置DPI回复
+ [self showLog:[NSString stringWithFormat:@"设置DPI回复 %@",@(success)]];
+ self.setDpi(success, nil);
+ break;
+ case 0x9c:
+ { //鼠标状态查询回复
+ uint16_t version;
+ [[data subdataWithRange:NSMakeRange(3, 2)] getBytes:&version length:2];
+
+ uint16_t DPI;
+ [[data subdataWithRange:NSMakeRange(5, 2)] getBytes:&DPI length:2];
+
+ uint16_t batteryState;
+ [[data subdataWithRange:NSMakeRange(7, 1)] getBytes:&batteryState length:1];
+
+ uint16_t batteryValue;
+ [[data subdataWithRange:NSMakeRange(8, 1)] getBytes:&batteryValue length:1];
+
+ AiMouseDeviceInfo *info = [[AiMouseDeviceInfo alloc] init];
+ info.version = version;
+ info.DPI = DPI;
+ info.batteryState = batteryState;
+ info.batteryValue = batteryValue;
+ [self showLog:info.description];
+ self.getMouseInfo(info, nil);
}
- else{
- [ws showLog:@"写入deviceSecret失败!"];
- [ws setDeviceSecret:ws.updateDeviceSecret completation:complete];
+ break;
+ case 0x9f:
+ {
+ //鼠标按键上报
+ NSData *subData = [data subdataWithRange:NSMakeRange(3, 1)];
+ [self sendCmdData:subData];
}
- }];
-}
-- (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];
+ break;
+ default:
+ break;
+ }
}
-/// 开始录音
+
- (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];
- }
- }
- }];
+ self.openRecord = finished;
+ NSData *data = [AiMouseTools dataWithHexString:@"030100"];
+ [self sendToDevice:data];
}
-/// 结束录音
- (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];
- }
- }
- }];
+ self.closeRecord = finished;
+ NSData *data = [AiMouseTools dataWithHexString:@"040100"];
+ [self sendToDevice:data];
}
-#pragma mark - other
+
+- (void)setDPI:(int)value completation:(void (^)(BOOL isSuccess,NSError *error))finished{
+ self.setDpi = finished;
+ NSData *data = [AiMouseTools dataWithHexString:[NSString stringWithFormat:@"0601010%d",value]];
+ [self sendToDevice:data];
+}
+- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{
+ self.getMouseInfo = finished;
+ NSData *data = [AiMouseTools dataWithHexString:@"0c0100"];
+ [self sendToDevice:data];
+}
+
- (void)sendRecordData:(NSData *)data{
-// if (self.authState != AiMouseAuthState_Success){
-// [self showLog:@"设备还未鉴权!!!"];
-// return;
-// };
-// [self showLog:[NSString stringWithFormat:@"[audio] %@",data]];
+ [self showLog:[NSString stringWithFormat:@"[send][audio] %@",data]];
if (self.delegate) [self.delegate aiMouseSendRecordData:data];
}
+
+#pragma mark - other
- (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];
+ [self.delegate aiMouseAddLog:[NSString stringWithFormat:@"[AiMouseSdk]%@",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];
- }];
- }
+- (void)sendToDevice:(NSData *)data{
+ [self showLog:[NSString stringWithFormat:@"[send][info] %@",data]];
+ [self.delegate aiMouseSendDeviceInfoData:data];
}
#pragma mark - deviceInfo
- (void)startRecord{
-// [self showLog:@"开始录音"];
[self.recordManager start];
}
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];
- }
- }];
+// __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];
@property (nonatomic,strong)void (^discoverDevice)(CBPeripheral *peripheral) ;/// 扫描到设备
@property (nonatomic,strong)void (^didConnectDevice)(CBPeripheral *peripheral);/// 连接成功
@property (nonatomic,strong)void (^didDisConnectDevice)(CBPeripheral *peripheral);/// 断开连接
-@property (nonatomic,strong)void (^authCallBack)(BOOL isSuccess);/// 鉴权回调
/// 单利
+(BleManager *)shared;
- (void)connectPeripheral:(CBPeripheral *)peripheral;
/// 获取设备信息
-- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))completation;
+- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished;
+/// setDPI
+- (void)setDPI:(int)value completation:(void (^)(BOOL isSuccess,NSError *error))finished;
+/// 打开录音
+- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
+
+/// 停止录音
+- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
@end
#import "Config.h"
// 服务id
-#define kServiceUUID @"FFF1"
+#define kServiceUUID @"FFF0"
//ai特征
-#define kAiUUID @"0783B03E-8535-B5A0-7140-A304D2194CB8"
-//设备信息特征
-#define kDeviceInfoUUID @"0783B63E-8535-B5A0-7140-A304D2495CB6"
+#define kAiUUID @"00010203-0405-0607-0809-0A0B0C0D2B18"
+//写设备信息特征
+#define kSetDeviceInfoUUID @"FFF1"
+//通知设备信息特征
+#define kNotifyDeviceInfoUUID @"FFF2"
@interface BleManager ()<CBCentralManagerDelegate,CBPeripheralDelegate,AiMouseDelegate>
@property(nonatomic, strong) CBCentralManager *centralManager;///蓝牙管理
@property(nonatomic, strong) CBPeripheral *connectPeripheral;//连接的设备
-@property(nonatomic, strong) CBCharacteristic *aiCha;//ai特征
@property(nonatomic, strong) CBCharacteristic *deviceInfoCha;//设备信息特征
@property (nonatomic,strong) NSMutableData *recordData;//录音的数据
@end
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
for (CBCharacteristic *characteristic in service.characteristics){
if ([characteristic.UUID.UUIDString isEqualToString:kAiUUID]) {
- //AI特征
- self.aiCha = characteristic;
+ //语音特征
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
- else if ([characteristic.UUID.UUIDString isEqualToString:kDeviceInfoUUID]) {
+ else if ([characteristic.UUID.UUIDString isEqualToString:kNotifyDeviceInfoUUID]) {
+ //通知设备信息特征
+ [peripheral setNotifyValue:YES forCharacteristic:characteristic];
+ }
+ else if ([characteristic.UUID.UUIDString isEqualToString:kSetDeviceInfoUUID]) {
//设备信息特征
self.deviceInfoCha = characteristic;
- [peripheral setNotifyValue:YES forCharacteristic:characteristic];
-
//切换代理
[AiMouse shared].delegate = self;
//切换当前连接类型
[[AiMouse shared] switchConnect:AiMouseConnectType_bluetooth];
-
}
}
}
//AI数据
[[AiMouse shared] sendAiDataToSdk:data];
}
- else if([characteristic.UUID.UUIDString isEqualToString:kDeviceInfoUUID]){
+ else if([characteristic.UUID.UUIDString isEqualToString:kNotifyDeviceInfoUUID]){
//设备信息数据
[[AiMouse shared] sendDeviceDataToSdk:data];
}
}
#pragma mark - AiDelegate
-/// 设备鉴权结果返回
-/// - Parameter authState: 鉴权状态
--(void)aiMouseAuthenticationResult:(AiMouseAuthState)authState{
- [self showLog:[NSString stringWithFormat:@"鉴权结果 = %@",@(authState)]];
- if(self.authCallBack){
- self.authCallBack(authState == AiMouseAuthState_Success);
- }
-}
+
/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备
/// - Parameter data: 数据
-(void)aiMouseSendDeviceInfoData:(NSData *)data{
// [self showLog:[NSString stringWithFormat:@"[send] %@",data]];
- [self.connectPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithoutResponse];
+ [self.connectPeripheral writeValue:data forCharacteristic:self.deviceInfoCha type:CBCharacteristicWriteWithResponse];
}
/// 鼠标按键指令回调
/// - Parameter data: 数据。
-/// 前 第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音)
-/// 中 单击42, 按下25(开始录音)抬起26(结束录音)
-/// 后 单击43,按下27(开始录音)抬起28(结束录音)
+/// 前 单击0x06, 按下0x13(开始录音)抬起0x14(结束录音)
+/// 中 单击0x03, 按下0x11(开始录音)抬起0x12(结束录音)
+/// 后 第一次单击0x01, 第二次单击0x02(结束录音) , 按下0x09(开始录音)抬起0x10(结束录音)
/// 其他未定义
- (void)aiMouseSendCmdData:(NSData *)data{
uint8 cmd;
[data getBytes:&cmd length:1];
- [self showLog:[NSString stringWithFormat:@"收到指令 = %X",cmd]];
- if(cmd == 0x31 || cmd == 0x21 || cmd == 0x25 ||cmd == 0x27){
+ if(cmd == 0x13 || cmd == 0x11 || cmd == 0x01 ||cmd == 0x09){
[self showLog:@"开始录音"];
self.recordData = [[NSMutableData alloc] init];
}
- else if(cmd == 0x32 || cmd == 0x22 || cmd == 0x26 ||cmd == 0x28){
+ else if(cmd == 0x14 || cmd == 0x12 || cmd == 0x02 ||cmd == 0x10){
[self showLog:@"结束录音"];
[self finishRecored:self.recordData];
}
}
/// 获取设备信息
-- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo * _Nonnull, NSError * _Nonnull))completation{
- [[AiMouse shared] getDeviceInfo:completation];
+- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo * _Nonnull, NSError * _Nonnull))finished{
+ [[AiMouse shared] getDeviceInfo:finished];
+}
+
+/// setDPI
+- (void)setDPI:(int)value completation:(void (^)(BOOL isSuccess,NSError *error))finished{
+ [[AiMouse shared] setDPI:value completation:finished];
}
+/// 打开录音
+- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
+ [[AiMouse shared] openRecord:finished];
+}
+
+/// 停止录音
+- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
+ [[AiMouse shared] closeRecord:finished];
+}
#pragma mark - other
//自动连接,获取已配对的蓝牙,取第一个连接
- (void)autoConnectDevice{
@interface DeviceManger : NSObject
@property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型
-@property (nonatomic,strong)void (^authCallBack)(BOOL isSuccess);/// 鉴权回调
@property (nonatomic,strong)void (^connectStateCallBack)(AiMouseConnectType connectType,BOOL isConnect);///是否连接成功
+(DeviceManger *)shared;
- (void)switchConnect:(AiMouseConnectType)type;
/// 获取设备信息
-- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))completation;
+- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished;
+/// setDPI
+- (void)setDPI:(int)value completation:(void (^)(BOOL isSuccess,NSError *error))finished;
+
+/// 打开录音
+- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
+
+/// 停止录音
+- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
@end
NS_ASSUME_NONNULL_END
- (void)setupHid{
self.hid = [HidManager shared];
__weak typeof(self) ws = self;
- self.hid.authCallBack = ^(BOOL isSuccess) {
- if(ws.authCallBack)ws.authCallBack(isSuccess);
- };
self.hid.connectStateCallBack = ^(BOOL isConnnect) {
if(ws.connectStateCallBack)ws.connectStateCallBack(AiMouseConnectType_hid,isConnnect);
};
- (void)setupBle{
self.ble = [BleManager shared];
__weak typeof(self) ws = self;
- self.ble.authCallBack = ^(BOOL isSuccess) {
- if(ws.authCallBack)ws.authCallBack(isSuccess);
- };
self.ble.didConnectDevice = ^(CBPeripheral *peripheral) {
if(ws.connectStateCallBack)ws.connectStateCallBack(AiMouseConnectType_bluetooth,true);
};
[self setupBleNotification];
}
-- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))completation{
+- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{
if ([AiMouse shared].connectType == AiMouseConnectType_bluetooth) {
- [self.ble getDeviceInfo:completation];
+ [self.ble getDeviceInfo:finished];
}
else{
- [self.hid getDeviceInfo:completation];
+ [self.hid getDeviceInfo:finished];
}
}
+/// setDPI
+- (void)setDPI:(int)value completation:(void (^)(BOOL isSuccess,NSError *error))finished{
+ if ([AiMouse shared].connectType == AiMouseConnectType_bluetooth) {
+ [self.ble setDPI:value completation:finished];
+ }
+ else{
+ [self.hid setDPI:value completation:finished];
+ }
+}
+/// 打开录音
+- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
+ if ([AiMouse shared].connectType == AiMouseConnectType_bluetooth) {
+ [self.ble openRecord:finished];
+ }
+ else{
+ [self.hid openRecord:finished];
+ }
+}
+/// 停止录音
+- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished{
+ if ([AiMouse shared].connectType == AiMouseConnectType_bluetooth) {
+ [self.ble closeRecord:finished];
+ }
+ else{
+ [self.hid closeRecord:finished];
+ }
+}
#pragma mark - notication
- (void)setupBleNotification{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bleDidConnect:) name:kDidConnectBleNotification object:nil];
@interface HidManager : NSObject
@property (nonatomic,strong)void (^connectStateCallBack)(BOOL isConnnect);/// 设备是否连上
-@property (nonatomic,strong)void (^authCallBack)(BOOL isSuccess);/// 鉴权回调
+(HidManager *)shared;
+- (void)showLog:(NSString *)log;
+
/// 获取设备信息
-- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))completation;
+- (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished;
+/// setDPI
+- (void)setDPI:(int)value completation:(void (^)(BOOL isSuccess,NSError *error))finished;
-- (void)showLog:(NSString *)log;
+/// 打开录音
+- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
+
+/// 停止录音
+- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished;
@end
NS_ASSUME_NONNULL_END
#import "Config.h"
//供应商id
-const long vendorID = 0x6675;
+const long vendorID = 0x10D6;
//产品id
-const long productID = 0x8601;
+const long productID = 0xB008;
@interface HidManager ()<AiMouseDelegate>
@property(nonatomic, assign) IOHIDManagerRef hidManager;///hid管理
-@property(nonatomic, assign) IOHIDDeviceRef aiCha;//ai通道
@property(nonatomic, assign) IOHIDDeviceRef deviceInfoCha;//设备信息通道
@property (nonatomic,strong) NSMutableData *recordData;//录音的数据
@end
[[HidManager shared] showLog:[NSString stringWithFormat:@"发现设备 %@\n ",inIOHIDDeviceRef]];
uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey));
uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey));
- if(PrimaryUsagePage == 1 && PrimaryUsage == 0){
+// if(PrimaryUsagePage == 1 && PrimaryUsage == 0){
//设备信息
[HidManager shared].deviceInfoCha = inIOHIDDeviceRef;
[[HidManager shared] connectDevice];
}
CFRetain(inIOHIDDeviceRef);
IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- }
- else if(PrimaryUsagePage == 65283 && PrimaryUsage == 0){
- //ai
- [HidManager shared].aiCha = inIOHIDDeviceRef;
- //注册消息回调
- unsigned char InputBuffer[128];
- IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL);
- IOReturn ret = IOHIDDeviceOpen(inIOHIDDeviceRef, 0);
- if (ret != kIOReturnSuccess) {
- NSLog(@"打开AI失败!");
- }else{
- NSLog(@"打开AI成功!");
- }
- CFRetain(inIOHIDDeviceRef);
- IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- }
+// }
+// else if(PrimaryUsagePage == 65283 && PrimaryUsage == 0){
+// //ai
+// [HidManager shared].aiCha = inIOHIDDeviceRef;
+// //注册消息回调
+// unsigned char InputBuffer[128];
+// IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), hidReceiveData, NULL);
+// IOReturn ret = IOHIDDeviceOpen(inIOHIDDeviceRef, 0);
+// if (ret != kIOReturnSuccess) {
+// NSLog(@"打开AI失败!");
+// }else{
+// NSLog(@"打开AI成功!");
+// }
+// CFRetain(inIOHIDDeviceRef);
+// IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+// }
}
/// 设备移除回调
if(PrimaryUsagePage == 1 && PrimaryUsage == 0){
[HidManager shared].deviceInfoCha = nil;
- [HidManager shared].aiCha = nil;
+// [HidManager shared].aiCha = nil;
[[AiMouse shared] didDisconnect];
}
}
NSInteger len = get_data_len(report, reportLength);
NSData *data = [[NSData alloc] initWithBytes:report length:len];
-// [[HidManager shared] showLog:[NSString stringWithFormat:@"[receive] 处理后 %@",[AiMouseTools dataToHexString:data]]];
+ [[HidManager shared] showLog:[NSString stringWithFormat:@"[receive] 处理后 %@",data]];
uint32_t PrimaryUsagePage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsagePageKey));
uint32_t PrimaryUsage = IOHIDDevGetUInt32Property(sender, CFSTR(kIOHIDPrimaryUsageKey));
[self sendData:data toDevice:self.deviceInfoCha];
}
-/// 设备鉴权结果返回
-/// - Parameter authState: 鉴权状态
--(void)aiMouseAuthenticationResult:(AiMouseAuthState)authState{
- [self showLog:[NSString stringWithFormat:@"鉴权结果 = %@",@(authState)]];
- if(self.authCallBack){
- self.authCallBack(authState == AiMouseAuthState_Success);
- }
-}
/// 鼠标按键指令回调
/// - Parameter data: 数据。
/// 前 第一次单击31(开始录音), 第二次单击32(结束录音) , 按下21(开始录音)抬起22(结束录音)
{
NSButton *btn = [[NSButton alloc]initWithFrame:NSMakeRect(50, self.view.bounds.size.height - 180, 100, 45)];
btn.bordered = true;
- btn.title = @"获取设备信息";
+ btn.title = @"选择指令";
[btn setTarget:self];
[btn setAction:@selector(geviceInfoAction)];
+ [btn setAction:@selector(showPopupMenu:)];
+
btn.state = 1;
[self.view addSubview:btn];
}
[self presentViewControllerAsModalWindow:vc];
}
-/// 获取设备信息
-- (void)geviceInfoAction{
- [[DeviceManger shared] getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) {
- if (deviceInfo) {
- NSString *info = deviceInfo.description;
- dispatch_async(dispatch_get_main_queue(), ^{
- self.deviceInfoLabel.stringValue = info;
- });
- }
- else{
- NSString *info = [NSString stringWithFormat:@"error == %@",error.description];
- NSLog(@"%@",info);
- dispatch_async(dispatch_get_main_queue(), ^{
- self.deviceInfoLabel.stringValue = info;
- });
- }
- }];
-}
-- (void)showAuthResult:(BOOL)isSuccess{
- dispatch_async(dispatch_get_main_queue(), ^{
- self.authLabel.stringValue = isSuccess?@"鉴权状态:鉴权成功":@"鉴权状态:鉴权失败";
- if(isSuccess){
- [self geviceInfoAction];
- }
- });
-}
- (void)connectStateDidChange:(AiMouseConnectType)type connectState:(BOOL)isConnected{
dispatch_async(dispatch_get_main_queue(), ^{
if(isConnected){
self.typeLabel.stringValue = type == AiMouseConnectType_bluetooth ?@"连接模式:蓝牙":@"连接模式:hid";
self.connectLabel.stringValue = isConnected?@"连接状态:已连接":@"连接状态:未连接";
- [self geviceInfoAction];
}
else{
self.typeLabel.stringValue = @"连接模式:--";
- (void)setupDeviceManger{
DeviceManger *manager = [DeviceManger shared];
__weak typeof(self) ws = self;
- manager.authCallBack = ^(BOOL isSuccess) {
- [ws showAuthResult:isSuccess];
- };
manager.connectStateCallBack = ^(AiMouseConnectType type,BOOL isConnected) {
[ws connectStateDidChange:type connectState:isConnected];
};
}
+
+- (void)showPopupMenu:(NSButton *)sender {
+ NSMenu *popupMenu = [[NSMenu alloc] initWithTitle:@"Popup Menu"];
+ NSMenuItem *item1 = [[NSMenuItem alloc] initWithTitle:@"语音开启" action:@selector(voiceStart:) keyEquivalent:@"1"];
+ NSMenuItem *item2 = [[NSMenuItem alloc] initWithTitle:@"语音停止" action:@selector(voiceStop:) keyEquivalent:@"2"];
+ NSMenuItem *item3 = [[NSMenuItem alloc] initWithTitle:@"设置DPI" action:@selector(setDPI:) keyEquivalent:@"3"];
+ NSMenuItem *item4 = [[NSMenuItem alloc] initWithTitle:@"鼠标状态查询" action:@selector(searchState:) keyEquivalent:@"3"];
+// NSMenuItem *item5 = [[NSMenuItem alloc] initWithTitle:@"向鼠标告知APP下载地址" action:@selector(setDownLoadURL:) keyEquivalent:@"3"];
+// NSMenuItem *item8 = [[NSMenuItem alloc] initWithTitle:@":读取鼠标序列号" action:@selector(getSN:) keyEquivalent:@"3"];
+// NSMenuItem *item9 = [[NSMenuItem alloc] initWithTitle:@":发送弹UR开关命令" action:@selector(sendUR:) keyEquivalent:@"3"];
+
+ [popupMenu addItem:item1];
+ [popupMenu addItem:item2];
+ [popupMenu addItem:item3];
+ [popupMenu addItem:item4];
+
+ NSPoint buttonLocation = [sender convertPoint:NSZeroPoint toView:self.view];
+ [popupMenu popUpMenuPositioningItem:nil atLocation:buttonLocation inView:self.view];
+}
+
+- (void)voiceStart:(NSMenuItem*)sender {
+ [[DeviceManger shared] openRecord:^(BOOL isSuccess, NSError * _Nonnull error) {
+
+ }];
+}
+- (void)voiceStop:(NSMenuItem*)sender {
+ [[DeviceManger shared] closeRecord:^(BOOL isSuccess, NSError * _Nonnull error) {
+
+ }];
+}
+- (void)setDPI:(NSMenuItem*)sender {
+ [[DeviceManger shared] setDPI:1 completation:^(BOOL isSuccess, NSError * _Nonnull error) {
+
+ }];
+}
+- (void)searchState:(NSMenuItem*)sender {
+ [[DeviceManger shared] getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) {
+// if (deviceInfo) {
+// NSString *info = deviceInfo.description;
+// dispatch_async(dispatch_get_main_queue(), ^{
+// self.deviceInfoLabel.stringValue = info;
+// });
+// }
+// else{
+// NSString *info = [NSString stringWithFormat:@"error == %@",error.description];
+// NSLog(@"%@",info);
+// dispatch_async(dispatch_get_main_queue(), ^{
+// self.deviceInfoLabel.stringValue = info;
+// });
+// }
+ }];
+}
+
@end