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

No reliable function to access MAC address of the device itself #523

Closed vishesh-varma closed 1 year ago

vishesh-varma commented 1 year ago

I want to name by device based on its MAC Address, as I plan to have multiple devices and I wanted to differentiate between them. For example, an ESP with addr: 43:5A:12:03:fA:65:02 would have myDevice 6502 as its BLE device name.

The examples I found on the internet only do this by first advertising, then scanning, and then getting the MAC address from the scanned data. That would work okay if there was only 1 BLE device in the area. But in case there are multiple devices, there's a change that a different BLE device's address will get scanned.

Can I not access the MAC Address without starting the advertisement? Is there a way to add it to the library?

h2zero commented 1 year ago

You can get the device address with NimBLEDevice::getAddress.

chegewara commented 1 year ago
    uint8_t mac[6] = {};
    esp_read_mac(mac, ESP_MAC_BT);

All you have to do is to convert hex values to chars.

vishesh-varma commented 1 year ago

Thanks!

NimBLEAddress addr = NimBLEDevice::getAddress();
const uint8_t *addrs = addr.getNative();
String name = "myDevice " + String((addrs[4]<<8)|(addrs[5]), HEX);
NimBLEDevice::init(name.c_str());

This is how I'm doing it after h2zero's comment. The code is untested right now, but I just wanted to know if this is anywhere near how it should be.

vishesh-varma commented 1 year ago

This is the final code snippet that has been tested:

  NimBLEDevice::init("X");
  NimBLEAddress addr = NimBLEDevice::getAddress();
  const uint8_t *addrs = addr.getNative();
  char name[15];
  sprintf(name, "myDevice %X\n", (addrs[1] << 8) | (addrs[0]));
  NimBLEDevice::setDeviceName(name);

Some things to note:

  1. I wasn't able to access Mac address if the BLE stack wasn't initialized. That's why I did the first init with a random name, and then changed the name later on.
  2. The getNative() function writes Right-Most Byte(idk if I can call it LSB) at index 0. I wanted the name to be myDevice EEFF if my MAC Address was AA:BB:CC:DD:EE:FF, but addrs[4] and addrs[5] returned BB and AA respectively. So, I changed it index to 1 and 0.
  3. I'm pretty sure it can be made even better with some more optimizations.
h2zero commented 1 year ago

Thanks for the update, glad it's working for you 😄