NimBLE-Arduino icon indicating copy to clipboard operation
NimBLE-Arduino copied to clipboard

gatt status 147 error on Samsung Galaxy, won't display in Windows

Open societyofrobots opened this issue 4 months ago • 2 comments

Arduino IDE, ESP32 v2.0.18 core me: intermediate level programmer

Was using v1.4.3: -works fine with most devices -didn't work at all with Samsung Galaxy -displays on Win11 ble scan but won't connect

So, I upgraded to v2.3.2 (Arduino IDE) and tried my best.

With v2.3.2: -visible/connects on Samsung Galaxy phone, but gives gatt status 147 error -visible/connects on iOS 15.3 phone -doesn't display on my Win11 scan

My device is not a keyboard or mouse, it just exchanges UART data. However, it must be displayed during BLE scans, so I assume it should continue to be HID. Correct? When I do it without HID, it just disappears from my device BLE scans. It does show up properly using nRF, though. No encryption needed, but can if required.

What am I doing wrong?

#include <NimBLEDevice.h>
#include <NimBLEHIDDevice.h>
#include <NimBLEServer.h>

#define SERVICE_UUID            "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_RX  "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX  "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

NimBLEServer* pServer = nullptr;
NimBLECharacteristic* pRxCharacteristic = nullptr;
NimBLECharacteristic* pTxCharacteristic = nullptr;
NimBLEHIDDevice* hidDevice = nullptr;
volatile bool newDataReady = false;

class MyCallbacks : public NimBLECharacteristicCallbacks {
    void onWrite(NimBLECharacteristic* pCharacteristic) {
        std::string rxValue = pCharacteristic->getValue();
        if (!rxValue.empty()) {
            newDataReady = true;
            Serial.print("Received: ");
            Serial.println(rxValue.c_str());
        }
    }
};

void bluetooth_setup() {
    NimBLEDevice::init("ESP32_UART_BLE");
    NimBLEDevice::setPower(ESP_PWR_LVL_P9);

    pServer = NimBLEDevice::createServer();

    // Add HID device to improve visibility across platforms
    hidDevice = new NimBLEHIDDevice(pServer);
    hidDevice->setManufacturer("OP");
    hidDevice->setPnp(0x02, 0x5E4, 0x820A, 0x0210); // USB VID, PID, version
    hidDevice->setHidInfo(0x00, 0x01);              // HID version 1.0

    // Create custom UART-like service
    NimBLEService* pService = pServer->createService(SERVICE_UUID);

    pTxCharacteristic = pService->createCharacteristic(
        CHARACTERISTIC_UUID_TX,
        NIMBLE_PROPERTY::NOTIFY
    );

    pRxCharacteristic = pService->createCharacteristic(
        CHARACTERISTIC_UUID_RX,
        NIMBLE_PROPERTY::WRITE
    );
    pRxCharacteristic->setCallbacks(new MyCallbacks());

    pService->start();
    Serial.println("BLE service started!");

    NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising();
    pAdvertising->addServiceUUID(SERVICE_UUID);
    pAdvertising->addServiceUUID(hidDevice->getHidService()->getUUID());

    pAdvertising->setAppearance(0x03C0); // Generic HID device

    // Proper scan response data (name + manufacturer)
    NimBLEAdvertisementData scanResponseData;
    scanResponseData.setName("ESP32_UART_BLE");
    scanResponseData.setManufacturerData("OP");
    pAdvertising->setScanResponseData(scanResponseData);

    pAdvertising->start();
    Serial.println("Waiting for a client connection...");
}

void setup() {
    Serial.begin(115200);
    bluetooth_setup();
}

void loop() {
    if (newDataReady) {
        newDataReady = false;
        std::string response = "OK\n";
        pTxCharacteristic->setValue(response);
        pTxCharacteristic->notify();
    }

    delay(10);
}

societyofrobots avatar Jul 31 '25 00:07 societyofrobots

I realize now what's going on here. Samsung Galaxy, Windows, and iOS have made it a point to filter out all devices except their approved whitelisted devices from a BLE scan. No way around it. Tried guessing whitelisted characteristics without luck. HID kinda worked, but not good enough.

I'm open to ideas.

Custom apps can still scan and find my device on these devices. But, it'll require a lot more app programming and a lot of confused people...

societyofrobots avatar Jul 31 '25 19:07 societyofrobots

As far as I know a custom app is all you can do.

h2zero avatar Jul 31 '25 23:07 h2zero