用户工具

站点工具


cc2640r2f:gatt_servapp_module

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
cc2640r2f:gatt_servapp_module [2017/08/31 16:30]
127.0.0.1 外部编辑
cc2640r2f:gatt_servapp_module [2021/06/22 23:14] (当前版本)
行 1: 行 1:
 <markdown> <markdown>
-# GATTServApp模块 # 
-GATT服务器应用程序(GATTServApp)存储和管理应用程序范围的属性表。各种配置文件使用此模块将其特性添加到属性表。蓝牙低功耗协议栈使用此模块来响应GATT客户端的发现请求。例如,GATT客户端可以发送**Discover all Primary Characteristics**消息。GATT服务器端的蓝牙低功耗协议栈接收到该消息,并使用GATTServApp查找并发送存储在属性表中的所有主要特性。这种类型的功能超出了本文档的范围,它们是在库代码中实现。可以从`gattservapp_util.c`中定义配置文件以及`BLE Stack API Reference`(GATTServApp部分)中描述的API来查看GATTServApp函数。这些功能包括查找特定属性和阅读或修改客户端特征配置。有关GATTServApp在应用程序中的功能的示例,请参见图46 . 
  
-下图示意了属性表的初始化这幅图实完全对GATT Services和Profile中的属性表。该流程图是程序上下文的具体实现过程图中可以看出在程序中分别使用前面涉及GGS_Addservice();GATTServApp_AddService();DevInfo_AddService();SimpleProfile_AddService();就这样一步一步在GATT Server中构建了属性+# GATT ServApp 模块 # 
 + 
 +GATT 服务器应用程序(GATT ServApp)用于存储和管理应用程序范围的属性表,各种配置文件使用此模块将特性添加到属性表。 
 + 
 +蓝牙低功耗协议栈使用此模块来响应 GATT 客户端发现请求。例如,GATT 客户端可以发送** Discover all Primary Characteristics **消息,GATT 服务器端的蓝牙低功耗协议栈接收到该消息,使用 GATT ServApp 查找并发送存储在属性表中的所有主要特性 
 + 
 +这种类型的功能超出了本范围,它们是在库代码中实现可以从 `gattservapp_util.c` 定义配置文件,也可以从 `BLE Stack API Reference`( GATT  ServApp 部)中描述的 API 来查看 GATT ServApp 函数,函数功能包括查找特定属性和阅读修改客户端特征配置 
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gatt_servapp_module/Images/Attribute.png) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gatt_servapp_module/Images/Attribute.png)
  
 +图1. GATT ServApp 的功能示例
 +
 +GATT ServApp 在应用程序中的功能示例如图 1,图中示意了属性表的初始化,对应着 GATT Services 和 Profile 中的属性表。该流程图是程序上下文的具体实现过程,程序中分别使用了 GGS_Addservice()、GATTServApp_AddService()、DevInfo_AddService()、SimpleProfile_AddService(),一步一步在 GATT Server 中构建了属性表。
  
 ## 构建属性表 ## ## 构建属性表 ##
-上电或重置时,应用程序使用GATTServApp来创建GATT表添加服务每个服务都包含具UUID权限以及读取和写入回调的属性列表。正如图46所示,所有这些信息是通过GATTServApp传递到GATT存储在堆栈中。 + 
-属性表初始化必须在应用程序初始化函数中出现,也就是simple_peripheral_init()。+上电或重置时,应用程序通过 GATT ServApp 创建 GATT 表添加服务每个服务都包含具体 UUID 值权限以及读取和写入回调的属性列表。正如图 所示,所有这些信息是通过 GATT ServApp 传递到 GATT 存储在堆栈中。 
 + 
 +属性表初始化必须在应用程序初始化函数中出现,也就是 simple_peripheral_init()。 
 ````C ````C
- //初始化GATT属性+ //初始化 GATT 属性
  GGS_AddService (GATT_ALL_SERVICES );          // GAP   GGS_AddService (GATT_ALL_SERVICES );          // GAP 
- GATTServApp_AddService (GATT_ALL_SERVICES );  // GATT属性+ GATTServApp_AddService (GATT_ALL_SERVICES );  // GATT 属性
 ```` ````
 +
 ## 在属性表中实现配置文件 ## ## 在属性表中实现配置文件 ##
  
 ### 属性表的定义 ### ### 属性表的定义 ###
-GATT属性的每个服务或组必须定义一个固定大小的属性表,该表被传递到GATT中。simple_gatt_profile.c中的此表定义如下+ 
 +GATT 属性的每个服务或组必须定义一个固定大小的属性表,该表被传递到 GATT 中。 simple_gatt_profile.c 中的此表定义如下: 
 ````C ````C
  static  gattAttribute_t  simpleProfileAttrTbl [ SERVAPP_NUM_ATTR_SUPPORTED ]  static  gattAttribute_t  simpleProfileAttrTbl [ SERVAPP_NUM_ATTR_SUPPORTED ]
 ```` ````
-表中的每个属性都是以下类型+ 
 +表中的每个属性都是以下类型: 
 ````C ````C
  typedef struct attAttribute_t  typedef struct attAttribute_t
  {  {
-    gattAttrType_t type; //!< 属性类型(2或16个八位字节UUID)+    gattAttrType_t type; //!< 属性类型(2 或 16 个八位字节 UUID)
     uint8 permissions;   //!< 属性权限     uint8 permissions;   //!< 属性权限
   
     uint16 handle;        //!< 属性句柄-由属性服务器内部分配     uint16 handle;        //!< 属性句柄-由属性服务器内部分配
   
-    uint8* const pValue; //!< 属性值 -属性值的最大长度为512 octets。+    uint8* const pValue; //!< 属性值 -属性值的最大长度为 512 octets。
  } gattAttribute_t;  } gattAttribute_t;
 ```` ````
-- **gattAttrType_t类型** + 
-  type是与放置在表中的属性相关联的UUID。gattAttrType_t本身定义为:+- ** gattAttrType_t 类型** 
 +  type 是与放置在表中的属性相关联的 UUID 。gattAttrType_t 本身定义为: 
 +  
 ````C ````C
  typedef  struct   typedef  struct 
  
-    uint8  len ;          //!<UUID的长度(2或16) +    uint8  len ;          //!<UUID 的长度(2或16) 
-    const  uint8  * uuid ;  //!<指向UUID的指针+    const  uint8  * uuid ;  //!<指向 UUID 的指针
  }  gattAttrType_t ;  }  gattAttrType_t ;
 ```` ````
-  其中长度可以是ATT_BT_UUID_SIZE(2字节)或 ATT_UUID_SIZE(16字节)。*uuid是指向蓝牙SIG(定义在gatt_uuid.c中)或在配置文件中定义的自定义UUID保留的数字的指针。 
  
-- **uint8权限** +  其中长度可以是 ATT_BT_UUID_SIZE(2字节)或 ATT_UUID_SIZE(16字节)。* uuid 是指向蓝牙 SIG(定义在 gatt_uuid.c 中)或配置文件中定义的自定义 UUID 保留的数字指针。 
-  强制GATT客户端设备如何以及如何访问该属性的值可能的权限在gatt.h中定义如下:+ 
 +- ** uint8 权限** 
 +  强制 GATT 客户端设备如何读取和访问该属性的值可能的权限在 gatt.h 中定义如下:
  
   |宏定义|16进制数|权限|   |宏定义|16进制数|权限|
行 59: 行 78:
   |#define GATT_PERMIT_ENCRYPT_WRITE|0x80|写需要加密|   |#define GATT_PERMIT_ENCRYPT_WRITE|0x80|写需要加密|
  
-  这里的认证、授权、加密后面GATT内存分配部分还会详细说明。+  这里的认证、授权、加密后面 GATT 内存分配部分还会详细说明。
  
-- **uint16 handle** +- ** uint16 handle ** 
-  handle不可修改,由属性服务器内部分配(顺序分配)。+  handle 不可修改,由属性服务器内部分配(顺序分配)。
  
-- **uint8 * const pValue** +- ** uint8 * const pValue ** 
-pValue是指向属性值的指针初始化后大小无法更改最大大小为512个字节。+  pValue 是指向属性值的指针初始化后大小无法更改最大为 512 个字节。 
 + 
 +### Service 声明 ### 
 + 
 +参考下面 simple_gatt_profile service 声明:
  
-### Service声明 ### 
-参考下面simple_gatt_profile service声明 
 ````C ````C
  // Simple Profile Service   // Simple Profile Service 
行 78: 行 99:
  }  }
 ```` ````
-其中type设置的是蓝牙SIG规范定义的主服务UUID(0x2800)权限为可读(GATT_PERMIT_READ),允许客户端读取该服务。pValue是指向服务的UUID的指针,自定义为0xFFF0。+ 
 +其中 type 设置的是蓝牙 SIG 规范定义的主服务 UUID(0x2800)权限为可读( GATT_PERMIT_READ),允许客户端读取该服务。pValue 是指向服务的 UUID的指针,自定义为 0xFFF0。 
 ````C ````C
- // Simple Profile Service属性+ // Simple Profile Service 属性
  static  CONST  gattAttrType_t  simpleProfileService   static  CONST  gattAttrType_t  simpleProfileService 
          
行 87: 行 110:
     };     };
 ```` ````
 +
 ### characteristic Declaration ### ### characteristic Declaration ###
-参考下面simple_gatt_profile Characteristic1 Declaration+ 
 +参考下面 simple_gatt_profile Characteristic1 Declaration: 
 ````C ````C
- //特征1声明+ //特征 1 声明
  
      ATT_BT_UUID_SIZE , characterUUID  }, // type       ATT_BT_UUID_SIZE , characterUUID  }, // type 
行 98: 行 124:
  },  },
 ```` ````
-type设置为蓝牙SIG定义的characteristic UUID(0x2803)。权限为可读(GATT_PERMIT_READ),允许客户端读取该服务。对于characteristic Declaration中的pValue值,传递给GATTServApp,GATTServApp只需要characteristic Value的权限,所以在characteristic Declaration的pValue中值传递了characteristic Value的权限,可读可写(0x0A)。GATTServApp会自动构建characteristic value的handle和UUID。放入characteristic Declaration的pValue的2-4个字节中。 
  
-注意:characteristic Declaration中pValue和characteristic Value中的权限是有区别的前者是GATT客户端可以读取看见属性后者是characteristic Value的真实权限,这意味着他们必须要一致会混淆GATT客户端开发者+type 设置为蓝牙 SIG 定义的 characteristic UUID(0x2803),权限为可读(GATT_PERMIT_READ)允许客户端读取该服务。对于 characteristic Declaration 中的 pValue 值传递给 GATT ServApp,GATT ServApp 只需要 characteristic Value 的权限。所以在 characteristic Declaration 的 pValue 值传递了 characteristic Value 的权限,可读可写(0x0A)。GATT ServApp 会自动构建 characteristic value 的 handle 和 UUID ,然后放入 characteristic Declaration 的 pValue 的 2-4 个字节中
  
-### 客户端Characteristic Configuration ### +>注意:characteristic Declaration 中的 pValue 和 characteristic Value 中的权限是有区别的前者是 GATT 客户端可以取看见的属性,后是 characteristic Value 的真实权限,这意味着们必须要一致不然会混淆 GATT 客户端的开发者
-这部分首先要明白一点,前面说的characteristic value 12,3,5都是客户端发送写命令服务端响应处理然后返回,但characteristic4 value不具有读写权限,他是通知属性意思就是characteristic4 value只能是服务端发送给客户端。下面代码设置了characteristic config 可读可写属性,所以客户端可以配置characteristic4 value,比如当前就是禁用通知。客户端可以设置characteristic config 的值来控制通知属性+
  
-参考simple_gatt_profile中Characteristic4配置+### 客户端 Characteristic Configuration ### 
 + 
 +首先要明白一点,前面说的 characteristic value 1、2、3、5 都是客户端发送读写命令,然后服务端响应处理并返回。但 characteristic 4 value 不具有读写权限,它仅仅是通知属性,只能是服务端发送给客户端。 
 + 
 +下面代码设置了 characteristic config 的可读可写属性,客户端可以配置 characteristic 4 value,比如当前就是禁用通知。客户端可以设置 characteristic config 的值来控制通知属性。 
 + 
 +参考 simple_gatt_profile 中 Characteristic 4 配置
  
 ````C ````C
行 124: 行 154:
    },    },
 ```` ````
 +
 ## 添加服务功能 ## ## 添加服务功能 ##
-如GATTServApp 模块所述,应用启动时,需要添加支持的GATT服务。每个配置文件都需要一个全局AddService函数,用于被应用程序调用。其中一些服务在协议栈中定义,如GAP GATT服务和GATT服务。用户定义的服务必须公开自己的AddService函数,该应用程序可以调用配置文件初始化。以SimpleProfile_AddService()为例,这些功能应该如下。 
  
-- 为客户端特征配置(CCC)阵列分配空间。作为示例,指向这些数组之一的指针在配置文件中初始化,如client_characteristic_configuration中所述。 +如 GATT ServApp 模块所述,应用启动时需要添加支持的 GATT 服务。每个配置文件都需要一个全局 AddService 函数,用于被应用程序调用。其中一些服务在协议栈中定义,如 GAP GATT 服务和 GATT 服务。用户定义的服务必须公开自己的 AddService 函数,该应用程序可以调用配置文件初始化。以 SimpleProfile_AddService()为例,这些功能应该如下: 
-AddService函数中,声明支持的连接,并为每个数组分配内存。只有一个CCC在simple_gatt_profile中定义,但可以有多个CCC。当有多个设备连接服务端,服务端的simpleProfileChar4Config必须为每个连接了的客户端分配一个内存,用于为每个设备保存通知配置。+ 
 +- 为客户端特征配置(CCC)阵列分配空间。作为示例,指向这些数组之一的指针在配置文件中初始化,如 client_characteristic_configuration 中所述。 
 +AddService 函数需要声明支持的连接,并为每个数组分配内存。只有一个 CCC 在 simple_gatt_profile 中定义,但可以有多个 CCC 。当有多个设备连接服务端,服务端的 simpleProfileChar4Config 必须为每个连接了的客户端分配一个内存,用于为每个设备保存通知配置。
  
 ````C  ````C
行 140: 行 172:
 ```` ````
  
-- 初始化CCC数组CCC值在掉电之后也能够保存下来,使用下面函数初始化CCC值。可以在连接设备时尝试使用之前保存的值,如果连接设备是新的设备则使用默认值。+使用下面的函数初始化 CCC 数组,这样 CCC 值在掉电之后也能够保存下来。可以在连接设备时尝试使用之前保存的值,如果连接设备是新的设备则使用默认值。 
 ````C ````C
  `GATTServApp_InitCharCfg ( INVALID_CONHANDLE , simpleProfileChar4Config  );`  `GATTServApp_InitCharCfg ( INVALID_CONHANDLE , simpleProfileChar4Config  );`
 ```` ````
-- 使用GATTServApp_RegisterService注册配置文件。该函数功能是将配置文件的属性表传递给GATTServApp,以便将配置文件的属性添加到由协议栈管理的应用程序范围的属性表中,并为每个属性分配句柄。这也将配置文件的回调指针传递给堆栈,以启动GATTServApp和配置文件之间的通信。+ 
 +- 使用 GATTServApp_RegisterService 注册配置文件。该函数功能是将配置文件的属性表传递给 GATT ServApp,以便将配置文件的属性添加到由协议栈管理的应用程序属性表中,并为每个属性分配句柄。这也将配置文件的回调指针传递给堆栈,以启动 GATT ServApp 和配置文件之间的通信。 
 ````C  ````C
  //Register GATT attribute list and CBs with GATT Server App  //Register GATT attribute list and CBs with GATT Server App
行 152: 行 187:
                                        &simpleProfileCBs  );                                        &simpleProfileCBs  );
 ```` ````
 +
 ## 注册应用程序回调函数 ## ## 注册应用程序回调函数 ##
-配置文件可以使用回调将邮件中继到应用程序。在simple_peripheral项目中,只要GATT客户端写入特征值,simple_gatt_profile将调用应用程序回调。对于要使用这些应用程序回调,配置文件必须定义一个注册应用程序回调函数,该应用程序在初始化期间用于设置回调。simple_gatt_profile的注册应用程序回调函数如下:+ 
 +配置文件可以使用回调将邮件中继到应用程序。在 simple_peripheral 项目中,只要 GATT 客户端写入特征值,simple_gatt_profile 将调用应用程序回调。如果要使用这些应用程序回调,配置文件必须定义一个注册应用程序回调函数,该应用程序在初始化期间用于设置回调。simple_gatt_profile 的注册应用程序回调函数如下: 
 ````C ````C
  bStatus_t  SimpleProfile_RegisterAppCBs ( simpleProfileCBs_t  * appCallbacks   bStatus_t  SimpleProfile_RegisterAppCBs ( simpleProfileCBs_t  * appCallbacks 
行 169: 行 207:
  }  }
 ```` ````
-其中回调typedef被定义如下。+ 
 +其中回调 typedef 被定义为: 
 ````C ````C
  typedef  struct   typedef  struct 
行 177: 行 217:
 ```` ````
  
-然后,应用程序必须定义此类型的回调,并将其传递给具有SimpleProfile_RegisterAppCBs()函数的simple_gatt_profile。这发生在simple_peripheral.c中,如下所示+然后,应用程序必须定义此类型的回调,并将其传递给具有 SimpleProfile_RegisterAppCBs()函数的 simple_gatt_profile 。这发生在 simple_peripheral.c 中,代码如下所示: 
 ````C  ````C
- //简单的GATT配置文件回调+ //简单的 GATT 配置文件回调
  #ifndef FEATURE_OAD_ONCHIP   #ifndef FEATURE_OAD_ONCHIP 
  static  simpleProfileCBs_t  SimpleBLEPeripheral_simpleProfileCBs   static  simpleProfileCBs_t  SimpleBLEPeripheral_simpleProfileCBs 
行 189: 行 230:
  // ...  // ...
   
- //使用SimpleGATTprofile注册回调+ //使用 SimpleGATTprofile 注册回调
  SimpleProfile_RegisterAppCB (&SimpleBLEPeripheral_simpleProfileCBs );  SimpleProfile_RegisterAppCB (&SimpleBLEPeripheral_simpleProfileCBs );
 ```` ````
-上述操作完成之后,一旦characteristic中value改变,SBP_CHAR_CHANGE_EVT事件被更新,应用程序就可以收到并处理改变的值。 
  
 +上述操作完成之后,一旦 characteristic 中 value 改变,SBP_CHAR_CHANGE_EVT 事件被更新,应用程序就可以收到并处理改变的值。
  
 ## 客户端读请求 ## ## 客户端读请求 ##
-如图所示当接收到来自GATT客户端的读取请求时,协议栈检查属性的权限如果属性可读,则调用Profile读回调函数。Profile复制该值,并在profile层执行特定处理,由ATT_ReadRsp指令发送给协议栈,协议栈使用ATT_READ_RSP发送给客户端。+ 
 +如图 所示当接收到来自 GATT 客户端的读取请求时,协议栈检查属性的权限如果属性可读,则调用 Profile 读回调函数。Profile 复制该值,并在 profile 层执行特定处理,由 ATT_ReadRsp 指令发送给协议栈,协议栈使用 ATT_READ_RSP 发送给客户端。
  
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gatt_servapp_module/Images/read.png) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gatt_servapp_module/Images/read.png)
 +
 +图2. 客户端读请求流程
  
 ## 客户端写请求 ## ## 客户端写请求 ##
-当收到来自GATT客户端给定属性的写请求时,协议栈会检查属性的权限如果该属性是允许写的,则调用该配置文件的回调。配置文件存储要写入的值,执行profile层响应处理,并在需要时通知应用程序。图显示了simple_gatt_profile中simpleprofileChar3的写入过程。+ 
 +当收到来自 GATT 客户端给定属性的写请求时,协议栈会检查属性的权限如果该属性是允许写的,则调用该配置文件的回调。配置文件存储要写入的值,执行 profile 层响应处理,并在需要时通知应用程序。图 显示了 simple_gatt_profile 中 simpleprofileChar3 的写入过程。
  
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gatt_servapp_module/Images/write.png) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gatt_servapp_module/Images/write.png)
  
-注意:协议栈程序最小化处理非常重要,在该示例中,应用程序通过消息队列的方式,在应用程序上下文中处理value改变之后额外的处理过程。+图3. 客户端写请求流程 
 + 
 + > 注意:协议栈程序最小化处理非常重要,在该示例中,应用程序在上下文中通过消息队列的方式处理 value 改变之后额外过程。
  
 ## 获取和设置函数 ## ## 获取和设置函数 ##
-包含characteristic的配置文件应为应用程序提供set和get抽象功能,以读取和写入配置文件的characteristic。设置参数功能还包括如果相关characteristic有通知或指示属性,则检查并实现通知和指示的逻辑。下面的显示了在simple_gatt_profile中设置simpleProfileChacteristic4这个例子。+ 
 +包含 characteristic 的配置文件应为应用程序提供 set 和 get 抽象功能,以读取和写入配置文件的 characteristic 。设置参数功能还包括如果相关 characteristic 有通知或指示属性,则检查并实现通知和指示的逻辑。 
 + 
 +图 4 是在 simple_gatt_profile 中设置 simpleProfile Chacteristic 4 的例子。
  
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gatt_servapp_module/Images/setandget.png) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gatt_servapp_module/Images/setandget.png)
  
-如,应用程序通过以下方法在simple_peripheral.c中将simpleProfileCharacteristic4初始化为0+图4. 设置 Chacteristic 4 示 
 + 
 +应用程序在 simple_peripheral.c 中将 simpleProfile Characteristic 4 初始化为 0 ,代码如下: 
 ````C ````C
  uint8_t charValue4 = 0;  uint8_t charValue4 = 0;
行 218: 行 271:
 ```` ````
  
-此函数的代码显示在以下代码片段中(来自simple_gatt_profile.c)。除了设置静态simpleProfileChar4的值之外,该函数还调用 GATTServApp_ProcessCharCfg(),因为它具有通知属性操作会强制GATTServApp检查GATT客户端是否已启用通知如果是这样GATTServApp会向GATT客户端发送此属性的通知。+以下代码片段在 simple_gatt_profile.c 中,除了设置静态 simpleProfileChar4 的值之外,该函数还调用 GATTServApp_ProcessCharCfg()。这个调用操作会强制 GATT ServApp 检查 GATT 客户端是否已启用通知如果启用GATT ServApp 会向 GATT 客户端发送此属性的通知。 
 ````C ````C
  bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )  bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
行 234: 行 288:
                                  INVALID_TASK_ID, simpleProfile_ReadAttrCB );                                  INVALID_TASK_ID, simpleProfile_ReadAttrCB );
  }  }
-```` +````  
 +
 ## 队列写 ## ## 队列写 ##
-当接收到多个写指令是,GATT服务端通过排队方式处理更多的有效数据。默认队列大小为5.默认MTU为23,有效载荷为18字节,最多可以接收90个字节的有效载荷。有关排队写入的更多信息,请参阅蓝牙核心规范版本5.0的排队写入部分([Vol 3],F部分,第3.4.6节)。 
  
-使用GATTServApp_SetParameter()与参数调整队列大小GATT_PARAM_NUM_PREPARE_WRITES。没有指定的限制,但它由可用的HEAPMGR空间限定。+当接收到多个写指令是,GATT 服务端通过排队方式处理更多的有效数据。默认队列大小为 5 ,默认 MTU 为 23,有效载荷为 18 字节,最多可以接收 90 个字节的有效载荷。有关排队写入的更多信息,请参阅蓝牙核心规范版本 5.0 的排队写入部分([Vol 3],F部分,第3.4.6节)。 
 + 
 +使用 GATTServApp_SetParameter()与参数调整队列大小 GATT_PARAM_NUM_PREPARE_WRITES。虽然没有指定的限制,但它由可用的 HEAPMGR 空间限定。
  
  
-## 为GATT程序分配内存 ##+## 为 GATT 程序分配内存 ##
  
-GATT和ATT有效载荷结构必须动态分配内存。例如,发送GATT_Notification时必须分配缓冲区。这里有两种方法,一种是上面讲过的首选方式调用SimpleProfile_SetParameter();一种是直接调用如果使用发送GATT通知或指示的首选方法,一种是直接使用GATT_Notification()或GATT_Indication();其实本质上SimpleProfile_SetParameter()也是调用的GATT_Notification()或GATT_Indication()。+GATT 和 ATT 有效载荷结构必须动态分配内存。例如,发送 GATT_Notification 时必须分配缓冲区。这里有两种方法,一种是上面讲过的首选方式调用 SimpleProfile_SetParameter(),一种是直接使用 GATT_Notification()或 GATT_Indication()其实本质上S impleProfile_SetParameter()也是调用的 GATT_Notification()或 GATT_Indication()。
  
-如果直接使用GATT_Notification()或GATT_Indication(),则必须如下添加内存管理(gattServApp_SendNotiInd中)。+如果直接使用 GATT_Notification()或 GATT_Indication(),则必须如下添加内存管理(gattServApp_SendNotiInd中)。
  
-1. 尝试使用GATT_bm_alloc()为通知或指示有效载荷分配内存。 +1. 尝试使用 GATT_bm_alloc()为通知或指示有效载荷分配内存。 
-2. 如果分配成功,则使用GATT_Notification()或 GATT_Indication()发送通知或指示。+2. 如果分配成功,则使用 GATT_Notification()或 GATT_Indication()发送通知或指示。
  
-注意:如果通知或指示的返回值为SUCCESS (0x00),则堆栈释放内存。+ > 注意:如果通知或指示的返回值为 SUCCESS (0x00),则堆栈释放内存。
  
-3. 如果返回值不是SUCCESS,则使用GATT_bm_free()来释放内存。以下是GATTServApp_SendNotiInd gattservapp_util.c文件中函数的一个示例。+3. 如果返回值不是 SUCCESS,则使用 GATT_bm_free()来释放内存。以下是 GATTServApp_SendNotiInd gattservapp_util.c 文件中函数的一个示例。
   
 ````C  ````C
行 287: 行 343:
  }  }
 ```` ````
-## 注册接收应用程序中的其他GATT事件 ## 
  
-使用GATT_RegisterForMsgs(),可以接收额外的GATT消息来处理某些角落情况。这种情况可以在SimpleBLEPeripheral_processGATTMsg()中看到。目前处理以下三种情况。+## 注册接收应用程序中其他 GATT 事件 ##
  
-- 堆栈中的GATT服务器无法发送ATT响应(由于缺少可用的HCI缓冲区):尝试在下一个连接间隔发送。另外,如果在蓝牙核心规范版本5.0中指定的ATT事务在30秒内未完成,则会发送bleTimeout状态。+使用 GATT_RegisterForMsgs() 可以接收额外的 GATT 消息处理某些角落情况,这些情况可以在 SimpleBLEPeripheral_processGATTMsg() 中看到,目前处理以下三种情况。 
 + 
 +- 堆栈中的 GATT 服务器无法发送 ATT 响应(由于缺少可用的 HCI 缓冲区):尝试在下一个连接间隔发送。另外,如果在蓝牙核心规范版本 5.0 中指定的 ATT 事务在 30 秒内未完成,则会发送 bleTimeout 状态。
  
 ````C ````C
行 313: 行 370:
  }  }
 ```` ````
-- ATT流量控制违规:通知应用程序连接的设备违反ATT流量控制规范,例如发送指示确认之前发送读取请求。在连接过程中,无需更多的ATT请求或指示。应用程序可能希望由于此违规而终止连接。作为simple_peripheral的一个例子,display被更新。+ 
 +- ATT 流量控制违规:通知应用程序连接的设备违反 ATT 流量控制规范,例如发送指示确认之前发送读取请求。在连接过程中,无需更多的 ATT 请求或指示。应用程序可能希望由于此违规而终止连接。作为 simple_peripheral 的一个例子,display 被更新。 
 ````C ````C
  else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)  else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)
行 325: 行 384:
  }  }
 ```` ````
-- 更新ATT MTU大小:通知应用程序,以防任何方式影响其处理。有关MTU 的更多信息,请参见最大传输单元(MTU)。作为simple_peripheral的一个例子,display被更新。+ 
 +- 更新 ATT MTU大小:通知应用程序,以防任何方式影响其处理。有关 MTU 的更多信息,请参见最大传输单元(MTU)。作为 simple_peripheral 的一个例子,display 被更新。 
 ````C ````C
  else if (pMsg->method == ATT_MTU_UPDATED_EVENT)  else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
行 335: 行 396:
  
 ## 加入我们 ## ## 加入我们 ##
 +
 文章所有代码、工具、文档开源。加入我们[**QQ群 591679055**](http://shang.qq.com/wpa/qunwpa?idkey=d94f12d37c3b37892af4b757c6dc34bea140f3f3128a8d68e556a3d728148e85)获取更多支持,共同研究CC2640R2F&BLE5.0。 文章所有代码、工具、文档开源。加入我们[**QQ群 591679055**](http://shang.qq.com/wpa/qunwpa?idkey=d94f12d37c3b37892af4b757c6dc34bea140f3f3128a8d68e556a3d728148e85)获取更多支持,共同研究CC2640R2F&BLE5.0。
 <div> <div>
行 344: 行 406:
  
 </markdown> </markdown>
- 
cc2640r2f/gatt_servapp_module.1504168239.txt.gz · 最后更改: 2021/06/22 23:14 (外部编辑)