This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

GATT service bt_gatt_notify argument const structbt_gatt_attr*attr

Hello,


I'm making an own service with a notify.

When I look at the bas service there is the following line to trigger the notifty:

rc = bt_gatt_notify(NULL, &bas.attrs[1], &level, sizeof(level));

Because I have serveral characteristics and the notify is not on the top.

The index of [1] should not be okay.

How can I determine the attribute index of my service?

Is there a easier way to join this, because when I add some attributes the index could change.


Greetings,

Peter

Parents
  • This is a very good question.

    If you look at the the documentation of bt_gatt_notify you can see that attr- Characteristic or Characteristic value attribute. 

    When you are populating a service in the nRF Connect SDK you can see that you are adding attributes within a service like below

    BT_GATT_SERVICE_DEFINE(bas,
    	BT_GATT_PRIMARY_SERVICE(BT_UUID_BAS),
    	BT_GATT_CHARACTERISTIC(BT_UUID_BAS_BATTERY_LEVEL,
    			       BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
    			       BT_GATT_PERM_READ, read_blvl, NULL,
    			       &battery_level),
    	BT_GATT_CCC(blvl_ccc_cfg_changed,
    		    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
    );

    Here the characteristic declaration that has the CCCD for the BAS notifications  is declared after the first characteristic declaration. So the ATT table looks like below

    Index 0  - Service declaration attribute (service declaration has only one attribute)
    Index 1 - One attributes for the characteristic declaration
    Index 2 - Characteristic value for the above characteristic declaration.
    Index 3 - CCCD declaration attribute.

    Note that CCC attribute declaration should always be after the characteristic declaration. Now based on the documentation of bt_gatt_notify you need pass the attribute for the characteristic that has the notification properties in it. Note that index 1 is the attribute which represents the characteristic for this. Hence you pass this index.

    In Zephyr you need to know your attribute table to be able use some API like this. Since there are rules on how the attribute table is populated, once you get used to it, it wont look hard. Unfortunately this is compile time static on how you populate the table unless you use GATT pools

Reply
  • This is a very good question.

    If you look at the the documentation of bt_gatt_notify you can see that attr- Characteristic or Characteristic value attribute. 

    When you are populating a service in the nRF Connect SDK you can see that you are adding attributes within a service like below

    BT_GATT_SERVICE_DEFINE(bas,
    	BT_GATT_PRIMARY_SERVICE(BT_UUID_BAS),
    	BT_GATT_CHARACTERISTIC(BT_UUID_BAS_BATTERY_LEVEL,
    			       BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
    			       BT_GATT_PERM_READ, read_blvl, NULL,
    			       &battery_level),
    	BT_GATT_CCC(blvl_ccc_cfg_changed,
    		    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
    );

    Here the characteristic declaration that has the CCCD for the BAS notifications  is declared after the first characteristic declaration. So the ATT table looks like below

    Index 0  - Service declaration attribute (service declaration has only one attribute)
    Index 1 - One attributes for the characteristic declaration
    Index 2 - Characteristic value for the above characteristic declaration.
    Index 3 - CCCD declaration attribute.

    Note that CCC attribute declaration should always be after the characteristic declaration. Now based on the documentation of bt_gatt_notify you need pass the attribute for the characteristic that has the notification properties in it. Note that index 1 is the attribute which represents the characteristic for this. Hence you pass this index.

    In Zephyr you need to know your attribute table to be able use some API like this. Since there are rules on how the attribute table is populated, once you get used to it, it wont look hard. Unfortunately this is compile time static on how you populate the table unless you use GATT pools

Children
No Data
Related