This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to write/read GATT attribute values?

Hi, 

I am trying to implement BLE on nRF52840 using Zephyr APIs. I am wondering if anyone can elaborate how to use bt_gatt_write() and bt_gatt_read(). As of now, I am able to see the definition and description of these function in gatt.h, but there is some information I need to know before I can use these two functions properly. 

I know there is this structure called bt_gatt_write_params for passing parameters in bt_gatt_write function but as in the header file it's defined as:

struct bt_gatt_write_params {
/** Response callback */
bt_gatt_write_func_t func;
/** Attribute handle */
uint16_t handle;
/** Attribute data offset */
uint16_t offset;
/** Data to be written */
const void *data;
/** Length of the data */
uint16_t length;
};

So, Its not clear to me what does data offset means here. FYI we need a custom service having a couple of characteristics. Now, I need to write and read those characteristics.  I made the service as follows:

BT_GATT_SERVICE_DEFINE(Service_name,
BT_GATT_PRIMARY_SERVICE(&SERVICE_UUID),

//Dev ID
BT_GATT_CHARACTERISTIC(&DEV_ID_UUID,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE,
BT_GATT_PERM_READ, NULL, NULL,
dev_ID),


//Device type,
BT_GATT_CHARACTERISTIC(&DEV_TYPE_UUID,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE,
BT_GATT_PERM_READ, NULL, NULL,
0x00),


//Dev description
BT_GATT_CHARACTERISTIC(&DEV_DESC_UUID,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE,
BT_GATT_PERM_READ, NULL, NULL,
0x00),


//Status
BT_GATT_CHARACTERISTIC(&STATUS_UUID,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, NULL, NULL,
0x00),


//TX
BT_GATT_CHARACTERISTIC(&TX_UUID,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE,
BT_GATT_PERM_WRITE, NULL, NULL,
100),

//RX
BT_GATT_CHARACTERISTIC(&RX_UUID,
BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP,
BT_GATT_PERM_READ, NULL, NULL,
0x00)
);

Can you please guide me how to read and write to any of these attribute let say if I want to write to TX and read from RX characteristics?

Parents
  • I recommend you to study the samples peripheral_cts_client and central_uart and their associated service libraries cts_client.c and nus_client.c, where you can see examples of how to use the functions bt_gatt_write() and bt_gatt_read()

    Regarding the offset field, It was hard to find information about it. All the other bluetooth samples are just setting it to 0. I looked at zephyr\subsys\bluetooth\host\gatt.c and saw that it would trigger bt_gatt_prepare_write() if the offset was set to a nonzero value, while gatt_send() would get triggered if the offset is set to zero (and the length is less than the MTU), you may look into these function to understand the offset field better. I think the prepare write function is used for long write situations, but I need to investigate this more to give you a certain answer.

    However, I think you should be fine just setting it to 0.

    I will investigate this further on Friday or next Tuesday (There are national holidays on Thursday and Monday in Norway).

    Best regards,

    Simon

  • Hi Simon,

    Thanks for your efforts. I am using Softdevice S140 now rather than using Zephyr APIs. I am wondering how can I implement my custom service as stated earlier. I am following this tutorial. The problem is I have UUIDs for Service and Characteristic unrelated (Characteristic UUIDs are not related to the Primary service UUID). 

    I tried using sd_ble_gatts_service_add() API, to add custom service without using sd_ble_uuid_vs_add() as I was trying to avoid supplying BASE UUID and 16 bit UUID separately. But I guess we need to use sd_ble_uuid_vs_add() to add vendor specific UUID to ATT table. In my case, SERVICE_UUID (refer to my first post), DEV_ID_UUID, DEV_TYPE_UUID,.. all are different. 

    Can you please tell me how to implement custom services using proprietary UUIDs for service and cahracteristics?

    In a nutshell, I want to implement what I am doing in the second part of my earlier post using Softdevice S140 APIs. FYI this would be the structure for my service:

    Primary Service with UUID = f3800767-c8a6-4857-9049-896521c7379e

          DEV_ID Characteristic with UUID = 22d7b64e-9bd3-4f30-b1ea-8eb3445c9877

          DEV_TYPE Characteristic with UUID = 89d7c21e-5be3-6d60-c3ea-7be1236b1410

Reply
  • Hi Simon,

    Thanks for your efforts. I am using Softdevice S140 now rather than using Zephyr APIs. I am wondering how can I implement my custom service as stated earlier. I am following this tutorial. The problem is I have UUIDs for Service and Characteristic unrelated (Characteristic UUIDs are not related to the Primary service UUID). 

    I tried using sd_ble_gatts_service_add() API, to add custom service without using sd_ble_uuid_vs_add() as I was trying to avoid supplying BASE UUID and 16 bit UUID separately. But I guess we need to use sd_ble_uuid_vs_add() to add vendor specific UUID to ATT table. In my case, SERVICE_UUID (refer to my first post), DEV_ID_UUID, DEV_TYPE_UUID,.. all are different. 

    Can you please tell me how to implement custom services using proprietary UUIDs for service and cahracteristics?

    In a nutshell, I want to implement what I am doing in the second part of my earlier post using Softdevice S140 APIs. FYI this would be the structure for my service:

    Primary Service with UUID = f3800767-c8a6-4857-9049-896521c7379e

          DEV_ID Characteristic with UUID = 22d7b64e-9bd3-4f30-b1ea-8eb3445c9877

          DEV_TYPE Characteristic with UUID = 89d7c21e-5be3-6d60-c3ea-7be1236b1410

Children
Related