• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

iOS-JL_Bluetooth: iOS杰理蓝牙SDK接入基础

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

iOS-JL_Bluetooth

开源软件地址:

https://gitee.com/Jieli-Tech/iOS-JL_Bluetooth

开源软件介绍:

iOS杰理蓝牙SDK接入基础

[toc]

  • 对应的芯片类型:AC692x,AC693x,AC695x,BD29
  • APP开发环境:iOS平台,iOS 10.0以上,Xcode 11.0以上
  • 基于「杰理蓝牙控制库SDK v1.5.0 (多设备版)」 开发

声明

  1. 本项⽬所参考、使⽤技术必须全部来源于公知技术信息,或⾃主创新设计。

  2. 本项⽬不得使⽤任何未经授权的第三⽅知识产权的技术信息。

  3. 如个⼈使⽤未经授权的第三⽅知识产权的技术信息,造成的经济损失和法律后果由个⼈承担。

版本

版本日期编辑修改内容
v1.42020年12月17日冯 洪鹏1、手表表盘操作(表盘OTA);
v1.32020年12月11日冯 洪鹏1、重新整理代码框架;
2、增加多设备管理;
v1.22020年12月09日冯 洪鹏更新文档
v1.12020年04月20日冯 洪鹏增加升级的错误回调
v1.02019年09月09日冯 洪鹏OTA升级功能

概述

本文档是为了后续开发者更加便捷移植杰理蓝牙控制功能而创建。

1、导入JL_BLEKit.framework

1、将「 JL_BLEKit.framework 」导入Xcode工程,添加两个权限:

  • Privacy - Bluetooth Peripheral Usage Description
  • Privacy - Bluetooth Always Usage Description

2、SDK具体使用的两种方式:

​ 第一种,使用自定义的蓝牙连接API进行OTA:所有BLE的操作都自行实现,SDK只负责对OTA数据包解析

从而实现OTA功能。

​ 第二种,使用SDK内的蓝牙连接API进行OTA:完全使用SDK。​
​ 3、针对【杰理之家APP】的开发文档,请看《杰理蓝牙控制库_IOS_SDK开发说明》描述杰理之家内部所有功​​ 能的实现。​

4、本工程可Build出的ipa需要iPhone手机系统版本在iOS10.0以上。

2、使用自定义的蓝牙API接入SDK

参考Demo:「OTA_Update_M(外部BLE)

1、支持的功能

  • BLE设备握手连接;
  • 获取设备信息;
  • OTA升级能实现;
  • 注意:所有BLE扫描、连接、断开、重连等操作都需自行实现。

2、接触到的类

  • JL_BLEAction:实现BLE设备握手连接;(可选,需设备支持)
  • JL_Handle:RCSP数据格式分包器;(必须)
  • JL_ManagerM:命令处理中心,所有的命令操作都集中于此;(必须)
  • JLModel_Device:设备信息存储的数据模型;(必须)

3、BLE参数

  • 【服务号】:AE00
  • 【写】特征值:AE01
  • 【读 】特征值:AE02

2.1、初始化SDK

//主要是3个类,分别是配对器、数据分包器、命令中心类/*--- 配对器 ---*/bleAction = [[JL_BLEAction alloc] init];bleAction.delegate = self;        /*--- 数据结构分包 ---*/bleHandle = [[JL_Handle alloc] init];bleHandle.delegate = self;        /*--- 命令处理中心 ---*/self.mCmdManager = [[JL_ManagerM alloc] init];self.mCmdManager.delegate = self;

2.2、BLE握手连接(可选)

/** 蓝牙设备配对 @param pKey 配对码(默认传nil) @param bk   配对回调YES:成功 NO:失败 */-(void)bluetoothPairingKey:(NSData*)pKey Result:(ATC_Block)bk  //外部蓝牙更新通知特征的状态的回调处实现,以下:#pragma mark - 更新通知特征的状态- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(nonnull CBCharacteristic *)characteristic             error:(nullable NSError *)error{    if (error) { NSLog(@"Err: Update NotificationState For Characteristic fail."); return; }    if (characteristic.isNotifying) {        if ([characteristic.UUID.UUIDString containsString:@"AE02"])        {            QCY_BLE_LEN_45 = [peripheral maximumWriteValueLengthForType:CBCharacteristicWriteWithoutResponse];            NSLog(@"BLE ---> MTU:%lu",(unsigned long)QCY_BLE_LEN_45);                                NSData *pairKey = nil;//使用内置默认            [bleAction bluetoothPairingKey:pairKey Result:^(BOOL ret) {                if (ret) {                    self.mBlePeripheral = peripheral;                    self.lastUUID = peripheral.identifier.UUIDString;                    self.mBleName = peripheral.name;                                        [JL_Tools setUser:self.lastUUID forKey:kUUID_BLE_LAST];                                        /*--- 存储名字和UUID ---*/                    [self.mCmdManager setBleUuid:self.lastUUID];                    [self.mCmdManager setBleName:self.mBleName];                                        /*--- 告之SDK,设备连接成功 ---*/                    [JL_Tools post:kJL_BLE_M_ENTITY_CONNECTED Object:peripheral];                                    }else{                    NSLog(@"Err: bluetooth pairing fail.");                    [self->bleManager cancelPeripheralConnection:peripheral];                }            }];                        /*            //不需要握手可以这样处理。                    self.lastUUID = peripheral.identifier.UUIDString;                    self.mBleName = peripheral.name;                                        [JL_Tools setUser:self.lastUUID forKey:kUUID_BLE_LAST];                                        //存储名字和UUID                    [self.mCmdManager setBleUuid:self.lastUUID];                    [self.mCmdManager setBleName:self.mBleName];                                        //告之SDK,设备连接成功                    [JL_Tools post:kJL_BLE_M_ENTITY_CONNECTED Object:peripheral];            */        }    }}

2.3、BLE设备返回的数据传入SDK

//外部蓝牙数据接收处,实现以下:#pragma mark - 设备返回的数据 GET- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic             error:(NSError *)error{    if (error) { NSLog(@"Err: receive data fail."); return; }        NSData *data = characteristic.value;    if (data.length <= 0) { return; }        /*--- 【命令】通道返回的数据 ---*/    if ([characteristic.UUID.UUIDString containsString:QCY_BLE_RCSP_R])    {        /*--- 配对输入 ---*/        [bleAction inputPairData:data];                /*--- RCSP数据结构分包 ---*/        [bleHandle inputHandleData:data];    }}

2.4、实现SDK的Delete方法

#pragma mark -【JL_BLEActionDelegate】配对数据输出-(void)onPairOutputData:(NSData *)data{    [self writeRcspData:data];//使用外部蓝牙发数API}#pragma mark -【JL_HandleDelegate】RCSP数据包-(void)onHandleOutputPKG:(JL_PKG *)pkg{    [self.mCmdManager inputPKG:pkg];}#pragma mark -【JL_ManagerMDelegate】RCSP数据包-(void)onManagerSendPackage:(JL_PKG *)pkg{    NSData *data = [bleHandle sendPackage:pkg WithName:self.mBleName];    [self writeRcspData:data];//使用外部蓝牙发数API}

2.5、设备断开的处理

//外部蓝牙设备断开连接处,实现以下:#pragma mark - 设备断开连接- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral                 error:(nullable NSError *)error{    NSLog(@"BLE Disconnect ---> Device %@ error:%d",peripheral.name,(int)error.code);        /*--- 表盘清除回调 ---*/    [self.mCmdManager cmdFlashActionDisconnect];        /*--- 告之SDK,设备已断开 ---*/    [JL_Tools post:kJL_BLE_M_ENTITY_DISCONNECTED Object:peripheral];}

2.6、手机蓝牙状态传入SDK

//外部蓝牙,手机蓝牙状态回调处,实现以下:#pragma mark - 蓝牙初始化 Callback- (void)centralManagerDidUpdateState:(CBCentralManager *)central{    NSInteger st = central.state;    if (st != CBManagerStatePoweredOn) {        /*--- 表盘清除回调 ---*/        [self.mCmdManager cmdFlashActionDisconnect];                /*--- 告之SDK,手机已关闭蓝牙 ---*/        [JL_Tools post:kJL_BLE_M_OFF Object:@(0)];    }}

2.7、功能实现

2.7.1、获取设备信息

    [bt_ble.mCmdManager cmdTargetFeatureResult:^(NSArray * _Nullable array) {        JL_CMDStatus st = [array[0] intValue];        if (st == JL_CMDStatusSuccess) {            JLModel_Device *model = [self->bt_ble.mCmdManager outputDeviceModel];            JL_OtaStatus upSt = model.otaStatus;            if (upSt == JL_OtaStatusForce) {                NSLog(@"---> 进入强制升级.");                [self noteOtaUpdate:nil];                return;            }else{                if (model.otaHeadset == JL_OtaHeadsetYES) {                    NSLog(@"---> 进入强制升级: OTA另一只耳机.");                    [self noteOtaUpdate:nil];                    return;                }            }            NSLog(@"---> 设备正常使用...");        }else{            NSLog(@"---> ERROR:设备信息获取错误!");        }    }];

2.7.2、固件OTA升级

   //升级流程:连接设备-->获取设备信息-->是否强制升级-->(是)则必须调用该API去OTA升级;     //                                                                        |_______>(否)则可以正常使用APP;                                                                                    NSData *otaData = [[NSData alloc] initWithContentsOfFile:@"OTA升级文件路径"];    [bt_ble.mCmdManager cmdOTAData:otaData Result:^(JL_OTAResult result, float progress) {        if (result == JL_OTAResultSuccess) {            NSLog(@"--->升级成功.");        }        if (result == JL_OTAResultFail) {            NSLog(@"--->OTA升级失败");        }        if (result == JL_OTAResultDataIsNull) {            NSLog(@"--->OTA升级数据为空!");        }        if (result == JL_OTAResultCommandFail) {            NSLog(@"--->OTA指令失败!");        }        if (result == JL_OTAResultSeekFail) {            NSLog(@"--->OTA标示偏移查找失败!");        }        if (result == JL_OTAResultInfoFail) {            NSLog(@"--->OTA升级固件信息错误!");        }        if (result == JL_OTAResultLowPower) {            NSLog(@"--->OTA升级设备电压低!");        }        if (result == JL_OTAResultEnterFail) {            NSLog(@"--->未能进入OTA升级模式!");        }        if (result == JL_OTAResultUnknown) {            NSLog(@"--->OTA未知错误!");        }        if (result == JL_OTAResultFailSameVersion) {            NSLog(@"--->相同版本!");        }        if (result == JL_OTAResultFailTWSDisconnect) {            NSLog(@"--->TWS耳机未连接");        }        if (result == JL_OTAResultFailNotInBin) {            NSLog(@"--->耳机未在充电仓");        }                if (result == JL_OTAResultPreparing ||            result == JL_OTAResultUpgrading)        {            if (result == JL_OTAResultUpgrading) NSLog(@"---> 正在升级:%.1f",progress*100.0f);            if (result == JL_OTAResultPreparing) NSLog(@"---> 检验文件:%.1f",progress*100.0f);        }                if (result == JL_OTAResultPrepared) {            NSLog(@"---> 检验文件【完成】");        }        if (result == JL_OTAResultReconnect) {            NSLog(@"---> OTA正在回连设备... %@",self->bt_ble.mBleName);            [self->bt_ble connectPeripheralWithUUID:self->bt_ble.lastUUID];//自行实现回连        }    }];

2.7.3、⼿表切换表盘(OTA功能)

  • 详情看【FAT_Demo】
  • 导⼊【FATApi】【FATTool】⽂件内代码;
STEP.1、设置命令中⼼类
        JL_RunSDK *bleSDK = [JL_RunSDK sharedMe];        bt_ble = bleSDK.bt_ble;                /*--- 设置命令处理中心 ---*/        [FatsObject makeCmdManager:bt_ble.mCmdManager];
STEP.2、获取外挂Flash的信息
//调⽤该API需要⽤异步,[JL_Tools subTask:^{}]为异步代码块 [JL_Tools subTask:^{        JL_ManagerM *mCmdManager = self->bleSDK.mBleEntityM.mCmdManager;         [mCmdManager cmdGetFlashInfoResult:^(JLModel_Flash * _Nullable model) {                 [JL_Tools mainTask:^{                        //mFlashSize;     //flash大小                        //mFatfsSize;     //FAT系统大小                        //mFlashType;     //系统类型 0:FAT                        //mFlashStatus;   //系统当前状态,0x00正常,0x01异常                        //mFlashVersion;  //Flash版本                        //mFlashMtu;      //发包窗口大小                        //mFlashCluster;  //扇区大小                         [DFUITools showText:@"FATFS信息已更新" onView:self delay:1.0];                 }];         }]; }];
STEP.3、初始化本地FATFS系统
//调⽤该API需要⽤异步 [JL_Tools subTask:^{        JLModel_Device *model = [self->bleSDK.mBleEntityM.mCmdManager outputDeviceModel];        uint32_t flashSize = model.flashInfo.mFlashSize;//外挂Flash剩余空间        uint32_t fatsSize = model.flashInfo.mFatfsSize; //统⼤⼩        BOOL isOk = [FatsObject makeFlashSize:flashSize FatsSize:fatsSize];         [JL_Tools mainTask:^{                NSString *txt = @"FATFS Mount OK !";                if (isOk == NO) txt = @"FATFS Mount Fail~";                 [DFUITools showText:txt onView:self delay:1.0];         }]; }];
读取表盘(⽂件)名字
//调⽤该API需要⽤异步 [JL_Tools subTask:^{            self->dataArray = [FatsObject makeListPath:@"/"];            NSLog(@"Fats List ---> %@",self->dataArray);             [JL_Tools mainTask:^{                     [self->subTableView reloadData];             }]; }];
新增表盘(⽂件)
    NSString *pathMatch = [DFFile find:@"watch6.zip"];    NSData *data = [NSData dataWithContentsOfFile:pathMatch];    NSLog(@"-->创建的文件大小:%lld",(long long)data.length);        NSString *path = @"/watch6";        [JL_Tools subTask:^{#if IS_FROM_BLE        /*--- 开始写文件 ---*/        __block uint8_t mFlag_0 = 0;        NSLog(@"--->Fats Insert stat.");        [mCmdManager cmdInsertFlashPath:path Size:(uint32_t)data.length                                   Flag:0x01 Result:^(uint8_t flag) {            mFlag_0 = flag;        }];        if (mFlag_0 != 0) {            NSLog(@"--->Fats Insert Fail.");            [JL_Tools mainTask:^{                [self setLoadingText:@"创建文件失败!" Delay:0.5];            }];            return;        }#endif                BOOL isOk = [FatsObject makeCreateFile:path Content:data Result:^(float progress) {            [JL_Tools mainTask:^{                //NSLog(@"---> Progress: %.1f",progress*100.0f);                NSString *txt = [NSString stringWithFormat:@"正在升级:%.1f%%",progress*100.0f];                self->progressLabel.text = txt;                self->progressView.progress = progress;            }];        }];        NSLog(@"Fats Add ---> %d",isOk);                [JL_Tools mainTask:^{            if (isOk) {                [self setLoadingText:@"创建文件成功!" Delay:0.5];#if IS_FROM_BLE                [JL_Tools subTask:^{                    /*--- 结束写文件 ---*/                    NSLog(@"--->Fats Insert end.");                    [mCmdManager cmdInsertFlashPath:nil Size:0 Flag:0x00 Result:nil];                }];#endif                [JL_Tools delay:1.0 Task:^{                    self->progressView.hidden = YES;                    self->progressLabel.hidden = YES;                    self->progressView.progress = 0.0f;                    /*--- 读取列表 ---*/                    [wSelf btn_List:nil];                }];            }else{                [self setLoadingText:@"创建文件失败!" Delay:0.5];            }        }];    }];
删除表盘(⽂件)
    [self startLoadingView:@"删除文件..." Delay:20.0];    NSString *path = [N 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap