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

How does reading and "sending" characteristic values work?

This is what I believe, of course, my beliefs are flawed, so please DO point my errors out:

  1. There is this attribute table on server/peripheral devices. The actual location is not important but if you have to ask, it can be designated by function like sd_ble_gatts_characteristic_add() in a memory managed by the softdevice.

  2. Among these attributes, lie the things we want: characteristics.

  3. Within a characteristic, lies something we care the most: values.

  4. The value resides inside a section of SD managed memory, and is usually accessed by a pointer, the point is, it gets read into the central/client device altogether the first time. You can provide it with a default value, and you can not.

  5. When you use functions like sd_ble_gatts_hvx() to "push" messages from server to client, the mcu don't actually send the new content (let's say heartrate) to the client/central yet, it updates that aforementioned value inside the attribute table. And then, it sends out a notification/indication telling the client that the value has just been updated. And subsequently, the client will look up the new values on that notification/indication.

Now, how many things did I get completely wrong?

Parents
  • Hi Mitch,

    Your points 1-3 are basically correct. There are few notable details such as:

    • While ATT (Attribute Protocol layer) introduced Server/Client role and "table" of up to 65,534 "handles" which can be independent/unorganized, upper GATT (Generic Attribute Profile layer) is setting clear rules which organize ATT handles into service/characteristic/values/descriptors structures (services being primary/secondary, having any number of characteristics etc.)
    • The fact that most of BLE devices which are GAP/GATT compliant implement GATT Server on top of GAP Peripheral role (and GATT Client on GAP Central role on opposite side) is just one of available choices, you can run it in opposite configuration or even in dual configurations (e.g. today's iOS and Android devices can be both GAP Central and Peripheral and at the same time GATT Client and Server).

    To your point #4 - by "pointer" you probably mean "handle" which is in the end the only identifier when you talk over radio by ATT layer methods (which are working to manipulate with GATT structures as well). The "names" aka UUIDs are just values of some handles which combined with GATT rules tell you how the space of 16-bit ATT handles is organized (into services, characteristics etc.) Pointers would evoke that you can access real parts of nRF5x memory (owned by SoftDevice) over the radio which is nonsense.

    To your point #5 - again you got the point but probably just not using 100% precise wording. SoftDevice API allows you to ask GATT layer to do something (e.g. update internal value or send some value as notify event) and it will then handle BLE protocol part to fulfill BT SIG specification. E.g. notify event will be sent out on very next connection event in case that connection is ongoing (obviously) and if server notifications are enabled by client.

    The whole reason why something like SoftDevice exists is that running BLE stack requires microsecond precision and pretty big know-how and IP put into actual implementation of all BT LE layers. So to separate it into dedicated "RTOS-like" thing allows you to handle precise timing and at the same time protecting your know-how against easy copy by other vendors (which would happen if you deliver it in open source form of SDK).

    In general I would recommend to go (probably more than once) through some BLE training, e.g. the one linked here. After that it should be much easier to understand link between how BLE stack works in abstract/specification world and how it is implemented by Nordic inside SoftDevice (and interfaced from outer world = your application through SoftDevice API).

    Cheers Jan

Reply
  • Hi Mitch,

    Your points 1-3 are basically correct. There are few notable details such as:

    • While ATT (Attribute Protocol layer) introduced Server/Client role and "table" of up to 65,534 "handles" which can be independent/unorganized, upper GATT (Generic Attribute Profile layer) is setting clear rules which organize ATT handles into service/characteristic/values/descriptors structures (services being primary/secondary, having any number of characteristics etc.)
    • The fact that most of BLE devices which are GAP/GATT compliant implement GATT Server on top of GAP Peripheral role (and GATT Client on GAP Central role on opposite side) is just one of available choices, you can run it in opposite configuration or even in dual configurations (e.g. today's iOS and Android devices can be both GAP Central and Peripheral and at the same time GATT Client and Server).

    To your point #4 - by "pointer" you probably mean "handle" which is in the end the only identifier when you talk over radio by ATT layer methods (which are working to manipulate with GATT structures as well). The "names" aka UUIDs are just values of some handles which combined with GATT rules tell you how the space of 16-bit ATT handles is organized (into services, characteristics etc.) Pointers would evoke that you can access real parts of nRF5x memory (owned by SoftDevice) over the radio which is nonsense.

    To your point #5 - again you got the point but probably just not using 100% precise wording. SoftDevice API allows you to ask GATT layer to do something (e.g. update internal value or send some value as notify event) and it will then handle BLE protocol part to fulfill BT SIG specification. E.g. notify event will be sent out on very next connection event in case that connection is ongoing (obviously) and if server notifications are enabled by client.

    The whole reason why something like SoftDevice exists is that running BLE stack requires microsecond precision and pretty big know-how and IP put into actual implementation of all BT LE layers. So to separate it into dedicated "RTOS-like" thing allows you to handle precise timing and at the same time protecting your know-how against easy copy by other vendors (which would happen if you deliver it in open source form of SDK).

    In general I would recommend to go (probably more than once) through some BLE training, e.g. the one linked here. After that it should be much easier to understand link between how BLE stack works in abstract/specification world and how it is implemented by Nordic inside SoftDevice (and interfaced from outer world = your application through SoftDevice API).

    Cheers Jan

Children
  • Hello, on point 5, do you mean that the server will send out the actual new data to the client, AS a notification event?

    Also, is there any detailed description on all the members of ble_gatts_attr_md_t,ble_gatts_char_md_t and ble_gatts_attr_t? Nordic site has only very brief descriptions.

  • Yes, notification is actual value "push", not just indication that client should re-read the value. You have Read/Write methods if you enjoy this obsolete concept but all people use full potential of GATT with Write (without response) from client to server and Notification (without confirmation) from server to client today. That gives you the best throughput (if you are able to manage queuing/buffering on application layer of course). If your characteristic is read/write then you can update value and then let client to read it whenever it wants (there is different Nordic SoftDevice API procedure for that). I believe you want to read carefully all message sequence charts for S132 (assuming you are using nRF52 chips), you can start with GATT Server sequences here.

Related