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}