Hello,
How can I configure for a GATT characteristic which type will be used.
Without defining it will be a byte array.
I'd like to configure for example an int16 number or int32 number.
Greetings,
Peter Kwekkeboom
Hi Peter
The normal way to handle this is to define your data in a struct, and then create a union type that allows your struct to be accessed either through its various fields (that could be int32, int16 or anything else), or as a byte array that you can pass to functions that expect it.
I made a small example to demonstrate this. The data struct is called my_data_t, and here you can define the values that you want to include in your characteristic:
#include <zephyr.h> #include <device.h> #include <devicetree.h> typedef struct { uint32_t var1; uint16_t var2; } __packed my_data_t; typedef union { my_data_t data; uint8_t byte_array[sizeof(my_data_t)]; } my_compound_type_t; void main(void) { my_compound_type_t char_data; char_data.data.var1 = 1; char_data.data.var2 = 2; printk("Data in byte format: "); uint8_t *data_ptr = char_data.byte_array; uint32_t data_length = sizeof(my_data_t); for(int i = 0; i < data_length; i++) { printk("0x%.2x ", data_ptr[i]); } printk("\n"); while (1) { } }
Best regards
Torbjørn
Hello Torbjørn,
This is not what I realy mean. In the bluetooth GATT protocol there is a way to describe which format a characteristic must be displayed on the app side.
I allready found out that gatt descriptor with UID 0x2904 must be used. But are there also specific libarary functions for to define is for the characteristic?
Gr. Peter
Hi Peter
Thanks for clarifying. It sounds like what you are looking for is how to set up the characteristic presentation format descriptor then.
Essentially you can use the BT_GATT_CPF macro for this.
You just need to provide the right value, according to the type you want to use. This list can be found various places, including here.
When using the macro it is important to put it the right place in the service and characteristic declaration, since the order of service, characteristic and descriptor declarations has to match the order they should have in the attribute table, according to the Bluetooth specification.
Essentially you have to put any descriptor after the characteristic they belong to, and if a characteristic uses the CCCD descriptor (meaning the BT_GATT_CCC macro is used) the CCCD should be the first descriptor in the list.
As an example, I modified the heart rate service declaration (from here) to add a CPF descriptor to the HRS body sensor characteristic like this, defining the type as uint32 (0x08):
/* Heart Rate Service Declaration */ BT_GATT_SERVICE_DEFINE(hrs_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_HRS), BT_GATT_CHARACTERISTIC(BT_UUID_HRS_MEASUREMENT, BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_NONE, NULL, NULL, NULL), BT_GATT_CCC(hrmc_ccc_cfg_changed, HRS_GATT_PERM_DEFAULT), BT_GATT_CHARACTERISTIC(BT_UUID_HRS_BODY_SENSOR, BT_GATT_CHRC_READ, HRS_GATT_PERM_DEFAULT & GATT_PERM_READ_MASK, read_blsc, NULL, NULL), BT_GATT_CPF(0x08), BT_GATT_CHARACTERISTIC(BT_UUID_HRS_CONTROL_POINT, BT_GATT_CHRC_WRITE, HRS_GATT_PERM_DEFAULT & GATT_PERM_WRITE_MASK, NULL, NULL, NULL), );
Best regards
Torbjørn