BLE: Purpose of esp_ble_gattc_register_for_notify

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

BLE: Purpose of esp_ble_gattc_register_for_notify

Postby kolban » Wed Sep 27, 2017 12:46 am

There is a function in the ESP-IDF called "esp_ble_gattc_register_for_notify". See:

http://esp-idf.readthedocs.io/en/latest ... t8uint16_t

It is described as:
This function is called to register for notification of a service.
What I'd like to understand and discuss is "what does this mean?".

My best guess is that it reaches out to the target BLE server, looks for a descriptor within the specified characteristic with UUID 0x2902 and, if found, switches on the "notification enablement" bit.

See: https://www.bluetooth.com/specification ... ration.xml for a description of the "Client Characteristic Configuration" (UUID -x2902).

However, my problem is that when I run nRF Connect to run as a BLE server and perform an ESP32 client side notification request, I do not see the flag get toggled. This makes me believe I am either missing or mistaken on a concept or else the latest ESP-IDF Git master as of the date of this post might have a bug.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

Lucas.Hutchinson
Posts: 79
Joined: Tue Apr 26, 2016 5:10 am

Re: BLE: Purpose of esp_ble_gattc_register_for_notify

Postby Lucas.Hutchinson » Wed Sep 27, 2017 2:47 am

Hi Neil,

From my experience the "esp_ble_gattc_register_for_notify" function seems to register a callback inside the client ble stack for that characteristic, so that when a notification is received it will correctly handle the data and pass it to the application.

Then to enable notifications/indications you must write to the characteristic descriptor using "esp_ble_gattc_write_char_descr".

This is just from experience in using the stack and getting a feeling for how the function works.

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: BLE: Purpose of esp_ble_gattc_register_for_notify

Postby kolban » Wed Sep 27, 2017 3:02 am

Howdy Lucas,
By no means am I saying you aren't correct ... but I'm not seeing it.

The "esp_ble_gattc_register_for_notify" takes no callback function handle for callbacks to be invoked. Now the "esp_ble_gattc_register_callback" function does take a callback ... but this callback is invoked for every possible incoming (from BLE Server) event of which event notification is but one possibility (ESP_GATTC_NOTIFY_EVT).
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: BLE: Purpose of esp_ble_gattc_register_for_notify

Postby WiFive » Wed Sep 27, 2017 3:42 am

But in order to receive ESP_GATTC_NOTIFY_EVT you have to register for it per characteristic or you will not receive it at all in the main callback, right?

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: BLE: Purpose of esp_ble_gattc_register_for_notify

Postby kolban » Wed Sep 27, 2017 4:54 am

I'm reading through as much as I can on the theory. From what I can tell ... the protocol says the following:

A BLE Server can transmit either notifications or indications to a connected partner (a BLE Client).

A notification is a message sent from the BLE Server to the client with no expected acknowledgement.
An indication is a message sent from the BLE Server to the client with an an expectation of acknowledgement.

(I'll just talk about notifications from now on and leave indications for another story).

When a server "defines" a characteristic in a service, that characteristic contains "characteristic properties" which include whether or not the characteristic even "supports" notifications. This can be read by the client so that the client can the learn whether or not there will *ever* be notifications on that characteristic.

If the server owned characteristic *does* say that it supports notification, then that characteristic *must* have a BLE descriptor with UUID 0x2902 (Client Characteristic Configuration or CCC). The is a "writable" descriptor. That means that a BLE client can gain access to it and change its value remotely (remember, the value is housed on the BLE Server associated with the descriptor associated with the characteristic associated with the service). There is a "bit" within the descriptor (0x2902) which if set to 1, means notifications are enabled and if set to 0, means notifications are disabled.

And it is here things get a little fuzzy. My comprehension of this works as follows ...

Imagine a BLE Server that has a sensor attached to it (for example, a temperature sensor). Rather than the client poll the characteristic to get the temperature, what we want to have happen is that the server will detect a change in temperature and then push (notify) the client only when the temperature changes. Sounds good. But rather than the server unilaterally transmitting the sensor data when ever it detects a change, my belief is that the server wants some form of "assurance" that the client at the other end of the connection actually wants that data. Think for example of a BLE server with many sensors attached to it ... if it was internally monitoring those sensors and publishing them merrily down the radio pipe to a client, that would be a lot of expensive radio transmission when *maybe* the client is only interested in some sensor values and not others.

And here is where the parts come together. It is my understanding that the client should "inform" (register?) the BLE server that for a given characteristic, it is actively interested in receiving notifications. It does this by making a write request (from the BLE Client to the BLE Server) to switch on the bit that enables BLE notifications in the 0x2902 descriptor. When the server now detects a change in temperature it *first* examines the bit in the 0x2902 descriptor to ascertain whether the client wants a notification and, only if it is true, will the server send a notification.

In pseudo code it is similar to:

Code: Select all

while(true) {
   if (value of temperature has changed) {
      if (Notifications enabled bit of 0x2902 descriptor is true) {
          transmit a Notification for this characteristic with new sensor data;
      }
   }
}
With this *theory*, now let us look at the ESP32 API called "esp_ble_gattc_register_for_notify". This is a BLE client API ... and it takes a characteristic ID/handle as a parameter. But what does it actually do?

My guess is that it connects to the BLE Server, finds the characteristic within the target service and then looks for descriptor 0x2902. It then sets the "Notifications enabled" bit to be true. This would then be the "indication" to the BLE server that should it determine that it is time that it "could" send a notification that it "should" (because the information has been requested).

Unfortunately ... there is but one fault in this story. Using the tooling / techniques that I know about, after executing an "esp_ble_gattc_register_for_notify", I am *not* seeing the "notifications enabled" bit being set to true in the BLE Server (I am testing with nRF Connect and working with other BLE devices that should start notifying after this call also are not).

This means that either I am mis-understanding the theory, mis-understanding the protocols (both of which are very possible) ... or don't understand what the ESP32 ESP-IDF is "supposed to do" or is "actually doing" .... alternatively ... I do understand it correctly ... and it just "isn't" doing it because of a possible breakage (anything is possible ... but I usually lean to a failure in my understanding before saying "its broke").

Hence this post ...
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: BLE: Purpose of esp_ble_gattc_register_for_notify

Postby WiFive » Wed Sep 27, 2017 5:14 am

That sounds correct, but what I'm suggesting is that all it does is say "yes, generate ESP_GATTC_NOTIFY_EVT events for that characteristic and send them to my gattc callback" and is an extra step in addition to the other stuff. So that if you didn't call it then even if you set the notification flag and the server sent you a notification it would not be passed to your callback.

Lucas.Hutchinson
Posts: 79
Joined: Tue Apr 26, 2016 5:10 am

Re: BLE: Purpose of esp_ble_gattc_register_for_notify

Postby Lucas.Hutchinson » Wed Sep 27, 2017 7:19 pm

Hi,

Sorry, yes what i said wasn't strictly accurate.
I think it enables some callback or flag within the stack which generates the "ESP_GATTC_NOTIFY_EVT " notification events as WiFive cleared up.

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: BLE: Purpose of esp_ble_gattc_register_for_notify

Postby kolban » Wed Sep 27, 2017 11:41 pm

I am for sure saying y'alls notions aren't wrong ... but that would give us a new puzzle. If I am hearing the belief right now then the story would be:

1. A BLE Server must claim that it "can" generate a notification.
2. A BLE Server "won't" generate a notification until/unless a client explicitly switches on the 0x2902 enablement flag.
3. A Client won't receive notifications until it explicitly switches on the 0x2902 enablement flag on the server.
4. A Client won't receive notifications until/unless it registers a callback function to receive them.
5. A Client won't receive notification events in its callback function until/unless it calls "esp_ble_gattc_register_for_notify"

It is "5" that would seem to be out of place. In "3" it explicitly declared that it wants notification events and has indicated to the server that it wants the server to spend energy sending them. In "4" it registered a callback function that is under the coding control of the client programmer who will see all events and then determine what to do with them. I'm not sensing a value add for "5". If the client wanted to stop receiving notifications, it would toggle the 0x2902 enablement flag at the server. This should not only stop new notification events from being processed at the client, it would stop notification events being generated by the server (and save energy).

Again ... please be sure I am not casting doubt on y'alls knowledge and skills ... I'm trying to clear up *MY* confusion which is my own limitation.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: BLE: Purpose of esp_ble_gattc_register_for_notify

Postby WiFive » Wed Sep 27, 2017 11:56 pm

Well the other option is to pass all notifications to your callback, assuming there is no situation where you may want to ignore notifications. But in the case of multiple clients where one switches on notifications is the flag on the server side global or per connection? Will all clients receive notifications or only the ones that set the flag?

I think all you are saying is that it would be nice to have a function to combine steps 2,3,5 into one.

yaoxiansheng
Posts: 1
Joined: Thu Dec 14, 2017 7:35 am

Re: BLE: Purpose of esp_ble_gattc_register_for_notify

Postby yaoxiansheng » Thu Dec 14, 2017 7:43 am

But how does a server connects to multiple clients ? A server shut down its ADV once it connects to a client, how do other server connect to it ?

Who is online

Users browsing this forum: ghmyers, Google [Bot] and 116 guests