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.
454 lines
16 KiB
454 lines
16 KiB
// |
|
// JL_RunSDK.m |
|
// JL_OTA_InnerBle |
|
// |
|
// Created by 凌煊峰 on 2021/10/9. |
|
// |
|
|
|
#import "JL_RunSDK.h" |
|
#import "Bluetooth.h" |
|
#import <SVProgressHUD/SVProgressHUD.h> |
|
|
|
|
|
@interface JL_RunSDK() <JL_ManagerMDelegate> |
|
|
|
@property (strong, nonatomic) NSString *selectedOtaFilePath; |
|
|
|
/// 手表表盘资源文件 |
|
@property (nonatomic ,strong) NSArray *mWatchList; |
|
|
|
/// 是否正在升级 |
|
@property (nonatomic ,assign) BOOL isOtaUpdate; |
|
|
|
/// <#arguments#> |
|
@property (nonatomic ,strong) NSString *mOtaPath; |
|
|
|
@property (nonatomic ,strong) NSString *otaString; |
|
|
|
@property (nonatomic ,strong) JL_Timer *mTimer; |
|
|
|
@end |
|
|
|
@implementation JL_RunSDK |
|
|
|
static JL_RunSDK *singleton = nil; |
|
+ (instancetype)sharedInstance { |
|
static dispatch_once_t onceToken; |
|
dispatch_once(&onceToken, ^{ |
|
singleton = [[self alloc] init]; |
|
}); |
|
return singleton; |
|
} |
|
|
|
- (instancetype)init |
|
{ |
|
self = [super init]; |
|
if (self) { |
|
self.bt_ble = [[Bluetooth alloc] init]; |
|
self.mTimer = [[JL_Timer alloc] init]; |
|
} |
|
return self; |
|
} |
|
|
|
+(BOOL)isConnectDevice |
|
{ |
|
JL_RunSDK *bleSDK = [JL_RunSDK sharedInstance]; |
|
Bluetooth *bt_ble = bleSDK.bt_ble; |
|
|
|
/*--- 判断是否已连接设备 ---*/ |
|
if (bt_ble.currenModel == nil) { |
|
[SVProgressHUD showErrorWithStatus:@"请先连设备!"]; |
|
// UIWindow *win = [DFUITools getWindow]; |
|
// [DFUITools showText: onView:win delay:1.0]; |
|
return NO; |
|
} |
|
return YES; |
|
} |
|
|
|
|
|
+(BOOL)isNeedUpdateResource{ |
|
|
|
/*--- 设备信息 ---*/ |
|
JL_ManagerM *mCmdManager = singleton.bt_ble.mAssist.mCmdManager; |
|
JLModel_Device *model = [mCmdManager outputDeviceModel]; |
|
|
|
/*--- BLE是否需要更新资源 ---*/ |
|
if (model.otaWatch == JL_OtaWatchYES) { |
|
[SVProgressHUD showErrorWithStatus:@"需要升级手表!"]; |
|
// UIWindow *win = [DFUITools getWindow]; |
|
// [DFUITools showText:@"需要升级手表!" onView:win delay:1.0]; |
|
return YES; |
|
} |
|
return NO; |
|
} |
|
|
|
+(BOOL)isNeedUpdateResource_1{ |
|
|
|
/*--- 设备信息 ---*/ |
|
JL_ManagerM *mCmdManager = singleton.bt_ble.mAssist.mCmdManager; |
|
JLModel_Device *model = [mCmdManager outputDeviceModel]; |
|
|
|
/*--- BLE是否需要更新资源 ---*/ |
|
if (model.otaWatch == JL_OtaWatchYES) { |
|
return YES; |
|
} |
|
return NO; |
|
} |
|
|
|
+(BOOL)isNeedUpdateOTA{ |
|
/*--- 设备信息 ---*/ |
|
JL_ManagerM *mCmdManager = singleton.bt_ble.mAssist.mCmdManager; |
|
JLModel_Device *model = [mCmdManager outputDeviceModel]; |
|
|
|
/*--- BLE是否需要OTA升级 ---*/ |
|
if (model.otaStatus == JL_OtaStatusForce) { |
|
// UIWindow *win = [DFUITools getWindow]; |
|
// [DFUITools showText:@"需要升级手表!" onView:win delay:1.0]; |
|
|
|
[SVProgressHUD showErrorWithStatus:@"需要升级手表!"]; |
|
return YES; |
|
} |
|
return NO; |
|
} |
|
|
|
+(BOOL)isNeedUpdateOTA_1{ |
|
/*--- 设备信息 ---*/ |
|
JL_ManagerM *mCmdManager = singleton.bt_ble.mAssist.mCmdManager; |
|
JLModel_Device *model = [mCmdManager outputDeviceModel]; |
|
|
|
/*--- BLE是否需要OTA升级 ---*/ |
|
if (model.otaStatus == JL_OtaStatusForce) { |
|
return YES; |
|
} |
|
return NO; |
|
} |
|
|
|
- (void)otaFuncWithFilePath:(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.bt_ble.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(@"校验文件中 %@",txt); |
|
if (result == JL_OTAResultUpgrading) NSLog(@"正在升级 %@",txt); |
|
|
|
[self otaTimeCheck];//增加超时检测 |
|
} else if (result == JL_OTAResultPrepared) { |
|
NSLog(@"---> 检验文件【完成】"); |
|
[self otaTimeCheck];//增加超时检测 |
|
} else if (result == JL_OTAResultReconnect) { |
|
NSLog(@"---> OTA正在回连设备... "); |
|
[self otaTimeCheck];//关闭超时检测 |
|
} else if (result == JL_OTAResultReconnectWithMacAddr) { |
|
NSLog(@"---> OTA正在通过Mac Addr方式回连设备... "); |
|
|
|
[self otaTimeCheck];//关闭超时检测 |
|
} else if (result == JL_OTAResultSuccess) { |
|
NSLog(@"--->升级成功."); |
|
|
|
} else if (result == JL_OTAResultReboot) { |
|
NSLog(@"--->设备重启."); |
|
[self otaTimeClose];//关闭超时检测 |
|
} else if (result == JL_OTAResultFail) { |
|
|
|
[self otaTimeClose]; |
|
NSLog(@"--->升级失败"); |
|
|
|
}else { |
|
// 其余错误码详细 Command+点击JL_OTAResult 查看说明 |
|
NSLog(@"ota update result: %d", result); |
|
} |
|
|
|
|
|
if ([weakSelf.delegate respondsToSelector:@selector(otaProgressWithOtaResult:withProgress:)]) { |
|
[weakSelf.delegate otaProgressWithOtaResult:result withProgress:progress]; |
|
} |
|
}]; |
|
} |
|
|
|
|
|
- (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 = Bluetooth.shareInstance.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)transportFile:(NSString*)path fileName:(NSString *)fileName Result:(void(^_Nullable)(JL_BigFileResult result, float progress))callback |
|
{ |
|
JL_ManagerM *mCmdManager = Bluetooth.shareInstance.mAssist.mCmdManager; |
|
///设置需要Unicode命名⻓⽂件名 |
|
[mCmdManager.mFileManager setIsOtherEncode:true]; |
|
///设置编码格式 |
|
[mCmdManager.mFileManager setEncodeType:NSUTF16LittleEndianStringEncoding]; |
|
JLModel_Device *deviceModel = [mCmdManager outputDeviceModel]; |
|
if (deviceModel.audioFileType == JL_AudioFileTypeYES) |
|
{ |
|
|
|
} |
|
[JL_Tools mainTask:^{ |
|
[mCmdManager.mFileManager setCurrentFileHandleType:[self getMusicTargetDev:deviceModel]]; |
|
//设置设备的环境变量 |
|
[mCmdManager.mFileManager cmdPreEnvironment:0x00 Result:^(JL_CMDStatus status, uint8_t sn, NSData * _Nullable data) { |
|
if (status == JL_CMDStatusSuccess) |
|
{ |
|
//大文件传输API |
|
[mCmdManager.mFileManager cmdBigFileData:path WithFileName:fileName Result:^(JL_BigFileResult result,float progress) { |
|
callback(result,progress); |
|
if (result == JL_BigFileTransferEnd) |
|
{ |
|
NSLog(@"传输完成,清除播放列表缓存"); |
|
[mCmdManager.mFileManager cmdCleanCacheType:[self getCardTypeDev:deviceModel]]; |
|
// [self loadRootFiles]; |
|
} |
|
}]; |
|
} |
|
}]; |
|
|
|
// [JL_Tools delay:2.0 Task:^{ |
|
// [self stopTransport]; |
|
// }]; |
|
|
|
}]; |
|
} |
|
|
|
|
|
|
|
- (void)stopTransport |
|
{ |
|
JL_ManagerM *mCmdManager = Bluetooth.shareInstance.mAssist.mCmdManager; |
|
[mCmdManager.mFileManager cmdStopBigFileData]; |
|
} |
|
|
|
static NSTimer *otaTimer = nil; |
|
static int otaTimeout= 0; |
|
-(void)otaTimeCheck{ |
|
otaTimeout = 0; |
|
if (otaTimer == nil) { |
|
otaTimer = [JL_Tools timingStart:@selector(otaTimeAdd) |
|
target:self Time:1.0]; |
|
} |
|
} |
|
|
|
-(void)otaTimeClose{ |
|
[JL_Tools timingStop:otaTimer]; |
|
otaTimeout = 0; |
|
otaTimer = nil; |
|
} |
|
|
|
-(void)otaTimeAdd{ |
|
otaTimeout++; |
|
if (otaTimeout == 20) { |
|
self.isOtaUpdate = NO; |
|
[self otaTimeClose]; |
|
[SVProgressHUD showErrorWithStatus:NSLocalizedString(@"OTA升级超时", nil)]; |
|
NSLog(@"OTA ---> 超时了!!!"); |
|
// [self removeOTAzip]; |
|
} |
|
} |
|
|
|
|
|
/** |
|
* 获取音乐文件传输句柄 |
|
*/ |
|
- (JL_FileHandleType)getMusicTargetDev:(JLModel_Device*)deviceModel { |
|
|
|
if ([deviceModel.cardArray containsObject:@(JL_CardTypeSD_1)]) { |
|
return JL_FileHandleTypeSD_1; |
|
} else if ([deviceModel.cardArray containsObject:@(JL_CardTypeSD_0)] && [deviceModel.cardArray containsObject:@(JL_CardTypeSD_1)]) { |
|
return JL_FileHandleTypeSD_1; |
|
} else if ([deviceModel.cardArray containsObject:@(JL_CardTypeSD_0)]) { |
|
return JL_FileHandleTypeSD_0; |
|
} else if ([deviceModel.cardArray containsObject:@(JL_CardTypeUSB)]) { |
|
return JL_FileHandleTypeUSB; |
|
} |
|
return JL_FileHandleTypeSD_1; |
|
} |
|
|
|
|
|
/** |
|
* 获取音乐文件传输句柄 |
|
*/ |
|
- (JL_CardType)getCardTypeDev:(JLModel_Device*)deviceModel { |
|
|
|
if ([deviceModel.cardArray containsObject:@(JL_CardTypeSD_1)]) { |
|
return JL_CardTypeSD_1; |
|
} else if ([deviceModel.cardArray containsObject:@(JL_CardTypeSD_0)] && [deviceModel.cardArray containsObject:@(JL_CardTypeSD_1)]) { |
|
return JL_CardTypeSD_1; |
|
} else if ([deviceModel.cardArray containsObject:@(JL_CardTypeSD_0)]) { |
|
return JL_CardTypeSD_0; |
|
} else if ([deviceModel.cardArray containsObject:@(JL_CardTypeUSB)]) { |
|
return JL_CardTypeUSB; |
|
} |
|
return JL_CardTypeSD_1; |
|
} |
|
|
|
-(void)loadRootFiles |
|
{ |
|
JL_ManagerM *mCmdManager = Bluetooth.shareInstance.mAssist.mCmdManager; |
|
// JLModel_Device *deviceModel = [mCmdManager outputDeviceModel]; |
|
// |
|
// JLModel_File *fileModel = [JLModel_File new]; |
|
// fileModel.fileType = JL_BrowseTypeFolder; |
|
// fileModel.cardType = JL_CardTypeSD_1; |
|
// fileModel.fileHandle = deviceModel.handleSD_1; |
|
// fileModel.fileName = @"SD Card"; |
|
// fileModel.folderName = @"SD Card"; |
|
// fileModel.fileClus = 0; |
|
// |
|
// //读取目录 |
|
// [mCmdManager.mFileManager cmdBrowseModel:fileModel Number:10 Result:nil]; |
|
|
|
[mCmdManager cmdGetSystemInfo:JL_FunctionCodeCOMMON |
|
SelectionBit:0x04 |
|
Result:nil]; |
|
|
|
[mCmdManager.mFileManager cmdBrowseMonitorResult:^(NSArray * _Nullable array, JL_BrowseReason reason) { |
|
switch (reason) { |
|
case JL_BrowseReasonReading:{ |
|
NSLog(@"---> 正在读取:%@",array); |
|
}break; |
|
case JL_BrowseReasonCommandEnd:{ |
|
NSLog(@"读取命令结束:%lu",(unsigned long)array.count); |
|
}break; |
|
case JL_BrowseReasonFolderEnd:{ |
|
NSLog(@"---> 目录读取结束:%lu",(unsigned long)array.count); |
|
}break; |
|
case JL_BrowseReasonBusy:{ |
|
NSLog(@"设备在忙"); |
|
}break; |
|
case JL_BrowseReasonDataFail:{ |
|
NSLog(@"数据读取失败"); |
|
}break; |
|
case JL_BrowseReasonPlaySuccess:{ |
|
NSLog(@"---> 播放成功"); |
|
}break; |
|
case JL_BrowseReasonUnknown:{ |
|
NSLog(@"未知错误"); |
|
} |
|
default: |
|
break; |
|
} |
|
}]; |
|
|
|
} |
|
|
|
|
|
@end
|
|
|