h2zero / NimBLE-Arduino

A fork of the NimBLE library structured for compilation with Arduino, for use with ESP32, nRF5x.
https://h2zero.github.io/NimBLE-Arduino/
Apache License 2.0
672 stars 138 forks source link

WebBluetooth connection issues #552

Closed pwilkowski closed 1 year ago

pwilkowski commented 1 year ago

Hello, I am trying to implement ble simple server with notify and write services. ESP32-S3

It seems to work well inside nrf connect (to check for debugging)

However when i try to connect via web bluetooth i seem to be getting error: NotSupportedError: GATT Error Unknown

as soon as i try to subscribe to notifications (i checked if i connect to correct control point and even tried to swap them)

this.ctrlChar = await btService.getCharacteristic(BluetoothTransport.CONTROL_POINT);
console.log(this.ctrlChar);
this.ctrlChar.addEventListener('characteristicvaluechanged', this.resolver.bind(this));
console.log(1);
await this.ctrlChar.startNotifications();

this my code for whole server:

#include "AppSerial.h"

BLEServer* pServer = NULL;
BLECharacteristic* pTxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint8_t txValue = 0;

void bleLoop(void* p) {
    while (true) {
        if (deviceConnected) {
            pTxCharacteristic->setValue(&txValue, 1);
            pTxCharacteristic->notify();
            txValue++;
            delay(10);  // bluetooth stack will go into congestion, if too many packets are sent
        }

        // disconnecting
        if (!deviceConnected && oldDeviceConnected) {
            delay(500);                   // give the bluetooth stack the chance to get things ready
            bool success = pServer->startAdvertising();  // restart advertising
            Serial.print("start advertising: ");
            Serial.println(success ? "true" : "false");
            oldDeviceConnected = deviceConnected;
        }
        // connecting
        if (deviceConnected && !oldDeviceConnected) {
            // do stuff here on connecting
            oldDeviceConnected = deviceConnected;
        }
        delay(10);
    }
}

void bleSetup() {
    // Serial.begin(115200);

    // Create the BLE Device
    BLEDevice::init("UART Service");
    NimBLEDevice::setPower(ESP_PWR_LVL_P9);

    // Create the BLE Server
    pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());

    // Create the BLE Service
    BLEService* pService = pServer->createService(SERVICE_UUID);

    // Create a BLE Characteristic
    pTxCharacteristic = pService->createCharacteristic(
        CHARACTERISTIC_UUID_TX, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY
    );

    NimBLE2904* pBeef2904 = (NimBLE2904*)pTxCharacteristic->createDescriptor("2904");
    pBeef2904->setFormat(NimBLE2904::FORMAT_UTF8);

    BLECharacteristic* pRxCharacteristic =
        pService->createCharacteristic(CHARACTERISTIC_UUID_RX, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE, 128);

    pRxCharacteristic->setCallbacks(new MyCallbacks());

    // Start the service
    pService->start();

    // Start the server
    pServer->start();

    NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising();
    pAdvertising->addServiceUUID(pService->getUUID());
    /** If your device is battery powered you may consider setting scan response
     *  to false as it will extend battery life at the expense of less data sent.
     */
    pAdvertising->setScanResponse(true);
    // Start advertising
    pAdvertising->start();

    Serial.println("Waiting a client connection to notify...");

    xTaskCreatePinnedToCore(bleLoop, "bleLoop", 8192, nullptr, 6, nullptr, ARDUINO_RUNNING_CORE);
}

void MyCallbacks::onWrite(BLECharacteristic* pCharacteristic) {
    std::string rxValue = pCharacteristic->getValue();

    if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++) Serial.print(rxValue[i]);

        Serial.println();
        Serial.println("*********");
    }
}

void MyServerCallbacks::onConnect(BLEServer* pServer) {
    deviceConnected = true;
}

void MyServerCallbacks::onDisconnect(BLEServer* pServer) {
    deviceConnected = false;
}

what am i doing wrong?

pwilkowski commented 1 year ago

Nevermind, figured it out, if anyone stumbled upon this error, you should not create Descriptor for notify service, it's created automatically. So this code above works just delete those lines:

NimBLE2904* pBeef2904 = (NimBLE2904*)pTxCharacteristic->createDescriptor("2904");
    pBeef2904->setFormat(NimBLE2904::FORMAT_UTF8);