百科知识

蓝牙PIN码到底是个啥玩意儿

蓝牙设备的配对过程通常在首次建立连接时启动,当本端完成对蓝牙设备的搜索并获取到相应的BluetoothDevice信息后,即可启动配对流程。

所谓配对,就是指利用特定技术将两个设备进行绑定,使得它们能够相互识别。在蓝牙技术广泛应用的今天,蓝牙配对已成为使用蓝牙功能时不可或缺的一步。本文将详细探讨安卓系统中蓝牙配对的实现机制。

在应用层面,通过framework层的BluetoothDevice接口调用createBond()方法可以启动配对流程。createBondOutOfBand()方法则采用OOB技术进行配对,但实际应用中较少使用。因此,应用开发者需要根据具体的使用场景选择合适的接口。

在蓝牙服务层,配对流程的操作相对简单,主要是向下层发送指令,并在指令完成后通过JNI层的异步回调机制处理配对状态的变化,并将状态变化对外进行广播。配对流程的时序图如下:

从时序图中可以看出,唯一需要注意的细节是,在启动配对流程之前需要停止搜索扫描流程(如果底层正在执行该流程)。之所以要增加这一操作,是为了确保配对流程能够顺利进行。因为搜索扫描和配对流程都会对远端设备进行Discovery操作,为了避免这两个流程相互干扰导致配对失败,需要先停止搜索扫描。

当协议栈接收到开始配对的指令后,会按照以下配对状态机进行状态切换(以Numeric Comparison模式为例):

IDLE:初始状态GET_REM_NAME:获取远端设备的蓝牙名称WAIT_PIN_REQ:等待Controller请求PIN码WAIT_LOCAL_IOCAPS:等待本端提供IO能力WAIT_NUM_CONFIRM:等待本端Host确认配对WAIT_AUTH_COMPLETE:等待鉴权(配对)流程完成状态切换在HCI上的交互示意图如下:

从这张图中可以清晰地了解每个配对状态切换的触发时机,这里不再进行详细分析。感兴趣的开发者可以尝试根据上图中的HCI命令跟踪代码执行流程。

协议栈的配对状态会在鉴权完成事件Authentication Complete上报后切换回初始状态,但这并不意味着整个配对流程已经完成。在安卓系统中,实际上还需要进行后续步骤,因为上报JNI层的配对状态变化回调并不是通过鉴权完成事件上报完成的。

配对流程的主要工作完成后,协议栈还会继续对该设备进行SDP服务发现,以搜索该设备支持哪些协议服务。只有当SDP服务搜索完成后,才会上报JNI层配对状态变为Bonded。

触发SDP服务搜索的时机是在处理上报Link Key的回调bta_dm_new_link_key_cback()中,通过 event = BTA_DM_AUTH_CMPL_EVT 触发的。

随后在函数btif_dm_auth_cmpl_evt()中尝试对该设备进行SDP服务发现,具体流程如下:

SDP服务发现完成后,通过回调处理函数btif_dm_search_services_evt()中 event = BTA_DM_DISC_RES_EVT 上报JNI层配对状态变化到Bonded。

至此,安卓系统中蓝牙配对流程才算完全闭环。上述过程以Numeric Comparison配对模型为基础进行了介绍,其他配对模型的流程类似,这里不再一一说明。但需要注意的是,协议栈配对状态机的全部值如下,其他配对模型的流程也是在这些状态机的组合下进行切换运行的:

蓝牙配对流程并非孤立存在,而是与搜索扫描、连接等流程相互配合、共同作用的,彼此之间依赖性强,缺一不可。