Skip to first unread message
Assigned to ewpa...@gmail.com by chrisw...@gmail.com

S Leven

unread,
Apr 6, 2019, 6:51:04 AM4/6/19
to MIT App Inventor Forum
Hi,

in my application, I use the

 1) BluetoothLE.RegisterForBytes function of the BluetoothLE extension to enable notifications of a given characteristic in a given service
 2) Byte values are then read in with the Bluetooth.BytesReceived callback
 3) For disabling notifications, I use the Bluetooth.UnregisterForValues function with the same UUIDs for service and characteristic.

On the App Inventor application side, this works great.

However, I noticed, that the Bluetooth.UnregisterForValues function does not disable notifications on the GATT server side (BLE peripheral device).
So, in the background, the device continues emitting notifications. Since the callback on the App Inventor side has been unregistered, the notifications remain hidden on the app side.

However, regarding my BLE peripheral, this is not the behavior that I'd expect. I want notifications to be turned off on the peripheral. 

Did anyone observe the same behavior? Is there a workaround? The BLE extension does not seem to provide other functions to write to the "Client Characteristic Configuration" descriptor associated with the characteristic that is notified.

Any help is appreciated,

SLE


Chris Ward

unread,
Apr 6, 2019, 8:37:19 AM4/6/19
to MIT App Inventor Forum
Hi 

The behavior of the peripheral sounds normal - essentially, if you do not want further data from it, it should be switched off (perhaps that can be done via the App and a Relay Switch).

What is the Make/Model of the peripheral?

S Leven

unread,
Apr 6, 2019, 3:26:12 PM4/6/19
to MIT App Inventor Forum
Hi Chris,

I tested this with a Cypress PSoC 6 BLE and the Cypress application note CE217639 for a "BLE Heart Rate Server". 

If Bluetooth.UnregisterForValues does not disable notifications on the GATT server side, how else would I be able to do this?

Disabling notifications is a standard Bluetooth LE feature. Disabling notifications should not require resetting/restarting the BLE peripheral.

Thanks,
SLE

ABG

unread,
Apr 6, 2019, 4:26:51 PM4/6/19
to MIT App Inventor Forum
Maybe there's a command you can send, like
"stop Heart Rate"?

On second thought, don't try this on humans.

ABG

Chris Ward

unread,
Apr 6, 2019, 7:44:26 PM4/6/19
to MIT App Inventor Forum
Hi SLE

A conundrum. Traditionally, a Client would not be the master, the Server would be. The Server device could be used to support several other devices (Clients), so in that scenario it would not make sense for one Client to be able to disable it's notifications.

I did not suggest resetting/restarting but switching the device off. This is often desirable when the device runs on battery power. Would have been a good idea to state the type of device service you are using in your first description :) 

According to Cyprus, their device is not a microcontroller, yet effectively it is, albeit a Rolls Royce rather than a Fiat Panda.

CE217639 is an example project. It does not suggest that the Client will disable Server notifications. What it says is that if a Client is disconnected from the service, the server will automatically go into sleep mode after a 180 second time out, to preserve power.


GATT defines client and server roles. GATT procedures can be considered to be split into three basic types: Discovery procedures, Client-initiated procedures and Server-initiated procedures. The GATT server stores the data transported over the ATT and accepts ATT requests, commands and confirmations from the GATT client. The GATT server sends responses to requests and sends indications and notifications asynchronously to the GATT client when specified events occur on the GATT server. GATT also specifies the format of data contained on the GATT server.









S Leven

unread,
Apr 7, 2019, 6:14:00 AM4/7/19
to MIT App Inventor Forum
Hi Chris,

Thanks for your explanation. I can understand that it is not a common use-case to disable notifications in BLE client-server connections. However, in my opinion, disabling notifications is still a regular BLE feature.

In my first post, I was making a general remark about disabling notifications, independent of the GATT service. Therefore, I did not mention the Heart Rate Profile. I am using the Cypress PSoC6 and the Heart Rate Profile application note for my own training. This is not the GATT service I will implement in my own application.

For my own application, I would benefit from enabling AND disabling notifications. However, with the App Inventor BLE extension, there does not seem to be a direct way to write to UUID 0x2902 ("Client Characteristic Configuration") for a given service/characteristic. I suppose, in order to enable notifications, the Bluetooth.RegisterForX functions internally writes to UUID 0x2902.

Best,
SLE

gerrikoio

unread,
Apr 8, 2019, 5:58:02 AM4/8/19
to MIT App Inventor Forum
However, I noticed, that the Bluetooth.UnregisterForValues function does not disable notifications on the GATT server side (BLE peripheral device).
So, in the background, the device continues emitting notifications. Since the callback on the App Inventor side has been unregistered, the notifications remain hidden on the app side.


From the sounds of things, this would still be a device side coding issue. 

But it would be worth testing device side behaviour to confirm this, by using a utility app like nRFconnect. Use this app to connect to your device and then select and then deselect the notification option and see what happens on the device side.

If you're using a PSoC 6 to test you would need to find the correct handler by trawling through the BLE component datasheet as looking at the heart rate example it may not be the correct one used in the callback handler. 


S Leven

unread,
Apr 8, 2019, 3:44:11 PM4/8/19
to MIT App Inventor Forum
Hi gerrikoio,

you are saying that the BLE extension function Bluetooth.UnregisterForValue actually tries to disable notifications on the BLE device? 

Of course, I tried connecting to my BLE device with a Bluetooth dongle (CySmart) and then enabled/disabled notifications manually. This works fine, the BLE device clearly receives the write request to the GATT CCCD and enables/disables notifications.

However, when I call Bluetooth.UnregisterForValue, the write request to the CCCD never happens. On the contrary, with Bluetooth.RegisterForX I can again observe the write request to the CCCD, enabling notifications.

Best,
SLE

Chris Ward

unread,
Apr 8, 2019, 4:27:27 PM4/8/19
to MIT App Inventor Forum
Hi Sle

Evan Patton is the MIT developer of the BLE extension. Assigning your post for his comments.

gerrikoio

unread,
Apr 9, 2019, 8:00:57 AM4/9/19
to MIT App Inventor Forum
Hi SLE

Nope, I haven't tested that function to that extent but might try to do that later this week as have a couple of BLE PSoC devices (and dongles) lying around.

Sounds like a bug alright.

Rgds

G

S Leven

unread,
Apr 9, 2019, 11:47:18 AM4/9/19
to MIT App Inventor Forum
Hi gerrikoio,

ok, thanks. Looking forward to your observations.

Unfortunately, I have no clue where to look for in the source code of the BLE extension (if available?). Otherwise, I would have done some inspection on the sources myself.

I suspect that the Bluetooth.UnregisterForValues function just unregisters the app's local callback, but does not send out a write request to the GATT's CCCD to disable the notifiation on the BLE device.

Best,
SLE


Chris Ward

unread,
Apr 9, 2019, 1:25:06 PM4/9/19
to MIT App Inventor Forum

Chris Ward

unread,
Apr 9, 2019, 1:38:12 PM4/9/19
to MIT App Inventor Forum
...line 881

S Leven

unread,
Apr 9, 2019, 4:44:00 PM4/9/19
to MIT App Inventor Forum
Hi Chris,

ok, I tried to have a look at the extension's source code. However, you will agree that from the file that you linked in your post one cannot tell anything. It is necessary to go further into the details and look at "inner.UnregisterForValues" and so forth. After some browsing, it seems in fact that the normal behavior of Bluetooth.UnregisterForValues is to send a write request to the CCCD in order to disable notifications on the BLE device. The write request seems symmetric to the one in Bluetooth.RegisterForX, with "false" as parameter to disable notifications

If a had any idea how to look at the log messages that the Java code generates during execution, I would probably get a hint why the CCCD is not written to in my case, at least for disabling notifications (again, for enabling notifications, all works fine).

I just repeated the experiment with another characteristic (not in the Heart Rate Profile), and the outcome is the same.

Any more ideas?

SLE

S Leven

unread,
Apr 10, 2019, 3:17:11 AM4/10/19
to MIT App Inventor Forum
Hi again,

on a closer look, I am finally pretty sure there is an asymmetry in the Bluetooth.RegisterForX and Bluetooth.UnregisterForValues functions.

"gatt.writeDescriptor" with the notification bit set.
Then, there is a call to "gatt.setCharacteristicNotification(char, true)". 

Now, in the "unsubscribe" function, there is no call to "gatt.writeDescriptor" with the notification bit cleared. There is only the call to "gatt.setCharacteristicNotifiction(char, false)" which unregisters the callback.

I am now convinced that my observation is true. There should be an additional call to "gatt.writeDescriptor" in the "unsubscribe" function in order to actually disable notifications on the BLE device.

Is this the behavior intended by the extension developers?

It would be interesting to have their opinion.

Best,
SLE

gerrikoio

unread,
Apr 10, 2019, 7:36:11 AM4/10/19
to MIT App Inventor Forum
Wow. That's good to know that you found a difference between subscribe/unsubscribe functions. 

No, I think you are right, it should be included in the unsubscribe function, and hence I would view this as a bug.

I would suggest that you post your observation noting this issue on the AppInventor BLE Github page (Issues).

gerrikoio

unread,
Apr 10, 2019, 11:46:18 AM4/10/19
to MIT App Inventor Forum
SLE

I've just uploaded the heart rate server example on my PSoC 6 and can confirm that via the PSoC 6 serial output no disable notifications trigger is received which is as per your post.

What I did notice is that on the app side it no longer updates the values when you make a UnregisterForValues request.

S Leven

unread,
Apr 10, 2019, 2:26:58 PM4/10/19
to MIT App Inventor Forum
gerrikoio,

thanks for testing! So your experience matches mine. From looking at the source code, I believe that the problem is general and not specific to the PSoC example.

I will do as you suggest and post a note about this issue on the github page.

Best,
SLE

Evan Patton

unread,
Apr 12, 2019, 4:05:26 PM4/12/19
to MIT App Inventor Forum
Hi SLE,

I'm not sure when we'll be able to get to it, but I've seen your bug report. Since we might not be able to get to it for a while, if you'd like to make an attempt to implement your proposed fix we'd be please to accept a pull request.

Regards,
Evan

S Leven

unread,
Apr 17, 2019, 5:15:10 AM4/17/19
to MIT App Inventor Forum
Hi Evan,

it would be interesting to work on this. However, I think I would not be very efficient. The development tools necessary for compiling App Inventor and the BLE extension are not installed on my machine and I have never worked with them.

What I can propose is to send you the change proposal (at the end, only a few lines of code are added). Then, probably with a few clicks, you can generate a preliminary .aix file of the extension. I would be willing to test it with my running setup. This would be quick on my side. However, I don't know how much formal testing you would like to do on your side? I believe a regression is unlikely.

Just let me know what you think about this approach.


    @Override
   
public void unsubscribe(final BluetoothGatt gatt) {
     
synchronized (pendingOperationsByUuid) {
       
BluetoothGattDescriptor desc = characteristic
         
.getDescriptor(BluetoothLEGattAttributes.CLIENT_CHARACTERISTIC_CONFIGURATION);
         
        desc
.setValue(DISABLE_NOTIFICATION_VALUE);
        gatt
.writeDescriptor(desc);
       
       
...
     
}
   
}

Checking for "desc != null" should not be necessary. We already know that this characteristic has a descriptor since we were able to call the "subscribe" function on it. This would only be problematic if the remote BLE device dynamically changes its GATT table, but this is another story.

Best,
SLE

S Leven

unread,
Apr 17, 2019, 9:13:21 AM4/17/19
to MIT App Inventor Forum
Hi again,

with the help of a tutorial I managed to re-compile the extension myself (in a few clicks ..., it was much easier than expected). I will test tonight and let you know.

Best,
SLE

Chris Ward

unread,
Apr 17, 2019, 11:47:42 AM4/17/19
to MIT App Inventor Forum
Hi SLE

Sounds good!
Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted
0 new messages