123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999 |
- //
- // BTDataProcessVC.m
- // Unity-iPhone
- //
- // Created by duowan123 on 2021/2/3.
- //
- #import "AFNetworking.h"
- #import "ZipArchive.h"
- #import "BTDataProcess.h"
- //
- #import "IOSPlatformSDK.h"
- //算法类
- #import "AlgorithmTool.h"
- //systemte
- #define IOS_NSUSERDEFAULT [NSUserDefaults standardUserDefaults]
- #define CUS_NOTIFICATIONCENTER [NSNotificationCenter defaultCenter]
- //蓝牙提供的sdk算法
- #import "GameObjc.h"
- #define LEFT_FOOT_OC 1
- #define RIGHT_FOOT_OC 2
- //动作数据
- typedef NS_ENUM(NSInteger, GAME_MOTION) {
- MOTION_STOP =0,
- MOTION_RUN,// 跑
- MOTION_JUMP, // 跳
- MOTION_DOWN, // 蹲
- MOTION_LEFT, // 滑左
- MOTION_RIGHT, // 滑右
- MOTION_FRONT, // 滑前
- MOTION_BACK, // 滑后
- MOTION_LEFT_UP, // 点击-左上
- MOTION_LEFT_DOWN, // 点击-左下
- MOTION_RIGHT_UP, // 点击-右上
- MOTION_RIGHT_DOWN, // 点击-右下
- MOTION_STEP, // 点击-原地踩
- NUMBERS_OF_MOTION
- };
- //蓝牙状态
- typedef NS_ENUM(NSInteger, BLETOOTH_STUTAS){
- CONNECT_DIS =0, // 未链接
- CONNECT_ING , //链接中
- CONNECT_ED,// 已链接
- CONNECT_LOST, // 丢失链接 /链接失败
- };
- @interface BTDataProcess ()<NSURLSessionDataDelegate>
- @property (strong, nonatomic)NSMutableArray * deviceArray; /**< 蓝牙设备个数 */
- @property (nonatomic,strong)IOSPlatformSDK * sdk;// ios_sdk
- @property (nonatomic,strong)GameObjc * game ;//主设备蓝牙算法sdk
- @property (nonatomic,strong)GameObjc * viceDeviceGame ;//副设备设备蓝牙算法sdk
- @property(nonatomic,weak)NSTimer * timer;//定时器 定时请求主、副设备电量
- //是否在游戏模式
- @property(nonatomic,assign)BOOL gameModel;
- //调试框
- @property (nonatomic,strong)UILabel * testLabel;
- //当前的时间戳+丢包
- @property (nonatomic,assign)int tempTs;
- @property (nonatomic,assign)int loss;
- @property (nonatomic,assign)int totalPackages;
- //缓存plist
- @property (nonatomic,strong)NSMutableArray * dataArr;
- @property (nonatomic,strong)NSString * dataString;
- @end
- @implementation BTDataProcess
- #pragma mark ===============================================>> 静态的初始化方法 init的时候(建立蓝牙中心管理类,设置代理)
- //单例静态
- static BTDataProcess* instance = nil;
- +(instancetype)sharedInstance{
- // NSLog(@"创建单例一次 1");
- return [[self alloc] init];
- }
- + (instancetype)allocWithZone:(struct _NSZone *)zone{
- // NSLog(@"创建单例一次 2");
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [super allocWithZone:zone];
- });
- return instance;
- }
- - (instancetype)init{
- // NSLog(@"创建单例一次 3");
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [super init];
- [self initNotification];
- });
- return instance;
- }
- //监听所有通知
- -(void)initNotification{
- //默认游戏模式关
- self.gameModel = NO;
- //监听unity --> 开始游戏/结束游戏/震动
- [CUS_NOTIFICATIONCENTER addObserver:self selector:@selector(gameStartInitData) name:@"gameStartInitData" object:nil];
- [CUS_NOTIFICATIONCENTER addObserver:self selector:@selector(gameEndInitData:) name:@"gameEndInitData" object:nil];
- [CUS_NOTIFICATIONCENTER addObserver:self selector:@selector(vibrationAction:) name:@"vibrationAction" object:nil];
- //监听程序从后台返回 系统方法
- [CUS_NOTIFICATIONCENTER addObserver:self selector:@selector(appBackForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
- //监听 app group 消息
- CFStringRef strRef = (__bridge CFStringRef)@"DISCONNECT_BLE";
- CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
- NULL,
- disConnectBle,
- strRef,
- NULL,
- CFNotificationSuspensionBehaviorDeliverImmediately);
- [self inittestLabel];
-
- }
- //趣动APP吊起 发送通知->断开游戏的所有的蓝牙连接 (C语言函数)
- //C语言函数内 只能用指针instance调用实例不能用self
- void disConnectBle (CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){
- [instance disConnedctBle];
- }
- //断开蓝牙
- -(void)disConnedctBle{
- NSLog(@"BTDataProcess 通知断开蓝牙操作");
- [LEManager cancelPeripheralConnection];
- }
- //监听程序从后台返回
- -(void)appBackForeground{
-
- // NSLog(@"BTDataProcess 收到程序从后台返回 peripheral.state = %ld",LEManager.peripheral.state);
- if (LEManager.peripheral!=nil&&LEManager.peripheral.state != CBPeripheralStateConnected){//蓝牙不为空 且蓝牙断开链接(有三种情况)
- [self connectPeripheral:LEManager.peripheral];//蓝牙重链接
- }
- if (LEManager.vicePeripheral!=nil&&LEManager.vicePeripheral.state != CBPeripheralStateConnected){//蓝牙不为空 且蓝牙断开链接
- [self connectPeripheral:LEManager.vicePeripheral];//蓝牙重链接
- }
-
- }
- //监听通知开始游戏
- -(void)gameStartInitData{
- NSLog(@"通知开始游戏 --> BTDataProcess");
- self.gameModel = YES;
- //反馈->蓝牙sdk
- // [self.game start];
- }
- //监听通知结束游戏
- -(void)gameEndInitData:(NSNotification*)notification{
- NSLog(@"通知结束游戏 --> BTDataProcess");
- self.gameModel = NO;
- //反馈->蓝牙sdk
- // [self.game end];
- }
- //监听通知震动
- -(void)vibrationAction:(NSNotification*)notification{
-
- //unity回调数据
- NSDictionary * notificationDict = notification.userInfo;
- // NSLog(@"弹出视图事件notificationDict == %@",notificationDict);
- NSNumber * typeNumber = [notificationDict objectForKey:@"type"];
- NSNumber * durationNumber = [notificationDict objectForKey:@"duration"];
- int deviceType = [typeNumber intValue];
- int duration = [durationNumber intValue];
- // NSLog(@"通知游戏震动 --> BTDataProcess %d",deviceType);
- [self vibration:(DEVICE_TYPE)deviceType duration:duration];
- //每次踩对就反馈->蓝牙sdk
- // [self.game isBingo];
-
- }
- #pragma mark ============================================================== leon new manager
- //测试自己封装的蓝牙类
- -(void)initCBCentralManager{
-
- [LEManager initCBCentralManager];
-
- LEManager.stateUpdateBlock = ^(CBCentralManager * central){
-
- switch(central.state){
- case 0:
- NSLog(@"当前的蓝牙状态 ==================================>> CBCentralManagerStateUnknown");
- break;
- case 1:
- NSLog(@"当前的蓝牙状态 ==================================>> CBCentralManagerStateResetting");
- break;
- case 2:
- NSLog(@"当前的蓝牙状态 ==================================>> CBCentralManagerStateUnsupported");
- break;
- case 3:
- NSLog(@"当前的蓝牙状态 ==================================>> CBCentralManagerStateUnauthorized");
- break;
- case 4:{
- NSLog(@"当前的蓝牙状态 ==================================>> 蓝牙已关闭");
- if (LEManager.peripheral!=nil){
-
- [self.sdk bridgingDeviceAction:DEVICETYPE_MAIN
- name:LEManager.peripheral.name
- address:LEManager.peripheral.identifier.UUIDString
- status:CONNECT_LOST
- electricity:0];
- }
- if (LEManager.vicePeripheral!=nil){
-
- [self.sdk bridgingDeviceAction:DEVICETYPE_VICE
- name:LEManager.vicePeripheral.name
- address:LEManager.vicePeripheral.identifier.UUIDString
- status:CONNECT_LOST
- electricity:0];
- }
-
- }
- break;
- case 5:{
- NSLog(@"当前的蓝牙状态 ==================================>> 蓝牙已开启");//蓝牙已开启
- //扫描蓝牙外设
- [LEManager scanForPeripheralsWithServices:nil options:nil];
- }
- break;
- default:
- break;
- }
-
- };
-
- //扫描蓝牙外设
- // [LEManager scanForPeripheralsWithServices:nil options:nil];
- [self.deviceArray removeAllObjects];
- //发现蓝牙
- LEManager.discoverPeripheralBlock = ^(CBCentralManager * _Nonnull central, CBPeripheral * _Nonnull peripheral, NSDictionary * _Nonnull advertisementData, NSNumber * _Nonnull RSSI){
-
- // NSLog(@"扫描发现蓝牙设备advertisementData = %@",advertisementData);
- if (peripheral.name.length>0&& [peripheral.name hasPrefix:@"SH_"]){//SH_DANCE BLE_LOOP Shoes_4530 Shoes_2A74
- // NSLog(@"主设备扫描发现有效的蓝牙设备 =============== %@ identifier == %@",peripheral.name,peripheral.identifier.UUIDString);
-
- if (self.deviceArray.count == 0){//数据源为0
-
- // NSLog(@"add 扫描发现蓝牙设备 %@",peripheral.name);
- [self.deviceArray addObject:peripheral];
- //判断扫描到外设之后是否要链接蓝牙
- [self ifAppJumpWithIdentifier:peripheral];
-
- }else{
-
- BOOL isExist = NO;
-
- for (int i = 0; i < self.deviceArray.count; i++){
- CBPeripheral *per = [self.deviceArray objectAtIndex:i];
- if ([per.identifier.UUIDString isEqualToString:peripheral.identifier.UUIDString]){
- isExist = YES;
- [self.deviceArray replaceObjectAtIndex:i withObject:peripheral];
- }
- }
-
- if (!isExist){
- [self.self.deviceArray addObject:peripheral];
- //判断扫描到外设之后是否要链接蓝牙
- [self ifAppJumpWithIdentifier:peripheral];
- }
-
- }
-
- //数据回调给 搜索蓝牙弹窗
- if (self.deviceArrBLock != nil){
- self.deviceArrBLock(self.deviceArray);
- }
- }
-
- };
- }
- #pragma mark ===============================================>> 主设备蓝牙数据
- //是否是app跳转传参 区分app跳转和弹窗搜索 type=0的时候才会执行该方法 type=0的时候才会执行该方法 当时弹框的时候type==1 不执行该方法
- -(void)ifAppJumpWithIdentifier:(CBPeripheral*)peripheral{
-
- if (self.macAddress!=nil && [peripheral.identifier.UUIDString isEqualToString:self.macAddress]){//app跳转过来 主动链接蓝牙
- [self connectPeripheral:peripheral];
- }
-
- }
- #pragma mark ===============================================>> 链接蓝牙设备公用方法 可外部操作
- //app跳转或选中tableview 链接蓝牙
- -(void)connectPeripheral:(CBPeripheral*)peripheral{
-
- if(instance!=NULL && peripheral!=NULL){
-
- self.sdk = [IOSPlatformSDK sharedInstance];//蓝牙数据经过sdk数据转换后 ios call unity
- //app游戏列表id转为bobo sdk需要的游戏id
- switch (self.game_id){
- case 1://跳舞
- self.game_id = 2;
- break;
- case 2://赛达尔传说
- self.game_id = 3;
- break;
- case 3://跑酷
- self.game_id = 1;
- break;
- case 4://测试demo
- self.game_id = 2;
- break;
- default:
- break;
- }
- // self.deviceType = DEVICETYPE_VICE;
- self.game_id = 2;
- NSLog(@" connectPeripheral self.deviceType ==>> %ld self.game_id ==>> %d",(long)self.deviceType,self.game_id);
-
- //初始化运轨sdk
- if (self.deviceType==DEVICETYPE_MAIN){
- LEManager.peripheral = peripheral;
- self.game = [[GameObjc alloc] initWithGametype:self.game_id];
- }else if (self.deviceType == DEVICETYPE_VICE){
- LEManager.vicePeripheral = peripheral;
- self.viceDeviceGame = [[GameObjc alloc] initWithGametype:self.game_id];
- }
- //根据ios_sdk传入deviceType 链接 主/副 设备
- [self connectBLEManagerData:peripheral deviceType:self.deviceType];
-
- }
-
- }
- //链接主副设备 + 绑定特征
- -(void)connectBLEManagerData:(CBPeripheral*)peripheral deviceType:(DEVICE_TYPE)deviceType{
-
- //链接蓝牙 此时 LEManager.peripheral || LEManager.vicePeripheral 还未init
- [LEManager connectPeripheral:peripheral options:nil];
- //发现服务和特征
- LEManager.discoverCharacteristicsBlock = ^(CBPeripheral * _Nonnull peripheral, CBService * _Nonnull service, NSArray * _Nonnull characteristics, NSError * _Nonnull error){
-
- if (peripheral==LEManager.peripheral&&deviceType==DEVICETYPE_MAIN){//主设备
-
- for (CBCharacteristic * cha in service.characteristics){
-
- if (cha.properties == 12){//写
-
- LEManager.write = cha;
- [self initGameAction:DEVICETYPE_MAIN];
- }else if (cha.properties == 16){//读
-
- LEManager.read = cha;
- [LEManager.peripheral readValueForCharacteristic:cha];
- [LEManager.peripheral setNotifyValue:YES forCharacteristic:cha];
-
- }
- }
- }else if (peripheral==LEManager.vicePeripheral&&deviceType==DEVICETYPE_VICE){//副设备
- for (CBCharacteristic * cha in service.characteristics){
-
- if (cha.properties == 12){//写
- LEManager.viceWrite = cha;
- [self initGameAction:DEVICETYPE_VICE];
- }else if (cha.properties == 16){//读
- LEManager.viceRead = cha;
- [LEManager.vicePeripheral readValueForCharacteristic:cha];
- [LEManager.vicePeripheral setNotifyValue:YES forCharacteristic:cha];
- }
- }
- }
- };
-
- //读取特征的报文数据
- LEManager.readValueForCharacteristicBlock = ^(CBPeripheral * _Nonnull peripheral, CBCharacteristic * _Nonnull characteristic, NSData * _Nonnull value, NSError * _Nonnull error, DEVICE_TYPE type){
- if ([characteristic.UUID.UUIDString isEqualToString:@"6E400003-B5A3-F393-E0A9-E50E24DCCA9E"]){//判断是不是我们设备的特征值
- // NSLog(@"characteristic.UUID.UUIDString = %@",characteristic.UUID.UUIDString);
- [self verifyData:characteristic deviceType:type];
- }
- };
-
- // //写入数据的回调 暂时用不到
- // LEManager.writeToCharacteristicBlock = ^(CBPeripheral * _Nonnull peripheral,CBCharacteristic * _Nonnull characteristic, NSError * _Nonnull error, DEVICE_TYPE type)
- // };
-
- }
- //启动定时器
- -(void)initGameAction:(DEVICE_TYPE)deviceType{
-
- //每次链接成功后 开启游戏模式 初始化步数数据 立马查询一次设备信息
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(),^{
-
- if (deviceType==DEVICETYPE_MAIN){
-
- [self startGameModel:DEVICETYPE_MAIN];
- [self queryDevideInfo];
- self.jump_count = 0;
- self.crouch_count = 0;
- self.step_count = 0;
-
- }else if (deviceType ==DEVICETYPE_VICE){
-
- [self startGameModel:DEVICETYPE_VICE];
- [self queryDevideInfo];
-
- }
-
- });
-
- //之后开启启定时器查询电量 一分钟查询一次
- self.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(queryDevideInfo) userInfo:nil repeats:YES];
-
- }
- //报文数据 长度+校验位 校验
- -(void)verifyData:(CBCharacteristic*)characteristic deviceType:(DEVICE_TYPE)deviceType{
-
- if (characteristic.value.length>3){
- //带cmd位的有效数据 计算校验位
- if ([AlgorithmTool verificationRusult:characteristic.value]==YES){
- [self analysisCharacteristic:characteristic.value deviceType:deviceType];
- }
- }else{
- NSLog(@"无效报文");
- }
-
- }
- //报文数据解析
- -(void)analysisCharacteristic:(NSData*)characteristic deviceType:(DEVICE_TYPE)deviceType{
-
- // NSLog(@"接收到的数据data = %@",characteristic);
- int frameHead = [AlgorithmTool dataToChar:[characteristic subdataWithRange:NSMakeRange(0, 1)]];//帧头数据aa
- int messageLength = [AlgorithmTool dataToChar:[characteristic subdataWithRange:NSMakeRange(1, 1)]];//报文长度
- int messageLengthNegation = ~messageLength;//报文长度取反
- int dataType = [AlgorithmTool dataToChar:[characteristic subdataWithRange:NSMakeRange(3, 1)]];//cmd类型
-
- if (dataType == 4 && characteristic.length == 60){//获取主动推过来的数据
- //右脚坐标数据
- int right_X = [AlgorithmTool dataToSwapBigIntToHost:characteristic andRange:NSMakeRange(4, 4)];
- int right_Y = [AlgorithmTool dataToSwapBigIntToHost:characteristic andRange:NSMakeRange(8, 4)];
- int right_Z = [AlgorithmTool dataToSwapBigIntToHost:characteristic andRange:NSMakeRange(12, 4)];
- int right_pos[3] = {right_X,right_Y,right_Z};
- //左脚坐标数据
- int left_X = [AlgorithmTool dataToSwapBigIntToHost:characteristic andRange:NSMakeRange(16, 4)];
- int left_Y = [AlgorithmTool dataToSwapBigIntToHost:characteristic andRange:NSMakeRange(20, 4)];
- int left_Z = [AlgorithmTool dataToSwapBigIntToHost:characteristic andRange:NSMakeRange(24, 4)];
- int left_pos[3] = {left_X,left_Y,left_Z};
- //右脚姿势数据
- short righrPosture_X = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(28, 2)];
- short righrPosture_Y = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(30, 2)];
- short righrPosture_Z = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(32, 2)];
- int right_att[3] = {righrPosture_X,righrPosture_Y,righrPosture_Z};
- //左脚姿势数据
- short leftPosture_X = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(34, 2)];
- short leftPosture_Y = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(36, 2)];
- short leftPosture_Z = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(38, 2)];
- int left_att[3] = {leftPosture_X,leftPosture_Y,leftPosture_Z};
- //右脚三维数据
- short righrAcc_x = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(40, 2)];
- short righrAcc_Y = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(42, 2)];
- short righrAcc_z = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(44, 2)];
- int righrAcc[3] = {righrAcc_x,righrAcc_Y,righrAcc_z};
- //左脚三维数据
- short leftAcc_x = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(46, 2)];
- short leftAcc_y = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(48, 2)];
- short leftAcc_z = [AlgorithmTool dataToSwapBigShortToHost:characteristic andRange:NSMakeRange(50, 2)];
- int left_acc[3] = {leftAcc_x,leftAcc_y,leftAcc_z};
- //左脚、右脚、蹲 、跳四个动作信息数据
- int actionInformation = [AlgorithmTool dataToChar:[characteristic subdataWithRange:NSMakeRange(52, 1)]];;//0c 16进制字符串
- int girlShoes = actionInformation & 16;
- if (girlShoes!=0){
- girlShoes=1;
- }else{
- girlShoes=0;
- }
- int rightZupt = actionInformation & 8;
- if (rightZupt!=0){
- rightZupt=1;
- }else{
- rightZupt=0;
- }
- int leftZupt = actionInformation & 4;
- if (leftZupt!=0){
- leftZupt=1;
- }else{
- leftZupt=0;
- }
- int down = actionInformation & 2;
- if (down!=0){
- down=1;
- }else{
- down=0;
- }
- int jump = actionInformation & 1;
- if (jump!=0){
- jump=1;
- }else{
- jump=0;
- }
- int rssi = [AlgorithmTool dataToChar:[characteristic subdataWithRange:NSMakeRange(53, 1)]];//rssi 信号强度
- int ts = [AlgorithmTool dataToChar:[characteristic subdataWithRange:NSMakeRange(54, 1)]];;//ts 时间戳
- int right_press = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(55, 2)]];//3 29新增 右鞋压力
- int left_press = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(57, 2)]];//3 29新增 左鞋压力
- int frameCheck = [AlgorithmTool dataToChar:[characteristic subdataWithRange:NSMakeRange(59, 1)]];//校验位
-
- if (deviceType==DEVICETYPE_MAIN){//主设备
-
- //调取鞋子SDK
- [self shoseSDKRight_pos:right_pos Right_att:right_att LeftPos:left_pos Left_att:left_att ts:ts rightZupt:rightZupt leftZupt:leftZupt jump:jump down:down rssi:rssi girlShoes:girlShoes right_press:right_press left_press:left_press];
-
- }else if (deviceType==DEVICETYPE_VICE){//副设备动作数据
-
- //调取鞋子SDK
- [self viceShoseSDKRight_pos:right_pos Right_att:right_att LeftPos:left_pos Left_att:left_att ts:ts rightZupt:rightZupt leftZupt:leftZupt jump:jump down:down rssi:rssi girlShoes:girlShoes right_press:right_press left_press:left_press];
-
- }
-
- }else if (dataType == -95){//获取的是查询的数据 char-->int a1 = -95
- if (characteristic.length == 74){//A1+0 >> 0: 设备基本信息 ==>> 预留参数 趣动app用 sdk暂未调用
-
- // NSString *deviceModel = [[NSString alloc] initWithData:[characteristic subdataWithRange:NSMakeRange(5, 18)] encoding:NSUTF8StringEncoding];
- // NSString *softwareVer = [AlgorithmTool hexadecimalString:[characteristic subdataWithRange:NSMakeRange(69, 2)]];//0102
- // NSString *hardwareVer = [AlgorithmTool hexadecimalString:[characteristic subdataWithRange:NSMakeRange(71, 2)]];//0104
-
- }else if (characteristic.length == 26){//A1+1 >> 1: 设备数据(左鞋,右鞋) aa 14 eb a1 01 64 00 1a 0000981d 64 00 17 00000000 f9
-
- int leftElectricity = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(5, 1)]];
- // int leftTempreature = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(6, 1)]];
- // int leftPressure = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(7, 4)]];
- // int leftStepCount = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(11, 4)]];
- // int rightElectricity = [self dataToInt:[characteristic subdataWithRange:NSMakeRange(12, 1)]];
- int rightElectricity = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(15, 1)]];//龙哥新协议
- // int rightTempreature = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(16, 1)]];
- // int rightPressure = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(17, 4)]];
- // int rightStepCount = [AlgorithmTool dataToInt:[characteristic subdataWithRange:NSMakeRange(21, 4)]];
-
- NSLog(@"接收到的数据data 26 = %@ 电量 %d %d",characteristic,leftElectricity,rightElectricity);
- if (deviceType==DEVICETYPE_MAIN){//主设备
-
- //主 设备定时器 60秒调一次 /******************ios call unity*****************/
- [self.sdk bridgingDeviceAction:DEVICETYPE_MAIN
- name:LEManager.peripheral.name
- address:LEManager.peripheral.identifier.UUIDString
- status:CONNECT_ED
- electricity:leftElectricity<=rightElectricity?leftElectricity:rightElectricity];
-
- }else if (deviceType==DEVICETYPE_VICE){//副设备
-
- //副 设备定时器 60秒调一次 /******************ios call unity*****************/
- [self.sdk bridgingDeviceAction:DEVICETYPE_VICE
- name:LEManager.vicePeripheral.name
- address:LEManager.vicePeripheral.identifier.UUIDString
- status:CONNECT_ED
- electricity:leftElectricity<=rightElectricity?leftElectricity:rightElectricity];
-
- }
-
- }
-
- }
-
- }
- //报文数据解析后 -- 调用蓝牙鞋子SDK装换数据 -- ios call unity 更新游戏动作
- -(void)shoseSDKRight_pos:(int[3])right_pos
- Right_att:(int[3])right_att
- LeftPos:(int[3])left_pos
- Left_att:(int[3])left_att
- ts:(int)ts
- rightZupt:(int)rightZupt
- leftZupt:(int)leftZupt
- jump:(int)jump
- down:(int)down
- rssi:(int)rssi
- girlShoes:(int)girlShoes
- right_press:(int)right_press
- left_press:(int)left_press{
-
- /********************初始化 运动轨迹算法 SDK *****************/
- [self.game gameProcess:ts
- rightPos:right_pos
- rightAtt:right_att
- rightZupt:rightZupt
- right_press:right_press
- leftPos:left_pos
- leftAtt:left_att
- leftZupt:leftZupt
- left_press:left_press
- jump:jump
- down:down
- rssi:rssi
- girl_shoes:girlShoes];
- int length = 4;
- int result[length];
- [self.game getGameResult:result];
- // NSLog(@"result == %d %d %d %d \n",result[0],result[1],result[2],result[3]);
-
- /******************步频数据处理 + 回调*****************/
- int leftStepStatus = [self.game getStepStatus:LEFT_FOOT_OC];
- int leftStepFreq = [self.game getStepFreq:LEFT_FOOT_OC];
- int leftStepCount = [self.game getStepCount:LEFT_FOOT_OC];
- int rightStepStatus = [self.game getStepStatus:RIGHT_FOOT_OC];
- int rightStepFreq = [self.game getStepFreq:RIGHT_FOOT_OC];
- int rightStepCount = [self.game getStepCount:RIGHT_FOOT_OC];
-
- //ios call unity
- // [self.sdk bridgingStepAction:DEVICETYPE_MAIN leftStatus:leftStepStatus rightStatus:rightStepStatus leftFrag:leftStepFreq rightFrag:rightStepFreq];//左右脚速度 步频
- //数据回调缓存
- if (self.allMotionCountBLock){
- self.step_count = leftStepCount+rightStepCount;
- self.allMotionCountBLock(self.jump_count, self.crouch_count, leftStepCount+rightStepCount);
- }
-
- /******************左右脚动作数据处理 + 回调*****************/
- int motionLeft = result[0];//左脚的动作
- int motionRight = result[1];//右脚的动作
- int motionJump = result[2];//jump
- int motionDown = result[3];//down
- // if (motionLeft==-1 && motionRight == -1&& motionJump == -1&& motionDown == -1){//无效动作
- // return;
- // }else{
- //跳跃和蹲下的动作 双脚是同步的
- if (motionJump == MOTION_JUMP){
- motionLeft = motionJump;
- motionRight = motionJump;
- self.jump_count++;
- NSLog(@" 主设备 ================================== 跳起来 ");
- }
- if (motionDown == MOTION_DOWN){
- motionLeft = motionDown;
- motionRight = motionDown;
- self.crouch_count++;
- NSLog(@" 主设备 =================================== 蹲下去 ");
- }
- //ios call unity
- // if (self.gameModel==YES){//当前是游戏模式
- [self.sdk bridgingMotionAction:DEVICETYPE_MAIN left:motionLeft right:motionRight];//左右脚动作
- // }else{//当前是交互模式
- // int interaction = [self.game getInteractionCMD];
- // [self.sdk bridgingInteraction:DEVICETYPE_MAIN code:interaction];
- // }
- // }
-
- //
- int difference = abs(ts) - abs(self.tempTs);
- //当前丢包数>2算作丢包
- if (abs(difference)>=2){
- self.loss = self.loss + abs(difference)-1;
- self.totalPackages = self.totalPackages+abs(difference);
- // NSLog(@"总数据包 1== >> self.totalPackages %d",self.totalPackages);
- }else{
- self.totalPackages++;
- // NSLog(@"总数据包 2== >> self.totalPackages %d",self.totalPackages);
- }
- self.tempTs = abs(ts);
- // NSLog(@"收到数据包 ===================>> ts: %d 当前包LOSS: %d 总包数: %d 总LOSS: %d",ts,abs(difference),self.totalPackages,self.loss);
- // self.testLabel.text = [NSString stringWithFormat:@"数据:[%d,%d,%d,%d] RSSI: %d 总包数: %d 总丢包: %d",result[0],result[1],result[2],result[3],rssi,self.totalPackages,self.loss];
- self.testLabel.text = [NSString stringWithFormat:@"数据:[%d,%d,%d,%d] RSSI: %d 总包数: %d 总丢包: %d",motionLeft,motionRight,motionJump,motionDown,rssi,self.totalPackages,self.loss];
-
- //写入沙盒数据
- // [self.dataArr addObject:[NSString stringWithFormat:@"数据:[%d,%d,%d,%d] RSSI: %d 总包数: %d 总丢包: %d",motionLeft,motionRight,motionJump,motionDown,rssi,self.totalPackages,self.loss]];
- self.dataString = [NSString stringWithFormat:@"%@\n数据:[%d,%d,%d,%d] RSSI: %d 总包数: %d 总丢包: %d",self.dataString,motionLeft,motionRight,motionJump,motionDown,rssi,self.totalPackages,self.loss];
- [self writeFileToplist];
-
- }
- //报文数据解析后 -- 调用蓝牙鞋子SDK装换数据 -- ios call unity 更新游戏动作
- -(void)viceShoseSDKRight_pos:(int[3])right_pos
- Right_att:(int[3])right_att
- LeftPos:(int[3])left_pos
- Left_att:(int[3])left_att
- ts:(int)ts
- rightZupt:(int)rightZupt
- leftZupt:(int)leftZupt
- jump:(int)jump
- down:(int)down
- rssi:(int)rssi
- girlShoes:(int)girlShoes
- right_press:(int)right_press
- left_press:(int)left_press{
-
- /********************运轨数据初始化*****************/
- [self.viceDeviceGame gameProcess:ts
- rightPos:right_pos
- rightAtt:right_att
- rightZupt:rightZupt
- right_press:right_press
- leftPos:left_pos
- leftAtt:left_att
- leftZupt:leftZupt
- left_press:left_press
- jump:jump
- down:down
- rssi:rssi
- girl_shoes:girlShoes];
- int length = 4;
- int result[length];
- [self.viceDeviceGame getGameResult:result];
- // NSLog(@"result == %d %d %d %d \n",result[0],result[1],result[2],result[3]);
-
- /********************蓝牙sdk返回的鞋子 状态 步频 步数*****************/
- int leftStepStatus = [self.viceDeviceGame getStepStatus:LEFT_FOOT_OC];
- int leftStepFreq = [self.viceDeviceGame getStepFreq:LEFT_FOOT_OC];
- // int leftStepCount = [self.viceDeviceGame getStepCount:LEFT_FOOT_OC];
- int rightStepStatus = [self.viceDeviceGame getStepStatus:RIGHT_FOOT_OC];
- int rightStepFreq = [self.viceDeviceGame getStepFreq:RIGHT_FOOT_OC];
- // int rightStepCount = [self.viceDeviceGame getStepCount:RIGHT_FOOT_OC];
- //ios call unity
- [self.sdk bridgingStepAction:DEVICETYPE_VICE leftStatus:leftStepStatus rightStatus:rightStepStatus leftFrag:leftStepFreq rightFrag:rightStepFreq];//副设备左右脚速度 步频
-
- /********************蓝牙sdk返回的鞋子 动作*****************/
- int motionLeft = result[0];//左脚的动作
- int motionRight = result[1];//右脚的动作
- int ivce_motionJump = result[2];//jump
- int ivce_motionDown = result[3];//down
- if (motionLeft==-1 && motionRight == -1&& ivce_motionJump == -1&& ivce_motionDown == -1){//无效动作
- return;
- }else{
- //跳跃和蹲下的动作 双脚是同步的
- if (ivce_motionJump == MOTION_JUMP){
- motionLeft = ivce_motionJump;
- motionRight = ivce_motionJump;
- NSLog(@"副设备 ======================================== 跳起来 jump_count = %d ",self.jump_count);
- }
- if (ivce_motionDown == MOTION_DOWN){
- motionLeft = ivce_motionDown;
- motionRight = ivce_motionDown;
- NSLog(@"副设备 ========================================= 蹲下去 crouch_count = %d ",self.crouch_count);
- }
- //ios call unity as相互NX你·
- [self.sdk bridgingMotionAction:DEVICETYPE_VICE left:motionLeft right:motionRight];//副设备左右脚动作
- }
-
- }
- #pragma mark ===============================================>> 蓝牙发送各类数据
- //查询设备信息
- - (void)queryDevideInfo{
-
- //头帧AA + 数据长度 + 长度取反 + cmd + 数据 + 校验
- NSMutableData * writeData = [NSMutableData new];
-
- Byte header = 0xaa;
- Byte length = 0x06;//长度A1->6 A2->5 A3->7
- Byte lengthNegation = ~length;
- Byte cmd = 0xA1;
- Byte data = 0x1;
- Byte byte[] = {header,length,lengthNegation,cmd,data};
- writeData = [[NSMutableData alloc] initWithBytes:byte length:sizeof(byte)];
- // [writeData appendData:msData];
- Byte bcc = [AlgorithmTool byteSumBBC:writeData];
- [writeData appendBytes:&bcc length:sizeof(bcc)];
- if (LEManager.peripheral!=nil){
- NSLog(@"发送的报文 主设备查询设备信息 %@", writeData);
- [LEManager writeValue:writeData forCharacteristic:LEManager.write writeType:CBCharacteristicWriteWithResponse deviceType:DEVICETYPE_MAIN];
- }
- if (LEManager.vicePeripheral!=nil){
- NSLog(@"发送的报文 副设备查询设备信息 %@", writeData);
- [LEManager writeValue:writeData forCharacteristic:LEManager.viceWrite writeType:CBCharacteristicWriteWithResponse deviceType:DEVICETYPE_VICE];
- }
-
- }
- //打开游戏模式
- - (void)startGameModel:(DEVICE_TYPE)type{
-
- //头帧AA + 数据长度 + 长度取反 + cmd + 数据 + 校验
- NSMutableData * writeData = [NSMutableData new];
- Byte header = 0xaa;
- Byte length = 0x06;//长度A1->6 A2->5 A3->7
- Byte lengthNegation = ~length;
- Byte cmd = 0xA2;
- Byte data = 0x1;
- //计算校验位
- Byte byte[] = {header,length,lengthNegation,cmd,data};
- writeData = [[NSMutableData alloc] initWithBytes:byte length:sizeof(byte)];
- Byte bcc = [AlgorithmTool byteSumBBC:writeData];
- //传输数据 -->> NSData
- [writeData appendBytes:&bcc length:sizeof(bcc)];
- if (type==DEVICETYPE_MAIN&&LEManager.peripheral!=nil){
- NSLog(@"发送的报文 主设备开启游戏模式: %@", writeData);
- [LEManager writeValue:writeData forCharacteristic:LEManager.write writeType:CBCharacteristicWriteWithResponse deviceType:DEVICETYPE_MAIN];
- }
-
- if (type == DEVICETYPE_VICE&&LEManager.vicePeripheral!=nil){
- NSLog(@"发送的报文 副设备开启游戏模式: %@", writeData);
- [LEManager writeValue:writeData forCharacteristic:LEManager.viceWrite writeType:CBCharacteristicWriteWithResponse deviceType:DEVICETYPE_VICE];
- }
-
- }
- //设置震动
- - (void)vibration:(DEVICE_TYPE)deviceType duration:(int)duration{
-
- //头帧AA + 数据长度 + 长度取反 + cmd + 数据 + 校验
- NSMutableData * writeData = [NSMutableData new];
- Byte header = 0xaa;
- Byte length = 0x07;//长度A1->6 A2->5 A3->7
- Byte lengthNegation = ~length;
- Byte cmd = 0xA4;
- //振动时间 2字节
- short ms = 400;//400毫秒
- Byte mslow = (Byte) (0x00FF & ms);//定义第一个byte
- Byte mshigh = (Byte) (0x00FF & (ms>>8));//定义第二个byte
- //计算校验位
- Byte bytes[] = {header,length,lengthNegation,cmd,mshigh,mslow};
- Byte bcc = [AlgorithmTool bbcByte:bytes];
- //传输数据 Byte -->> NSData
- Byte newByte[] = {header,length,lengthNegation,cmd,mshigh,mslow,bcc};
- writeData = [[NSMutableData alloc] initWithBytes:newByte length:sizeof(newByte)];
- if (deviceType==DEVICETYPE_MAIN){
- NSLog(@"发送的报文 主 设备震动 %@", writeData);
- [LEManager writeValue:writeData forCharacteristic:LEManager.write writeType:CBCharacteristicWriteWithResponse deviceType:DEVICETYPE_MAIN];
- }else if (deviceType == DEVICETYPE_VICE){
- NSLog(@"发送的报文 副 设备震动 %@", writeData);
- [LEManager writeValue:writeData forCharacteristic:LEManager.viceWrite writeType:CBCharacteristicWriteWithResponse deviceType:DEVICETYPE_VICE];
- }
-
- }
- #pragma mark ===============================================>> 懒加载 -- 蓝牙设备数据源
- -(NSMutableArray*)deviceArray{
- if (!_deviceArray){
- _deviceArray = [NSMutableArray new];
- }
- return _deviceArray;;
- }
- #pragma mark ===============================================>> DEBUG
- -(void)inittestLabel{
-
- self.testLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 0, [UIScreen mainScreen].bounds.size.width-100, 40)];
- self.testLabel.textColor = [UIColor redColor];
- self.testLabel.font = [UIFont boldSystemFontOfSize:20];
- self.testLabel.backgroundColor = [UIColor clearColor];
- self.testLabel.textAlignment = NSTextAlignmentCenter;
- self.testLabel.numberOfLines = 2;
-
- UIButton * uploadButton = [UIButton buttonWithType:UIButtonTypeCustom];
- uploadButton.frame = CGRectMake([UIScreen mainScreen].bounds.size.width-100, 0, 50, 40);
- // uploadButton.backgroundColor = [UIColor redColor];
- [uploadButton.titleLabel setTextColor:[UIColor redColor]];
- [uploadButton setFont: [UIFont systemFontOfSize:20]];
- [uploadButton setTitle:@"上传" forState:UIControlStateNormal];
- [uploadButton addTarget:self action:@selector(uploadpPlistFile) forControlEvents:UIControlEventTouchUpInside];
- UIViewController *rootVC = [[UIApplication sharedApplication].delegate window].rootViewController;
- UIViewController *parent = rootVC;
- while ((parent = rootVC.presentedViewController) != nil ){
- rootVC = parent;
- }
- while ([rootVC isKindOfClass:[UINavigationController class]]){
- rootVC = [(UINavigationController *)rootVC topViewController];
- }
- // [rootVC addChildViewController:searchVC];
- [rootVC.view addSubview:self.testLabel];
- [rootVC.view addSubview:uploadButton];
- self.dataArr = [NSMutableArray new];
-
- }
- #pragma mark ===============================================>> 存储和上传数据
- -(void)writeFileToplist{
-
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- //获取完整路径
- NSString *documentsDirectory = [paths objectAtIndex:0];
- NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:@"lossLog.txt"];//这里就是你将要存储的沙盒路径(.plist文件,名字自定义)
-
- if(![[NSFileManager defaultManager] fileExistsAtPath:plistPath]) {//plistPath这个文件\文件夹是否存在
-
- NSLog(@"------1----- 写入 不 成功");
- [self.dataString writeToFile:plistPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
- }else{
-
- [self.dataString writeToFile:plistPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
- // NSLog(@"------2---- 写入 成功");
- // NSLog(@"%@",plistPath);
-
- }
-
- }
- -(void)uploadpPlistFile{
-
- //这个方法获取出的结果是一个数组.因为有可以搜索到多个路径.
- NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- //在这里,我们指定搜索的是Cache目录,所以结果只有一个,取出Cache目录
- NSString *documentsDirectory = array[0];
- // NSLog(@"%@",documentsDirectory);
- //拼接文件路径
- NSString *filePathName = [documentsDirectory stringByAppendingPathComponent:@"lossLog.txt"];
- //如果保存的是一个数组.那就通过数组从文件当中加载.
- NSString *string = [NSString stringWithContentsOfFile:filePathName encoding:NSUTF8StringEncoding error:nil];
- // NSLog(@"%@",string);
- //4.设置请求体
- NSData *upData = [string dataUsingEncoding:NSUTF8StringEncoding];
- //
- AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
- manager.requestSerializer.timeoutInterval=15;
- [manager.requestSerializer setValue:@"multipart/form-data" forHTTPHeaderField:@"Content-Type"];
- manager.requestSerializer = [AFJSONRequestSerializer serializer];
- manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain",@"text/html",@"application/json",@"text/javascript",@"image/jpeg",@"image/png",@"application/octet-stream",@"application/x-www-form-urlencoded", nil];
- // NSLog(@"请求URL ===================>> %@",urlString);
- NSLog(@"******************* 请求头参数 = %@ ***************************",manager.requestSerializer.HTTPRequestHeaders);
-
- AFHTTPSessionManager *sessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:nil];
- [sessionManager POST:@"http://172.16.14.127:8080/upload" parameters:nil headers:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData){
- [formData appendPartWithFileData:upData name:@"file" fileName:[NSString stringWithFormat:@"loss%@.txt",[self getNowTimeTimestamp]] mimeType:@"text/plain"];
- // [formData appendPartWithFileData:upData name:@"file" fileName:[NSString stringWithFormat:@"lossLog%@.txt",@"1"] mimeType:@"text/plain"];
- }progress:^(NSProgress * _Nonnull uploadProgress){
- NSLog(@"上传进度 = %@",uploadProgress);
- }success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject){
- NSLog(@"上传成功");
- }failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error){
- for (NSString * key in error.userInfo){
- if ([key isEqualToString:@"com.alamofire.serialization.response.error.data"]){
- id errorObject = [NSJSONSerialization JSONObjectWithData:error.userInfo[key] options:1 error:nil];
- NSLog(@"上传失败 ===>> %@",errorObject);
- }
-
- }
-
- }];
-
- }
- //获取当前时间戳有两种方法(以秒为单位)
- -(NSString *)getNowTimeTimestamp{
- NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
- [formatter setDateStyle:NSDateFormatterMediumStyle];
- [formatter setTimeStyle:NSDateFormatterShortStyle];
- [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
- //设置时区,这个对于时间的处理有时很重要
- NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
- [formatter setTimeZone:timeZone];
- NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式
- NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];
- return timeSp;
- }
-
- @end
|