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. [洛谷P2396]yyy loves Maths VII $\&$ [CF327E]Axis Walking

    这道题是一个状压动归题.子集生成,每一位表示是否选择了第$i$个数. 转移:$f[S] = \sum f[S-\{x\}]$且$x\in S$,当该子集所有元素的和为$b_1$或$b_2$时不转移. ...

  2. 如何利用Fiddler4进行Android APP / IOS APP抓包

    Fiddler抓包 1.Fiddler介绍 Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据. F ...

  3. centos 7.6修改ssh端口,设置防火墙规则

    一.修改ssh端口 1 使用 root 用户进入 /etc/ssh目录 2 备份ssh配置文件 cp sshd_config sshd_config-bak 3 使用 vim 打开 sshd_conf ...

  4. kafka里的一些管理脚本

    kafka-server-start脚本 ------启动kafka server kafka-server-stop脚本 ------关闭kafka server kafka-topics脚本 -- ...

  5. Redis(十)集群:Redis Cluster

    一.数据分布 1.数据分布理论 2.Redis数据分区 Redis Cluser采用虚拟槽分区,所有的键根据哈希函数映射到0~16383整数槽内,计算公式:slot=CRC16(key)&16 ...

  6. Scrapy 之settings配置

    BOT_NAME 默认: 'scrapybot' 当您使用 startproject 命令创建项目时其也被自动赋值. ROBOTSTXT_OBEY = False 是否遵守rebotes.txt协议 ...

  7. git出现Your branch and 'origin/master' have diverged解决方法

    如果不需要保留本地的修改,只要执行下面两步:git fetch origingit reset --hard origin/master 当我们在本地提交到远程仓库的时候,如果遇到上述问题,我们可以首 ...

  8. Web信息搜集

    文件是转载原文https://www.freebuf.com/articles/web/204883.html  如有侵权 请联系 对一个网站挖掘的深浅来说,信息收集是非常的重要的,这篇文章主要分享本 ...

  9. 创建 numpy.array

    # 导包 import numpy as np numpy.array nparr = np.array([i for i in range(10)]) nparr # array([0, 1, 2, ...

  10. P2380 狗哥采矿

    #include<iostream> #include<algorithm> #include<cstring> ; using namespace std; in ...