You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1375 lines
52 KiB

//
// Bluetooth.m
// BluetoothDemo
//
// Created by mac on 17/3/9.
// Copyright © 2017年 . All rights reserved.
//
#import "Bluetooth.h"
#import "L2DataParse.h"
#import <SVProgressHUD/SVProgressHUD.h>
#import "NSString+methods.h"
#import "BLETools.h"
#import "BLEConst.h"
#import "BLEBaseBl.h"
#import "Lookfit-Swift.h"
#import <CoreLocation/CoreLocation.h>
#import "User_Http.h"
NSString *kFLT_BLE_FOUND = @"FLT_BLE_FOUND"; //发现设备
NSString *kFLT_BLE_PAIRED = @"FLT_BLE_PAIRED"; //BLE已配对
NSString *kFLT_BLE_CONNECTED = @"FLT_BLE_CONNECTED"; //BLE已连接
NSString *kFLT_BLE_DISCONNECTED = @"FLT_BLE_DISCONNECTED"; //BLE断开连接
NSString *FLT_BLE_SERVICE = @"AE00"; //服务号
NSString *FLT_BLE_RCSP_W = @"AE01"; //命令“写”通道
NSString *FLT_BLE_RCSP_R = @"AE02"; //命令“读”通道
// 超时间隔
#define TimeOutNumber 5
// 连接延时
#define ConnectPeripheralTimerName @"Bluetooth_ConnectPeripheralTimerName"
#define ConnectPeripheralTimerName2 @"Bluetooth_ConnectPeripheralTimerName2"
@interface Bluetooth () <CBPeripheralDelegate,CBCentralManagerDelegate>//CLLocationManagerDelegate
@property (nonatomic, strong) CBPeripheralManager *peripheralManager;
/** 蓝牙请求计数 */
@property (nonatomic, assign) NSInteger timeNumber;
/** 是否正在执行 */
@property (nonatomic, assign) BOOL isExecuting;
/** 超时定时器 */
@property (nonatomic, strong) NSTimer *checkoutTimer;
/** 当前执行的命令 */
@property (nonatomic, strong) BlueToothItem *currenItem;
/** 当前接收的数据 */
@property (nonatomic, strong) NSMutableData *currenData;
/** 总数据包 */
@property (nonatomic, strong) NSMutableData *totalData;
/** crc校验是否成功 */
@property (nonatomic, assign) BOOL isCrc;
/** 防止手表多次调用特征值变化 */
@property (nonatomic, assign) BOOL isChangeCharacteristic;
/** 重连外设 */
@property (nonatomic, strong) CBPeripheral *reconnectPeripheral;
/** 是否DFU扫描 */
@property (nonatomic, assign) BOOL isDFUScan;
//@property (nonatomic ,strong) CLLocationManager *locationManager;
//
//@property (nonatomic ,strong) CLBeaconRegion *beaconRegion;
/** */
@property (nonatomic, assign) BOOL is_JL;
/// 手表表盘资源文件
@property (nonatomic ,strong) NSArray *mWatchList;
/// 是否正在升级
@property (nonatomic ,assign) BOOL isOtaUpdate;
/// <#arguments#>
@property (nonatomic ,strong) NSString *mOtaPath;
@property (nonatomic ,strong) NSString *otaString;
@end
@implementation Bluetooth
+ (nullable instancetype)shareInstance {
static Bluetooth *share = nil;
static dispatch_once_t oneToken;
dispatch_once(&oneToken, ^{
share = [[self alloc] init];
});
return share;
}
- (id)init {
self = [super init];
if (self) {
self.isIndependentOff = NO;
self.bleRequestSid = 0;
self.bluetoothItems = [NSMutableArray array];
self.currenData = [NSMutableData new];
self.totalData = [NSMutableData new];
self.cMgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionRestoreIdentifierKey: @"myCentralManagerIdentifier"}];
self.isChangeCharacteristic = NO;
self.is_JL = NO;
self.mAssist = [[JL_Assist alloc] init];
self.mAssist.mNeedPaired = YES; //是否需要握手配对
self.mAssist.mPairKey = nil; //配对秘钥
self.mAssist.mService = FLT_BLE_SERVICE; //服务号
self.mAssist.mRcsp_W = FLT_BLE_RCSP_W; //特征「写」
self.mAssist.mRcsp_R = FLT_BLE_RCSP_R; //特征「读」
// 监听时间改变
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(timeDidChanged)
name:UIApplicationSignificantTimeChangeNotification
object:nil];
}
return self;
}
/**
实时同步时间到设备
*/
- (void)timeDidChanged{
if ([[Bluetooth shareInstance] isConnected]) {
// 延迟请求,防止时制切换未反应
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[[BLEBaseBl alloc] init] setIngTimeWithBleCmdType:BleCMD_setIngTime];
});
}
// 更改了时间通知主要界面刷新界面,1为时间标示
[[NSNotificationCenter defaultCenter] postNotificationName:SycnDatas object:@(1)];
}
/**
扫描外设Peripherals
@param serviceUUIDs 过滤的服务UUID
@param isDFU 是否DFU升级使用
*/
- (void)scanForPeripheralsWithdiscoverServices:(nullable NSArray<CBUUID *> *)serviceUUIDs
IsDFU:(BOOL)isDFU {
// 停止扫描
[self cancelScan];
self.isDFUScan = isDFU;
// 获取系统已配对的手环平台设备,存在则加入
NSMutableArray *connectedArray = [self getPairedConnectedArray];
for (BLEModel *bleModel in connectedArray) {
[self.delegate onDiscoverToPeripheralsBleModel:bleModel];
}
// DFU模式不使用uuid的筛选扫描
if (isDFU || [[NSUserDefaults standardUserDefaults] objectForKey:DFUMASString])
{
NSDictionary *options= [NSDictionary dictionaryWithObject:@NO forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
[self.cMgr scanForPeripheralsWithServices:nil options:options];
return;
}
NSArray *uuids = @[[CBUUID UUIDWithString:BraceletServicesUUID]];
NSDictionary *scanForPeripheralsWithOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@YES};
[self.cMgr scanForPeripheralsWithServices:uuids options:scanForPeripheralsWithOptions];
}
#pragma mark - coreBlueTooth --系统代理
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
self.state = central.state;
[self.mAssist assistUpdateState:central.state];
if (central.state == CBManagerStatePoweredOn)
{
// 蓝牙开始重连
[self startAndStopReconnect:YES];
}
else if (central.state == CBManagerStatePoweredOff)
{
[[NSNotificationCenter defaultCenter] postNotificationName:BluetoothNotificationAtPowerOff object:@"PowerOff"];
CGFloat systemVision = DEVICEVERSION;
if (systemVision <10 || systemVision >= 11) {
if (self.isConnected) {
// 连接断开发出通知
self.isConnected = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:BluetoothNotificationAtDisconnect object:nil];
// 清空所有
self.writecharacteristic = nil;
// 断开连接后处理,当前队列若存在则清空并且停止定时器
if (self.bluetoothItems.count) {
[self.bluetoothItems removeAllObjects];
[self.checkoutTimer invalidate];
self.timeNumber = 0;
_executing = NO;
}
}
}
[self startAndStopReconnect: NO];
}
}
//搜索蓝牙设备
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(@"[蓝牙通讯] 搜索到了设备:%@ \n设备UUID:%@ \n advertisementData:%@",peripheral.name,
peripheral.identifier.UUIDString,
advertisementData);
NSString *ble_name = advertisementData[@"kCBAdvDataLocalName"];
NSString *MACString = [[NSString alloc] init];
NSData *manufacturerData = advertisementData[@"kCBAdvDataManufacturerData"];
if (manufacturerData && manufacturerData.length >= 8)
{
NSData *MACData = [advertisementData[@"kCBAdvDataManufacturerData"] subdataWithRange:NSMakeRange(2, 6)];
MACString = [BluetoothTool getPositiveSequenceMacWithData:MACData];
}
BLEModel *bleModel = [[BLEModel alloc] initWithCentral:central
Peripheral:peripheral
AdvertisementData:advertisementData
RSSI:RSSI
UUIDString:peripheral.identifier.UUIDString
MACString:MACString];
// 未完成升级设备 || 需要重连的设备
if ((self.isDFUScan && [peripheral.name isEqual:@"DfuTarg"]) || [bleModel.MACString isEqualToString:[UserDefaultsManager getLocalDeviceMacID]]) {
__weak typeof(self) weakSelf = self;
[GCDTimer.ocShareInstance scheduledDispatchTimerWithTimerName:ConnectPeripheralTimerName2 timeInterval:self.reconnectTime queue:dispatch_get_main_queue() repeats:false immediately:false action:^{
[weakSelf connectedWithBleModel:bleModel];
weakSelf.reconnectTime = 0;
}];
}
if (self.delegate && [self.delegate respondsToSelector:@selector(onDiscoverToPeripheralsBleModel:)])
{
[self.delegate onDiscoverToPeripheralsBleModel:bleModel];
}
// ota升级过程,回连使用
if (manufacturerData != nil && self.is_JL)
//if ([JL_BLEAction otaBleMacAddress:self.lastBleMacAddress isEqualToCBAdvDataManufacturerData:manufacturerData])
{
// self.is_JL = NO;
[self connectedWithBleModel:bleModel];
}
}
// 蓝牙状态的保存和恢复,进入后台和重新启动有关
- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *, id> *)dict
{
}
// 已经连接外设
- (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@"[蓝牙通讯] BLE Connected ---> Device %@", peripheral.name);
peripheral.delegate = self;
[peripheral discoverServices:nil];
[self cancelScan];
// [peripheral discoverServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:ServicesUUID]]];//再去发现服务
// 若是Dfu模式外设则在此处发出连接成功的通知
if ([peripheral.name rangeOfString:@"DfuTarg"].location != NSNotFound)
{
NSLog(@"DFUl连接成功!!!!");
self.isConnected = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:BluetoothNotificationAtDFUConnectSuccess object:nil];
}
}
// 连接外设失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"[蓝牙通讯] 设备:%@--连接失败",peripheral.name);
//if (self.isIndependentOff)
[SVProgressHUD showInfoWithStatus:NSLocalizedString(@"连接失败", nil)];
// 连接失败发出通知
[[NSNotificationCenter defaultCenter] postNotificationName:BluetoothNotificationAtConnectFail object:peripheral.name];
self.isConnected = NO;
//self.isRay = NO;
}
// 已经断开连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(@"[蓝牙通讯] 设备:%@--断开连接",peripheral.name);
/*--- JLSDK ADD ---*/
[self.mAssist assistDisconnectPeripheral:peripheral];
// 连接断开发出通知
self.isConnected = NO;
//self.isRay = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:BluetoothNotificationAtDisconnect object:peripheral.name];
// 清空所有
self.writecharacteristic = nil;
// 断开连接后处理,当前队列若存在则清空并且停止定时器
if (self.bluetoothItems.count)
{
[self.bluetoothItems removeAllObjects];
[self.checkoutTimer invalidate];
self.timeNumber = 0;
_executing = NO;
}
//if (!self.isIndependentOff)
[self startAndStopReconnect:YES];
}
// characteristic订阅状态改变
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error
{
NSLog(@"[蓝牙通讯] //characteristic订阅状态改变的block---- %@",characteristic.value);
// 判断是否监听设备广播通知成功 -->成功才发送连接成功通知
if (characteristic.isNotifying && [characteristic.UUID isEqual:[CBUUID UUIDWithString:NotifycharacteristicUUIDString]])
{
NSLog(@"[蓝牙通讯] 连接成功!!!!!!");
// 连接成功保存UUID,做重连使用
[[NSUserDefaults standardUserDefaults] setObject:peripheral.identifier.UUIDString forKey:AutomaticReconnectionDevice];
// 订阅了读数据才发出连接成功通知
self.isConnected = YES;
self.reconnectPeripheral = peripheral;
[[NSNotificationCenter defaultCenter] postNotificationName:BluetoothNotificationAtConnectSuccess object:self.currenModel];
}
[self jlTimeClose];
self.is_JL = NO;
__weak typeof(self) weakSelf = self;
[self.mAssist assistUpdateCharacteristic:characteristic Peripheral:peripheral Result:^(BOOL isPaired) {
if (isPaired == YES)
{
[[NSUserDefaults standardUserDefaults] setObject:peripheral.identifier.UUIDString forKey:AutomaticReconnectionDevice];
NSLog(@"[蓝牙通讯] 配对成功");
self.reconnectPeripheral = peripheral;
[JL_Tools post:kFLT_BLE_PAIRED Object:peripheral];
JL_EntityM *entity = [[JL_EntityM alloc] init];
[entity setBlePeripheral:peripheral];
self.mAssist.mCmdManager.mEntity = entity;
weakSelf.lastBleMacAddress = nil;
[JL_Tools delay:0.5 Task:^{
[self getInfo];
}];
}
else
{
[weakSelf.cMgr cancelPeripheralConnection:peripheral];
}
}];
}
//外设传来数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
// NSLog(@" 设备发过来的 characteristic name:%@ value is:%@",characteristic.UUID,characteristic.value);
/*--- JLSDK ADD ---*/
[self.mAssist assistUpdateValueForCharacteristic:characteristic];
if (characteristic.value.length && [characteristic.UUID isEqual:[CBUUID UUIDWithString:NotifycharacteristicUUIDString]]) {
// 接收到的数据处理
[self handleReceiveData:[characteristic value]];
}
// FRQ OTA是否存在数据
if (characteristic.value.length && [characteristic.UUID isEqual:[CBUUID UUIDWithString:kFRQReadCharacteristicUUID]]) {
[[NSNotificationCenter defaultCenter] postNotificationName:FRQReadCharacteristicUUIDNotify object:characteristic.value];
}
if (self.delegate && [self.delegate respondsToSelector:@selector(OnReadValueForCharacteristic:characteristicsL:)]) {
[self.delegate OnReadValueForCharacteristic:peripheral characteristicsL:characteristic];
}
}
//发现服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (error) { NSLog(@"Err: Discovered services fail."); return; }
for (CBService *service in peripheral.services)
{
NSLog(@"[蓝牙通讯] BLE Service ---> %@", service.UUID.UUIDString);
[peripheral discoverCharacteristics:nil forService:service];
}
if (self.delegate && [self.delegate respondsToSelector:@selector(onDiscoverServices:)])
{
[self.delegate onDiscoverServices:peripheral];
}
}
//发现特征值
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
[self.mAssist assistDiscoverCharacteristicsForService:service Peripheral:peripheral];
if (IsDelegate(self, OnDiscoverCharacteristics:Service:)) {
[self.delegate OnDiscoverCharacteristics:peripheral Service:service];
}
if ([service.UUID isEqual:[CBUUID UUIDWithString:ServicesUUID]]) {
for (CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:NotifycharacteristicUUIDString]]) {
[peripheral setNotifyValue:true forCharacteristic:characteristic];
}
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:WirtecharacteristicUUIDString]]) {
self.writecharacteristic = characteristic;
}
}
}
// FRQ OTA
if ([service.UUID isEqual:[CBUUID UUIDWithString:kFRQServiceUUID]]) {
for (CBCharacteristic *characteristic in service.characteristics ) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kFRQReadCharacteristicUUID]]) {
[peripheral setNotifyValue:true forCharacteristic:characteristic];
}
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kFRQWriteCharacteristicUUID]]) {
self.frqOTAwritecharacteristic = characteristic;
}
}
}
}
//写入值的监听
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
NSLog(@"写入成功");
}
/**
停止扫描
*/
- (void)cancelScan {
[self.cMgr stopScan];
}
//-(void)centralManager:(CBCentralManager *)central connectionEventDidOccur:(CBConnectionEvent)event
// forPeripheral:(CBPeripheral *)peripheral
//{
// if (event == CBConnectionEventPeerConnected)
// {
// NSLog(@"---> 系统界面,已连接设备:%@",peripheral.name);
// if (peripheral.name.length > 0) {
// [self connectBLE:peripheral];
// }
// }
//
// if (event == CBConnectionEventPeerDisconnected) {
// NSLog(@"---> 系统界面,断开设备:%@",peripheral.name);
// }
//}
//-(void)connectBLE:(CBPeripheral*)peripheral
//{
// self.reconnectPeripheral = peripheral;
// [self.reconnectPeripheral setDelegate:self];
//
// [self.cMgr connectPeripheral:self.reconnectPeripheral
// options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES),
// CBConnectPeripheralOptionNotifyOnConnectionKey:@(YES)
// }];
// [self.cMgr stopScan];
//
// NSLog(@"BLE Connecting... Name ---> %@ UUID:%@",peripheral.name,peripheral.identifier.UUIDString);
//}
/**
连接设备
@param bleModel ble模型
*/
- (void)connectedWithBleModel:(BLEModel *)bleModel
{
self.currenModel = bleModel;
self.reconnectPeripheral = bleModel.peripheral;
// 连接设备
NSLog(@"BLE Connecting... Name ---> %@", bleModel.peripheral.name);
[bleModel.peripheral setDelegate:self];
//[self.cMgr connectPeripheral:bleModel.peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}];
if (@available(iOS 13.0, *)) {
[self.cMgr connectPeripheral:bleModel.peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES),CBConnectPeripheralOptionEnableTransportBridgingKey:@(YES)}];
} else {
[self.cMgr connectPeripheral:bleModel.peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}];
}
// 停止扫描
[self cancelScan];
}
/// 断开当前连接的设备
/// @param isUnbind 是否解绑
- (void)disConnectedCurrenDevice:(BOOL)isUnbind
{
if (isUnbind) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:AutomaticReconnectionDevice];
}
// 调用则立刻设置为断开
self.isConnected = NO;
// 存在设备则断开
if (self.reconnectPeripheral)
{
[self.cMgr cancelPeripheralConnection:self.reconnectPeripheral];
if (isUnbind)
{
self.reconnectPeripheral = nil;
self.currenModel = nil;
}
}
}
/**
蓝牙设备重连
@param isStart 开启停止
*/
- (void)startAndStopReconnect:(BOOL)isStart
{
if (!isStart || self.state != CBManagerStatePoweredOn) {
// 取消重连
if (self.reconnectPeripheral) {
[self.cMgr cancelPeripheralConnection:self.reconnectPeripheral];
}
return;
}
// 获取本地设备
NSString *reconnectionUUIDSrting = [[NSUserDefaults standardUserDefaults] objectForKey:AutomaticReconnectionDevice];
if (!reconnectionUUIDSrting) {
return;
}
// 重连系统已配对设备
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:reconnectionUUIDSrting];
NSArray *systemPeripherals = [self.cMgr retrievePeripheralsWithIdentifiers:@[uuid]];
if (systemPeripherals.count)
{
CBPeripheral *peripheral = systemPeripherals.firstObject;
BLEModel *bleModel = [[BLEModel alloc] initWithCentral:self.cMgr
Peripheral:peripheral
AdvertisementData:0
RSSI:[NSNumber numberWithInteger:0]
UUIDString:peripheral.identifier.UUIDString
MACString:nil];
self.currenModel = bleModel;
self.reconnectPeripheral = peripheral;
__weak typeof(self) weakSelf = self;
[GCDTimer.ocShareInstance scheduledDispatchTimerWithTimerName:ConnectPeripheralTimerName timeInterval:self.reconnectTime queue:dispatch_get_main_queue() repeats:false immediately:false action:^{
weakSelf.reconnectPeripheral.delegate = self;
[weakSelf.cMgr connectPeripheral:weakSelf.reconnectPeripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES),
CBConnectPeripheralOptionNotifyOnConnectionKey:@(YES),
CBConnectPeripheralOptionNotifyOnNotificationKey:@(YES)}];
weakSelf.reconnectTime = 0;
[self cancelScan];
}];
}
// 扫描设备
[self scanForPeripheralsWithdiscoverServices:nil IsDFU:true];
}
//========== 处理蓝牙指令 ========== //
/**
写入数据
@param bleItem 蓝牙命令模型
*/
- (void)writeWithBleItem:(BlueToothItem *)bleItem {
if (self.isConnected) {
[self.bluetoothItems addObject:bleItem];
[self loopRequest];
return;
}
// 代理超时返回
if (IsDelegate(bleItem.dataSource, bluetoothManager:sequenceID:didTimeOutWithData:cmdId:)) {
[bleItem.dataSource bluetoothManager:self sequenceID:bleItem.sid didTimeOutWithData:nil cmdId:bleItem.cmd];
}
}
/// 清空指令队列
- (void)removeCmdItem {
// 当前队列若存在则清空并且停止定时器
if (self.bluetoothItems.count) {
[self.bluetoothItems removeAllObjects];
[self.checkoutTimer invalidate];
self.timeNumber = 0;
_executing = NO;
}
}
- (void)firmwareCompleteResetDelegate {
self.cMgr.delegate = self;
}
/**
循环串行 执行蓝牙请求(先进先出)
*/
- (void)loopRequest
{
if (_bluetoothItems.count > 0 && _executing == NO) {
BlueToothItem *bleItem = _bluetoothItems.firstObject;
if (!bleItem.isExecuting) {
self.currenItem = bleItem;
// 分包发送数据
[self handleWithByteBuffer:self.currenItem.byteBuffer];
bleItem.isExecuting = YES;
_executing = YES;
// 定时器开启 3秒超时
self.timeNumber = 0;
CGFloat timeOut = 1.0;
NSTimer *checkoutTimer = [NSTimer scheduledTimerWithTimeInterval:timeOut target:self selector:@selector(clickTimeout:) userInfo:nil repeats:YES];
self.checkoutTimer = checkoutTimer;
NSLog(@"[蓝牙通讯] 发送了蓝牙指令 %@ 序号是 %ld 指令是 %ld",bleItem.byteBuffer,bleItem.sid,bleItem.cmd);
}
}
}
/**
超时处理,进入此方法则重发
*/
- (void)clickTimeout:(NSTimer *)timer {
self.timeNumber++;
NSLog(@"[蓝牙通讯] 超时了,第 %ld 秒",self.timeNumber);
// 超时五秒后重发
if (self.timeNumber > TimeOutNumber) {
// 重发三次
if (self.currenItem.requestCount < 2) {
self.timeNumber = 0;
NSLog(@"[蓝牙通讯] 重新发送了 %ld",self.currenItem.requestCount);
self.currenItem.requestCount++;
// 重新发送时置空数据包
self.currenData = [NSMutableData new];
self.totalData = [NSMutableData new];
// 分包发送数据
[self handleWithByteBuffer:self.currenItem.byteBuffer];
}else {
// 超时隐藏提示框
[SVProgressHUD dismiss];
// [SVProgressHUD showInfoWithStatus:NSLocalizedString(@"请求超时", nil)];
// // 超时断开设备
// [self disConnectedCurrenDevice:false];
// 代理超时返回
if (IsDelegate(self.currenItem.dataSource, bluetoothManager:sequenceID:didTimeOutWithData:cmdId:)) {
[self.currenItem.dataSource bluetoothManager:self sequenceID:self.currenItem.sid didTimeOutWithData:nil cmdId:self.currenItem.cmd];
}
// 超时处理
[self completeAndTimeouthandleWithItem:self.currenItem];
}
}
}
/**
分包数据发送处理
*/
- (void)handleWithByteBuffer:(NSMutableData *)byteBuffer
{
// 发送时默认回调数据校验成功
self.isCrc = YES;
// 大于20字节则分包发送
if (byteBuffer.length > 20)
{
NSInteger count = byteBuffer.length / 20;
for (int i = 0; i <= count; i++)
{
NSData *data = [[NSData alloc] init];
if (i < count)
{
data = [byteBuffer subdataWithRange:NSMakeRange(i * 20, 20)];
}
else if (byteBuffer.length % 20)
{
// 最后不足20字节的数据
data = [byteBuffer subdataWithRange:NSMakeRange(i * 20, byteBuffer.length % 20)];
}
if (data)
{
if (self.writecharacteristic)
{
// 写入数据
[self.reconnectPeripheral writeValue:data forCharacteristic:self.writecharacteristic type:CBCharacteristicWriteWithoutResponse];
// NSLog(@"写入数据 %@",data);
}
}
}
}
else
{
if (self.writecharacteristic)
{
// 写入数据
[self.reconnectPeripheral writeValue:byteBuffer forCharacteristic:self.writecharacteristic type:CBCharacteristicWriteWithoutResponse];
//NSLog(@"写入数据 %@",byteBuffer);
}
}
// for (int i = 0; i < byteBuffer.length; i += 20)
// {
// // 预加 最大包长度,如果依然小于总数据长度,可以取最大包数据大小
// if ((i + 20) < byteBuffer.length)
// {
// NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, 20];
// NSData *subData = [byteBuffer subdataWithRange:NSRangeFromString(rangeStr)];
// NSLog(@"%@",subData);
// if (self.writecharacteristic)
// {
// // 写入数据
// [self.reconnectPeripheral writeValue:subData forCharacteristic:self.writecharacteristic type:CBCharacteristicWriteWithoutResponse];
// NSLog(@"写入数据 %@",subData);
// }
// //根据接收模块的处理能力做相应延时
// usleep(20 * 1000);
// }
// else {
// if (self.writecharacteristic)
// {
// // 写入数据
// [self.reconnectPeripheral writeValue:byteBuffer forCharacteristic:self.writecharacteristic type:CBCharacteristicWriteWithoutResponse];
// NSLog(@"写入数据 %@",byteBuffer);
// }
// usleep(20 * 1000);
// }
// }
}
/**
任务完成 || 超时 处理
@param item 当前蓝牙命令
*/
- (void)completeAndTimeouthandleWithItem:(BlueToothItem *)item {
[self.checkoutTimer invalidate];
_executing = NO;
self.currenData = [NSMutableData new];
self.totalData = [NSMutableData new];
[self.bluetoothItems removeObject:item];
[self loopRequest];
}
/**
根据序号查找当前队列是否存在
*/
- (BlueToothItem *)requestItemFromIndex:(int)index {
for (BlueToothItem *item in _bluetoothItems)
{
if (item.sid == index) {
return item;
}
}
return nil;
}
/**
处理收到的数据
@param data 返回的数据
*/
#pragma mark ---- 处理收到的数据
- (void)handleReceiveData:(NSData *)data {
NSLog(@"[蓝牙通讯] 接收到的数据------%@",data);
// 如果存在队列 收到数据则重新计算超时
if (_bluetoothItems.count) {
self.timeNumber = 0;
}
// 处理命令后的返回数据
[self.currenData appendData:data];
// 判断数据是否完整
Byte *currentDataBytes = (Byte *)[self.currenData bytes];
int contenLenght = (currentDataBytes[2] & 0xff) << 8 | (currentDataBytes[3] & 0xff);
int actualLenght = (int)self.currenData.length - 8;
// NSLog(@"现在的数据------ %@",self.currenData);
// NSLog(@"应该有的长度------ %d 现在的长度-------- %d",contenLenght,actualLenght);
//Byte *buffer = (Byte *)[self.currenData bytes];
// 接收到的数据包完整
if (contenLenght == actualLenght) {
// 判断序号是否存在当前队列
int sid = (currentDataBytes[6] & 0xff) << 8 | (currentDataBytes[7] & 0xff);
BlueToothItem *item = [self requestItemFromIndex:sid];
if (item) {
// 判断err,1:成功 0:失败
BOOL err = [self checkDataWithData:self.currenData ByteIndex:1 bitIndex:2];
if (err) {
// 大于200bytes字节的数据不做CRC处理
if (contenLenght <= 200) {
// CRC校验(失败则返回重发)
if (![BluetoothTool checkCRCWithData:self.currenData]) {
self.isCrc = NO;
}
}
// 判断是否有后续数据包返回 1:有 0:无
BOOL isData = [self checkDataWithData:self.currenData ByteIndex:1 bitIndex:1];
if (!isData && !self.isCrc) {
// 不存在后续数据并且数据检验失败直接重发
return;
}
if (isData) {
// 还有后续数据则将当前完整数据包以分隔符拼接
[self.totalData appendData:self.currenData];
self.currenData = [NSMutableData new];
[self.totalData appendData:[DataSeparator dataUsingEncoding:NSUTF8StringEncoding]];
return;
}else{
// 拼接最后完整数据包
[self.totalData appendData:self.currenData];
// 代理返回成功数据
if (IsDelegate(item.dataSource, bluetoothManager:sequenceID:didCompleteWithData:cmdId:)) {
[self.currenItem.dataSource bluetoothManager:self sequenceID:item.sid didCompleteWithData:self.totalData cmdId:item.cmd];
}
// 当前数据处理完成
[self completeAndTimeouthandleWithItem:item];
}
}
}else {
// 不存在此队列(设备主动发送过来的数据)
[self handleDeviceControlWithData:self.currenData];
self.currenData = [NSMutableData new];
}
}else {
// 数据不完整返回拼接
return;
}
}
/**
处理设备发送过来的指令(找手机,拍照功能,实时数据)
*/
- (void)handleDeviceControlWithData:(NSMutableData *)data {
NSLog(@"处理设备发送过的指令 ------- %@",data);
// 检查是否为指令
if (((Byte*)([data bytes]))[0] == 0xCB) {
// 判断err是否正确
BOOL err = [self checkDataWithData:data ByteIndex:1 bitIndex:2];
if (err) {
Byte key = ((Byte*)([data bytes]))[10];
BleCMD blecmd = 0;
switch (key) {
case 0x46: //!< 拍照开关 0X46
{
blecmd = BleCMD_cameraSwitch;
}
break;
case 0x47: //!< 拍照 0X47
{
blecmd = BleCMD_cameraON;
}
break;
case 0x48: //!< 退出拍照 0X48
{
blecmd = BleCMD_cameraOFF;
}
break;
case 0x51: //!< 查找手机 0X51
{
blecmd = BleCMD_findPhone;
}
break;
case 0xB4: //!< 实时计步,心率,血压,血氧-> 同步实时数据
case 0xB3:
case 0xB6:
case 0xB7:
case 0xB8:
{
blecmd = BleCMD_realTimesync;
}
break;
case 0x01: //!< 抬手亮屏设置
{
blecmd = BleCMD_gesturesControl;
}
break;
case 0xA5: //!< 辅助运动,的运动数据
{
//blecmd = BleCMD_sportModelData;
blecmd = BleCMD_syncHealth;
}
break;
case 0x41: //!< 电量
{
blecmd = BleCMD_batteryBack;
}
break;
default:
break;
}
// 将设备控制的指令类型通知出去
if (blecmd) {
if (blecmd == BleCMD_realTimesync)
[BLEBaseBl.shareInstance readProfileWithBleCmdType:BleCMD_readProfile];
// 处理设备端发来的实时步数,心率,血压血氧
if (blecmd == BleCMD_realTimesync||blecmd == BleCMD_syncHealth) {
NSDictionary *dict = [L2DataParse L2_ParseData:data type:blecmd];
BleCMD reportCMD = [dict[@"DataType"] integerValue];
[[NSNotificationCenter defaultCenter] postNotificationName:DeviceReportRealTimeHealthData object:@(reportCMD) userInfo:dict];
return;
}
// 回复设备发出通知
[self checkCRCHandleWithData:data confirm:YES];
[[NSNotificationCenter defaultCenter] postNotificationName:DeviceControlNotification object:@(blecmd) userInfo:@{@"data": data}];
return;
}
} else {
[self checkCRCHandleWithData:data confirm:NO];// 回复设备发出通知
}
} else {
return; // 非请求返回的数据也不是设备发送过来的数据不处理
}
}
/**
处理设备的运动状态
*/
- (void)handleSportStateWithData:(NSMutableData *)data {
// Byte *buffer = (Byte *)[data bytes];
// int sportState = buffer[13];
//
// UserGlobal *userGlobal = [UserGlobal ocShareInstance];
// if (!userGlobal.locationAide) {
// userGlobal.locationAide = [[LocationAide alloc]init];
// }
// if (sportState == 1) {//运动结束
// [userGlobal.locationAide stopLocation];
// } else {//运动开始
// [userGlobal.locationAide stratLocation];
// userGlobal.locationAide.gpsSignalBlock = ^(NSInteger signal) {
// [[[BLEBaseBl alloc] init] GPSSignalStrengthWithBleCmdType:BleCMD_GPSSignalStrength dialType:signal];
// NSLog(@"signal = %ld",(long)signal);
// };
// }
}
/**
处理设备发送过来的数据
*/
- (void)handleDeviceDataCMD:(BleCMD)blecmd Data:(NSMutableData *)data {
NSDictionary *dict = [L2DataParse L2_ParseData:data type:blecmd];
BleCMD reportCMD = [dict[@"DataType"] integerValue];
[[NSNotificationCenter defaultCenter] postNotificationName:DeviceReportRealTimeHealthData object:@(reportCMD) userInfo:dict];
}
/**
检查data中某个字节中的某位的值 1:YES 0:NO
@param data 数据包
@param byteIndex 字节的下标
@param bitIndex 位的下标(从左到又)
*/
- (BOOL)checkDataWithData:(NSMutableData *)data ByteIndex:(NSInteger)byteIndex bitIndex:(NSInteger)bitIndex {
int num = ((Byte*)([data bytes]))[byteIndex];
UInt8 confirm = (UInt8)num;
confirm = confirm << bitIndex;
confirm = confirm >> 7;
return confirm;
}
/**
CRC校验成功或失败后回复设备端
*/
- (void)checkCRCHandleWithData:(NSMutableData *)data confirm:(BOOL)confirm {
if(data.length <=12) { //l1层就有13个字节了。不够长的数据是垃圾数据
return;
}
Byte byte = confirm == YES ? [BluetoothTool stitchWithErr:1 Ack:1 Vision:0] : [BluetoothTool stitchWithErr:0 Ack:1 Vision:0];
// 替换L1层第二个字节
[data replaceBytesInRange:NSMakeRange(1, 1) withBytes:&byte length:1];
// 替换长度为不带参数的5
Byte buffer[2];
buffer[0] = 5 >> 8;
buffer[1] = 5 & 0xff;
[data replaceBytesInRange:NSMakeRange(2, 2) withBytes:buffer length:2];
Byte dataLength[2];
dataLength[0] = 0;
dataLength[1] = 0;
[data replaceBytesInRange:NSMakeRange(11, 2) withBytes:dataLength length:2];
// NSLog(@"发送给设备端的确认码--------%@ 是否正确:%d",[data subdataWithRange:NSMakeRange(0, 13)],confirm);
// 发送L1层确认码给设备端
[self.reconnectPeripheral writeValue:[data subdataWithRange:NSMakeRange(0, 13)] forCharacteristic:self.writecharacteristic type:CBCharacteristicWriteWithoutResponse];
}
/**
获取系统已配对的设备
*/
- (NSMutableArray *)getPairedConnectedArray {
NSMutableArray *connectedArray = [[NSMutableArray alloc] init];
NSArray *braceletDeviceArr = [self.cMgr retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:ServicesUUID]]];
for (NSInteger i = 0; i < braceletDeviceArr.count; i ++) {
CBPeripheral *peripheral = braceletDeviceArr[i];
BLEModel *bleModel = [[BLEModel alloc] initWithCentral:self.cMgr
Peripheral:peripheral
AdvertisementData:0
RSSI:[NSNumber numberWithInteger:0]
UUIDString:peripheral.identifier.UUIDString
MACString:nil];
bleModel.isPaired = YES;
[connectedArray addObject:bleModel];
}
return connectedArray;
}
#pragma mark 杰里升级
/// 打开表盘文件
- (void)openDialFile
{
[DialManager openDialFileSystemWithCmdManager:self.mAssist.mCmdManager withResult:^(DialOperateType type, float progress) {
if (type == DialOperateTypeUnnecessary) {
NSLog(@"已开启!");
}
if (type == DialOperateTypeFail || type == DialOperateTypeCmdFail) {
NSLog(@"获取失败!");
}
if (type == DialOperateTypeSuccess) {
NSLog(@"获取成功!");
}
}];
}
-(void)getInfo
{
[self.mAssist.mCmdManager cmdTargetFeatureResult:^(JL_CMDStatus status, uint8_t sn, NSData * _Nullable data) {
JLModel_Device *model = [self.mAssist.mCmdManager outputDeviceModel];
if (status == JL_CMDStatusSuccess) {
JL_OtaStatus upSt = model.otaStatus;
self.mOtaPath = [[NSUserDefaults standardUserDefaults] objectForKey:@"OTAPATH"];
if (upSt == JL_OtaStatusForce) {
NSLog(@"---> 进入强制升级.");
//[JL_Tools delay:5 Task:^{
[self onUpdateOTA];
//}];
return;
}else{
if (model.otaHeadset == JL_OtaHeadsetYES) {
NSLog(@"---> 进入强制升级: OTA另一只耳机.");
// [DFUITools showText:@"需要强制升级!" onView:self.view delay:1.0];
// [JL_Tools post:@"kJL_OTA_CONNECT" Object:nil];
// [JL_Tools delay:5 Task:^{
[self onUpdateOTA];
//}];
return;
}
}
NSLog(@"---> 设备正常使用...");
[self openDialFile];
[JL_Tools mainTask:^{
//[DFUITools showText:@"设备正常使用" onView:self.view delay:1.0];
/*--- 获取公共信息 ---*/
[self.mAssist.mCmdManager cmdGetSystemInfo:JL_FunctionCodeCOMMON Result:nil];
}];
}else{
NSLog(@"---> ERROR:设备信息获取错误!");
}
}];
}
#pragma mark - OTA升级监听超时定时器(也可不监听超时)
static NSTimer *otaTimer = nil;
static int otaTimeout= 0;
static NSTimer *jlTimer = nil;
- (void)otaTimeCheck {
otaTimeout = 0;
if (otaTimer == nil) {
otaTimer = [JL_Tools timingStart:@selector(otaTimeAdd) target:self Time:1.0];
}
}
#pragma mark 关闭超时检测
- (void)otaTimeClose {
[JL_Tools timingStop:otaTimer];
otaTimeout = 0;
otaTimer = nil;
}
- (void)otaTimeAdd {
otaTimeout++;
if (otaTimeout == 10) {
[self otaTimeClose];
NSLog(@"OTA ---> 超时了!!!");
[SVProgressHUD showErrorWithStatus:@"升级超时"];
}
}
/////////////////////////////////////////
- (void)ljTimeCheck {
if (jlTimer == nil) {
jlTimer = [JL_Tools timingStart:@selector(scanForPeripherals) target:self Time:1.0];
}
}
- (void)scanForPeripherals
{
[self scanForPeripheralsWithdiscoverServices:nil IsDFU:YES];
}
- (void)jlTimeClose
{
[JL_Tools timingStop:jlTimer];
jlTimer = nil;
}
- (void)otaFuncWithFilePaths:(NSString *)otaFilePath
{
[[NSUserDefaults standardUserDefaults] setObject:otaFilePath forKey:@"OTAPATH"];
self.mOtaPath = otaFilePath;
NSString *lastZip = [[self.mOtaPath lastPathComponent] stringByReplacingOccurrencesOfString:@".zip" withString:@""];
NSString *lastPath = [JL_Tools listPath:NSDocumentDirectory MiddlePath:lastZip File:@""];
[JL_Tools removePath:lastPath];
// [self.mTimer threadContinue];
NSArray *zipArr = [FatfsObject unzipFileAtPath:self.mOtaPath toDestination:lastPath];
if (zipArr.count == 0) {
[SVProgressHUD showErrorWithStatus:@"文件解压出错"];
return;
}
if (zipArr.count > 1)
{
[DialManager listFile:^(DialOperateType type, NSArray * _Nullable array) {
if (type == DialOperateTypeSuccess && array.count > 0)
{
self.mWatchList = array;
[JL_Tools subTask:^{
[self onUpdateResource:^{
[self onUpdateOTA];
}];
}];
}
}];
}
else
{
/*--- 只需要【OTA升级】 ---*/
[JL_Tools mainTask:^{
[self onUpdateOTA];
}];
}
}
- (void)onUpdateOTA
{
NSData *otaData = [self outputDataOfOtaPath:self.mOtaPath];
__weak typeof(self) weakSelf = self;
[self.mAssist.mCmdManager.mOTAManager cmdOTAData:otaData Result:^(JL_OTAResult result, float progress) {
if (result == JL_OTAResultUpgrading || result == JL_OTAResultPreparing)
{
NSString *txt = [NSString stringWithFormat:@"%.1f%%",progress*100.0f];
if (result == JL_OTAResultPreparing)
{
NSLog(@"JL-校验文件中 %@",txt);
[SVProgressHUD showWithStatus:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"校验文件", nil),txt]];
}
if (result == JL_OTAResultUpgrading)
{
NSLog(@"JL-正在升级 %@",txt);
[SVProgressHUD showWithStatus:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"正在升级", nil),txt]];
}
[self otaTimeCheck];//增加超时检测
}
else if (result == JL_OTAResultPrepared)
{
NSLog(@"JL----> 检验文件【完成】");
[self otaTimeCheck];//增加超时检测
}
else if (result == JL_OTAResultReconnect)
{
NSLog(@"JL----> OTA正在回连设备... ");
[self startAndStopReconnect:YES];
[self otaTimeCheck];//关闭超时检测
}
else if (result == JL_OTAResultReconnectWithMacAddr)
{
[SVProgressHUD dismiss];
[SVProgressHUD showWithStatus:NSLocalizedString(@"正在重新连接", nil)];
JLModel_Device *model = [self.mAssist.mCmdManager outputDeviceModel];
NSLog(@"JL----> OTA正在通过Mac Addr方式回连设备... \n%@",model);
//[self startAndStopReconnect:YES];
self.lastBleMacAddress = model.bleAddr;
self.is_JL = YES;
[self ljTimeCheck];
[self otaTimeCheck];//关闭超时检测
}
else if (result == JL_OTAResultReboot)
{
[SVProgressHUD dismiss];
//[SVProgressHUD showWithStatus:NSLocalizedString(@"设备重启,正在回连", nil)];
NSLog(@"JL---->设备重启.");
[self otaTimeClose];//关闭超时检测
}
else if (result == JL_OTAResultSuccess || result == JL_OTAResultFail)
{
if ([weakSelf.jl_delegate respondsToSelector:@selector(otaProgressWithOtaResult:withProgress:)]) {
[weakSelf.jl_delegate otaProgressWithOtaResult:result withProgress:progress];
}
}
else
{
[SVProgressHUD showErrorWithStatus:NSLocalizedString(@"发生错误,升级失败", nil)];
// 其余错误码详细 Command+点击JL_OTAResult 查看说明
NSLog(@"JL-ota update result: %d", result);
}
}];
}
- (void)startScanBLE
{
NSLog(@"BLE ---> startScanBLE.");
if (self.cMgr) {
if (self.cMgr.state == CBManagerStatePoweredOn) {
[self.cMgr scanForPeripheralsWithServices:nil options:nil];
} else {
__weak typeof(self) weakSelf = self;
dispatch_after(0.5, dispatch_get_main_queue(), ^{
if (weakSelf.cMgr.state == CBManagerStatePoweredOn) {
[weakSelf.cMgr scanForPeripheralsWithServices:nil options:nil];
}
});
}
}
}
- (NSData*)outputDataOfOtaPath:(NSString*)path
{
NSString *folderName = [[path lastPathComponent] stringByReplacingOccurrencesOfString:@".zip" withString:@""];
NSString *zipPath = [JL_Tools listPath:NSDocumentDirectory MiddlePath:folderName File:@""];
[FatfsObject unzipFileAtPath:path toDestination:zipPath];
NSArray *zipArray = [JL_Tools subPaths:zipPath];
for (NSString *name in zipArray)
{
if ([name hasSuffix:@".ufw"])
{
NSString *otaPath = [JL_Tools listPath:NSDocumentDirectory MiddlePath:folderName File:name];
NSLog(@"---->Start OTA:%@ ",otaPath);
NSData *otaData = [[NSData alloc] initWithContentsOfFile:otaPath];
return otaData;
}
else
{
}
}
return nil;
}
typedef void(^OTA_VIEW_BK)(void);
-(void)onUpdateResource:(OTA_VIEW_BK __nullable)result
{
self.isOtaUpdate = YES;
JL_ManagerM *mCmdManager = self.mAssist.mCmdManager;
/*--- 更新资源标志 ---*/
[mCmdManager.mFlashManager cmdWatchUpdateResource];
/*--- 展示手表更新资源UI ---*/
NSLog(@"--->Fats Update UI.(OTA)");
__block uint8_t m_flag = 0;
[mCmdManager.mFlashManager cmdUpdateResourceFlashFlag:JL_FlashOperateFlagStart
Result:^(uint8_t flag) {
m_flag = flag;
}];
if (m_flag != 0) {
[JL_Tools mainTask:^{
//[DFUITools showText:@"升级请求失败!" onView:self.view delay:1.0];
[SVProgressHUD showErrorWithStatus:NSLocalizedString(@"升级请求失败!", nil)];
}];
self.isOtaUpdate = NO;
return;
}
[DialManager updateResourcePath:self.mOtaPath List:self.mWatchList
Result:^(DialUpdateResult updateResult,
NSArray * _Nullable array,
NSInteger index, float progress){
[JL_Tools mainTask:^{
if (updateResult == DialUpdateResultReplace) {
[self otaTimeCheck];//增加超时检测
NSString *fileName = array[index];
[SVProgressHUD showWithStatus:[NSString stringWithFormat:@"正在更新表盘:%@(%d/%lu)\n%.1f%%",
fileName,(int)index+1,(unsigned long)array.count,progress*100.0]];
return;
}
if (updateResult == DialUpdateResultAdd)
{
[self otaTimeCheck];//增加超时检测
NSString *fileName = array[index];
[SVProgressHUD showWithStatus:[NSString stringWithFormat:@"正在传输新表盘%@(%d/%lu)\n%.1f%%",
fileName,(int)index+1,(unsigned long)array.count,progress*100.0]];
return;
}
if (updateResult == DialUpdateResultFinished) self.otaString = @"资源更新完成";
if (updateResult == DialUpdateResultNewest) self.otaString = @"资源已是最新";
if (updateResult == DialUpdateResultInvalid) self.otaString = @"无效资源文件";
if (updateResult == DialUpdateResultEmpty) self.otaString = @"资源文件为空";
if (updateResult == DialUpdateResultNoSpace) self.otaString = @"资源升级空间不足";
if (updateResult == DialUpdateResultZipError) self.otaString = @"ZIP资源文件错误";
[SVProgressHUD showErrorWithStatus:self.otaString];
// [JL_Tools delay:1.0 Task:^{
// [SVProgressHUD showErrorWithStatus:NSLocalizedString(self.otaString, nil)];
// if (result) result();
// }];
}];
}];
}
- (void)downloadZipUrl:(NSString *)url updatePath:(NSString *)path
{
[[User_Http shareInstance] downloadUrl:url Path:path Result:^(float progress, JLHTTP_Result result) {
[JL_Tools mainTask:^{
//self.updateTxt.text = kJL_TXT("下载固件");
if (result == JLHTTP_ResultDownload) {
// self.progressTxt.text = [NSString stringWithFormat:@"%.1f%%",progress*100.0];
// self.progressView.progress = progress;
//[DFUITools showTransparentHUDOnWindowWithLabel:[NSString stringWithFormat:@"%.1f%%",progress*100.0]];
[SVProgressHUD showWithStatus:[NSString stringWithFormat:@"%@ %.1f%%",NSLocalizedString(@"下载中", nil),progress*100.0]];
}
if (result == JLHTTP_ResultSuccess) {
/*--- 现在完直接升级 ---*/
[self otaFuncWithFilePaths:path];
}
if (result == JLHTTP_ResultFail) {
[SVProgressHUD showErrorWithStatus:@"下载失败"];
}
}];
}];
}
@end