Skip to content

Writing >20 Bytes to Characteristic causes all registered Write Callbacks to fire #4046

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
emitategh opened this issue May 31, 2020 · 14 comments

Comments

@emitategh
Copy link

emitategh commented May 31, 2020

As explained in title: When sending more than 20 bytes to any Characteristic causes all registered Write Callbacks to fire.

Board: ESP32 DevKit v1
Chip: ESP32D0WDQ6 (revision
Features: WiFi, BT, Dual Core, 240MHz
Auto-detected Flash size: 4MB
Core Instalation date: 01/05/2020
IDE: Arduino 1.8.12
Upload Speed: 115200
Computer OS: Windows 10 Pro

Description:
Same as title

Example Sketch

#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLECharacteristic.h>
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID         "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC1_UUID "aeb5483e-36e1-4688-b7f5-ea07361b26a8"
#define CHARACTERISTIC2_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class Characteristic1_Callbacks: public BLECharacteristicCallbacks {
  void onRead(BLECharacteristic *pCharacteristic){
    Serial.println("Characteristic1 Read");
  }
  void onWrite(BLECharacteristic *pCharacteristic){
    Serial.print("Characteristic1 Written: ");
    Serial.println((char *) pCharacteristic->getData());
  }
};

class Characteristic2_Callbacks: public BLECharacteristicCallbacks {
  void onRead(BLECharacteristic *pCharacteristic){
    Serial.println("Characteristic2 Read");
  }
  void onWrite(BLECharacteristic *pCharacteristic){
    Serial.print("Characteristic2 Written: ");
    Serial.println((char *) pCharacteristic->getData());
  }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");

  BLEDevice::init("Long name works now");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC1_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pCharacteristic->setCallbacks(new Characteristic1_Callbacks());
  pCharacteristic->setValue("I am Characteristic #1");


  pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC2_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pCharacteristic->setCallbacks(new Characteristic2_Callbacks());
  pCharacteristic->setValue("I am Characteristic #2");

  pService->start();
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("Characteristic defined! Now you can read it in your phone!");
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
}

Debug Messages:

Starting BLE work!
[D][FreeRTOS.cpp:189] take(): Semaphore taking: name: RegisterAppEvt (0x3ffdd05c), owner: <N/A> for registerApp
[D][FreeRTOS.cpp:198] take(): Semaphore taken:  name: RegisterAppEvt (0x3ffdd05c), owner: registerApp
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][FreeRTOS.cpp:189] take(): Semaphore taking: name: CreateEvt (0x3ffdd2b4), owner: <N/A> for createService
[D][FreeRTOS.cpp:198] take(): Semaphore taken:  name: CreateEvt (0x3ffdd2b4), owner: createService
[D][FreeRTOS.cpp:189] take(): Semaphore taking: name: CreateEvt (0x3ffdd518), owner: <N/A> for executeCreate
[D][FreeRTOS.cpp:198] take(): Semaphore taken:  name: CreateEvt (0x3ffdd518), owner: executeCreate
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][BLEService.cpp:225] addCharacteristic(): Adding characteristic: uuid=aeb5483e-36e1-4688-b7f5-ea07361b26a8 to service: UUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, handle: 0x0028
[D][FreeRTOS.cpp:189] take(): Semaphore taking: name: SetValue (0x3ffddb88), owner: <N/A> for <Unknown>
[D][FreeRTOS.cpp:198] take(): Semaphore taken:  name: SetValue (0x3ffddb88), owner: <Unknown>
[D][BLEService.cpp:225] addCharacteristic(): Adding characteristic: uuid=beb5483e-36e1-4688-b7f5-ea07361b26a8 to service: UUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, handle: 0x0028
[D][FreeRTOS.cpp:189] take(): Semaphore taking: name: SetValue (0x3ffde714), owner: <N/A> for <Unknown>
[D][FreeRTOS.cpp:198] take(): Semaphore taken:  name: SetValue (0x3ffde714), owner: <Unknown>
[D][BLECharacteristic.cpp:90] executeCreate(): Registering characteristic (esp_ble_gatts_add_char): uuid: aeb5483e-36e1-4688-b7f5-ea07361b26a8, service: UUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, handle: 0x0028
[D][FreeRTOS.cpp:189] take(): Semaphore taking: name: CreateEvt (0x3ffddac8), owner: <N/A> for executeCreate
[D][FreeRTOS.cpp:198] take(): Semaphore taken:  name: CreateEvt (0x3ffddac8), owner: executeCreate
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][BLECharacteristic.cpp:90] executeCreate(): Registering characteristic (esp_ble_gatts_add_char): uuid: beb5483e-36e1-4688-b7f5-ea07361b26a8, service: UUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, handle: 0x0028
[D][FreeRTOS.cpp:189] take(): Semaphore taking: name: CreateEvt (0x3ffde654), owner: <N/A> for executeCreate
[D][FreeRTOS.cpp:198] take(): Semaphore taken:  name: CreateEvt (0x3ffde654), owner: executeCreate
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][FreeRTOS.cpp:189] take(): Semaphore taking: name: StartEvt (0x3ffdd5d8), owner: <N/A> for start
[D][FreeRTOS.cpp:198] take(): Semaphore taken:  name: StartEvt (0x3ffdd5d8), owner: start
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[I][BLEDevice.cpp:554] getAdvertising(): create advertising
[D][BLEDevice.cpp:556] getAdvertising(): get advertising
[D][BLEDevice.cpp:556] getAdvertising(): get advertising
[D][BLEAdvertising.cpp:189] start(): - advertising service: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
Characteristic defined! Now you can read it in your phone!
[D][BLEDevice.cpp:556] getAdvertising(): get advertising
[D][BLEAdvertising.cpp:491] handleGAPEvent(): handleGAPEvent [event no: 0]
[D][BLEDevice.cpp:556] getAdvertising(): get advertising
[D][BLEAdvertising.cpp:491] handleGAPEvent(): handleGAPEvent [event no: 1]
[D][BLEDevice.cpp:556] getAdvertising(): get advertising
[D][BLEAdvertising.cpp:491] handleGAPEvent(): handleGAPEvent [event no: 6]
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][BLEDevice.cpp:556] getAdvertising(): get advertising
[D][BLEAdvertising.cpp:491] handleGAPEvent(): handleGAPEvent [event no: 20]
[D][BLEDevice.cpp:556] getAdvertising(): get advertising
[D][BLEAdvertising.cpp:491] handleGAPEvent(): handleGAPEvent [event no: 20]
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][BLECharacteristic.cpp:285] handleGATTServerEvent():  - Response to write event: New value: handle: 2a, uuid: aeb5483e-36e1-4688-b7f5-ea07361b26a8
[D][BLECharacteristic.cpp:288] handleGATTServerEvent():  - Data: length: 18, data: 71776572747975696f707177657274797569
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][BLECharacteristic.cpp:285] handleGATTServerEvent():  - Response to write event: New value: handle: 2a, uuid: aeb5483e-36e1-4688-b7f5-ea07361b26a8
[D][BLECharacteristic.cpp:288] handleGATTServerEvent():  - Data: length: 3, data: 6f7031
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
Characteristic1 Written: qwertyuiopqwertyuiop1
Characteristic2 Written: I am Characteristic #2
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown
[D][BLEDevice.cpp:102] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... Unknown

@emitategh
Copy link
Author

I found that the same bug was present in the original Esp32 snippets. The following link is the original issue and was fixed and closed

nkolban/esp32-snippets#796

@vicatcu
Copy link
Contributor

vicatcu commented May 31, 2020

Yes, I still blow away the BLE files in the v1.0.4 arduino-esp32 board support package release and replace them with what is on master from nkolban/esp32-snippets... I wish this would get fixed in this package so I can stop having to do that. Unfortunate that the vestigial code is more stable than the official code in this regard. I'm sure there's a good reason though.

@me-no-dev
Copy link
Member

The reason is that nobody actually made a PR for this. This is not the "official" code here. It's just a snapshot from the moment that Colban started his new job and @chegewara stopped supporting the lib. PRs are welcome

@vicatcu
Copy link
Contributor

vicatcu commented Jun 1, 2020

I can open a PR, it's just likely to be a pretty size-able change set and I'm not really equipped to evaluate the full scope of that change set for correctness. My fear would be that it would overwrite / revert fixes that might exist in this repo. I'll give it a shot anyway.

@emitategh
Copy link
Author

Sorry I deleted the other comment (It was from my job account)

Sorry, I'm not the right one to open a PR. Have almost 0 experience with C++, I'm learning in the process!
@vicatcu thanks for the info, I guess I'll do the same.

Either way, thanks for the product and the library!

@TryingToGITthis
Copy link

Yes, I still blow away the BLE files in the v1.0.4 arduino-esp32 board support package release and replace them with what is on master from nkolban/esp32-snippets... I wish this would get fixed in this package so I can stop having to do that. Unfortunate that the vestigial code is more stable than the official code in this regard. I'm sure there's a good reason though.

Where are the BLE files in Kolban's snippets? I only see the BLE Scanner.

After checking heap space last night, I realized that the default BLE consumes 120k of heap!

@vicatcu
Copy link
Contributor

vicatcu commented Jun 1, 2020

See my PR... they come from ./cpp_utils

@TryingToGITthis
Copy link

Thanks. I downloaded the files and replaced the Espressif files. However, am I doing something wrong or does BLE really consume so much space?

Free heap before BLE: 147564
BLE Name: Test-8866
Free heap after BLE: 49688

@chegewara
Copy link
Contributor

After checking heap space last night, I realized that the default BLE consumes 120k of heap!

about 70kB

@geeksville
Copy link
Contributor

Btw - I had a variant of this bug also, so I tried @vicatcu's awesome PR. Alas, I can report a regression compared to the code currently in master:

In my app I use light-sleep, and to do so I have to carefully not just turnoff bluetooth, but stop and delete my various services before going to sleep. That still works fine.

But when I go to recreate my services after wake, something is spinning somewhere - and that step never completes. I'll debug more - but I thought I should mention it.

geeksville added a commit to meshtastic/arduino-esp32-archive that referenced this issue Jun 13, 2020
So I merged the pull-request mentioned in espressif#4046, and noticed a regression
compared to the code currently in master:

In my app I use light-sleep, and to do so I have to carefully not
just turnoff bluetooth, but stop and delete my various services before
going to sleep. During this process I would call BLEDevice::deinit(false).
That still works fine.

However, when my app woke from light-sleep and needed to restart bluetooth
it was hanging in registerApp:

```
Starting bluetooth
[D][BLEDevice.cpp:80] createServer(): >> createServer
[D][BLEServer.cpp:291] registerApp(): >> registerApp - 1
[D][FreeRTOS.cpp:164] take(): Semaphore taking: name: RegisterAppEvt (0x3ffdd7b0), owner: <N/A> for registerApp
[D][FreeRTOS.cpp:173] take(): Semaphore taken:  name: RegisterAppEvt (0x3ffdd7b0), owner: registerApp
```

To I poked around a bit, and it seems that in the PR espressif#4050 branch, there
is a change compared to master.  A bit of code that used to be #ifdef
was changed to be #ifndef.  Which has the effect of never setting
initialized to false.  If initialized is left true, my call to BLEDevice::init()
was having no effect.

So I've changed this ifdef back to what master had, and now my app works
nicely and the corruption I was previously seeing in my BLE structures
seems fixed (the original goal of pulling in 4050.
@geeksville
Copy link
Contributor

Okay - all happy now and OMG this PR fixes nasty BLE problems I was having. So thank ya'll for your work!

geeksville added a commit to meshtastic/arduino-esp32-archive that referenced this issue Jun 13, 2020
Informed by the discussion in the bug and the code in 'that other branch'
the fix was clear.  Just set a flag if we start handling a write, and
use that flag to guard the long write complete call.
@stale
Copy link

stale bot commented Aug 12, 2020

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Aug 12, 2020
@geeksville
Copy link
Contributor

any questions on the associated #4086 PR? I suspect others will want it.

@stale
Copy link

stale bot commented Aug 12, 2020

[STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it openin the future.

@stale stale bot removed the Status: Stale Issue is stale stage (outdated/stuck) label Aug 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants