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.
455 lines
16 KiB
455 lines
16 KiB
![]()
2 years ago
|
//
|
||
|
// 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
|