pycom / pycom-micropython-sigfox

A fork of MicroPython with the ESP32 port customized to run on Pycom's IoT multi-network modules.
MIT License
199 stars 167 forks source link

BLE API doesn't have Descriptor #37

Open kutysam opened 7 years ago

kutysam commented 7 years ago

I am connecting my device to a HM-10 BLE product using GATTC.

In super summary, BLE works the following way for GATT, There is a service, which MAY contain characteristics. The characteristics will have a value and may have a descriptor. http://static.thegeekstuff.com/wp-content/uploads/2014/07/ti-ble-profile.png

Usually if you expect a reply from a client, you have to enable the notifications / indications to be 1 within the descriptor field of the characteristic you want to have a reply.

For example, in HM-10, if i send a "AT", i should receive "OK" For my android phones, and pygatt software and micropython(https://github.com/MrSurly/micropython-esp32/blob/dev-bluetooth/esp32/bluetooth_docs.md), to receive the "OK" command, I will have to manually set the notifications or indications field to be true. It works on all the devices.

However, there is no way for me to set it to be true in pycom micropython as there is no descriptor function within characteristic.

dir(blecharacteristic) ['uuid', 'instance', 'properties', 'read', 'write', 'callback']

I believe you guys missed this portion of the API. Do let me know if you guys need logs or anything.

kutysam commented 7 years ago

https://github.com/pycom/pycom-micropython-sigfox/blob/master/esp32/mods/modbt.c

Yup, it is commented out. Line 197, 550, 1663, 1673-1677 Any reason why??

danicampora commented 7 years ago

Hello @kutysam it's pending to be implemented. We are moving this upfront in the backlog. Expect it soon :-)

kutysam commented 7 years ago

Thank you so much! Looking forward to it!

SgAu commented 7 years ago

@danicampora would this feature also enable a bluetooth client (e.g. smartphone) to register for notifications from a pycom device acting as a BLE server/peripheral, and allow that pycom device to push out notifications to the client? If so, that would be awesome.

danicampora commented 7 years ago

@danicampora would this feature also enable a bluetooth client (e.g. smartphone) to register for notifications from a pycom device acting as a BLE server/peripheral, and allow that pycom device to push out notifications to the client? If so, that would be awesome.

This is already possible :-). Have you tried it?

SgAu commented 7 years ago

@danicampora Thanks for replying. Yes, I've tried it but haven't got it working.

I have programmed a LoPy to advertise a BLE service and characteristic with Read, Indicate & Notify properties. (Bluetooth server / peripheral)

I am testing the connection using generic BLE apps (BLE Scanner for Android & LightBlue Explorer for iOS) to connect to the LoPy and read the values. The apps can connect and read the values from the LoPy, and the apps appear to show that I can successfully subscribe to notifications. However, it seems that the notification isn't triggered from the LoPy when the value changes. No errors are logged at either end.

What I'd expect to see is that once the mobile app registers for notifications then any subsequent change in value on the LoPy side would trigger the new value to be sent to the mobile app, but only manually triggered reads seem to be working.

Is there something obvious that I might be missing?

SgAu commented 7 years ago

Subscribing to BLE notifications appears to involve setting a value on the "Client Characteristic Configuration" descriptor of the characteristic you want to subscribe to.

This is an example of how an Android app would subscribe to notifications on an xxPy device: https://developer.android.com/guide/topics/connectivity/bluetooth-le.html#notification The Android app sets the CLIENT_CHARACTERISTIC_CONFIG descriptor to equal ENABLE_NOTIFICATION_VALUE on the remote BLE server(peripheral/LoPy) in order to enable notifications.

As notifications appear to be dependent on descriptor functionality, and as per @kutysam's original issue, this is why I suspect notifications won't work until the descriptor functionality is implemented.

@danicampora Does this sound right?

I'll try again once descriptor functionality is implemented. Thanks!

jmarcelino commented 7 years ago

I think what's possible is to receive notifications from a GATT server - when the Pycom board is acting a a GATT client (with the Bluetooth.CHAR_NOTIFY_EVENT callback) - but not notify a GATT client when the LoPy is the server.

SgAu commented 7 years ago

Yes, that appears to be the case.

Sending notifications while acting as a BLE GATT server is a critical feature for making a BLE peripheral with a xxPy device.

Hopefully the pending GATT descriptor implementation work will enable this functionality. It would be good to know for sure.

kutysam commented 7 years ago

Based on the latest commit for 1.7.7b1, there is still no way to enable indications for gattc clients

I see at https://github.com/pycom/pycom-micropython-sigfox/blob/master/esp32/mods/modbt.c

    case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
        // printf("Register for Notify event\n");
        uint16_t notify_en = 1;
        esp_ble_gattc_write_char_descr(gattc_if, conn_id, &p_data->reg_for_notify.srvc_id, &p_data->reg_for_notify.char_id, &bt_notify_descr_id,
                                       sizeof(notify_en), (uint8_t *)&notify_en, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
        break;
        }

But i have no idea on how to access this through micropython. any idea..? Hope the documentation gets updated :) I'm eagar as I'm in testing phase and if this works, I'll be probably purchasing more devices.

kutysam commented 7 years ago

@danicampora This is a simple ble GATTC notifications test ran on 1.7.8b1

import binascii
from network import Bluetooth
conn = bluetooth.connect(binascii.unhexlify("C8FD1966CC5F"))

def cb(chr):
    print(chr.value()) #I tried with chr.read() too, but this hangs the device.

conn.services()[2].characteristics()[0].callback(trigger=Bluetooth.CHAR_NOTIFY_EVENT, handler=cb)
conn.services()[2].characteristics()[0].write("AT")

Expected result: OK

However, the momment I run conn.services()[2].characteristics()[0].callback(trigger=Bluetooth.CHAR_NOTIFY_EVENT, handler=cb) There is a continous "b'\x00'" until I type the write AT command or run other commands. OK never shows too.

There is still an error on receiving notifications from GATTC devices. I am using a HM-10 device and tested it on pygatt and android. Once I send an "AT" with notifications enabled, I will receive a "OK" reply on these devices.

I really hope this get solved soon. I am honestly thinking of getting many more wipy devices if this works for a project.

danicampora commented 7 years ago

@kutysam I'm ordering an HM-10 right now to test and solve your issue. Will keep you posted. Thanks for reporting the problem!

kutysam commented 7 years ago

Thank you so much @danicampora

For more information for the HM-10 device, you can take a look at here https://github.com/MrSurly/micropython-esp32/issues/2#issuecomment-316053581 You need to MANUALLY enable remote mode to get the device to reply AT commands via BLE.

In addition, do beware! There are ALOT of clones. Refer to here to get a guide to which is genuine https://github.com/MrSurly/micropython-esp32/issues/2#issuecomment-314498138

Btw, MrSurly build now works but there are some bugs. He requires a manually set descriptor flag for notifications to be shown.

trojanc commented 4 years ago

Hi, this issue is a few years old. There is still no descriptor support?

one0410 commented 2 years ago

Any updates ??