3.使用JL_BLEKit.framework蓝牙连接方式
以下实现方法兼容于JL_BLEKit.framework的老版本:V1.7.0/1.6.3/1.6.4
区别于旧版SDK,新版JL_BLEKit.framework依赖于其他的SDK,所以在导入时应包含以下:
JL_OTALib.framework——OTA升级业务库
JL_AdvParse.framework——杰理蓝牙设备广播包解析业务库
JL_HashPair.framework——设备认证业务库
重要
在OTA过程中不允许进行其他命令的交互
3.1. SDK外部蓝牙管理
外部蓝牙管理,在使用JL_BLEKit.framework的同时,在蓝牙管理部分交由 外边(开发者自定义蓝牙)统筹管理 ,可保障使用时的多样化。
参考Demo:「 JL_OTA项目的 BleByAssist文件夹」 支持的功能 :
BLE设备握手连接;
获取设备信息;
OTA升级能实现;
注意:相对于 3.2.2 中描述的所有BLE操作都需自行实现;
会用到的类 :
JL_Assist :部署SDK类;(必须)
JL_ManagerM :命令处理中心,所有的命令操作都集中于此;(必须)
JLModel_Device :设备信息存储的数据模型;(必须)
BLE参数 :
【服务号】 :AE00
【写】特征值 :AE01
【读 】特征值 :AE02
3.1.1. 初始化SDK
1 /*--- JLSDK ADD ---*/
2 _mAssist = [[JL_Assist alloc] init];
3 _mAssist.mNeedPaired = _isPaired; //是否需要握手配对
4 /*--- 自定义配对码(16个字节配对码) ---*/
5 //char pairkey[16] = {0x01,0x02,0x03,0x04,
6 // 0x01,0x02,0x03,0x04,
7 // 0x01,0x02,0x03,0x04,
8 // 0x01,0x02,0x03,0x04};
9 //NSData *pairData = [NSData dataWithBytes:pairkey length:16];
10 _mAssist.mPairKey = nil; //配对秘钥(或者自定义配对码pairData)
11 _mAssist.mService = FLT_BLE_SERVICE; //服务号
12 _mAssist.mRcsp_W = FLT_BLE_RCSP_W; //特征「写」
13 _mAssist.mRcsp_R = FLT_BLE_RCSP_R; //特征「读」
3.1.2. BLE设备特征回调
1#pragma mark - 设备特征回调
2- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service
3 error:(nullable NSError *)error
4{
5 if (error) { NSLog(@"Err: Discovered Characteristics fail."); return; }
6
7 /*--- JLSDK ADD ---*/
8 [self.mAssist assistDiscoverCharacteristicsForService:service Peripheral:peripheral];
9}
3.1.3. BLE更新通知特征的状态
1#pragma mark - 更新通知特征的状态
2- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(nonnull CBCharacteristic *)characteristic
3 error:(nullable NSError *)error
4{
5 if (error) { NSLog(@"Err: Update NotificationState For Characteristic fail."); return; }
6
7 /*--- JLSDK ADD ---*/
8 __weak typeof(self) weakSelf = self;
9 [self.mAssist assistUpdateCharacteristic:characteristic Peripheral:peripheral Result:^(BOOL isPaired) {
10 if (isPaired == YES) {
11 weakSelf.lastUUID = peripheral.identifier.UUIDString;
12 weakSelf.lastBleMacAddress = nil;
13
14 weakSelf.mBlePeripheral = peripheral;
15 /*--- UI配对成功 ---*/
16 [JL_Tools post:kFLT_BLE_PAIRED Object:peripheral];
17 } else {
18 [weakSelf.bleManager cancelPeripheralConnection:peripheral];
19 }
20 }];
21}
3.1.4. BLE设备返回的数据
1#pragma mark - 设备返回的数据 GET
2- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
3 error:(NSError *)error
4{
5 if (error) { NSLog(@"Err: receive data fail."); return; }
6
7 /*--- JLSDK ADD ---*/
8 [self.mAssist assistUpdateValueForCharacteristic:characteristic];
9}
3.1.5. BLE设备断开连接
1#pragma mark - 设备断开连接
2- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral
3 error:(nullable NSError *)error
4{
5 NSLog(@"BLE Disconnect ---> Device %@ error:%d", peripheral.name, (int)error.code);
6 self.mBlePeripheral = nil;
7
8 /*--- JLSDK ADD ---*/
9 [self.mAssist assistDisconnectPeripheral:peripheral];
10
11 /*--- UI刷新,设备断开 ---*/
12 [JL_Tools post:kFLT_BLE_DISCONNECTED Object:peripheral];
13}
3.1.6. 手机蓝牙状态更新
1//外部蓝牙,手机蓝牙状态回调处,实现以下:
2#pragma mark - 蓝牙初始化 Callback
3- (void)centralManagerDidUpdateState:(CBCentralManager *)central
4{
5 _mBleManagerState = central.state;
6
7 /*--- JLSDK ADD ---*/
8 [self.mAssist assistUpdateState:central.state];
9
10 if (_mBleManagerState != CBManagerStatePoweredOn) {
11 self.mBlePeripheral = nil;
12 self.blePeripheralArr = [NSMutableArray array];
13 }
14}
3.1.7. 获取设备信息
BLE连接且配对后必须执行一次
1 [self.mAssist.mCmdManager cmdTargetFeatureResult:^(NSArray * _Nullable array) {
2 JL_CMDStatus st = [array[0] intValue];
3 if (st == JL_CMDStatusSuccess) {
4 JLModel_Device *model = [weakSelf.mAssist.mCmdManager outputDeviceModel];
5 JL_OtaStatus upSt = model.otaStatus;
6 if (upSt == JL_OtaStatusForce) {
7 NSLog(@"---> 进入强制升级.");
8 if (weakSelf.selectedOtaFilePath) {
9 [weakSelf otaFuncWithFilePath:weakSelf.selectedOtaFilePath];
10 } else {
11 callback(true);
12 }
13 return;
14 } else {
15 if (model.otaHeadset == JL_OtaHeadsetYES) {
16 NSLog(@"---> 进入强制升级: OTA另一只耳机.");
17 if (weakSelf.selectedOtaFilePath) {
18 [weakSelf otaFuncWithFilePath:weakSelf.selectedOtaFilePath];
19 } else {
20 callback(true);
21 }
22 return;
23 }
24 }
25 NSLog(@"---> 设备正常使用...");
26 [JL_Tools mainTask:^{
27 /*--- 获取公共信息 ---*/
28 [weakSelf.mAssist.mCmdManager cmdGetSystemInfo:JL_FunctionCodeCOMMON Result:nil];
29 }];
30 } else {
31 NSLog(@"---> ERROR:设备信息获取错误!");
32 }
33}];
3.1.8. 固件OTA升级
1//升级流程:连接设备-->获取设备信息-->是否强制升级-->(是)则必须调用该API去OTA升级;
2 // (否)则可以正常使用APP;
3
4 NSLog(@"current otaFilePath ---> %@", otaFilePath);
5self.selectedOtaFilePath = otaFilePath;
6NSData *otaData = [[NSData alloc] initWithContentsOfFile:otaFilePath];
7
8JL_OTAManager *otaManager = self.mAssist.mCmdManager.mOTAManager;
9
10[otaManager cmdOTAData:otaData Result:^(JL_OTAResult result, float progress) {
11
12 if (result == JL_OTAResultUpgrading || result == JL_OTAResultPreparing) {
13 if (result == JL_OTAResultPreparing) NSLog(@"---> 校验文件中");;
14 if (result == JL_OTAResultUpgrading) NSLog(@"---> 正在升级");
15 } else if (result == JL_OTAResultPrepared) {
16 NSLog(@"---> 检验文件【完成】");
17 } else if (result == JL_OTAResultReconnect) {
18
19 NSLog(@"---> OTA正在回连设备... %@", self.mAssist.mCmdManager);
20
21 //TODO: 这里需要开发者自行操作回连设备的UUIDString
22
23 [self otaTimeClose];//关闭超时检测
24 } else if (result == JL_OTAResultReconnectWithMacAddr) {
25
26 NSLog(@"---> OTA正在通过Mac Addr方式回连设备... %@", [JLBleManager sharedInstance].mBlePeripheral.name);
27 JLModel_Device *model = [self.mAssist.mCmdManager outputDeviceModel];
28
29 //TODO: 开发者需要利用这里的model.bleAddr地址去搜索回连已经升级了一半的设备,然后继续发起查询,再完成升级
30
31 [self otaTimeClose];//关闭超时检测
32 } else if (result == JL_OTAResultSuccess) {
33 NSLog(@"--->升级成功.");
34 } else if (result == JL_OTAResultReboot) {
35 NSLog(@"--->设备重启.");
36 } else {
37 // 其余错误码详细 Command+点击JL_OTAResult 查看说明
38 NSLog(@"ota update result: %d", result);
39 }
40
41}];
3.2. SDK内部蓝牙管理
以下实现方法基于JL_BLEKit.framework的内部集成蓝牙连接方法,开发者无需管理蓝牙对象,只专注升级业务即可。
参考Demo:「 JL_OTA项目的 SDKBleManager文件夹」
1. 支持的功能 :
BLE设备的扫描、连接、断开、收发数据、回连功能;
BLE设备过滤;
BLE设备握手连接;
BLE连接服务和特征值设置;
获取设备信息;
OTA升级能实现;
2. 会用到的类 :
JL_BLEUsage :可设置BLE过滤、握手、参数;查看蓝牙状态;
JL_Entity :BLE设备的模型类,记录设备的相关信息(如名字、UUID、UID、PID等);
JL_BLEMultiple :BLE扫描、连接、断开、回连;
JL_ManagerM :获取设备信息、OTA操作;
3.2.1. 初始化SDK
1self.mBleMultiple = [[JL_BLEMultiple alloc] init];
2self.mBleMultiple.BLE_FILTER_ENABLE = YES; // 过滤非杰理蓝牙设备
3 // self.mBleMultiple.filterKey = nil; // 一般情况赋值nil即可
4self.mBleMultiple.BLE_PAIR_ENABLE = YES;
5 /*--- 自定义配对码(16个字节配对码) ---*/
6//char pairkey[16] = {0x01,0x02,0x03,0x04,
7// 0x01,0x02,0x03,0x04,
8// 0x01,0x02,0x03,0x04,
9// 0x01,0x02,0x03,0x04};
10//NSData *pairData = [NSData dataWithBytes:pairkey length:16];
11// self.mBleMultiple.pairKey = nil; // 配对秘钥(或者自定义配对码pairData)
12self.mBleMultiple.BLE_TIMEOUT = 7;
3.2.2. 扫描设备
1/*--- 搜索蓝牙设备 ---*/
2[[JL_RunSDK sharedInstance].mBleMultiple scanStart];
3
4// 监听通知【kJL_BLE_M_FOUND】【kJL_BLE_M_FOUND_SINGLE】回调设备数组
5[JL_Tools add:kJL_BLE_M_FOUND Action:@selector(reloadTableView) Own:self];
6[JL_Tools add:kJL_BLE_M_FOUND_SINGLE Action:@selector(reloadTableView) Own:self];
7
8 // 获取设备数组
9 - (void)reloadTableView {
10 self.btEnityList = [JL_RunSDK sharedInstance].mBleMultiple.blePeripheralArr;
11 if ([JL_RunSDK sharedInstance].mBleEntityM && ![self.btEnityList containsObject:[JL_RunSDK sharedInstance].mBleEntityM]) {
12 [self.btEnityList insertObject:[JL_RunSDK sharedInstance].mBleEntityM atIndex:0];
13 }
14 [self.subTableView reloadData];
15 }
3.2.3. 连接和断开设备
1//API通过【JL_BLEMultiple】使用
2/**
3连接设备
4@param entity 蓝牙设备类
5*/
6-(void)connectEntity:(JL_EntityM*)entity Result:(JL_EntityM_STATUS_BK)result;
7
8/**
9断开连接
10*/
11-(void)disconnectEntity:(JL_EntityM*)entity Result:(JL_EntityM_STATUS_BK)result;
12
13/**
14* BLE状态通知
15*/
16extern NSString *kJL_BLE_M_FOUND; //发现设备
17extern NSString *kJL_BLE_M_FOUND_SINGLE; //发现单个设备
18extern NSString *kJL_BLE_M_ENTITY_CONNECTED; //连接有更新
19extern NSString *kJL_BLE_M_ENTITY_DISCONNECTED; //断开连接
20extern NSString *kJL_BLE_M_ON; //BLE开启
21extern NSString *kJL_BLE_M_OFF; //BLE关闭
22extern NSString *kJL_BLE_M_EDR_CHANGE; //经典蓝牙输出通道变化
3.2.4. 获取设备信息(必须)
1[[JL_RunSDK sharedInstance] getDeviceInfo:^(BOOL needForcedUpgrade) {
2 if (needForcedUpgrade) {
3 NSLog(@"设备需要强制升级,请到升级界面选择ota升级文件进行升级!");
4 [self startLoadingView:@"设备需要强制升级,请到升级界面选择ota升级文件进行升级!" Delay:1.0];
5 }
6}];
3.2.5. 固件OTA升级
1//升级流程:连接设备-->获取设备信息-->是否强制升级-->
2//(是)则必须调用该API去OTA升级;
3//(否)则可以正常使用APP;
4
5// 设置代理
6@interface JLUpdateViewController () <JL_RunSDKOtaDelegate>
7// 设置ota升级过程状态回调代理
8[JL_RunSDK sharedInstance].otaDelegate = self;
9
10/**
11* 选择文件后,点击启动OTA升级
12*/
13- (IBAction)updateBtnFunc:(id)sender {
14 if (![JL_RunSDK sharedInstance].mBleEntityM) {
15 self.updateSeekLabel.text = @"";
16 [DFUITools showText:@"请先连接设备" onView:self.view delay:1.0];
17 return;
18 }
19
20 /*--- 获取设备信息 ---*/
21 [[JL_RunSDK sharedInstance] otaFuncWithFilePath:_selectFilePath];
22}
23
24#pragma mark - JL_RunSDKOtaDelegate
25
26/**
27* ota升级过程状态回调
28*/
29- (void)otaProgressWithOtaResult:(JL_OTAResult)result withProgress:(float)progress {
30 if (result == JL_OTAResultUpgrading || result == JL_OTAResultPreparing) {
31 if (result == JL_OTAResultPreparing) self.updateLabel.text = @"校验文件中";
32 if (result == JL_OTAResultUpgrading) self.updateLabel.text = @"正在升级";
33 } else if (result == JL_OTAResultPrepared) {
34 NSLog(@"---> 检验文件【完成】");
35 } else if (result == JL_OTAResultReconnect) {
36 NSLog(@"---> OTA正在回连设备... %@", [JL_RunSDK sharedInstance].mBleEntityM.mPeripheral.name);
37 } else if (result == JL_OTAResultReconnectWithMacAddr) {
38 NSLog(@"---> OTA正在通过Mac Addr方式回连设备... %@", [JL_RunSDK sharedInstance].mBleEntityM.mPeripheral.name);
39 } else if (result == JL_OTAResultSuccess) {
40 NSLog(@"--->升级成功.");
41 } else if (result == JL_OTAResultReboot) {
42 NSLog(@"--->设备重启.");
43 } else {
44 // 其余错误码详细 Command+点击JL_OTAResult 查看说明
45 NSLog(@"ota update result: %d", result);
46 }
47}