ble/gattdb/service.h header reference
[Bluetooth Low Energy library module]

The source code of this header can be browsed online.

Description [link] 

A service declaration is a struct ble_gattdb_service_s object containing all the characteristics and their parameters.

Standard Service, Characteristic and Descriptors assigned-numbers are provided in relevant headers for services, characteristics, and descriptors assigned numbers, they can be used freely for all device's service declarations.

Service, Characteristics and their parameters are defined through constant structures. This can be written explicitly, but there are various macros provided to shorten the declaration process.

Here is the explicit version of a Device Information Service declaration where we define characteristic values, UUID objects and characteristic array, and finally, service object.

// A Characteristic array
static const
struct ble_gattdb_characteristic_s dis_service_characteristic_array[] =
{
{
.type = BLE_UUID_BT_BASED_P(BLE_GATT_CHAR_MANUFACTURER_NAME_STRING),
.permissions = BLE_GATTDB_PERM_OTHER_READ,
.mode = BLE_GATTDB_CHARACTERISTIC_CONSTANT,
.data.constant.data = "MutekH",
.data.constant.size = 6,
}, {
.type = BLE_UUID_BT_BASED_P(BLE_GATT_CHAR_MODEL_NUMBER_STRING),
.permissions = BLE_GATTDB_PERM_OTHER_READ,
.mode = BLE_GATTDB_CHARACTERISTIC_CONSTANT,
.data.constant.data = "BLE RGB Led",
.data.constant.size = 11,
},
};

// Service definition object
const struct ble_gattdb_service_s dis_service = {
.flags = BLE_GATTDB_SERVICE_PRIMARY,
.type = BLE_UUID_BT_BASED_P(BLE_GATT_SERVICE_DEVICE_INFORMATION),
.include = NULL,
.characteristic = dis_service_characteristic_array,
.characteristic_count = 2,
};

But this code is too long and verbose. It should be shorter to get maintainable. Hopefully, library defines helper macros to define services.

For instance, the above declaration can be shortened as:

Because a service declaration is simple and explicit, there is no library of service declarations: this is unneeded.

Then, registration of service is done through a call to ble_gattdb_service_register. This is enough to get the service exposed in the GATT database. ble/gattdb/db.h.

A custom service gets declared the same way. For instance, Apple-designed MIDI over BLE Service gets declared as:

BLE_GATTDB_SERVICE_DECL(
midi_service,
BLE_GATTDB_SERVICE_PRIMARY | BLE_GATTDB_SERVICE_ADVERTISED,
BLE_UUID_P(0x03B80E5A, 0xEDE8, 0x4B33, 0xA751, 0x6CE34EC4C700ULL),
NULL,
BLE_GATTDB_CHAR(
BLE_UUID_P(0x7772E5DB, 0x3868, 0x4112, 0xA1A9, 0xF2669D106BF3ULL),
BLE_GATTDB_PERM_AUTH_WRITE | BLE_GATTDB_PERM_AUTH_READ | BLE_GATTDB_NOTIFIABLE,
BLE_GATTDB_CHAR_DATA_DYNAMIC(NULL, on_midi_data_write, NULL)),
);

This declares a service with type 03B80E5A-EDE8-4B33-A751-6CE34EC4C700. This service will be declared as primary and advertised in AD. It contains a write/notify secure characteristic with type 7772E5DB-3868-4112-A1A9-F2669D106BF3. User-provided on_midi_data_write function will be called to handle writes to the characteristic.

See examples/ble/midi/midi.c for complete example.

Services defined with the GATT DB library only consider Characteristics. All indices target characteristic index in service, or descriptor index in characteristic. Handle allocation for attributes is completely hidden. For instance, third argument to on_midi_data_write above is the characteristic number in the characteristic array (will be 0). This permits to set the same callback function for many characteristics.

Service flags [link] 

Service flags let the service be defined as Primary, and allow to advertise the service in Advertise Data (AD).

If primary service flag is not set, service will be exposed as secondary service in GATT DB.

Advertised service flag makes the service UUID exported in ble_gattdb_srv16_list_get and ble_gattdb_srv128_list_get calls, used internally by stack context to build AD.

Characteristic data modes [link] 

There are 3 main characteristic modes:

  • Constant, where characteristic value is a constant data object in memory, without callback functions;

  • Plain, where characteristic value is a global data object, but where callback functions may be defined to handle read, writes, and subscription to notification or indication;

  • Dynamic, where data is dynamically computed for each access.

Constant mode [link] 

For Constant mode, user must define data blob and size. Relevant macro is BLE_GATTDB_CHAR_CONSTANT_BLOB. There is a shortcut for constant string: BLE_GATTDB_CHAR_CONSTANT_STRING.

static const uint16_t appearance = BLE_GAP_APPEARANCE_HID_MOUSE;

BLE_GATTDB_SERVICE_DECL(gap_service,
BLE_GATTDB_SERVICE_PRIMARY,
BLE_UUID_SHORT_P(BLE_UUID_GENERIC_ACCESS_SERVICE),
NULL,
BLE_GATTDB_CHAR_CONSTANT_BLOB(
BLE_UUID_SHORT_P(BLE_UUID_GAP_APPEARANCE_CHAR),
&appearance, sizeof(appearance)),
BLE_GATTDB_CHAR_CONSTANT_STRING(
BLE_UUID_SHORT_P(BLE_UUID_GAP_DEVICE_NAME_CHAR),
"Mouse"),
);

Plain mode [link] 

For Plain mode, user must define data blob and size, and may specify callbacks for subscription and write actions.

static uint8_t battery_level;

static
uint8_t batt_level_subscribe(struct ble_gattdb_registry_s *reg,
uint8_t charid,
bool_t subscribed)
{
printk("Battery level %s\n", subscribed ? "subscribed" : "unsubscribed");

return 0;
}

BLE_GATTDB_SERVICE_DECL(
batt_service,
BLE_GATTDB_SERVICE_PRIMARY,
BLE_UUID_SHORT_P(BLE_UUID_BATTERY_SERVICE),
NULL,
// One characteristic
BLE_GATTDB_CHAR(
// Type
BLE_UUID_SHORT_P(BLE_UUID_BATTERY_LEVEL_CHAR),
// Readable by all, notifiable
BLE_GATTDB_NOTIFIABLE | BLE_GATTDB_PERM_OTHER_READ,
// Backed by a global data blob "battery_level"
// Library must call batt_level_subscribe on subscription change
// No write callback
BLE_GATTDB_CHAR_DATA_PLAIN(&battery_level, sizeof(battery_level),
batt_level_subscribe, NULL),
);

Dynamic mode [link] 

For Dynamic mode, user must define callbacks for subscription, read and write actions, depending on characteristic access flags.

static
uint8_t on_midi_data_write(struct ble_gattdb_client_s *client,
struct ble_gattdb_registry_s *reg, uint8_t charid,
const void *data, size_t size)
{
printk("midi data write: %P\n", data, size);

return 0;
}

BLE_GATTDB_SERVICE_DECL(
midi_service,
BLE_GATTDB_SERVICE_PRIMARY | BLE_GATTDB_SERVICE_ADVERTISED,
BLE_UUID_P(0x03B80E5A, 0xEDE8, 0x4B33, 0xA751, 0x6CE34EC4C700ULL),
NULL,
BLE_GATTDB_CHAR(
BLE_UUID_P(0x7772E5DB, 0x3868, 0x4112, 0xA1A9, 0xF2669D106BF3ULL),
// PERM_AUTH_READ implies pairing before subscribing,
// but as there is not read handler, reading value
// will not be permitted.
BLE_GATTDB_PERM_AUTH_WRITE | BLE_GATTDB_PERM_AUTH_READ | BLE_GATTDB_NOTIFIABLE,
// Dont implement read
// Call on_midi_data_write on write
// Dont notify code on subscription
BLE_GATTDB_CHAR_DATA_DYNAMIC(NULL, on_midi_data_write, NULL)),
);

For notifiable characteristics, code may call ble_gattdb_char_changed to push a notification to GATT client.

Characteristic perimissions [link] 

Characteristic permissions can limit how characteristic values are accessed by peer GATT client. See enum ble_gattdb_permission_e.

Access to Characteristic values is an inclusive list: BLE_GATTDB_PERM_AUTH_... implies BLE_GATTDB_PERM_ENC_... implies BLE_GATTDB_PERM_OTHER_.... A client coming in clear text has OTHER permissions. Once encrypted, ENC permissions are also granted, then, if pairing is authenticated, AUTH permissions are also granted.

Library checks for readability for allowing subscription to characteristic value notifications and indications. A dynamic characteristic that can not be read but notified only should still be declared as BLE_GATTDB_PERM_OTHER_READ, BLE_GATTDB_PERM_ENC_READ or BLE_GATTDB_PERM_AUTH_READ in order for the library to tell how to enforce acces control to the value. on_read callback can still be NULL in such cases.

Service includes [link] 

Service includes are mostly useful for standard profiles implementation. In the library, service include is done referencing a service definition structure from another. This could lead to some ambiguity if included service is present more than once in GATT DB, but this case never actually happens in practice.

Members [link] 

Types [link] 

Macros [link] 

Members detail [link] 

#define BLE_GATTDB_CHAR(type_, perms_, args_...) [link] 

This macro is declared in ble/gattdb/service.h source file, line 531.

Helper to define a characteristic.

#define BLE_GATTDB_CHAR_CONSTANT_BLOB(type_, value_, size_) [link] 

This macro is declared in ble/gattdb/service.h source file, line 489.

Helper to define a characteristic in Constant mode, where backing data is a blob.

#define BLE_GATTDB_CHAR_CONSTANT_STRING(type_, value_) [link] 

This macro is declared in ble/gattdb/service.h source file, line 502.

Helper to define a characteristic in Constant mode, where backing data is a string.

#define BLE_GATTDB_CHAR_DATA_CONSTANT(data_, size_) [link] 

This macro is declared in ble/gattdb/service.h source file, line 541.

Helper to define a characteristic data in constant mode.

#define BLE_GATTDB_CHAR_DATA_DYNAMIC(read_, write_, subs_) [link] 

This macro is declared in ble/gattdb/service.h source file, line 559.

Helper to define a characteristic data in dynamic mode.

#define BLE_GATTDB_CHAR_DATA_PLAIN(data_, size_, subs_, changed_) [link] 

This macro is declared in ble/gattdb/service.h source file, line 549.

Helper to define a characteristic data in plain mode.

#define BLE_GATTDB_CHAR_DATA_STREAM(read_, get_data_, subs_) [link] 

This macro is declared in ble/gattdb/service.h source file, line 569.

Helper to define a characteristic data in streaming mode.

Preprocessor condition: defined( CONFIG_BLE_GATTDB_STREAM )

#define BLE_GATTDB_DESCRIPTORS(items_...) [link] 

This macro is declared in ble/gattdb/service.h source file, line 579.

Helper to define descriptors in a characteristic.

#define BLE_GATTDB_DESCRIPTOR_USER_DESCRIPTION(desc_) [link] 

This macro is declared in ble/gattdb/service.h source file, line 586.

Helper to define a user description descriptor.

#define BLE_GATTDB_SERVICE_DECL(name_, flags_, type_, included_, chars_...) [link] 

This macro is declared in ble/gattdb/service.h source file, line 519.

Helper to define a service.

#define BLE_GATTDB_SERVICE_H [link] 

This macro is declared in ble/gattdb/service.h source file, line 21.

#define BLE_GATTDB_SERVICE_INCLUDED_(included_) [link] 

This macro is declared in ble/gattdb/service.h source file, line 510.

Helper to define inclusion list for a service.

Alternate declarations with same identifier: [1], [2].

Preprocessor condition: defined( CONFIG_BLE_GATTDB_INCLUDE )

#define BLE_GATTDB_SERVICE_INCLUDED_(included_) [link] 

This macro is declared in ble/gattdb/service.h source file, line 513.

Documentation from alternate declaration:

Helper to define inclusion list for a service.

Alternate declarations with same identifier: [1], [2].

Preprocessor condition: not defined( CONFIG_BLE_GATTDB_INCLUDE )

enum ble_gattdb_characteristic_mode_e [link] 

This enum is declared in ble/gattdb/service.h source file, line 254.

this enum defines various characteristic data modes.

See also Characteristic data modes.

IdentifierDescription
BLE_GATTDB_CHARACTERISTIC_CONSTANTConstant data mode, characteristic data will be defined in ble_gattdb_characteristic_s::data::constant.
BLE_GATTDB_CHARACTERISTIC_PLAINPlain data mode, characteristic data will be defined in ble_gattdb_characteristic_s::data::plain.
BLE_GATTDB_CHARACTERISTIC_DYNAMICDynamic data mode, characteristic data will be defined in ble_gattdb_characteristic_s::data::dynamic.
BLE_GATTDB_CHARACTERISTIC_STREAMStreaming data mode, characteristic may be read from, or notified/indicated, but not written to. Gatt DB will call user code back to get more data to send to client.
BLE_GATTDB_CHARACTERISTIC_DYNAMIC_PREPAREDDynamic Prepared data mode, this is still unimplemented.

struct ble_gattdb_characteristic_s [link] 

This struct is declared in ble/gattdb/service.h source file, line 344.

this struct defines a characteristic in the service definition.

FieldDescription
const struct ble_uuid_s * type;Characteristic type
uint16_t permissions;Characteristic permissions
enum ble_gattdb_characteristic_mode_e mode:8;Characteristic data mode
uint8_t descriptor_count;Characteristic descriptor count
const struct ble_gattdb_descriptor_s * descriptor;Characteristic descriptor array
union <anonymous> {Characteristic data definition, depending on mode
struct <anonymous> {Characteris data constant mode
const void * data;Data buffer
size_t size;Data buffer size
} constant;
struct <anonymous> {Characteristic data plain mode
void * data;Data buffer
size_t size;Data buffer size
uint8_t (*on_subscribe)(struct ble_gattdb_registry_s *reg, uint8_t charid, bool_t subscribed) ;Callback on subscription of characteristic
uint8_t (*on_changed)(struct ble_gattdb_client_s *client, struct ble_gattdb_registry_s *reg, uint8_t charid) ;Callback on value change of characteristic. If this function returns an error, write is rejected and value is not updated.
The return value is an error value
} plain;
struct <anonymous> {Characteristic data dynamic mode
uint8_t (*on_subscribe)(struct ble_gattdb_registry_s *reg, uint8_t charid, bool_t subscribed) ;Callback on subscription of characteristic
uint8_t (*on_write)(struct ble_gattdb_client_s *client, struct ble_gattdb_registry_s *reg, uint8_t charid, const void *datasize_t size) ;Callback on write to characteristic.
uint8_t (*on_read)(struct ble_gattdb_client_s *client, struct ble_gattdb_registry_s *reg, uint8_t charid, uint16_t offset, void *datasize_t *size) ;Callback on read from characteristic.
} dynamic;
struct <anonymous> {Characteristic data stream mode
uint8_t (*on_subscribe)(struct ble_gattdb_registry_s *reg, uint8_t charid, bool_t subscribed) ;Callback on subscription
uint8_t (*on_read)(struct ble_gattdb_client_s *client, struct ble_gattdb_registry_s *reg, uint8_t charid, uint16_t offset, void *datasize_t *size) ;Callback on read from characteristic (used on explicit read, if supported).
error_t (*on_get_data)(struct ble_gattdb_client_s *client, struct ble_gattdb_registry_s *reg, uint8_t charid, struct buffer_s *buffer) ;Callback getting next item to stream. May return -EAGAIN to tell gattdb that there is no more data to stream available.
} stream;
struct <anonymous> {Characteristic dynamic prepared mode, unimplemented
uint8_t (*on_subscribe)(struct ble_gattdb_registry_s *reg, uint8_t charid, bool_t subscribed) ;
uint8_t (*on_read)(struct ble_gattdb_client_s *client, struct ble_gattdb_registry_s *reg, uint8_t charid, uint16_t offset, void *datasize_t *size) ;
uint8_t (*on_write_part)(struct ble_gattdb_client_s *client, struct ble_gattdb_registry_s *reg, uint8_t charid, uint16_t offset, const void *datasize_t size) ;
uint8_t (*on_execute)(struct ble_gattdb_client_s *client, struct ble_gattdb_registry_s *reg, uint8_t charid) ;
} dynamic_prepared;
} data;

struct ble_gattdb_descriptor_s [link] 

This struct is declared in ble/gattdb/service.h source file, line 325.

this struct defines additional descriptor data. This is needed for non-gatt descirptors (CCCD is not concerned here).

Preprocessor condition: defined( CONFIG_BLE_GATTDB_DESCRIPTOR )

FieldDescription
const struct ble_uuid_s * type;Descriptor type
const void * data;Descriptor value
uint16_t size;Descriptor value size, it is static
bool_t writable;Whether to allow client to write to characteristic

enum ble_gattdb_permission_e [link] 

This enum is declared in ble/gattdb/service.h source file, line 286.

this enum defines various characteristic access permissions.

See also Characteristic perimissions.

IdentifierDescription
BLE_GATTDB_PERM_OTHER_READCharacteristic may be read by anyone
BLE_GATTDB_PERM_OTHER_WRITECharacteristic may be written by anyone
BLE_GATTDB_PERM_ENC_READCharacteristic may be read over an encrypted link
BLE_GATTDB_PERM_ENC_WRITECharacteristic may be written over an encrypted link
BLE_GATTDB_PERM_AUTH_READCharacteristic may be read over an secure link
BLE_GATTDB_PERM_AUTH_WRITECharacteristic may be written over an secure link
BLE_GATTDB_PERM_ENC_READ
BLE_GATTDB_PERM_ENC_WRITE
BLE_GATTDB_PERM_AUTH_READ
BLE_GATTDB_PERM_AUTH_WRITE
BLE_GATTDB_NOTIFIABLECharacteristic may notified
BLE_GATTDB_INDICABLECharacteristic may indicated
BLE_GATTDB_BROADCASTABLECharacteristic may broadcasted (still unimplemented)

enum ble_gattdb_service_flags_e [link] 

This enum is declared in ble/gattdb/service.h source file, line 478.

this enum defines service flags.

See also Service flags.

IdentifierDescription
BLE_GATTDB_SERVICE_PRIMARYService will be declared as Primary service in the DB
BLE_GATTDB_SERVICE_ADVERTISEDService will be listed in ble_gattdb_srv16_list_get and ble_gattdb_srv128_list_get.

struct ble_gattdb_service_s [link] 

This struct is declared in ble/gattdb/client.h source file, line 52.

this struct defines the service definition for GATT Database.

See also Services declaration.

FieldDescription
const struct ble_uuid_s * type;Service type
const struct ble_gattdb_service_s ** include;Service include list, NULL terminated
const struct ble_gattdb_characteristic_s * characteristic;Service characteristic array
uint8_t characteristic_count;Service characteristic array size
uint8_t flags;Service flags
Valid XHTML 1.0 StrictGenerated by diaxen on Thu Aug 4 15:44:05 2022 using MkDoc