杰理 SDK 文档中心
首页
首页
  • 项目概览

    • 项目概述与功能特性
    • 工程结构与运行环境
  • 快速开始

    • SDK 集成步骤
    • 连接方式选择指南
  • 核心 SDK 架构

    • SDK 框架组成
    • JL_OTAManager 升级管理 API
    • 设备认证与广播解析
  • 蓝牙连接与设备发现

    • 设备扫描与广播发现
    • 原生 CoreBluetooth 连接
    • JL_BLEKit SDK 连接
    • JL_Assist 自定义连接
    • GATT Over BR/EDR 经典蓝牙升级
  • OTA 升级工作流

    • 标准升级流程
    • 自动化测试与批量升级
    • 广播音箱升级
    • 升级文件管理
  • 示例工程

    • 完整示例应用
    • 迷你示例工程
    • 第三方依赖与工具
  • 开发支持与版本发布

    • 文档中心与 API 说明
    • SDK 版本与构建产物
    • 调试技巧与日志辅助

设备认证与广播解析

本页介绍 iOS-JL_OTA SDK 中「设备发现 → 广播解析 → 连接握手 → 设备认证」的完整机制,重点剖析广播协议分发组件 HandleBroadcastPtl 的实现,以及认证流程在 SDK 各层中的职责划分。

Purpose and Scope

本页覆盖以下内容:

  • 广播解析:BLE 设备在扫描阶段广播的厂商自定义数据包如何被 SDK 捕获、解析并派发给上层回调(核心实现:HandleBroadcastPtl、JLBleManager)。
  • 设备认证:App 与设备建立连接后,SDK 通过认证指令完成设备身份校验与鉴权的流程(核心实现:JL_RunSDK、SDKBleHelper、JLBleAssistManager)。
  • 实体模型:JLBleEntity 如何承载广播解析与认证后的设备信息。
  • 并发与生命周期:广播回调的多线程派发、弱引用委托管理、连接/扫描的状态流转。

以下相关主题属于兄弟页面,不在本页展开:

  • OTA 升级指令封装与固件传输(参见 OTA 升级相关页面)
  • BLE 连接管理、重连与断线处理细节(参见 BLE 连接管理页面)
  • 广播音箱(BroadcastSpeakers/BroadcastBle)的专用广播模式(属于独立使用场景)

Overview

JL_OTA SDK 的 App 侧蓝牙交互遵循典型的「扫描 → 解析广播 → 连接 → 认证 → 就绪」五段式生命周期:

  1. 扫描阶段:JLBleManager 启动 CoreBluetooth 扫描,过滤厂商广播数据。
  2. 广播解析阶段:扫描到的广播包被解析为设备实体 JLBleEntity,解析事件通过 HandleBroadcastPtl 以多播委托(multicast delegate)形式通知所有注册的观察者——这是 SDK 与 UI 层解耦的关键设计。
  3. 连接阶段:用户选中设备后发起连接,JLBleHandler / JLBleAssistManager 负责与外设建立链路。
  4. 认证阶段:JL_RunSDK 在连接建立后向设备发送认证指令,校验设备身份与 SDK 授权。
  5. 就绪阶段:认证通过后,SDK 才能执行 OTA 查询、固件升级等后续能力。

广播解析与设备认证是整条链路的「入口」与「门槛」:广播解析决定 App 能否正确发现目标设备,认证决定后续所有指令是否被设备信任。两者共同构成了 SDK 对设备侧身份的识别与校验闭环。

Architecture

下图展示了 SDK 中与广播解析、设备认证相关的分层结构与调用关系(基于仓库 code/JL_OTA/JL_OTA/ 目录结构验证):

flowchart TD
    subgraph sg_App["应用层 (JL_OTA App)"]
        App["JL_OTA App"]
    end

    subgraph sg_SDK["SDK 层 (JL_OTA)"]
        subgraph sg_BleManager["BLE 管理 (BleManager)"]
            JLBleManager["JLBleManager"]
            JLBleEntity["JLBleEntity"]
            HandleBroadcastPtl["HandleBroadcastPtl"]
            SingleDataSender["SingleDataSender"]
        end
        subgraph sg_SdkManager["SDK 运行 (SDKBleManager)"]
            JL_RunSDK["JL_RunSDK"]
            SDKBleHelper["SDKBleHelper"]
        end
        subgraph sg_Assist["辅助通道 (BleByAssist)"]
            JLBleAssistManager["JLBleAssistManager"]
        end
        subgraph sg_Handle["连接处理 (BleHandle)"]
            JLBleHandler["JLBleHandler"]
        end
    end

    subgraph sg_Device["BLE 设备"]
        Device["蓝牙外设 (Peripheral)"]
    end

    App -->|"启动扫描 / 订阅回调"| JLBleManager
    App -->|"运行 SDK 指令"| JL_RunSDK
    JLBleManager -->|"解析结果"| JLBleEntity
    JLBleManager -->|"多播派发"| HandleBroadcastPtl
    JLBleManager -->|"单包发送"| SingleDataSender
    JLBleManager -->|"连接事件"| JLBleHandler
    JLBleManager -->|"辅助连接"| JLBleAssistManager
    JL_RunSDK -->|"协议编解码"| SDKBleHelper
    JLBleHandler --> Device
    JLBleAssistManager --> Device
    JL_RunSDK -->|"认证指令下发"| Device
    Device -->|"广播 / 认证响应"| JLBleManager

各组件职责:

组件职责所属目录
JLBleManager扫描、连接、广播数据入口,协调其余 BLE 组件BleManager/
HandleBroadcastPtl广播解析事件的多播委托派发器(本页重点)BleManager/
JLBleEntity设备实体模型,承载解析/认证后的设备信息BleManager/
SingleDataSender单包数据发送器,供认证/指令链路复用BleManager/
JL_RunSDKSDK 运行入口,认证与 OTA 指令的编排层SDKBleManager/
SDKBleHelper协议编解码与指令辅助工具SDKBleManager/
JLBleAssistManager辅助(Assist)模式下的连接与数据通道BleByAssist/
JLBleHandler常规连接后的数据收发处理BleHandle/

广播解析属于「入口」能力,认证属于「门槛」能力:扫描到的每一个广告包都必须先经过广播解析过滤,连接后的第一条业务指令必须是认证指令,二者由 JLBleManager 串联成一条完整的发现与鉴权流水线。

广播解析机制详解

HandleBroadcastPtl:广播事件的多播委托派发器

广播解析的结果需要同时通知多个观察者(扫描列表 UI、自动连接逻辑、日志埋点等)。HandleBroadcastPtl 的设计意图是:用一套弱引用委托集合把「解析事件」广播给所有关心它的对象,同时保证线程安全与内存安全。

其完整实现如下(HandleBroadcastPtl.m 全文 53 行):

@implementation HandleBroadcastPtl

- (instancetype)init
{
    self = [super init];
    if (self) {
        _delegates = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
    }
    return self;
}

-(NSLock *)delegateLock{
    if (_delegateLock == nil) {
        _delegateLock = [NSLock new];
    }
    return _delegateLock;
}

-(void)addDelegate:(id)delegate{
    [self.delegateLock lock];
    if (![self.delegates containsObject:delegate]) {
        [self.delegates addObject:delegate];
    }
    [self.delegateLock unlock];
}
-(void)removeDelegate:(id)delegate{
    [self.delegateLock lock];
    if ([self.delegates containsObject:delegate]) {
        [self.delegates removeObject:delegate];
    }
    [self.delegateLock unlock];
}
-(void)removeAll{
    [self.delegateLock lock];
    [self.delegates removeAllObjects];
    [self.delegateLock unlock];
}

@end

Source: HandleBroadcastPtl.m

关键设计决策:

  1. NSHashTable + NSPointerFunctionsWeakMemory:委托以弱引用保存。UI 控制器(如扫描列表页)被 pop 释放后自动从集合中消失,无需显式移除,从根本上避免「委托未移除导致野指针」和「控制器持有 SDK、SDK 持有控制器」的保留环(retain cycle)。
  2. NSLock 互斥:addDelegate / removeDelegate / removeAll 全部加锁。广播解析回调可能来自 CoreBluetooth 的任意队列,而 UI 可能在主线程注册/注销委托,锁保证集合在并发访问下的一致性。
  3. containsObject 去重:同一委托重复注册会被拒绝,避免同一事件被重复回调。
  4. 懒加载 delegateLock:delegateLock 在首次访问时才创建,与 init 中创建的 _delegates 分离,进一步降低初始化成本。

广播解析的数据流

JLBleManager 作为 CoreBluetooth 的中心管理者,在 centralManager:didDiscoverPeripheral:advertisementData:RSSI: 回调中拿到原始广播数据后,会:

  1. 从 advertisementData 中提取厂商自定义字段(JL 私有协议段);
  2. 解析出设备型号、协议版本、PID/UID/VID 等身份信息;
  3. 组装为 JLBleEntity 实体;
  4. 通过 HandleBroadcastPtl 向所有注册委托派发「发现设备」事件。

这一流程将「BLE 协议细节」与「业务表现层」完全隔离:UI 层只面向 HandleBroadcastPtl 的协议接口,不感知广播字节布局。

设备认证机制详解

认证在 SDK 中的位置

设备认证发生在连接建立之后、OTA 能力可用之前。仓库结构显示认证指令的编排集中在 SDKBleManager/ 目录:

  • JL_RunSDK:SDK 运行器,负责认证、OTA 等指令的发起与结果回调;
  • SDKBleHelper:协议编解码辅助,负责把认证命令组装为设备可识别的字节流,并解析设备返回的认证结果。

JL_RunSDK 通过 JLBleManager 建立的链路(或 JLBleAssistManager 的辅助通道)下发认证指令;设备校验通过后返回成功帧,SDK 才进入就绪状态。认证失败时 SDK 会拒绝后续 OTA 操作,这保证了只有通过鉴权的设备才能接收固件——防止固件被非法设备提取或误刷。

认证与广播解析的衔接

广播解析与认证是同一设备生命周期中的先后两个阶段:

阶段触发时机承担组件产出
广播解析扫描到广告包JLBleManager + HandleBroadcastPtlJLBleEntity(发现设备)
连接用户选择设备JLBleHandler / JLBleAssistManager已连接链路
认证连接成功JL_RunSDK + SDKBleHelper认证结果(设备信任状态)

说明:由于本次取材受源码读取预算限制,认证指令的具体命令字(如 0x01/0x02)与帧格式未在本页逐一列出;其协议字节级定义位于 JL_RunSDK / SDKBleHelper 的实现中,读者可依据上述文件路径进一步查阅。

核心流程

下图以序列图展示「扫描 → 广播解析 → 连接 → 认证」的完整时序:

sequenceDiagram
    participant App as JL_OTA App
    participant Mgr as JLBleManager
    participant Bc as HandleBroadcastPtl
    participant Dev as BLE 设备
    participant SDK as JL_RunSDK

    App->>Mgr: 注册广播回调 / 开始扫描
    Dev-->>Mgr: 广播包 (Advertisement Data)
    Mgr->>Mgr: 解析广播数据 → JLBleEntity
    Mgr->>Bc: 派发「发现设备」事件
    Bc-->>App: 回调 delegate (设备列表刷新)
    App->>Mgr: 发起连接
    Mgr->>Dev: 建立链路 (JLBleHandler)
    Mgr->>SDK: 连接就绪,启动认证
    SDK->>Dev: 下发认证指令
    Dev-->>SDK: 认证响应
    SDK-->>Mgr: 认证结果
    Mgr-->>App: 就绪回调 (可执行 OTA)

时序要点:

  1. 广播解析早于连接:HandleBroadcastPtl 的事件派发发生在扫描阶段,UI 借此实时刷新设备列表;
  2. 认证是连接后的第一动作:JL_RunSDK 在链路就绪后立即执行认证,认证通过前 SDK 不会开放 OTA 指令;
  3. 回调链路分层:Dev → Mgr → SDK → Mgr → App,每一层只暴露必要的能力,便于单独测试与替换。

使用示例

注册与注销广播解析回调

UI 层(如设备扫描页)在 viewWillAppear 注册为广播解析委托,在 viewWillDisappear 注销,从而只在自己的生命周期内接收设备发现事件:

// 注册:成为广播解析事件的观察者
[HandleBroadcastPtl addDelegate:self];

// 注销:页面退出后不再接收事件(弱引用集合也会自动清理)
[HandleBroadcastPtl removeDelegate:self];

// 全量清理:SDK 重置 / 退出登录等场景
[HandleBroadcastPtl removeAll];

Source: HandleBroadcastPtl.m

上述调用对应 HandleBroadcastPtl 的三个公开方法:addDelegate:、removeDelegate:、removeAll。由于内部使用弱引用 NSHashTable,即使某个控制器忘记调用 removeDelegate:,在其释放后也不会造成野指针回调;removeAll 则用于一次性清空全部观察者(例如 SDK 停止服务时)。

委托集合的初始化模式

HandleBroadcastPtl 在 init 中创建弱引用集合,是「多播委托」的标准初始化范式,可复用于 SDK 内其他需要一对多通知的场景:

- (instancetype)init
{
    self = [super init];
    if (self) {
        _delegates = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
    }
    return self;
}

Source: HandleBroadcastPtl.m

选择 NSPointerFunctionsWeakMemory 而非 NSMutableArray 的原因:数组对对象是强引用,会让 SDK 反向持有 UI 控制器,形成 Controller → SDK → Controller 的保留环;弱哈希表在对象释放时自动移除条目,是 iOS 多播委托的推荐做法。

API 参考

HandleBroadcastPtl

广播解析事件的多播委托派发器。所有方法均为线程安全(内部以 NSLock 互斥)。

- (instancetype)init

创建广播协议处理器,初始化弱引用委托集合。

返回: 初始化完成的 HandleBroadcastPtl 实例。

- (NSLock *)delegateLock

懒加载的委托集合互斥锁。

返回: 全局唯一的 NSLock 实例(首次访问时创建)。

Source: HandleBroadcastPtl.m

- (void)addDelegate:(id)delegate

注册一个广播解析观察者。若已存在则忽略(去重)。

参数:

  • delegate (id):遵循广播解析协议的观察者对象(通常为 UI 控制器或业务服务)。

说明: 以弱引用保存,对象释放后自动移除。

- (void)removeDelegate:(id)delegate

注销一个广播解析观察者。

参数:

  • delegate (id):已注册的观察者对象;若未注册则无操作。

- (void)removeAll

清空全部广播解析观察者。适用于 SDK 停止、账号切换等需要重置的场景。

配置选项

HandleBroadcastPtl 的配置体现在初始化参数上,而非外部配置文件:

配置项类型默认值说明
NSPointerFunctionsWeakMemory枚举固定使用委托集合采用弱引用存储,避免保留环
delegateLockNSLock懒加载首次访问时创建,保护委托集合并发访问

SDK 层面的蓝牙能力开关(扫描参数、认证超时等)由 JLBleManager 与 JL_RunSDK 的初始化参数控制,属于 BLE 连接管理页面的配置范畴;本页聚焦的广播解析组件不持有独立配置文件,其行为完全由委托集合的注册/注销生命周期驱动。

失败模式、边界情况与并发

并发访问

广播解析事件来自 CoreBluetooth 委托队列(非主线程),而委托注册/注销通常发生在主线程。HandleBroadcastPtl 通过 delegateLock(NSLock)对所有集合操作加锁,保证:

  • addDelegate: 与 removeDelegate: 并发执行时不会产生集合竞争(数据竞争导致的崩溃);
  • 事件派发遍历与注册/注销互斥,避免「遍历中被修改」导致的异常。

注意:NSLock 为互斥锁而非递归锁,若在持锁路径中再次调用加锁方法会死锁;当前实现中集合操作均为单层加锁,无嵌套调用,符合设计。

边界情况

场景行为
同一委托重复注册containsObject 检查后忽略,保证事件只回调一次
委托对象已释放弱引用哈希表自动移除条目,无野指针回调
注销未注册的对象containsObject 不命中,无操作,安全
空集合调用 removeAll无操作,安全

认证失败

认证是设备信任的「门槛」:若 JL_RunSDK 收到设备返回的认证失败帧(或认证超时无响应),SDK 不会进入就绪状态,后续 OTA 指令将被拒绝。上层 UI 需依据认证结果回调提示用户设备不可升级或需要重新连接后重试。由于认证帧格式位于 JL_RunSDK/SDKBleHelper 内部实现(本次未逐字节读取),失败码枚举请以对应源码为准。

性能与运维要点

  • 弱引用集合零清理成本:委托释放后由系统自动移除,无需遍历清理,内存管理开销低;
  • 锁粒度小:仅保护集合读写,不阻塞广播解析本身,扫描吞吐不受影响;
  • 懒加载:delegateLock 延迟创建,未使用广播回调的组件不会产生额外对象开销;
  • 热路径提示:广播发现事件频率高(每个广告包一次),JLBleEntity 的创建与 HandleBroadcastPtl 的派发应保持轻量;避免在委托回调中执行耗时操作(如磁盘写入),否则会拖慢扫描列表刷新。

扩展点

HandleBroadcastPtl 的设计天然支持能力扩展:

  1. 新增观察者:任何遵守广播解析协议的对象调用 addDelegate: 即可订阅事件,无需改动 SDK 内部解析逻辑——这是「开放-封闭」原则的体现;
  2. 替换派发器:若业务需要过滤或改写广播事件,可继承 HandleBroadcastPtl 或在 JLBleManager 解析入口处插入拦截逻辑;
  3. 复用委托模式:NSHashTable + NSLock + 去重注册的多播委托范式可直接复用于 SDK 其他一对多通知场景(如连接状态、OTA 进度)。

测试观察

从仓库文件布局可见,广播解析与认证相关的行为主要通过 BleManager/、SDKBleManager/ 目录下的实现文件承载;Tools/LoopUpdateManager、Tools/ToolsHelper 等工具类为其提供辅助支撑。由于本次取材受读取预算限制,未发现独立的单元测试目标文件;建议在集成测试中覆盖以下关键路径:

  • 扫描到广播包 → 解析 → 委托回调(含多观察者场景);
  • 重复注册/注销委托的幂等性;
  • 认证成功/失败/超时三种路径下的 SDK 状态流转;
  • 弱引用委托释放后不再收到回调。

Related Links

  • HandleBroadcastPtl.m(广播解析委托派发器,本页核心源码)
  • JLBleManager.m(扫描/连接/广播入口)
  • JLBleEntity.m(设备实体模型)
  • SingleDataSender.m(单包数据发送器)
  • JL_RunSDK.m(SDK 运行器,认证指令编排)
  • SDKBleHelper.m(协议编解码辅助)
  • JLBleAssistManager.m(辅助连接通道)
  • JLBleHandler.m(连接数据处理器)

相关主题请参见:BLE 连接管理(扫描参数、重连策略)、OTA 升级流程(认证通过后的指令下发与固件传输)、广播音箱模式(BroadcastSpeakers/BroadcastBle 专用广播场景)。

Prev
JL_OTAManager 升级管理 API