1.1     背景

GAP(Generic Access Profile)位于主机协议栈的最顶层,用来定义BLE设备在待机或者连接状态中的行为,该Profile保证不同的Bluetooth产品可以互相发现对方并建立连接。GAP定义了:

蓝牙设备如何发现和建立与其他设备的安全/不安全连接;

处理一些一般模式的业务(如询问、命名和搜索)和一些安全性问题(如担保) ;

处理一些有关连接的业务(如链路建立、信道和连接建立);

下图直观地展示了GAP处于蓝牙协议栈的层次关系。

GAP Role

Description

BROADCASTER

A device that only sends advertising events.

OBSERVER

A device that only receives advertising events.

PERIPHERAL

A device that accepts the establishment of an LE physical link using the connection establishment procedure.

CENTRAL

A device that supports the Central role initiates the establishment of a physical connection.

1.2     广播(advertising)

蓝牙设备通过在广播数据包中发送广播包(PDUS)来允许其他设备(scanners)发现并连接它,这些广播数据最大长度支持31字节的可配置数据,针对到来的scan request,在scan response中,蓝牙设备(Broadcaster)可以发送额外的31字节数据。GAP一共定义了四种不同类型的广播数据包类型:

Advertising PDU

Description

Max Adv Data Len

Max Scan Res Len

Allow Connect

ADV_IND

用于发送可连接,非定向的广播

31 bytes

31 bytes

Yes

ADV_DIRECT_IND

用于发送可连接,定向广播

N/A

N/A

Yes

ADV_SCAN_IND

用于发送扫描,非定向广播

31 bytes

31 bytes

No

ADV_NONCONN_IND

用于发送非可连接,非定向广播

31 bytes

N/A

No

在上面的表格中,除了直接广播(ADV_DIRECT_IND),其余广播PDU携带广播数据报文最大长度是31字节。对于直接广播来说,其只携带了6字节的目标设备地址,该目标设备地址的预期被连接的设备地址。另外,所有的广播类型允许对于到来的scan response做出scan response,除了直接广播(ADV_DIRECT_IND)和非连接广播(ADV_NONCONN_IND),更多信息,请参考BT Core Spec V4.2 Vol. 6, Part B, Section 4.4。

下面的表格总结了广播过程中可以配置的参数:

Parameter

Description

Range

Advertising Interval

Time between the start of two consecutive advertising events

20ms to 10.24s

Advertising Types

Different PDUs are sent for different types of advertising

Connectable undirected, connectable directed, scannable directed, non-connectable

Advertising Channels

Advertising packets are sent on three channels

Different combinations of channels 37, 38 and 39.

蓝牙设备有三个特定的广播通道,分别是:通道37 (2402 MHz), 通道 38 (2426 MHz), 和通道39 (2480 MHz)。这三个通道选择能够将与WIFI干扰降低到最小,下图展示了一个广播事件,该事件使用了全部三个广播通道。

需要注意的是:在这三个广播通道上,相同的数据被传递,GAP允许设备只广播在某一个或者两个通道上。在更少的通道上进行广播,意味这激着更小的能量消耗。但是,会降低被对端设备侦听到的概率。

1.3     扫描(Scanning)

当设备处于连接状态时,其或可以发送广播包对外广播其存在,或扫描周边正在广播的设备。扫描周边设备的过程称为设备发现。GAP定义了两种扫描类型——主动(active)和(被动),两者的区别是,前者可以发送scan request从广播者获取更多额外的信息,而后者仅仅能够接收广播者的广播数据。如无特殊语境,“发现”和“扫描”两个术语讲不加区分,交替使用。下图演示了一个设备对广播者发送扫描请求以及广播者做出应答的时序图。

在扫描过程中,你需要熟悉一些扫描参数,每个参数都有特定的范围,下表罗列了这些参数的语义以及可配置范围。

Parameter

Description

Range

Scan Interval

Interval between the start of two consecutive scan windows

10ms to 10.24s

Scan Window

The duration in which the Link Layer scans on one channel

10ms to 10.24s

Scan Duration

The duration in which the device stays in the scanning state

10ms to infinity

GAP并没有规定扫描过程中,对三个广播通道的扫描顺序,扫描者在每个扫描间隔内,在一个扫描窗口期间内,依次扫描37,38,39通道。下图形象的展示了这些扫描参数的内涵:

1.4     模式/状态

一、发现模式(Discoverablity Modes), 对应于inquiry(inquiry request/response)

- Non-discoverable Mode: 不响应inquiry;

- Discoverable Mode: 是下面两种模式的总称, 设备进入INQUIRY_SCAN状态, 响应inquiry;

- Limited discoverable Mode: 响应LIAC inquiry;

- General discoverable Mode: 响应GIAC inquiry;

二、连接模式(Connectability Modes), 对应于paging(paging request/response)

- Non-connectable Mode: 不响应paging;

- Connectable Mode: 设备进入PAGE_SCAN状态, 响应paging;

三、配对模式(Bondable Modes), 对应于bonding/paring, 需要和SSP(Secure Simple Pairing)配合使用

- Non-bondable Mode: 设备不可接受来自远端设备的绑定/配对请求;

- Bondable Mode: 设备可接受来自远端设备的绑定/配对请求;

1.5     ADK信号时序

以ADK4.4为例,简单的罗列了设备在初始化时,如何进行扫描,广播初始化的,具体细节请见ADK源代码。

/*Power on -> start scan -> start(fast)advertising -> start(slow)advertising (if not connected)*/

sink_ble.c

sinkBleInitialiseDevice()-->

ConnectionDmBleAddTdlDevicesToWhiteListReq(BLE_ONLY)  /* Setup whitelist*/

sinkGattInitInitialiseDevice();  /* Initialise GATT */

sinkBleGapInitialise();-->

sinkBleGapInitGapConnFlag();

gapSetAdvSpeed(ble_gap_adv_speed_fast);

sinkBlePowerOnEvent()-->

sinkBleGapEvent(ble_gap_event_power_on)-->

gapStateIdleHandleEvent()-->

sinkBleSetGapState(ble_gap_state_scanning_advertising)

sinkBleCheckNoConnectionsEvent()-->BLE_INTERNAL_MESSAGE_EVENT_NO_CONNECTIONS

-->sinkBleGapEvent(ble_gap_event_no_connections)

gapStateScanAdvHandleEvent(ble_gap_event_no_connections)-->

sinkBleGapStartReadLocalName(ble_gap_read_name_advertising)

gapStartScanning(TRUE)-->

bleStartScanning()-->

ConnectionDmBleSetScanParametersReq()-->DM_HCI_ULP_SET_SCAN_PARAMETERS_REQ

ConnectionDmBleSetScanEnable(TRUE)

bluestack_handler.c

DM_HCI_READ_LOCAL_NAME_CFM-->

connectionHandleLocalNameComplete()-->

localNameComplete()-->CL_DM_LOCAL_NAME_COMPLETE

sinkBleHandleCLMessage()-->CL_DM_LOCAL_NAME_COMPLETE-->

sinkBleGapReadLocalNameComplete()-->

bleSetupAdvertisingData(ble_gap_read_name_advertising)-->

ConnectionDmBleSetAdvertisingDataReq()-->

DM_HCI_ULP_SET_ADVERTISING_DATA_REQ

DM_HCI_ULP_SET_ADVERTISING_DATA_CFM-->

connectionHandleDmBleSetAdvertisingDataCfm()-->CL_DM_BLE_SET_ADVERTISING_DATA_CFM-->

bleHandleSetAdvertisingData()-->

sinkBleGapEvent(ble_gap_event_set_advertising_complete)

gapStartAdvertising();-->

gapStartAdvertising()-->

sinkBleGetAdvertisingParameters()

sinkBleSetAdvertisingParamsDefault()

sinkGattManagerStartAdvertising()-->

sinkEnableGattConnectable()-->

enablePageScan(sink_scan_connectable_gatt)

gapStartFastAdvTimer()-->

MessageSendLater(BLE_INTERNAL_MESSAGE_FAST_ADV_TIMER)

BLE_INTERNAL_MESSAGE_FAST_ADV_TIMER-->

sinkBleGapEvent(ble_gap_event_fast_adv_timeout)-->

gapStateScanAdvHandleEvent()-->

gapStopAdvertising(ble_gap_adv_speed_slow)-->

gapSetAdvSpeed(new_speed) /* First stop fast advertising*/

sinkGattManagerStopAdvertising()-->  /* Then start slow advertising */

GattManagerCancelWaitForRemoteClient()

GATT_MANAGER_CANCEL_REMOTE_CLIENT_CONNECT_CFM-->

handleGattManagerCancelRemoteClientConnectCfm()-->

sinkBleCancelAdvertisingEvent()-->

sinkBleGapEvent(ble_gap_event_cancelled_advertising)-->

gapStateScanAdvHandleEvent()-->

sinkBleGapStartReadLocalName(ble_gap_read_name_advertising)

十、GAP的更多相关文章

  1. 十大经典排序算法总结(JavaScript描述)

    前言 读者自行尝试可以想看源码戳这,博主在github建了个库,读者可以Clone下来本地尝试.此博文配合源码体验更棒哦~~~ 个人博客:Damonare的个人博客 原文地址:十大经典算法总结 这世界 ...

  2. 十大经典排序算法总结——JavaScrip版

    首先,对于评述算法优劣术语的说明: 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面:即排序后2个相等键值的顺序和排序之前它们的顺序相同 不稳定:如果a原本在b的前面,而a=b,排序之后a ...

  3. JS的十大经典算法排序

    引子 有句话怎么说来着: 雷锋推倒雷峰塔,Java implements JavaScript. 当年,想凭借抱Java大腿火一把而不惜把自己名字给改了的JavaScript(原名LiveScript ...

  4. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

  5. Gap year | 最好金龟换酒

    Gap year | 最好金龟换酒 Gap year Posted on February 8, 2009 by 真 后.90后相比,说是虽然形成背景不同,但有很多特征相似,比如离经叛道,比如信仰缺失 ...

  6. 十大经典排序算法的JS版

    前言 个人博客:Damonare的个人博客 如遇到问题或有更好的优化方法,可以: 提issue给我 或是pull requests 我都会看到并处理,欢迎Star. 这世界上总存在着那么一些看似相似但 ...

  7. 排序算法——(2)Python实现十大常用排序算法

    上期为大家讲解了排序算法常见的几个概念: 相关性:排序时是否需要比较元素 稳定性:相同元素排序后是否可能打乱 时间空间复杂度:随着元素增加时间和空间随之变化的函数 如果有遗忘的同学可以看排序算法——( ...

  8. Android为TV端助力 转载:Android绘图Canvas十八般武器之Shader详解及实战篇(下)

    LinearGradient 线性渐变渲染器 LinearGradient中文翻译过来就是线性渐变的意思.线性渐变通俗来讲就是给起点设置一个颜色值如#faf84d,终点设置一个颜色值如#CC423C, ...

  9. 死锁问题分析(个人认为重点讲到了gap间隙锁,解决了我一些不明报死锁的问题)

    线上某服务时不时报出如下异常(大约一天二十多次):“Deadlock found when trying to get lock;”. Oh, My God! 是死锁问题.尽管报错不多,对性能目前看来 ...

随机推荐

  1. jmeter-操作mysql

    1.下载mysql驱动并放至如下目录:E:\soft\apache-jmeter-5.1.1\lib\ext 2.添加JDBC Connection Configuration(线程组-配置元件-JD ...

  2. 02jmeter-函数助手使用

    示例:__Random函数 1.打开函数助手,并按提示写入value 2.引用.复制出${__Random(1,99,gp)}放到需要引用的地方 3.请求成功后可通过debug sampler查看变量 ...

  3. Hive On HBase实战

    1.概述 HBase是一款非关系型.分布式的KV存储数据库.用来存储海量的数据,用于键值对操作.目前HBase是原生是不包含SQL操作,虽然说Apache Phoenix可以用来操作HBase表,但是 ...

  4. CMMS系统中工单派案&调度

    系统为客户经理提供一个有效的调度控制台,由客户经理负责将需要外派现场处理的工单进行统一的分配调度,系统显示每个技术人员的时间表,根据专业技能.可用性.距离或其他资格标准筛选技术服务人员,并向调度人员提 ...

  5. vue cli3.3 以上版本配置vue.config.js 及反向代理操作解决跨域操作

    const webpack = require('webpack') module.exports = { configureWebpack: { plugins: [ new webpack.Pro ...

  6. intellij idea - Project Structure 项目结构详解(简单明了)

    IDEA Project Structure 设置 可以点击  按钮,或者使用快捷键 Ctrl + Shift + Alt + S  打开 Project Structure .如下如所示: 项目的左 ...

  7. Codeforces Round #595 (Div. 3)D1D2 贪心 STL

    一道用STL的贪心,正好可以用来学习使用STL库 题目大意:给出n条可以内含,相交,分离的线段,如果重叠条数超过k次则为坏点,n,k<2e5 所以我们贪心的想我们从左往右遍历,如果重合部分条数超 ...

  8. Mybaits 源码解析 (八)----- 全网最详细,没有之一:结果集 ResultSet 自动映射成实体类对象(上篇)

    上一篇文章我们已经将SQL发送到了数据库,并返回了ResultSet,接下来就是将结果集 ResultSet 自动映射成实体类对象.这样使用者就无需再手动操作结果集,并将数据填充到实体类对象中.这可大 ...

  9. 转:NFS原理详解

    原文:http://atong.blog.51cto.com/2393905/1343950 一.NFS介绍 1)什么是NFS 它的主要功能是通过网络让不同的机器系统之间可以彼此共享文件和目录.NFS ...

  10. 学习笔记53_C#操作MongoDB

    1.配置MongoDB的连接字符串 MongoDB程序集引用 在使用db.GetCollerction<T>,也可以不指定类,因为Mongodb是无模式的. ****关系型数据设计转化为j ...