The GATT DB(Database) is an important data structure of the WICED Smart application, please refer to “Create GATT Database” for GATT DB description. This document introduces GATT DB definition, initialization, work flow and APIs.
GATT DB Definition
The GATT DB definition usually is in the beginning of application code, the following sample is in hello_sensor.c.
const UINT8 hello_sensor_gatt_database=
// Handle 0x01: GATT service
// Service change characteristic is optional and is not present
PRIMARY_SERVICE_UUID16 (0x0001, UUID_SERVICE_GATT),
// Handle 0x14: GAP service
// Device Name and Appearance are mandatory characteristics. Peripheral
// Privacy Flag only required if privacy feature is supported. Reconnection
// Address is optional and only when privacy feature is supported.
// Peripheral Preferred Connection Parameters characteristic is optional
// and not present.
PRIMARY_SERVICE_UUID16 (0x0014, UUID_SERVICE_GAP),
// Handle 0x15: characteristic Device Name, handle 0x16 characteristic value.
// Any 16 byte string can be used to identify the sensor. Just need to
// replace the "Hello" string below. Keep it short so that it fits in
// advertisement data along with 16 byte UUID.
CHARACTERISTIC_UUID16 (0x0015, 0x0016, UUID_CHARACTERISTIC_DEVICE_NAME,
LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE, 16),
// Handle 0x17: characteristic Appearance, handle 0x18 characteristic value.
// List of approved appearances is available at bluetooth.org. Current
// value is set to 0x200 - Generic Tag
CHARACTERISTIC_UUID16 (0x0017, 0x0018, UUID_CHARACTERISTIC_APPEARANCE,
LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE, 2),
// Handle 0x28: Hello Service.
// This is the main proprietary service of Hello Sensor. It has 2 characteristics.
// One will be used to send notification(s) to the paired client when button is
// pushed, another is a configuration of the device. The only thing which
// can be configured is number of times to send notification. Note that
// UUID of the vendor specific service is 16 bytes, unlike standard Bluetooth
// UUIDs which are 2 bytes. _UUID128 version of the macro should be used.
PRIMARY_SERVICE_UUID128 (HANDLE_HELLO_SENSOR_SERVICE_UUID, UUID_HELLO_SERVICE),
// Handle 0x29: characteristic Hello Notification, handle 0x2a characteristic value
// we support both notification and indication. Peer need to allow notifications
// or indications by writing in the Characteristic Client Configuration Descriptor
// (see handle 2b below). Note that UUID of the vendor specific characteristic is
// 16 bytes, unlike standard Bluetooth UUIDs which are 2 bytes. _UUID128 version
// of the macro should be used.
CHARACTERISTIC_UUID128 (0x0029, HANDLE_HELLO_SENSOR_VALUE_NOTIFY, UUID_HELLO_CHARACTERISTIC_NOTIFY,
LEGATTDB_CHAR_PROP_READ | LEGATTDB_CHAR_PROP_NOTIFY | LEGATTDB_CHAR_PROP_INDICATE,
// Handle 0x2b: Characteristic Client Configuration Descriptor.
// This is standard GATT characteristic descriptor. 2 byte value 0 means that
// message to the client is disabled. Peer can write value 1 or 2 to enable
// notifications or indications respectively. Not _WRITABLE in the macro. This
// means that attribute can be written by the peer.
LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_REQ, 2),
// Handle 0x2c: characteristic Hello Configuration, handle 0x2d characteristic value
// The configuration consists of 1 bytes which indicates how many notifications or
// indications to send when user pushes the button.
CHARACTERISTIC_UUID128_WRITABLE (0x002c, HANDLE_HELLO_SENSOR_CONFIGURATION, UUID_HELLO_CHARACTERISTIC_CONFIG,
LEGATTDB_CHAR_PROP_READ | LEGATTDB_CHAR_PROP_WRITE,
LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ, 1),
// Handle 0x4d: Device Info service
// Device Information service helps peer to identify manufacture or vendor
// of the device. It is required for some types of the devices (for example HID,
// and medical, and optional for others. There are a bunch of characteristics
// available, out of which Hello Sensor implements 3.
PRIMARY_SERVICE_UUID16 (0x004d, UUID_SERVICE_DEVICE_INFORMATION),
// Handle 0x4e: characteristic Manufacturer Name, handle 0x4f characteristic value
CHARACTERISTIC_UUID16 (0x004e, 0x004f, UUID_CHARACTERISTIC_MANUFACTURER_NAME_STRING, LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE, 8),
// Handle 0x50: characteristic Model Number, handle 0x51 characteristic value
CHARACTERISTIC_UUID16 (0x0050, 0x0051, UUID_CHARACTERISTIC_MODEL_NUMBER_STRING, LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE, 8),
// Handle 0x52: characteristic System ID, handle 0x53 characteristic value
CHARACTERISTIC_UUID16 (0x0052, 0x0053, UUID_CHARACTERISTIC_SYSTEM_ID, LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE, 8),
// Handle 0x61: Battery service
// This is an optional service which allows peer to read current battery level.
PRIMARY_SERVICE_UUID16 (0x0061, UUID_SERVICE_BATTERY),
// Handle 0x62: characteristic Battery Level, handle 0x63 characteristic value
CHARACTERISTIC_UUID16 (0x0062, 0x0063, UUID_CHARACTERISTIC_BATTERY_LEVEL,
LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE, 1),
BLE stack calls the APPLICATION_INIT to get the GATT DB configuration and initialize GATT DB before application runs. The following sample code is in hello_sensor.c.
GATT DB Working Flow
The following figure is the GATT DB working flow.
Client is able to read the data from the GATT DB after the server writes data to GATT DB. But server does not need to know how and when client's read is performed.
Client write data to GATT DB, the write callback function is called on server side, server read data from the GATT DB in callback function. If client write requires an acknowledgement, it is done by the stack without server being involved.
APIs for Server Role
INT32 bleprofile_ReadHandle(UINT16 hdl, BLEPROFILE_DB_PDU *p_pdu);
Read data from GATT DB.
INT32 bleprofile_WriteHandle(UINT16 hdl, BLEPROFILE_DB_PDU *p_pdu);
Write data to GATT DB.
void bleprofile_sendIndication(UINT16 attrHandle, UINT8 *attr, INT32 len, LEATT_NO_PARAM_CB cb);
Send an Indication to client.
Client sends back acknowledgement if it received the indication, sever will call the callback function “cb” if it receives the acknowledgement. Server should not send next indication until previous one has been acknowledged.
void bleprofile_sendNotification(UINT16 attrHandle, UINT8 *attr, INT32 len);
Send a notification to client. The notification does NOT need confirmation.
INT32 legattdb_regWriteHandleCb(LEGATTDB_WRITE_CB cb);
Register write callback function for GATT DB. The callback function “cb” will be called when client write data to GATT DB.
APIs for Client Role
void bleprofile_sendWriteReq(UINT16 attrHandle, UINT8 *attr, INT32 len);
Send write request to server.
Before calling this function, application can register a callback function to receive notification with write result by function leatt_regWriteRspCb.
void bleprofile_sendWriteCmd(UINT16 attrHandle, UINT8 *data, INT32 len);
Send write command to server.
void bleprofile_sendReadReq(UINT16 Handle);
Send read request to server.
Before calling this function, application typically register a callback function to receive notification with read result by function leatt_regReadRspCb.
void bleprofile_sendReadByTypeReq(UINT16 startHandle, UINT16 endHandle, UINT16 uuid16);
Send read request to server by type.
Before calling this function, application typically register a callback function to receive notification with read result by function leatt_regReadByTypeRspCb. This function usually is called by the client during GATT discovery.
void bleprofile_sendReadByGroupTypeReq(UINT16 startHandle, UINT16 endHandle, UINT16 uuid16);
Send read request to server by group type.
Before calling this function, application typically register a callback function to receive notification with read result by function leatt_regReadByGroupTypeRspCb. This function usually is called by the client during GATT discovery.
Send acknowledgement to server if received the indication.