德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈

目录

  • 前言:
  • 一、蓝牙协议栈简介:
  • 二、GAP层,通用访问配置文件:
    • 2.1、连接参数:
    • 2.2、有效连接间隔:
    • 2.3、连接参数注意事项:
    • 2.4、多连接下的连接参数限制:
    • 2.5、连接参数更新
    • 2.6、连接终止:
    • 2.7、GAP概述:
    • 2.8、配置GAP:
  • 三、GAPRole任务
    • 3.1、外设角色 peripheral:
    • 3.2、central主机:
  • 四、GATT通用属性配置文件:
    • 4.1、GATT:characteristics and attributes特征和属性:
    • 4.2、四个GATT配置文件:
    • 4.3、GAP GATT Service GGS服务:
      • 4.3.1、使用GGS:
    • 4.4、GATT服务:
      • 4.4.1、使用GATT服务:
    • 4.5、GATT client抽象:
      • 4.5.1、使用GATT:
    • 4.6、GATT服务抽象:
      • 4.6.1、GattServApp模块:
      • 4.6.2、profile架构:
        • 4.6.2.1、 属性表定义:
        • 4.6.2.2、添加服务功能:
        • 4.6.2.3、注册应用程序回调函数:
        • 4.6.2.4、读写回调函数:
        • 4.6.2.5、GET和set函数:
      • 4.6.3、排队书写:
    • 4.7、GATT过程中的动态内存:
    • 4.8在应用中接受更多GATT事件:
    • 4.9、GATT安全:
      • 4.9.1:认证:
      • 4.9.2:授权:

本系列文章由江山(csdn名:补不补布)(github:jianggogogo)自己写成,当中用到引用时都已经标记出来,如果出现版权问题,请直接联系我修改。当然,技术在于分享,欢迎大家转载,不过请注明出处。最后,如果出现有错误的地方欢迎大家指正。

前言:

基于谷雨cc2640教程

一、蓝牙协议栈简介:

对蓝牙有基础的朋友可能知道蓝牙的一些概念,这就是一个典型蓝牙协议栈。那么对于蓝牙新手来说,我们就可以降蓝牙协议栈看作是一个飞机,我们只需要学习如何开飞机就行,至于飞机怎么做,那不是我们现阶段需要考虑的事情。
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第1张图片

二、GAP层,通用访问配置文件:

  1. BLE协议栈的GAP负责连接功能,处理的是设备的接入过程
  2. 包括:设备发现,链路建立,链路终止,安全特性的启动和设备配置。

德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第2张图片

2.1、连接参数:

  1. connection interval连接间隔:在ble方案中,为使用跳频方案,就是两个设备旨在特定的频道上面交流数据,随后会在新的频道上面同行,而这个新的频道在上次的交流中约定。连接间隔的范围从6(7.5ms)到最大值3200(4.0s)
  2. slave latency从机延迟:这个参数是从机跳过多个连接事件的能力:如果外设没有要发送的数据就继续睡眠。当然,这个功能可以选择开启或者不开启。
  3. supervison time-out:监控超时,连词成功连接事件之间的最长时间,如果在这个时间内没有成功,那么设备将终止连接并且返回到未连接状态。以10ms为单位,可以从10(100ms)到3200(32.0s)之间。

2.2、有效连接间隔:

有效连接间隔等于两个连接事件之间的时间跨度。当没有数据从从机发送到主机时,从机每500ms 一个 连接事件 交互一次 。

2.3、连接参数注意事项:

德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第3张图片

2.4、多连接下的连接参数限制:

为了有时间能够扫描新设备,可以使用的最小连接间隔为12.5+5*n。n为当前连接的数量。

2.5、连接参数更新

外设可以发送连接参数更新请求来请求主机更改连接设置。
-该请求包含四个参数:最小连接间隔,最大连接间隔,从延迟和
监管 超时。这些值表外围设备对连接所需的参数(连接间隔作为范围给出)。当 主机 设备接收到该请求时,它可以接受或拒绝新的参数。

  • 根据
    GAPRole ,连接参数更新可以 调用 GAPRole_SendUpdateParam 或GAPCentralRole_UpdateLink 命令异步发送。

2.6、连接终止:

主机和从机可以由于任何原因终止连接,一方终止,另一方必须在两台设备退出连接状态之前进行相应。

2.7、GAP概述:

应用层可以直接调用GAP APi来执行BLE相关功能,大多数GAP由GAProle task处理。

德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第4张图片

2.8、配置GAP:

GAP层功能主要在库代码中定义,这些功能大多由GAPRole调用,不需要应用直接调用。

  • 开始GAPRole 之前可能需要修改的几个参数。这些参数可以通过 GAP_SetParamValue 和GAP_GetParamValue 函数进行设置或获取,包括 广播和扫描间隔、 窗口等(有关更多信息,请参阅 API )。以下是 simple_peripheral_init 中 GAP 层的配置:

德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第5张图片

三、GAPRole任务

  • 这是一个单独的任务,处理大多数GAP层的功能,并且释放应用层的空间。这个任务由应用程序启用和配置,许多蓝牙低功耗协议栈实际那由GAPRole任务直接处理而不传送到应用程序中。
  • 应用程序可以向GAPRole注册回调函数,用于在应用程序中处理某些事件。
    德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第6张图片

3.1、外设角色 peripheral:

操作流程:
1、 初始化GAPRole参数:
在这里插入图片描述
2、初始化GAPROle任务,并且将应用程序回调函数传回GAPRole。
在这里插入图片描述
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第7张图片
4、GAPRole任务处理了绝大多数GAP事件,将一些事件转发到应用程序。

3.2、central主机:

1、初始化参数:
在这里插入图片描述
2、启动任务:
在这里插入图片描述
3、从应用程序中发送数据之后,会通过central函数到达stack。
4、GAPRole任务也处理了一部分事件,然后将一部分事件转发到应用程序。

四、GATT通用属性配置文件:

GATT主要用于两个连接设备之间的数据通信。数据以特征值的形式传输和存储。从GATT的角度来看,:

  • gattu服务器:一个包含特性数据库中的设备,可以通过一个GATT客户端写入或者读取。
  • GATT客户端,是向GATT服务器写入或者读取数据的设备。
    德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第8张图片

4.1、GATT:characteristics and attributes特征和属性:

德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第9张图片

4.2、四个GATT配置文件:

1、gatt服务
2、通用属性服务:GATT服务器的信息。
3、设备信息服务:
4、simple_gatt_profile 这个是用于测试的profile文件。

以下是简单Profile 文件属性表的逐行描述,由以下句柄引用。
0x001F是 simple_gatt_profile 服务声明 。该声明的 UUID 为 0x2800 (蓝牙定义的
GATT_PRIMARY_SERVICE_UUID )。该声明的值是 simple_gatt_profile (自定义)的 UUID 。
0x0020是 SimpleProfileChar1 的特征声明 。该声明可以被认为是指向
SimpleProfileChar1 值的指针。该声明的 UUID 为 0x2803 (蓝牙定义的
GATT_CHARACTER_UUID )。 5 字节 的特征值如下 (从 MSB 到 LSB
字节0 :蓝牙规范中定义的 SimpleProfileChar1 的属性(以下是一些相关属性。)
0x02:允许读取特征值
0x04:允许写入特征值(无响应
0x08:允许写入特征值(带响应
0x10:允许通知特征值(无确认
0x20:允许通知特征值(带确认 0x0A 的值表示特性可读( 0x02 )和可写 0x08 )。

字节1 2 SimpleProfileChar1 值的字节反转句柄(句柄 0x0021
字节3 4 SimpleProfileChar1 值的 UUID (自定义 0xFFF1
0x0021是 SimpleProfileChar1 值 。该值的 UUID 为 0xFFF1 (自定义)。该值是特征的实际有效载荷数据。如其特征声明(句柄 0x0020 )所示,该值是可读写的。
0x0022是 SimpleProfileChar1 用户描述 。该描述的 UUID 为 0x2901 (蓝牙定义)。该
描述的值是描述特征的可读字符串。
0x00230x002F 是剩下的四个特征描述的 simpleProfileChar1 相同结构的属性。 唯一
不同的 属性,处理 0x002B ,描述如下。
0x002B是 SimpleProfileChar4 客户端特征配置 。此配置的 UUID 为 0x2902 (蓝牙定
义)。通过写入此属性, GATT 服务器可以将 SimpleProfileChar4 配置为通知。

4.3、GAP GATT Service GGS服务:

GGS是实主机或者外围设备的低功耗多必须的。当然,使用低功耗的设备也必然包含GGS。GGS的目的实在设备发现和连接启动的过程中进行辅助。

4.3.1、使用GGS:

  • 首先,我们也应该知道GGS同样也是以lib的形式存在于协议栈中。
    1、包含头文件 $install/src/inc #include "gapgattserver.h"
    2、初始化GGS参数:
// GAP GATT Attributes
 static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Peripheral"; GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);

3、使用GGS初始化应用程序回调。
4、将GGS添加到GATT服务器。

4.4、GATT服务:

该服务提供注册GATT服务的相关信息。

4.4.1、使用GATT服务:

这一部分要求用户必须使能GATT可变服务属性,当使用ble的时候。

4.5、GATT client抽象:

GATT客户端没有属性表或者profile文件。因为他是收集方。

4.5.1、使用GATT:

同样的,GATT的服务也在库中实现:

  • 客户端使用GATT:
    1、初始化客户端:
    VOID GATT_InitClient();
    2、注册接受传入的ATT指示和通知:
    GATT_RegisterForInd(selfEntity);
    3、执行GATT客户端过程:

德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第10张图片
4、接受处理GATT,当收到事件的时候,最后由库发送数据。
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第11张图片

5、GATT客户端可以从GATT服务器接受指示或者数据。

4.6、GATT服务抽象:

GATT得大部分配置在:GattServApp

4.6.1、GattServApp模块:

GATTServApp存储和管理应用程序范围的属性表。各种 Profile 文件使用此模块将其特性添加到属性表 中 。低功耗蓝牙 协议栈 使用此模块来响应 GATT 客户端的请求。例如, GATT客户端可以发送“发现所有主要特征”消息。 GATT 服务器上的 低功耗蓝牙协议栈 收到此消息,并使用 GATTServApp 查找并发送存储在属性表中的所有主要特性。从 Profile 文件访的GATTServApp 功能在 gattservapp_util.c 中定义。

1、创建属性表:

// 初始化GATT属性
GGS_AddService(GATT_ALL_SERVICES); //添加服务
GATTServApp_AddService(GATT_ALL_SERVICES); //添加属性服务
DevInfo_AddService(); // 加入设备信息服务
 #ifndef FEATURE_OAD_ONCHIP 
 SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile #endif //!FEATURE_OAD_ONCHIP

德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第12张图片

4.6.2、profile架构:

我们可以查到profile的翻译有:轮廓;简介;形象;外形。但是你在蓝牙协议中这个词语究竟是代表什么。其实不是很好定义,不妨我们直接就简单的把这个profile看成字母A,然后我们自己来定义这个定义:

4.6.2.1、 属性表定义:

每个GATT属性的服务,都需要一个属性表:
表的定义:
static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED]

typedef struct attAttribute_t { gattAttrType_t type; //!< Attribute type (2 or 16 octet UUIDs)
uint8 permissions; //!< Attribute permissions 
uint16 handle; //!< Attribute handle - assigned internally by attribute server 
uint8* const pValue; //!< Attribute value - encoding of the octet array is defined in //!< the applicable profile. The maximum length of an attribute //!< value shall be 512 octets. } gattAttribute_t;

权限配置:

德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第13张图片

特征声明:
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第14张图片
特征值:
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第15张图片
特征值配置:
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第16张图片

4.6.2.2、添加服务功能:

应用程序启动的时候,需要添加所支持的GATT服务:
1、为客户端特征配置CCC数组分配空间:
在这里插入图片描述
2、初始化CCC数组,
GATTServApp_InitCharCfg(INVALID_CONHANDLE, simpleProfileChar4Config );
3、使用GATTServApp注册配置文件:

4.6.2.3、注册应用程序回调函数:

在这里插入图片描述
当然,我们必须实现这一个回调函数:
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第17张图片

4.6.2.4、读写回调函数:

1、客户端读取请求:
当给定属性收到GATT客户端的读取请求的时候,调用回调文件。
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第18张图片
2、客户端的写请求:
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第19张图片
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第20张图片
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第21张图片
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第22张图片

4.6.2.5、GET和set函数:

用来读取和写入配置文件:
德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第23张图片

4.6.3、排队书写:

GATT_PARAM_NUM_PREPARE_WRITES

4.7、GATT过程中的动态内存:

德州CC2640R2f蓝牙芯片学习笔记(四)蓝牙协议栈_第24张图片

4.8在应用中接受更多GATT事件:

GATT_RegisterForMsgs可以接收到更多的GATT事件:
主要有以下三类:
1、GATT服务器无法发送ATT相应,尝试在下一个连接间隔发送。
2、ATT流量控制违规,通知应用程序接入的设备违反ATT流量规则。
3、更新ATT MTU大小。

4.9、GATT安全:

4.9.1:认证:

在客户端通过认证配对方法之前,无法访问需要身份验证的特性。

4.9.2:授权:

应用程序需要定义自己的授权请求,所以协议栈将这些特性的读写请求转发到应用程序层。
1、 注册授权回调:

CONST gattServiceCBs_t simpleProfileCBs = { 
simpleProfile_ReadAttrCB, // Read callback function pointer 
simpleProfile_WriteAttrCB, // Write callback function pointer 
simpleProfile_authorizationCB // Authorization callback function pointer };

2、调用回调函数:
不要再这里执行复杂的功能

static bStatus_t simpleProfile_authorizationCB( uint16 connHandle,gattAttribute_t *pAttr,uint8 opcode ) { 
//This is just an example implementation, normal use cases would require //more complex logic to determine that the device is authorized
if(clientIsAuthorized) 
	return SUCCESS; 
else return ATT_ERR_INSUFFICIENT_AUTHOR; }

你可能感兴趣的:(#,蓝牙,嵌入式通讯)