Skip to content
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

[Request for assistance] Broadcast info with manufacturerData field #266

Open
LeeNX opened this issue Feb 9, 2025 · 6 comments
Open

[Request for assistance] Broadcast info with manufacturerData field #266

LeeNX opened this issue Feb 9, 2025 · 6 comments

Comments

@LeeNX
Copy link
Contributor

LeeNX commented Feb 9, 2025

Looking to expose some info, like battery level and possible charging status using the manufacturerData, but my limited coding skills has me stumped.

Doing something like

void setAdvertisingData() {
    // Create new advertisement data object
    NimBLEAdvertisementData newAdvertisementData;
  
    // Add battery level to Manufacturer Data
    uint8_t manufacturerData[10];
    manufacturerData[0] = 0xff; // manufacturer data value - custom
    manufacturerData[1] = 0xff;
    manufacturerData[2] = 0xa0; // begin sig
    manufacturerData[3] = 0x00;
    manufacturerData[4] = advertiseInterval;    // how often broadcast
    manufacturerData[5] = batteryLevel;         // battery level
    manufacturerData[6] = chargingState;        // charging state
    manufacturerData[7] = 0x00; // end sig
    manufacturerData[8] = 0xa0;

    newAdvertisementData.setManufacturerData(std::string((char *)manufacturerData, sizeof(manufacturerData)));

    // Apply updated advertisement data
    pAdvertising->setAdvertisementData(newAdvertisementData);
}

Stops all over the BLE advertising data, I think I am missing the ServiceUUID, which I am not able to get from BleGamepad.

Is this possible get the ServiceUUID from BLEGamepad or make it a global in setup()?

@LeeNX
Copy link
Contributor Author

LeeNX commented Feb 9, 2025

I got the idea from my Home Assistant BLE tracking.

I can hear somebody say, why would you want the data broadcast, it could be a security issue. A use case that I can think of and will use, is that your BLE Proxy devices can report the advertising to your HA install and you can track usage and possible set notifications or alerts to charge your gamepad before your next big gaming session or something like that.

This would partially resolve #182

My broken example esp32blegamepad-blink-battery-broadcast-test-01 if anybody will look it over, please, no laughing or pointing fingers, I know I am not a good programmer.

@LeeNX
Copy link
Contributor Author

LeeNX commented Feb 9, 2025

Image
Example of test idea - 0xA0000F3F0100A0
0xA000 is start of sig
0x0F is how often broadcast would happen
0x3F is batter level - 63%
0x01 is charging status - 1 = Discharging / 2 = Charging / 3 = Fully Charged
0x00A0 is end of sig
Image
Is with a BLE gamepad, but no manufacturerData

@LeeNX LeeNX changed the title [Request for an assist] Broadcast info with manufacturerData field [Request for assistance] Broadcast info with manufacturerData field Feb 9, 2025
@lemmingDev
Copy link
Owner

FYI - I'm about to add support for Characteristic 0x2A1A - Battery Power State

If it's just power stuff you're interested in for now, might be good to hang off for a short time

I've been able to attach characteristic 0x2A1A to the existing NimBLE battery instance and the new characteristic is automatically detected by some apps as Battery Power State.

I am also able to notify data through that characteristic to Android, and have that data show up

There seems to be some confusion as to what data corresponds to what though. In some documentation, I see, in an 8 bit binary value, the 4 most least significant bits are basically Booleans for 4 different battery power state flags, and the remaining 4 bits are reserved

No Android apps that I've found seem to decipher actual battery state data in this way though, although I can see the data coming through

There is one Android app however, that seems to use 2 bits at a time to decipher battery data, where the first 2 define some information, the second 2 bits another and so on, for 4 different attributes

For each 2 bits, that's four possible states, 00, 01, 10, 11, and if I adopt that standard, the information is deciphered correctly by the app as 0x2A1A - Battery Power State data and shows whether it's charging/discharging etc, and if the battery level is good or critically low, among other things

I'm looking for documentation for this second way to see whether we should adopt it, as I can only find information on the first method

@lemmingDev
Copy link
Owner

There's actually a heap of built-in battery stuff as well (that perhaps isn't exposed through NimBLE-Arduino???) here https://github.com/espressif/esp-iot-solution/blob/ce1e2dd1/components/bluetooth/ble_services/bas/include/esp_bas.h

@LeeNX
Copy link
Contributor Author

LeeNX commented Feb 14, 2025

Interesting ... Nice find! Is this not possible another SDK or something? I will add to my notes and look over and see if I can learn any more.

As for my Request for assistance, which after trying my hand at programming, is more becoming a Feature Request, as I don't see a clean way to get this to work.

As a feature, called Custom Broadcast data, I wish to get two things right. First would be to help with some debugging and later, to add to my Home Assistant setup, been able to track battery and temperature (and maybe other things I have not come up with yet) ... Also setup alerts for when my battery is running low or stuff like that.

Really needs to be a broadcast, because I think (might be wrong), we can keep the broadcast running all the time, without having to pair and we can track this info from more than just one Host OS, like a bunch of BlueProxy devices.

I got to the point of write a basic gamepad sketch for testing, but after chatting with h2zero, I believe that we need to rebuild the Advertising each time we might change it - h2zero/NimBLE-Arduino#894

I was thinking we could expose the base/template Advertising data, and just update the setManufacturerData, but my limited C skill has me stumped. Welcome to look at my sketch esp32base-test

Come to learn that the advertising data is limited to 31 char, which might need some sort of warning for device names for the advertising. Does not effect the Device name Characteristic. Not sure how that would effect pairing, if they not the same.

@lemmingDev
Copy link
Owner

So, I ended up adding the 0x2A1A - Battery Power State characteristic, and the data can be set correctly, and read by nRF Connect on Android. In the pic below, I set the values to simulate a battery connected, charging, and at a good level. New version released...

I might circle back to this Custom Broadcast Data thing in a day or two if I get motivated
I wouldn't put my programming on a better level than yourself though

Image

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

2 participants