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
667 stars 138 forks source link

onAuthenticationComplete() never called #648

Closed sepp89117 closed 3 months ago

sepp89117 commented 3 months ago

Hi, I'm sure it's my fault but unfortunately I'm at a loss at the moment and hope someone can help me here. I wrote a code using esp's standard ble library to connect to gopros. That worked too. Due to the library's high RAM requirement, I wanted to switch to NimBLE. However, I can't get onAuthenticationComplete to be called.

Code for the ESP library:

BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
BLEDevice::setSecurityCallbacks(new MySecurity());
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND);
pSecurity->setCapability(ESP_IO_CAP_NONE);
pSecurity->setRespEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);

Code with NimBLE library;

NimBLEDevice::setSecurityAuth(true, false, true);
NimBLESecurity *pSecurity = new NimBLESecurity();
pSecurity->setAuthenticationMode(BLE_SM_PAIR_AUTHREQ_BOND);
pSecurity->setCapability(ESP_IO_CAP_NONE);
pSecurity->setRespEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);

I also tried with pClient->secureConnection(); before connect() without success.

The callback void onAuthenticationComplete(ble_gap_conn_desc *desc) is in class MyClientCallback : public NimBLEClientCallbacks and never called.

Log:

D NimBLEClient: >> secureConnection()
E NimBLEDevice: ble_gap_security_initiate: rc=7 
D NimBLEClient: >> connect(fa:46:96:f7:dc:72)
D NimBLEClient: Got Client event 
I NimBLEClient: Connected event
D NimBLEClient: Got Client event 
I NimBLEClient: mtu update event; conn_handle=0 mtu=255
I NimBLEClient: Connection established
D NimBLEClient: >> deleteServices
D NimBLEClient: << deleteServices
D NimBLEClient: << connect()

Thank you in advance

h2zero commented 3 months ago

Hello and welcome!

I'll save you some code here, you can replace this:

NimBLEDevice::setSecurityAuth(true, false, true);
NimBLESecurity *pSecurity = new NimBLESecurity();
pSecurity->setAuthenticationMode(BLE_SM_PAIR_AUTHREQ_BOND);
pSecurity->setCapability(ESP_IO_CAP_NONE);
pSecurity->setRespEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);

With just:

NimBLEDevice::setSecurityAuth(true, false, true);

Then the pairing/encryption should happen automatically when reading/writing to the devices characteristics, but if they do not enforce it that way then you should wait until connected and call pClient->secureConnection(); in your onConnect() callback method. Calling that before being connected results in the error code you see in the log.

sepp89117 commented 3 months ago

Thank you for the super quick answer! To set pClient->secureConnection(); in onConnect() was the solution!

Thank you!