Closed JuanJoseMoralesCalvo closed 5 months ago
same here. On PC reconnect works, but on Quest2 does not work. I also use the ESP32-BLE-Gamepad library https://github.com/lemmingDev/ESP32-BLE-Gamepad It did work in summer, but now, not anymore.
Can either of you share a debug log output when this occurs?
The workaround for me was to add security to the BLE, but honestly i dont know the reason :D
Attach to setup() after advertising:
NimBLESecurity *SECURITY_MANDATORY = new BLESecurity(); SECURITY_MANDATORY->setAuthenticationMode(ESP_LE_AUTH_BOND);
Thank you but this did not work. I tried a few other setting but decided it'll be better to go with debugging as @h2zero suggested.
from the log: GamePadPlus V3 is a BT gamepad device that reconnects successful. Cybershoes2 is our BT gamepad device that does reconnect but gamepad functionality fails upon reconnect.
Dear @h2zero, please can you hint at what makes the difference?
Looks like you need to enable bonding. Try adding this after initialization: `NimBLEDevice::setSecurityAuth(true, true, true);'
Have a look at the secure client/server examples.
yes, I did that as you see below. I am using NimBLE 1.38 with ESP32-BLE-Gamepad 0.5.1, because using NimBLE 1.40 makes my ESP32-C crash.
void BleGamepad::taskServer(void *pvParameter)
{
BleGamepad *BleGamepadInstance = (BleGamepad *)pvParameter; // static_cast<BleGamepad *>(pvParameter);
NimBLEDevice::init(BleGamepadInstance->deviceName);
NimBLEServer *pServer = NimBLEDevice::createServer();
pServer->setCallbacks(BleGamepadInstance->connectionStatus);
BleGamepadInstance->hid = new NimBLEHIDDevice(pServer);
BleGamepadInstance->inputGamepad = BleGamepadInstance->hid->inputReport(BleGamepadInstance->configuration.getHidReportId()); // <-- input REPORTID from report map
BleGamepadInstance->connectionStatus->inputGamepad = BleGamepadInstance->inputGamepad;
BleGamepadInstance->hid->manufacturer()->setValue(BleGamepadInstance->deviceManufacturer);
BleGamepadInstance->hid->pnp(0x01, vid, pid, 0x0110);
BleGamepadInstance->hid->hidInfo(0x00, 0x01);
NimBLESecurity *SECURITY_MANDATORY = new BLESecurity();
SECURITY_MANDATORY->setAuthenticationMode(ESP_LE_AUTH_BOND); // ESP_LE_AUTH_REQ_BOND_MITM,
SECURITY_MANDATORY->setCapability(ESP_IO_CAP_NONE);
/**
* @brief Set the authorization mode for this device.
* @param bonding If true we allow bonding, false no bonding will be performed.
* @param mitm If true we are capable of man in the middle protection, false if not.
* @param sc If true we will perform secure connection pairing, false we will use legacy pairing.
*/
//NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc);
NimBLEDevice::setSecurityAuth(true, true, true);
//NimBLEDevice::setSecurityAuth( BLE_SM_PAIR_AUTHREQ_MITM); // BEST must pair again each time but no need to unpair
//NimBLEDevice::setSecurityAuth(BLE_SM_PAIR_AUTHREQ_SC); //same as usual
uint8_t *customHidReportDescriptor = new uint8_t[hidReportDescriptorSize];
memcpy(customHidReportDescriptor, tempHidReportDescriptor, hidReportDescriptorSize);
for (int i = 0; i < hidReportDescriptorSize; i++)
Serial.printf("%02x", customHidReportDescriptor[i]);
BleGamepadInstance->hid->reportMap((uint8_t *)customHidReportDescriptor, hidReportDescriptorSize);
BleGamepadInstance->hid->startServices();
BleGamepadInstance->onStarted(pServer);
NimBLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->setAppearance(HID_GAMEPAD);
pAdvertising->addServiceUUID(BleGamepadInstance->hid->hidService()->getUUID());
pAdvertising->start();
//https://github.com/h2zero/NimBLE-Arduino/issues/464
//The workaround for me was to add security to the BLE, but honestly i dont know the reason :D
//Attach to setup() after advertising:
//NimBLESecurity *SECURITY_MANDATORY = new BLESecurity();
//SECURITY_MANDATORY->setAuthenticationMode(ESP_LE_AUTH_BOND);
//end of inserted code
BleGamepadInstance->hid->setBatteryLevel(BleGamepadInstance->batteryLevel);
ESP_LOGD(LOG_TAG, "Advertising started!");
vTaskDelay(portMAX_DELAY); // delay(portMAX_DELAY);
}
In a variation I also tried without
NimBLESecurity *SECURITY_MANDATORY = new BLESecurity();
SECURITY_MANDATORY->setAuthenticationMode(ESP_LE_AUTH_BOND); // ESP_LE_AUTH_REQ_BOND_MITM,
SECURITY_MANDATORY->setCapability(ESP_IO_CAP_NONE);
reconnecting our Cybershoes gives an encryption failed:
15:55:28.310 1683 1704 D BluetoothGattServer: onConnectionUpdated() - Device=34:B4:72:00:A1:D6 interval=9 latency=0 timeout=600 status=0
15:55:28.356 1412 2092 W bt_btif : btif_gatt_set_encryption_cb() - Encryption failed (1)
15:55:28.356 1412 2092 E bt_btif : bta_hh_security_cmpl() - encryption failed; status=0x000e, reason=0x000a
reconnecting GamePadPlus
15:54:46.249 1683 1704 D BluetoothGattServer: onConnectionUpdated() - Device=20:21:03:07:B9:98 interval=12 latency=0 timeout=200 status=0
15:54:46.331 1412 2092 W bt_stack : [WARNING:bta_gattc_api.cc(652)] notification already registered
15:54:46.332 1412 2092 I chatty : uid=1002(bluetooth) bt_main_thread identical 1 line
15:54:46.332 1412 2092 W bt_stack : [WARNING:bta_gattc_api.cc(652)] notification already registered
15:54:46.332 1412 2092 W bt_btif : bta_hh_co_open: Found an existing device with the same handle dev_status=2, address=20:21:03:07:b9:98, attr_mask=0x0000, sub_class=0x00, app_id=255
15:54:46.332 1412 1662 W bt_btif : btif_hh_upstreams_evt: BTA_HH_OPN_EVT: handle=16, status =0
15:54:46.332 1412 1662 W bt_btif : BTA_HH_OPEN_EVT: Found device...Getting dscp info for handle ... 16
15:54:46.332 1412 1662 I bt_btif_dm : get_cod remote_cod = 0x00000504
15:54:46.332 1412 1662 I bt_btif_dm : get_cod remote_cod = 0x00000504
15:54:46.336 1412 1412 D BluetoothAdapterService: getAdapterService() - returning com.android.bluetooth.btservice.AdapterService@590f4fe
15:54:46.336 1412 1662 W bt_btif : btif_hh_upstreams_evt: name = GamePadPlus V3
15:54:46.336 1412 1662 W bt_btif : bta_hh_co_send_hid_info: fd = 108, name = [GamePadPlus V3], dscp_len = 187
15:54:46.336 1412 1662 W bt_btif : bta_hh_co_send_hid_info: vendor_id = 0x1949, product_id = 0x0402, version= 0x0111,ctry_code=0x00
15:54:46.347 1412 1412 D BluetoothAdapterService: isQuetModeEnabled() - Enabled = false
and finally
15:54:46.547 1034 1142 I InputReader : Device added: id=15, name='GamePadPlus V3', sources=0x01000511
15:54:46.548 2020 2020 D GamepadListener: Adding Device: GamePadPlus V3 pid: 1026 sources: 16778513
15:54:46.549 3026 3026 D GamepadListener: Adding Device: GamePadPlus V3 pid: 1026 sources: 16778513
15:54:46.549 2236 2236 I [OAO] ShellOverlayServiceJNI: NativePTKServiceNotifyDeviceConnectionChanged
15:54:46.549 2236 2236 D [OAO] ShellApplication: PTKService enumerated keyboard: {vendorId: 0x1949 (0n6473), productId: 0x402 (0n1026)}
15:54:46.554 1734 1734 D GamepadListener: Adding Device: GamePadPlus V3 pid: 1026 sources: 16778513
15:54:46.577 2971 2971 D GamepadListener: Adding Device: GamePadPlus V3 pid: 1026 sources: 16778513
also no success with:
NimBLEDevice::setSecurityAuth(true, true, true);
NimBLESecurity *SECURITY_MANDATORY = new BLESecurity();
/**
* @brief Set requested authentication mode
* @param [in] auth_req A bitmask containing one or more of:
* * ESP_LE_AUTH_NO_BOND 0x00
* * ESP_LE_AUTH_BOND 0x01
* * ESP_LE_AUTH_REQ_MITM (1 << 2)
* * ESP_LE_AUTH_REQ_BOND_MITM (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM)
* * ESP_LE_AUTH_REQ_SC_ONLY (1 << 3)
* * ESP_LE_AUTH_REQ_SC_BOND (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY)
* * ESP_LE_AUTH_REQ_SC_MITM (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY)
* * ESP_LE_AUTH_REQ_SC_MITM_BOND (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND)
*/
SECURITY_MANDATORY->setAuthenticationMode(ESP_LE_AUTH_REQ_BOND_MITM); // ESP_LE_AUTH_REQ_BOND_MITM,ESP_LE_AUTH_BOND
//SECURITY_MANDATORY->setCapability(ESP_IO_CAP_NONE);
SECURITY_MANDATORY->setInitEncryptionKey(BLE_SM_PAIR_KEY_DIST_ENC);
SECURITY_MANDATORY->setRespEncryptionKey(BLE_SM_PAIR_KEY_DIST_ENC);
sometimes (once in 5-10 attempts) connection and reconnection (but then I need to confirm pairing again) works successfully with:
NimBLEDevice::setSecurityAuth(true, true, false);
I'm not too sure what the error is yet, the logs suggest an error in a value passed during pairing. What kind of pairing does the other device expect?
If not using PIN codes or any other mitm protection then try setting the last 2 parameters of the NimBLEDevice::setSecurityAuth
call to false. Otherwise just set the last parameter to false if mitm is required.
You should also remove this:
NimBLESecurity *SECURITY_MANDATORY = new BLESecurity();
/**
* @brief Set requested authentication mode
* @param [in] auth_req A bitmask containing one or more of:
* * ESP_LE_AUTH_NO_BOND 0x00
* * ESP_LE_AUTH_BOND 0x01
* * ESP_LE_AUTH_REQ_MITM (1 << 2)
* * ESP_LE_AUTH_REQ_BOND_MITM (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM)
* * ESP_LE_AUTH_REQ_SC_ONLY (1 << 3)
* * ESP_LE_AUTH_REQ_SC_BOND (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY)
* * ESP_LE_AUTH_REQ_SC_MITM (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY)
* * ESP_LE_AUTH_REQ_SC_MITM_BOND (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND)
*/
SECURITY_MANDATORY->setAuthenticationMode(ESP_LE_AUTH_REQ_BOND_MITM); // ESP_LE_AUTH_REQ_BOND_MITM,ESP_LE_AUTH_BOND
//SECURITY_MANDATORY->setCapability(ESP_IO_CAP_NONE);
SECURITY_MANDATORY->setInitEncryptionKey(BLE_SM_PAIR_KEY_DIST_ENC);
SECURITY_MANDATORY->setRespEncryptionKey(BLE_SM_PAIR_KEY_DIST_ENC);
That is conflicting with the security settings above it.
@CybershoesVR Try this workaround from chewara, it sounds like its happening the same:
class MyCallbacks : public BLEServerCallbacks { void onConnect(BLEServer pServer){ Serial.println("connected"); BLEDescriptor desc = input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); uint8_t val[] = {0x01, 0x00}; desc->setValue(val, 2); }
void onDisconnect(BLEServer* pServer){ Serial.println("disconnected"); } };
Issue Open: https://github.com/nkolban/esp32-snippets/issues/632
You have to add something like this on the onConenct:
BLEDescriptor *desc = input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); uint8_t val[] = {0x01, 0x00}; desc->setValue(val, 2);
I’m facing the same issue.
@JuanJoseMoralesCalvo Did your suggestion work for you?
The workaround on comment #12 didnt work as i understand its only for the nkolban esp32 libraries. Finally by adding security it worked.
NimBLESecurity *SECURITY_MANDATORY = new NimBLESecurity(); SECURITY_MANDATORY->setAuthenticationMode(ESP_LE_AUTH_BOND); // ESP_LE_AUTH_REQ_BOND_MITM, SECURITY_MANDATORY->setCapability(ESP_IO_CAP_NONE);
On which lines of which file should I put this?
Please explain me if I should add or replace code?
I would encourage not to use the security class as it has been deprecated.
The equivalent call is simply:
NimBLEDevice::setSecurityAuth(true, false, false); // enable bonding, no MITM, no SC
The IO caps default to NONE. Just put that line somewhere after initializing NimBLE.
@h2zero like this example in my gist?
https://gist.github.com/fabdelgado/60c715dec2651b46a0d342c46179fe48
Looks good to me
I will try that!
It has not worked for me with my chromecast v3 Google TV. You can review the video I have recorded for you.
https://user-images.githubusercontent.com/8621547/200147816-289740df-03e3-4b02-9f8e-d16e6ccdcda3.mp4
Hmm, please try erasing the flash of the esp32 then upload your code. Also remove any devices bonded to the TV if you can.
@h2zero this worked for me, thanks for the help.
https://user-images.githubusercontent.com/8621547/200183433-a0bfaea0-bfe1-4ad7-8a33-ad92f576229e.mp4
This is the code that I have used, I have left it for future issues.
`void setup() {
NimBLEDevice::init("NimBLE");
NimBLEDevice::setSecurityAuth(true, false, false); // enable bonding, no MITM, no SC }`
@h2zero I have another related problem, when I press forget device and then restart the Chromecast it unbinds the remote from Chromecast instead of ESP32. This problem happened to me before the problem of connecting and disconnecting. Do you have any idea?
I don't have any idea why that would happen, wouldn't have anything to do with the esp32 though.
Hi im trying to create an HID Gamepad so when i first pair the device all works great but when i (for example) reset the module it doesnt work. Any suggestion on the connect CallBack?