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

how to see mac of device #870

Open
mihaigabriel620 opened this issue Jan 19, 2025 · 7 comments
Open

how to see mac of device #870

mihaigabriel620 opened this issue Jan 19, 2025 · 7 comments

Comments

@mihaigabriel620
Copy link

mihaigabriel620 commented Jan 19, 2025

Hey im new here and i want to know how to see the device mac connected to the esp ( talking about phone here ) but not the mac that changes i mean the decrypted id that uses the irk or something else that can identify the phone from another one maybe its not mac i dunno im new

Using esp32c3

@h2zero
Copy link
Owner

h2zero commented Jan 20, 2025

The only way to get the static device ID address is to bond with it, then you can get the address from the onIdentity callaback.

@mihaigabriel620
Copy link
Author

can you give a code snippet example on how to implement once bonded i can see the mac on the serial monitor?

@mihaigabriel620
Copy link
Author

mihaigabriel620 commented Jan 20, 2025

and once bonded will it be the true mac of the device? and not the randoom one?

because i need the ability to identify a device from another one that is why i need the decrypted mac/resolved mac

@h2zero
Copy link
Owner

h2zero commented Jan 20, 2025

NimBLEDevice::setSecurityAuth(true, false, true); // first param enables bonding.

Please see the secure server example for more info.

Then implement the callback:

void NimBLEServerCallbacks::onIdentity(NimBLEConnInfo& connInfo) {

The identity address is in connInfo->getIdAddress()

@mihaigabriel620
Copy link
Author

Funny you say that i tried exactly that but the resulting mac is still the random one

@h2zero
Copy link
Owner

h2zero commented Jan 20, 2025

Works for me?

ble_client_identity.txt

@mihaigabriel620
Copy link
Author

for clarity im talking the esp is a server and the device that connects to it is a phone ( that is why i need to see the phone mac but not the randoom one ) take a look at my code
#include <Arduino.h>
#include <NimBLEDevice.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// DS18B20 Sensor Setup
#define PIN_BUS 4 // GPIO pin for DS18B20 data line
#define TEMP_OFFSET 0 // Calibration offset for temperature sensor
OneWire oneWire(PIN_BUS);
DallasTemperature sensors(&oneWire);

// BLE HID and Service UUIDs
#define HID_SERVICE_UUID "1812" // HID Service
#define HID_REPORT_UUID "2A4D"
#define SERVICE_UUID "abcdefab-cdef-1234-5678-1234567890ab"
#define SEND_CHAR_UUID "abcdefab-cdef-1234-5678-1234567890cd"
#define RECEIVE_CHAR_UUID "abcdefab-cdef-1234-5678-1234567890ef"

// HID Descriptor (Minimal Keyboard Example)
const uint8_t HID_DESCRIPTOR[] = {
0x05, 0x01, // Usage Page (Generic Desktop Controls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x05, 0x07, // Usage Page (Keyboard/Keypad)
0x19, 0xE0, // Usage Minimum (Keyboard Left Control)
0x29, 0xE7, // Usage Maximum (Keyboard Right GUI)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data, Variable, Absolute) ; Modifier byte
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x01, // Input (Constant) ; Reserved byte
0xC0 // End Collection
};

// BLE Server, Service, and Characteristics
NimBLEServer* pServer = nullptr;
NimBLEService* pService = nullptr;
NimBLEService* pHIDService = nullptr;
NimBLECharacteristic* sendChar = nullptr;
NimBLECharacteristic* receiveChar = nullptr;
NimBLECharacteristic* reportChar = nullptr;

// App Authentication
String correctPasscode = "23062008"; // App passcode

// RSSI Tracking
uint16_t connHandle = 0xFFFF; // Store connection handle
unsigned long connectionStartTime = 0; // Timestamp when the connection starts
unsigned long lastRssiUpdate = 0; // Timestamp of the last RSSI update
const unsigned long rssiUpdateInterval = 2000; // 2-second interval between RSSI updates
const unsigned long rssiDelayAfterConnect = 3000; // 3-second delay after reconnection

// RSSI Thresholds
const int8_t CLOSE_THRESHOLD = -50; // RSSI threshold for "close" detection
const int8_t FAR_THRESHOLD = -70; // RSSI threshold for "far" detection
bool isPhoneClose = false; // Tracks whether the phone is close

// Temperature Change Detection
float lastSentTemp = -127.0; // Last sent temperature
unsigned long lastTempPoll = 0; // Timestamp of the last temperature poll
const unsigned long tempPollInterval = 1000; // 1-second interval for temperature polling

// Function Declarations
void sendTemperatureToApp();
void pollAndSendTemperature();
void forwardCommandToMega(const String& command);
void handleReceivedData(const std::string& receivedData);
void restartAdvertising();
void checkRssi();

class ServerCallbacks : public NimBLEServerCallbacks {
void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) override {
Serial.println("Device connected.");
connHandle = connInfo.getConnHandle(); // Store connection handle
connectionStartTime = millis(); // Set connection start time

    // Request PHY update to LE Coded PHY (125 kbps)
    if (pServer->updatePhy(
            connHandle,
            BLE_HCI_LE_PHY_CODED, // TX PHY
            BLE_HCI_LE_PHY_CODED, // RX PHY
            0)) {
        Serial.println("Connection PHY set to LE Coded (125 kbps).");
    } else {
        Serial.println("Failed to update connection PHY to LE Coded.");
    }
}

void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) override {
    Serial.println("Device disconnected.");
    connHandle = 0xFFFF; // Invalidate the connection handle
    restartAdvertising(); // Restart advertising on disconnect
}

};

class CharacteristicCallbacks : public NimBLECharacteristicCallbacks {
void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override {
std::string receivedData = pCharacteristic->getValue();
handleReceivedData(receivedData);
}
};

void setup() {
Serial.begin(9600);
Serial1.begin(9600); // Communication with Arduino Mega

// Initialize DS18B20
oneWire.begin(PIN_BUS);
sensors.begin();

// Initialize BLE
NimBLEDevice::init("ESP32-C3 HID Device");
NimBLEDevice::setDeviceName("ESP32-C3 HID Device");
NimBLEDevice::setPower(ESP_PWR_LVL_P9); // Max TX power
NimBLEDevice::setSecurityAuth(true, false, true); // Enable bonding

pServer = NimBLEDevice::createServer();
pServer->setCallbacks(new ServerCallbacks());

// Create HID Service
pHIDService = pServer->createService(HID_SERVICE_UUID);
reportChar = pHIDService->createCharacteristic(
    HID_REPORT_UUID,
    NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY
);
reportChar->setValue(HID_DESCRIPTOR, sizeof(HID_DESCRIPTOR)); // Set HID Descriptor
pHIDService->start();

// Create Custom Service
pService = pServer->createService(SERVICE_UUID);
sendChar = pService->createCharacteristic(
    SEND_CHAR_UUID,
    NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY
);
receiveChar = pService->createCharacteristic(
    RECEIVE_CHAR_UUID,
    NIMBLE_PROPERTY::WRITE
);
receiveChar->setCallbacks(new CharacteristicCallbacks());
pService->start();

// Start advertising
restartAdvertising();

}

void loop() {
unsigned long currentMillis = millis();

// Check RSSI only after the initial delay following a connection
if (connHandle != 0xFFFF &&
    currentMillis - connectionStartTime >= rssiDelayAfterConnect &&
    currentMillis - lastRssiUpdate >= rssiUpdateInterval) {
    lastRssiUpdate = currentMillis;
    checkRssi();
}

// Poll temperature with a 1-second interval
if (currentMillis - lastTempPoll >= tempPollInterval) {
    lastTempPoll = currentMillis;
    pollAndSendTemperature();
}

}

void pollAndSendTemperature() {
sensors.requestTemperatures();
float currentTemp = sensors.getTempCByIndex(0);

if (currentTemp == DEVICE_DISCONNECTED_C) {
    Serial.println("Temperature sensor disconnected.");
    return;
}

// Calibrate the temperature
float calibratedTemp = currentTemp - TEMP_OFFSET;
if (calibratedTemp < 0) calibratedTemp = 0;
if (calibratedTemp > 40) calibratedTemp = 40;

// Send temperature only if there's a 1°C change
if (abs(calibratedTemp - lastSentTemp) >= 1.0) {
    lastSentTemp = calibratedTemp;
    sendTemperatureToApp();
}

}

void sendTemperatureToApp() {
String tempStr = String((int)lastSentTemp);
sendChar->setValue(tempStr.c_str());
sendChar->notify();
Serial.println("Temperature sent to app: " + tempStr);
}

void forwardCommandToMega(const String& command) {
Serial1.println(command); // Send the command to the Arduino Mega
Serial.println("Forwarded to Mega: " + command);
}

void handleReceivedData(const std::string& receivedData) {
String command = String(receivedData.c_str());
command.trim();

if (command == correctPasscode) {
    Serial.println("App authenticated or re-authenticated.");
    sendTemperatureToApp(); // Send the temperature whenever passcode is received
} else {
    // Forward all other commands to the Arduino Mega
    forwardCommandToMega(command);
}

}

void checkRssi() {
if (connHandle == 0xFFFF) {
Serial.println("No active connection.");
return;
}

int8_t rssi;
if (ble_gap_conn_rssi(connHandle, &rssi) == 0) { // Successfully retrieved RSSI
    Serial.print("RSSI: ");
    Serial.println(rssi);

    // Trigger close or far events
    if (!isPhoneClose && rssi >= CLOSE_THRESHOLD) {
        isPhoneClose = true;
        Serial1.println("7"); // Send 7 to Arduino Mega
        Serial.println("Phone is close: Sent 7 to Mega.");
    } else if (isPhoneClose && rssi <= FAR_THRESHOLD) {
        isPhoneClose = false;
        Serial1.println("8"); // Send 8 to Arduino Mega
        Serial.println("Phone is far: Sent 8 to Mega.");
    }
} else {
    Serial.println("Failed to retrieve RSSI.");
}

}

void restartAdvertising() {
NimBLEExtAdvertising* pAdvertising = NimBLEDevice::getAdvertising();
NimBLEExtAdvertisement advData(BLE_HCI_LE_PHY_CODED);
advData.setPrimaryPhy(BLE_HCI_LE_PHY_CODED);
advData.setSecondaryPhy(BLE_HCI_LE_PHY_CODED);
advData.setConnectable(true);
advData.setScannable(false);
advData.setName("ESP32-C3 HID Device");
advData.setCompleteServices16({NimBLEUUID(HID_SERVICE_UUID), NimBLEUUID(SERVICE_UUID)});

if (pAdvertising->setInstanceData(0, advData)) {
    if (pAdvertising->start(0, 0, 0)) {
        Serial.println("Started HID and BLE advertising with LE Coded PHY (125 kbps).");
    } else {
        Serial.println("Failed to start advertising.");
    }
} else {
    Serial.println("Failed to set advertising data.");
}

}

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