espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.77k stars 7.44k forks source link

BLE Client: Cannot register for more than 4 notifications #8015

Open Murkas94 opened 1 year ago

Murkas94 commented 1 year ago

Board

ESP32 WROOM32

Device Description

Breadboard, using some adapter PCBs

Hardware Configuration

Some buttons and a LCD-display, nothing special.

Version

malfunctioning: v2.0.7, v2.0.9, v2.0.11, v2.0.14 working fine: v2.0.4

IDE Name

VS Code + Arduino Extension

Operating System

Wingows 10

Flash frequency

80 Mhz

PSRAM enabled

yes

Upload speed

115200

Description

I am using two identical ESP32 as BLE Server and Client, which works fine so far.

The BLE Server is hosting two services with charactersistics like the following:

The client can find all of the services and characteristics and registers for notifications on all of them. The issue here is, that i am only receiving updates for the first four characteristics i am registering on. So basicaly i don't receive updates for my values D-F.

I've checked the BLE-Server using some Android Apps and i get notifications for all values, so i guess this is an client issue. I also can read and write to all the characteristics, so this is only an issue with the notifications.

I've tried the following:

I cant find anything in the documentation / reddit / other issues about notification limits, but i also can't see any limits in the BLE-sourcefiles.

Sketch

bool RemoteHandler::findRemoteCharacteristic(BLERemoteService* service, BLERemoteCharacteristic*& characteristic, BLEUUID ID, const String& name)
{
    characteristic = service->getCharacteristic(ID);
    Serial.print(F("BLE: Setting up characteristic \""));
    Serial.print(name);
    Serial.print(F("\" with ID "));
    Serial.println(ID.toString().c_str());
    if(characteristic == nullptr)
    {
        Serial.println(F("BLE: Failed to find characteristic."));
        enterMode(Status::Scanning);
        return false;
    }
    Serial.println(F("BLE: Found characteristic."));
    if(characteristic->canNotify())
    {
        characteristic->registerForNotify(
            [&](BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify)
            {
                Serial.print("BLE: Updated ");
                Serial.println(pBLERemoteCharacteristic->getUUID().toString().c_str());
                this->OnCharacteristicNotify(pBLERemoteCharacteristic, pData, length, isNotify);});
        Serial.println(F("BLE: Registered for notifications."));
    }else{
        Serial.println(F("BLE: Failed to register for notifications."));
    }
    return true;
}

bool RemoteHandler::findRemoteService(BLERemoteService*& service, BLEUUID ID, const String& name)
{
    service = bteClient->getService(ID);
    if (service == nullptr) {
        Serial.print(F("BLE: Failed to find service \""));
        Serial.print(name);
        Serial.print(F("\" with ID "));
        Serial.println(ID.toString().c_str());
        enterMode(Status::Scanning);
        return false;
    }
    return true;
}

void RemoteHandler::OnConnect()
{
    if(!findRemoteService(batteryService, batteryServiceUUID, F("Battery-Service"))){return;}
    if(!findRemoteCharacteristic(batteryService, RC_batteryPercentage, BLEUUID((uint16_t)0x2A19), F("Battery-Percentage"))){return;}
    yield();
    if(!findRemoteService(customService, customServiceUUID, F("Custom-Service"))){return;}
    if(!findRemoteCharacteristic(customService, RC_ValueA, BLEUUID((uint16_t)0x4501), F("ValueA"))){return;}
    if(!findRemoteCharacteristic(customService, RC_ValueB, BLEUUID((uint16_t)0x4502), F("ValueB"))){return;}
    if(!findRemoteCharacteristic(customService, RC_ValueC, BLEUUID((uint16_t)0x4503), F("ValueC"))){return;}
    if(!findRemoteCharacteristic(customService, RC_ValueD, BLEUUID((uint16_t)0x4601), F("ValueD"))){return;}
    if(!findRemoteCharacteristic(customService, RC_ValueE, BLEUUID((uint16_t)0x4621), F("ValueE"))){return;}
    if(!findRemoteCharacteristic(customService, RC_ValueF, BLEUUID((uint16_t)0x4622), F("ValueF"))){return;}
}

Debug Message

Following output is repeating:

BLE: Updated 00002a19-0000-1000-8000-00805f9b34fb
BLE: Updated 00004501-0000-1000-8000-00805f9b34fb
BLE: Updated 00004502-0000-1000-8000-00805f9b34fb
BLE: Updated 00004503-0000-1000-8000-00805f9b34fb

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

SuGlider commented 1 year ago

@Murkas94 - May it be related to this issue #8060 ?

The number of characteristics and descriptors may be limited to the number of handles that the BLE Service has been configured. By default, an ESP32 Remote Service is created with 15 handles only. Each BLE Characteristic takes 2 handles and each BLE Descriptor takes 1 handle.

Please submit a sketch that I can use to replicate the issue.

Murkas94 commented 1 year ago

@SuGlider Thank you. I will minimize my sketch as soon as i have time again. I am currently moving, so i guess i won't be able to do it in the next 1-2 weeks, but i will do it.

Murkas94 commented 1 year ago

Hello again,

I managed to minimize my sketches for further investigation. The archive contains two sketches, one for the BLE Server, one for the BLE Client, so you will need two ESP32 to run it.

I am sorry, that the code contains a bit more than the minimum. That is, because i've just reduced my own sketches (and added some dummy code to create changing values) and did not want to change anything to the suspect parts, as my setup is currently not built up again (after moving) and i currently cannot test it. But both sketches compile and the suspect parts are like they were when i had the issue.

Thanks in advance!

BLENotificationIssueSketches.zip

MSmeets94 commented 1 year ago

Hello. Altough i am not able to help you find the root cause of this issue, i did notice the same behaviour, as explained in the issue i just referenced. That project used esp board version 2.0.4, but due to a mistake on my side i was using the latest version, which did lead to me missing out on some BLE subscriptions. I tracked this behaviour down to 2.0.7 after which i also found this issue.

Murkas94 commented 1 year ago

I can confirm that it works fine with 2.0.4. Unfortunatly, i can't find any relevant changes in the bluetooth-sourcefiles between 2.0.4 and 2.0.7. Maybe it is an issue with the espressif sdk?

VojtechBartoska commented 1 year ago

@Murkas94 Can you test this also against 2.0.11 version, thanks?

Murkas94 commented 1 year ago

@VojtechBartoska Still not working with 2.0.11. Stuck with <= 4 notifications.

VojtechBartoska commented 1 year ago

Ok, adding to the Roadmap, we'll investigate this.

VojtechBartoska commented 2 months ago

Hello, sorry for looking into this after very long time.

@Murkas94 Will you be able to retest this against version 3.1.0-RC1? If not, we fully understand and will give it a try.