espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.51k stars 7.26k forks source link

NimBLE: lack of possibility to write long characterstic value (GATT) (IDFGH-3811) #5724

Closed dshil closed 4 years ago

dshil commented 4 years ago

Is your feature request related to a problem? Please describe.

We've been using bluedroid BLE for a long time but now we've run out of FLASH space and decided to switch to NimBLE. For the bluedroid we have such a wonderful instruction (thanks @Isl2017) how to do all the stuff.

The main issue is that I can't find the API for handling long writes on GATT server implemented on my ESP32 board. Existing GATT client (mobile app) sends long characteristics by chunks and I properly handle them with the following workflow in bluedroid:

The second type is used when the attribute to write is longer than what can be sent in one single ATT message by dividing the data into multiple chunks using Prepare Write Responses

@projectgus, probably you could elaborate somehow for NimBLE stuff? If not, could you please redirect me to someone who is familiar with it.

Alvin1Zhang commented 4 years ago

Thanks for raising this feature request, we will evaluate.

Isl2017 commented 4 years ago

+Hrish, Prasad, who will help you guide NimBLE stuff :)

2020年8月12日 下午11:26,Dmitriy Shilin notifications@github.com<mailto:notifications@github.com> 写道:

Is your feature request related to a problem? Please describe.

We've been using bluedroid BLE for a long time but now we've run out of FLASH space and decided to switch to NimBLE. For the bluedroid we have such a wonderful instructionhttps://github.com/espressif/esp-idf/blob/c77c4ccf6c43ab09fd89e7c907bf5cf2a3499e3b/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md (thanks @Isl2017https://github.com/Isl2017) how to do all the stuff.

The main issue is that I can't find the API for handling long writes on GATT server implemented on my ESP32 board. Existing GATT client (mobile app) sends long characteristics by chunks and I properly handle them with the following workflow in bluedroidhttps://github.com/espressif/esp-idf/blob/c77c4ccf6c43ab09fd89e7c907bf5cf2a3499e3b/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md#managing-write-events:

The second type is used when the attribute to write is longer than what can be sent in one single ATT message by dividing the data into multiple chunks using Prepare Write Responses

@projectgushttps://github.com/projectgus, probably you could elaborate somehow for NimBLE stuff? If not, could you please redirect me to someone who is familiar with it.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/espressif/esp-idf/issues/5724, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGD5AMM3PIKLDIKBLEHR6KDSAKYC3ANCNFSM4P43Y7FQ.

dshil commented 4 years ago

Hi @Isl2017 and thanks for a quick reply.

Hello @dhrishi @prasad-alatkar, let me clarify what is the issue.

We use ATT (The Attribute protocol) between ESP32 board and the mobile app. When manage write events in bluedroid we have a possibility to handle write of long characteristic value by using:

bool is_prep;             /*!< This write operation is prepare write */

Each chunk of long characteristics is written to user buffer on each prepare write request. At the end we receive the special event ESP_GATTS_EXEC_WRITE_EVT signalizing that long write is done and we are ready to handle the received characteristic. Do we have the same functionality for NimBLE (P.S. I surfed across the NimBLE components for the whole day and didn't find anything that can be used for this purpose)?

P.S. at the end I think I can prepare some kind of tutorial for migrating from bluedroid (BLE profile) to NimBLE. I think it can be useful for others too.

Thanks in advance.

prasad-alatkar commented 4 years ago

Hi @dshil ,

NimBLE uses the same approach to handle regular writes as well as long writes. It simply handles prepare write and execute write requests internally for ease of users. You get BLE_GATT_ACCESS_OP_WRITE_CHR event in characteristic access callback, wherein the total data is available in gatt context (struct ble_gatt_access_ctxt). You can call ble_hs_mbuf_to_flat to extract the total data in application buffer as done in: https://github.com/espressif/esp-idf/blob/master/examples/bluetooth/nimble/bleprph/main/gatt_svr.c#L100. You can get/save the length of total data received by passing fourth argument in ble_hs_mbuf_to_flat.

Please give it a try and let me know in case of any issues !!

dshil commented 4 years ago

Hi @prasad-alatkar, thanks for such a quick response and sorry for long response from my side, was too busy with porting all the stuff to NimBLE.

Well, it works without any issue! Thanks for such simplified API in comparison to bluedroid API.

A few things I want to mention:

Except mentioned things API is very simple and reduces a lot of boilerplate code found in bluedroid API. Thanks again.

P.S. I will close the issue since we've done here.