4643 views|0 replies

7422

Posts

2

Resources
The OP
 

(Transfer) CC2640R2F BLE5.0 Bluetooth protocol stack Generic Attribute Profile (GATT) [Copy link]

This post was last edited by freebsder on 2019-3-26 12:00
Generic Attribute Profile (GATT)
Just as the GAP layer is responsible for connection-related functions, GATT is mainly responsible for exchanging data between two connected devices. The GAP layer distinguishes BLE devices into Master (Central) and Slave (Perpherial), while the GATT layer distinguishes them into Server and Client. The client reads and writes the characteristic values stored on the server.
Server
This device contains the characteristics that are read or written by the GATT client.
Client
A Bluetooth device that reads or writes data from a GATT server.
Note: There is no direct relationship between the Server/Client role of GATT layer and the Master (Central)/Slave (Perpheral) of GAP layer. As shown in the figure above, the mobile phone acts as Central/Client and the CC2640R2 development board acts as Peripheral/Server.
GATTProfile, Service, Characteristics, Attributes
We must have a deep understanding of the concepts of Profile, Service, Characteristics, and Attributes of the GATT layer, because once the connection is established, these concepts are used for data interaction whether it is the embedded end or the application end. To help understand, we abstract the following inclusion relationship:
One or more Characteristic constitute a Service, one or more Services constitute a Profile, Characteristic is composed of multiple Attributes, and each Attribute consists of three attributes including Handle, Type, and Permissions.
Below we focus on Characteristic, which is also the final entity of our data interaction. Each characteristic contains the following four Attributes. l Characteristic Value
The value used for the characteristic
l Characteristic Declaration
A descriptor that stores the properties, location and type of the characteristic value
l Client Characteristic Configuration
Allows the GATT server to configure the characteristic to be notified (sent messages asynchronously) or indicated (sent messages asynchronously with confirmation)
l Characteristic User Description
An ASCII string describing the characteristic
These attributes are stored in the GATT server in the attribute table. In addition to the value, the following attributes are associated with each attribute.
Each of the above Attributes in turn consists of the following elements. l Handle
The index of the attribute in the table (each attribute has a unique handle)
l Type
Indicates what the attribute data represents (called UUIDs [Universally Unique Identifiers], some of which are defined by the Bluetooth SIG and some are custom)
l Permissions
Force GATT client devices how and what they can access the value of the attribute
GATTClient Abstraction Layer
As shown in the figure below, most GATT client applications directly use the GATT API (a few directly use the ATT layer API), and there is no profile file, because the GATT client is to get data and does not need to establish attribute tables and profiles.
GATTServer Abstraction Layer
As shown in the figure, on the GATT server side, most of the functions of the GATT layer are handled by independent profiles, and then you can see that the perfiles are handled by the GAttservApp module (a configurable module used to store and manage attribute tables, see BLE Stack API Reference for details).
So when setting up a GATT server, you first need to configure the profiles file. The profiles file calls the GattServAppApp module and uses its API to interface with the GATT layer. In this case, the application does not need to call the GATT layer API directly, and the application interfaces with the Profiles file.
GATT Services and Profile
As mentioned in the Overview section, a GATT service is a collection of characteristics. Multiple services can be combined to form a profile, and many profiles only implement one service, so profiles and services are interchangeable.
Four GATT services are defined in the simple_peripheral sample application project.
l GAP GATT Service (GGS)
This service contains device and access information, such as device name, vendor ID, and product ID.
The following characteristics are defined for this service:
Device Name
Appearance
Peripheral Preferred Connection Parameters
l Generic Attribute Service
This service contains information about the GATT server and is part of the Bluetooth low energy protocol stack. Each GATT server device needs to implement the Bluetooth 5.0 core specification.
l Device Information Service
This service exposes information about the device, such as hardware, software version, firmware version, specification information, compliance information, and manufacturer name. The Device Information Service is part of the Bluetooth low energy protocol stack and is configured by the application.
l simple_gatt_profile service
This service is a sample profile for testing and demonstration. The complete source code is provided in the simple_gatt_profile.c and simple_gatt_profile.h files. // Initialize GATT attributes GGS_AddService(GATT_ALL_SERVICES); // GAP GATT Service GATTServApp_AddService(GATT_ALL_SERVICES); // GATT Service DevInfo_AddService(); // Device InformationService SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile The following figure shows the attribute table in the simple_peripheral project. These attributes are set by the above four service functions. You can open them one by one to view and modify them. 407177 Using BTool to obtain the simple GATT profile attribute table. Red indicates Profile declaration, yellow indicates character declaration, and white indicates attributes related to a specific declaration. The simple_gatt_profile contains the following characteristics: l SIMPLEPROFILE_CHAR1
A 1-byte value that can be read or written from a GATT client device
l SIMPLEPROFILE_CHAR2
A 1-byte value that can be read from a GATT client device but not written
l SIMPLEPROFILE_CHAR3
A 1-byte value that can be written from a GATT client device but not read
l SIMPLEPROFILE_CHAR4
A 1-byte value that cannot be read or written directly from a GATT client device (this value is a notification attribute)
l SIMPLEPROFILE_CHAR5
A 5-byte value that can be read (but not written) from a GATT client device
0x001C is the simple_gatt_profile service declaration.
The UUID of this declaration is 0x2800 (Bluetooth defines GATT_PRIMARY_SERVICE_UUID). The value of this declaration is the UUID of simple_gatt_profile (custom).
0x001D is the SimpleProfileChar1 characteristic declaration.
This declaration can be thought of as a pointer to the SimpleProfileChar1 value. The UUID of this declaration is 0x2803 (Bluetooth defines GATT_CHARACTER_UUID). The following explains the meaning of the characteristic declaration value (MSB to LSB):
l Byte 0 is the Bluetooth Core Specification version 5.0x02: Allow reading of characteristic values 0x04: Allow writing of characteristic values (without response) 0x08: Allow writing of characteristic values (with response) 0x10: Allow notification of characteristic values (without confirmation) 0x20: Allow notification of characteristic values (with confirmation) characteristic1 0x0A means that the characteristic can be read and written (0x02|0x08) l Bytes 1-2: Handle of the value of SimpleProfileChar1 (handle 0x001E) l Bytes 3-4: UUID of the value of SimpleProfileChar1 (custom 0xFFF1) l 0x001E is the SimpleProfileChar1 characteristic value. This value has a UUID of 0xFFF1 (custom). This value is the actual payload data of the characteristic. As indicated by its SimpleProfileChar1 declaration (handle 0x01D), this value is readable and writable. 0x001F is the SimpleProfileChar1 characteristic user description. This description has a UUID of 0x2901 (Bluetooth defined). The value of this description is a user-readable string describing the characteristic. 0x0020 - 0x002C The remaining four characteristic descriptions have properties in the same structure as simpleProfileChar1. The only different properties are when handling 0x0028, which is described as follows. 0x0028 is the SimpleProfileChar4 client characteristic configuration. The UUID for this configuration is 0x2902 (Bluetooth defined). By writing to this attribute, a GATT server can configure the SimpleProfileChar4 to either notify (write 0x0001) or indicate (write 0x0002). Writing 0x0000 to this attribute disables both notifications and indications. GATT Security As described in GATT Server Abstraction, a GATT server may define permissions independently for each characteristic. A server may allow any client to access certain characteristics, while restricting access to other characteristics to only authenticated or authorized clients. These permissions are typically defined as part of a higher-level profile specification. For custom profiles, users can select the permissions they see fit. For more information on GATT security, see the Security Considerations section of the Bluetooth Core Specification Revision 5.0 ([Volume 3, Part G, Section 8]).
Authentication
Characteristics that require authentication cannot be accessed until the client has passed an authenticated pairing method. This verification is performed within the stack and does not require application processing. The only requirement is to have the GATT server properly registered with the characteristic.
For example, characteristic5 of the simple_gatt_profile is set to require authenticated reads. //characteristic 5 { ATT_BT_UUID_SIZE , simpleProfilechar5UUID } GATT_PERMIT_AUTHEN_READ , 0 , simpleProfileChar5 } When an unauthenticated client attempts to read this value, the GATT server will automatically reject it without calling simpleProfile_ReadAttrCB(). Only after authentication is successful will the read and write requests be forwarded to the read and write callbacks of profiles, see the following code, which is in the simpleProfile_ReadAttrCB() function in simple_gatt_profile.c.
case SIMPLEPROFILE_CHAR1_UUID:
case SIMPLEPROFILE_CHAR2_UUID:
case SIMPLEPROFILE_CHAR4_UUID:
*pLen = 1;
pValue[0] = *pAttr->pValue;
[ align=left] break;
case SIMPLEPROFILE_CHAR5_UUID:
*pLen = SIMPLEPROFILE_CHAR5_LEN;
VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN );
break;
default:
// Should never get here! (characteristics 3 and 4 do not have read permission)
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
Authorization
Authorization is the change or deletion of access rights to some documents that occurs after authentication, which requires authorization. Authorization is a security layer that BLE has implemented. Since applications need to define their own authorization requirements, the protocol stack forwards read/write requests for these characteristics to the application layer of the profile.
To register the authorization information of the GATT server from the profile file, it must define an authorization callback using the stack. As shown in the pseudo code below (authorization is not used in the example).
1.2. Implement the authorization callback code static bStatus_t simpleProfile_authorizationCB (uint16 connHandle, gattAttribute_t * pAttr, uint8 opcode) { // This is just an example implementation, normal use cases will require more complex logic to determine if the device is authorized if (clientIsAuthorized) return SUCCESS ; else return ATT_ERR_INSUFFICIENT_AUTHOR ; } The authorization callback is executed in the context of the stack, so no complex processing should be performed in this function. The exact implementation is up to the developer; the above callback should be considered a shell. SUCCESS is returned if the client has access to the characteristic, ATT_ERR_INSUFFICIENT_AUTHOR is not returned if authorization requires prior authentication over the connection, otherwise ATT_ERR_INSUFFICIENT_AUTHEN will be sent as an error response. If a characteristic requires authorization and an authorization callback is registered, but no application-level authorization callback is defined, the stack will return ATT_ERR_UNLIKELY. Because this error is not clear, TI recommends using the authorization callback.
Using the GATT layer directly
As mentioned above, the client abstraction also allows applications to use the GATT layer API directly. This section describes how to use the GATT layer in applications. The functions of the GATT layer are implemented in the library, but the header file functions can be found in gatt.h. A complete API reference is available in the BLE Stack API Reference. The general process of using the GATT layer as a GATT client (in the simple_central project) is as follows:
As can be seen in the figure, after the GATT client sends a command, it sends an ATT command to the protocol stack through ICALL, and then the protocol stack returns a response after processing. The ICALL then notifies the application with an ATT event, and the application processes the ATT event asynchronously. Note: In addition to receiving responses to its own commands, the GATT client can also receive asynchronous data from the GATT server as indications or notifications. Use GATT_RegisterForInd(selfEntity) to register to receive these ATT notifications and indications. These notifications and indications are also sent to the application as ATT events (ATT_HANDLE_VALUE_NOTI & ATT_HANDLE_VALUE_INDG). These events must be handled as described in GATT Services and Profiles.
GAP GATT Service (GGS)
As mentioned earlier in the GATT Services and Profiles, GGS services contain device and access information, such as device name, Appearance, and peripheral preferred connection parameters. The purpose of GGS is to assist in the device discovery and connection initiation process. For more information on GGS, refer to the "GAT service" and "Characteristics for GATTServer" sections of the Bluetooth Core Specification Version 5.0 ([Vol 3], Part C, Section 12). 1. Include headers #include “gapgattserver.h” 2. Initialize GGS parameters // GAP GATT Attributes static uint8_t attDeviceName [GAP_DEVICE_NAME_LEN ] = “This is a text” ; GGS_SetParameter (GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN , attDeviceName ); 3. Initialize application callbacks with GGS (optional). Applications are notified when any characteristic in GGS changes. GGS_RegisterAppCB (&appGGSCBs ); 4. Add GGS to the GATT server. bStatus_t GGS_AddService (GATT_ALL_SERVICES); After the above four steps, the GGS parameters are successfully set, and these parameters can be obtained when the central device connects to the peripheral device.Add GGS to the GATT server. bStatus_t GGS_AddService (GATT_ALL_SERVICES); After the above 4 steps, the parameters of GGS are successfully set, and these parameters can be obtained when the central device connects to the peripheral device.Add GGS to the GATT server. bStatus_t GGS_AddService (GATT_ALL_SERVICES); After the above 4 steps, the parameters of GGS are successfully set, and these parameters can be obtained when the central device connects to the peripheral device.Implementing the Authorization Callback Code static bStatus_t simpleProfile_authorizationCB (uint16 connHandle, gattAttribute_t * pAttr, uint8 opcode) { // This is just an example implementation, normal use cases will require more complex logic to determine if the device is authorized if (clientIsAuthorized) return SUCCESS; else return ATT_ERR_INSUFFICIENT_AUTHOR; } The authorization callback is executed in the context of the protocol stack, so no complex processing should be performed in this function. The specific implementation is up to the developer; the above callback should be treated as a shell. If the client has permission to access the characteristic, SUCCESS is returned. If not, ATT_ERR_INSUFFICIENT_AUTHOR is returned. Authorization requires prior authentication over the connection, otherwise ATT_ERR_INSUFFICIENT_AUTHEN will be sent as an error response.
If a characteristic that requires authorization is registered for an authorization callback, but no application-level authorization callback is defined, the protocol stack will return ATT_ERR_UNLIKELY. Because this error is not clear, TI recommends using the authorization callback.
Using the GATT layer directly
As mentioned above in the client abstraction, applications can also use the GATT layer API directly. This section describes how to use the GATT layer in an application. The functions of the GATT layer are implemented in the library, but the header file functions can be found in gatt.h. A complete API reference is available in the BLE Stack API Reference. The general process of using the GATT layer as a GATT client (in the simple_central project) is as follows:
As can be seen in the figure, after the GATT client sends a command, it sends an ATT command to the protocol stack through ICALL, and then the protocol stack processes and returns a response, and then ICALL notifies the application with an ATT event, and the application processes the ATT event asynchronously. Note: In addition to receiving responses to its own commands, the GATT client can also receive asynchronous data from the GATT server as indications or notifications. Use GATT_RegisterForInd(selfEntity) to register to receive these ATT notifications and indications. These notifications and indications are also sent to the application as ATT events (ATT_HANDLE_VALUE_NOTI & ATT_HANDLE_VALUE_INDG). These events must be handled as described in GATT Services and Profiles. GAP GATT Service (GGS) As mentioned in the previous GATT service and introduction, the GGS service contains device and access information, such as device name, Appearance, and peripheral preferred connection parameters. The purpose of GGS is to assist in the device discovery and connection initiation process. For more information about GGS, see the "GAT service" and "Characteristics for GATT Server" sections of the Bluetooth Core Specification Version 5.0 ([Vol 3], Part C, Section 12). 1. Include headers #include “gapgattserver.h” 2. Initialize GGS parameters // GAP GATT Attributes static uint8_t attDeviceName [GAP_DEVICE_NAME_LEN ] = “This is a text” ; GGS_SetParameter (GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN , attDeviceName ); 3. Initialize application callbacks with GGS (optional). Applications are notified when any characteristic in GGS changes. GGS_RegisterAppCB (&appGGSCBs ); 4. Add GGS to the GATT server. bStatus_t GGS_AddService (GATT_ALL_SERVICES); After the above four steps, the GGS parameters are successfully set, and these parameters can be obtained when the central device connects to the peripheral device.Implementing the Authorization Callback Code static bStatus_t simpleProfile_authorizationCB (uint16 connHandle, gattAttribute_t * pAttr, uint8 opcode) { // This is just an example implementation, normal use cases will require more complex logic to determine if the device is authorized if (clientIsAuthorized) return SUCCESS; else return ATT_ERR_INSUFFICIENT_AUTHOR; } The authorization callback is executed in the context of the protocol stack, so no complex processing should be performed in this function. The specific implementation is up to the developer; the above callback should be treated as a shell. If the client has permission to access the characteristic, SUCCESS is returned. If not, ATT_ERR_INSUFFICIENT_AUTHOR is returned. Authorization requires prior authentication over the connection, otherwise ATT_ERR_INSUFFICIENT_AUTHEN will be sent as an error response.
If a characteristic that requires authorization is registered for an authorization callback, but no application-level authorization callback is defined, the protocol stack will return ATT_ERR_UNLIKELY. Because this error is not clear, TI recommends using the authorization callback.
Using the GATT layer directly
As mentioned above in the client abstraction, applications can also use the GATT layer API directly. This section describes how to use the GATT layer in an application. The functions of the GATT layer are implemented in the library, but the header file functions can be found in gatt.h. A complete API reference is available in the BLE Stack API Reference. The general process of using the GATT layer as a GATT client (in the simple_central project) is as follows:
As can be seen in the figure, after the GATT client sends a command, it sends an ATT command to the protocol stack through ICALL, and then the protocol stack processes and returns a response, and then ICALL notifies the application with an ATT event, and the application processes the ATT event asynchronously. Note: In addition to receiving responses to its own commands, the GATT client can also receive asynchronous data from the GATT server as indications or notifications. Use GATT_RegisterForInd(selfEntity) to register to receive these ATT notifications and indications. These notifications and indications are also sent to the application as ATT events (ATT_HANDLE_VALUE_NOTI & ATT_HANDLE_VALUE_INDG). These events must be handled as described in GATT Services and Profiles. GAP GATT Service (GGS) As mentioned in the previous GATT service and introduction, the GGS service contains device and access information, such as device name, Appearance, and peripheral preferred connection parameters. The purpose of GGS is to assist in the device discovery and connection initiation process. For more information about GGS, see the "GAT service" and "Characteristics for GATT Server" sections of the Bluetooth Core Specification Version 5.0 ([Vol 3], Part C, Section 12). 1. Include headers #include “gapgattserver.h” 2. Initialize GGS parameters // GAP GATT Attributes static uint8_t attDeviceName [GAP_DEVICE_NAME_LEN ] = “This is a text” ; GGS_SetParameter (GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN , attDeviceName ); 3. Initialize application callbacks with GGS (optional). Applications are notified when any characteristic in GGS changes. GGS_RegisterAppCB (&appGGSCBs ); 4. Add GGS to the GATT server. bStatus_t GGS_AddService (GATT_ALL_SERVICES); After the above four steps, the GGS parameters are successfully set, and these parameters can be obtained when the central device connects to the peripheral device.Add GGS to the GATT server. bStatus_t GGS_AddService (GATT_ALL_SERVICES); After the above 4 steps, the parameters of GGS are successfully set, and these parameters can be obtained when the central device connects to the peripheral device.Add GGS to the GATT server. bStatus_t GGS_AddService (GATT_ALL_SERVICES); After the above 4 steps, the parameters of GGS are successfully set, and these parameters can be obtained when the central device connects to the peripheral device.h. A complete API reference is available in the BLE Stack API Reference. The general process of using the GATT layer as a GATT client (in the simple_central project) is as follows:
As can be seen in the figure, after the GATT client sends a command, it sends an ATT command to the protocol stack through ICALL, and then the protocol stack returns a response after processing. The ICALL then notifies the application with an ATT event, and the application processes the ATT event asynchronously. Note: In addition to receiving responses to its own commands, the GATT client can also receive asynchronous data from the GATT server as indications or notifications. Use GATT_RegisterForInd(selfEntity) to register to receive these ATT notifications and indications. These notifications and indications are also sent to the application as ATT events (ATT_HANDLE_VALUE_NOTI & ATT_HANDLE_VALUE_INDG). These events must be handled as described in GATT Services and Profiles. GAP GATT Service (GGS) As mentioned in the previous GATT service and introduction, the GGS service contains device and access information, such as device name, Appearance, and peripheral preferred connection parameters. The purpose of GGS is to assist in the device discovery and connection initiation process. For more information about GGS, see the "GAT service" and "Characteristics for GATT Server" sections of the Bluetooth Core Specification Version 5.0 ([Vol 3], Part C, Section 12). 1. Include headers #include “gapgattserver.h” 2. Initialize GGS parameters // GAP GATT Attributes static uint8_t attDeviceName [GAP_DEVICE_NAME_LEN ] = “This is a text” ; GGS_SetParameter (GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN , attDeviceName ); 3. Initialize application callbacks with GGS (optional). Applications are notified when any characteristic in GGS changes. GGS_RegisterAppCB (&appGGSCBs ); 4. Add GGS to the GATT server. bStatus_t GGS_AddService (GATT_ALL_SERVICES); After the above four steps, the GGS parameters are successfully set, and these parameters can be obtained when the central device connects to the peripheral device.h. A complete API reference is available in the BLE Stack API Reference. The general process of using the GATT layer as a GATT client (in the simple_central project) is as follows:
As can be seen in the figure, after the GATT client sends a command, it sends an ATT command to the protocol stack through ICALL, and then the protocol stack returns a response after processing. The ICALL then notifies the application with an ATT event, and the application processes the ATT event asynchronously. Note: In addition to receiving responses to its own commands, the GATT client can also receive asynchronous data from the GATT server as indications or notifications. Use GATT_RegisterForInd(selfEntity) to register to receive these ATT notifications and indications. These notifications and indications are also sent to the application as ATT events (ATT_HANDLE_VALUE_NOTI & ATT_HANDLE_VALUE_INDG). These events must be handled as described in GATT Services and Profiles. GAP GATT Service (GGS) As mentioned in the previous GATT service and introduction, the GGS service contains device and access information, such as device name, Appearance, and peripheral preferred connection parameters. The purpose of GGS is to assist in the device discovery and connection initiation process. For more information about GGS, see the "GAT service" and "Characteristics for GATT Server" sections of the Bluetooth Core Specification Version 5.0 ([Vol 3], Part C, Section 12). 1. Include headers #include “gapgattserver.h” 2. Initialize GGS parameters // GAP GATT Attributes static uint8_t attDeviceName [GAP_DEVICE_NAME_LEN ] = “This is a text” ; GGS_SetParameter (GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN , attDeviceName ); 3. Initialize application callbacks with GGS (optional). Applications are notified when any characteristic in GGS changes. GGS_RegisterAppCB (&appGGSCBs ); 4. Add GGS to the GATT server. bStatus_t GGS_AddService (GATT_ALL_SERVICES); After the above four steps, the GGS parameters are successfully set, and these parameters can be obtained when the central device connects to the peripheral device.

5.jpg (262.64 KB, downloads: 0)

5.jpg
This post is from RF/Wirelessly
Personal signature

默认摸鱼,再摸鱼。2022、9、28

 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

快速回复 返回顶部 Return list