Skip to content

How to pair with ESP32 Bluetooth device using passkey/PIN from smartphone? #1458

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

Closed
avinashs24 opened this issue Jun 2, 2018 · 59 comments
Closed
Assignees
Labels
Area: BT&Wifi BT & Wifi related issues

Comments

@avinashs24
Copy link

Hardware:

Board: ESP-WROOM-32
Core Installation/update date: 01/JUN/2018
IDE name: Arduino IDE
Flash Frequency: 80Mhz
Upload Speed: 921600

Description:

I am using the SerialToSerialBT example. I am able to scan and discover the Bluetooth device from my smartphone. But the pairing is without any security/passcode. It simply pairs immediately. How to make the pairing using PIN/Passkey entry?

Sketch:

#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  delay(5000);
  Serial.println("Starting..");
  SerialBT.begin("MyESP32"); //Bluetooth device name
  Serial.println("The device started, now you can pair it with bluetooth!");
  
}

void loop() {
  if (Serial.available()) {
    SerialBT.write(Serial.read());
  }
  if (SerialBT.available()) {
    Serial.write(SerialBT.read());
  }
  delay(20);
}

Debug Messages:

Starting..
The device started, now you can pair it with bluetooth!

@copercini
Copy link
Contributor

It depends of some IDF/Bluetooth core functions that aren't available yet... espressif/esp-idf#1541

once it is released, it will be implemented here as well

@copercini copercini added the Status: To be implemented Selected for Development label Jun 2, 2018
@maddmaxamofo
Copy link

I am also working on a Bluetooth device that needs this feature. Is there an estimate on its release date?

@nayan27
Copy link

nayan27 commented Sep 5, 2018

@copercini feature was implemented in commit espressif/esp-idf@8571170

Any idea on when it could be available for esp-idf ?

Thank you

@pir0c0pter0
Copy link

would be great to have this feature.

@mpbejo
Copy link

mpbejo commented Nov 16, 2018

Hi,
Any idea on when it could be available for Arduino ?
Thank You

@chegewara
Copy link
Contributor

I know its not the best solution, but you can try to use esp-idf functions in your app. Just saying.

@zdclaudy
Copy link

Anything more on this? It's a feature i am needing badly.

@HarpreetHeera
Copy link

No help.
I am using Lolin D32 with Arduino IDE. I have tried all the ways many examples, still serial terminal app is connecting to esp32 without facing any passkey authentication in bluetooth classic mode.

Looking forward for support.

Thanks

@chegewara
Copy link
Contributor

chegewara commented Dec 19, 2019

There is no option to build classic bluetooth with static key pairing (or any key pairing). It is because it requires to change settings in menuconfig. Classic bluetooth can be configured to use SSP (secure simple pairing) or legacy pairing which is controlled in menuconfig.
Only option is to use arduino as component.

@HarpreetHeera
Copy link

Hi everyone,
Thanks to all.
I have successfully implemented pass key aka pin code authentication functionality in my lolin 32 using Arduino as IDE in classic Bluetooth mode for sending data over serial Bluetooth profile.
What I did is as following.

  1. I uninstall latest version of of espressif esp32 Arduino 1.0.4 release.
  2. Install espressif/ Arduino ver. 1.0.1 from board manager.
  3. Select board.
  4. Download disable_ssp.zip from BluetoothSerial Status && API discussion for passkey/PIN #2320 (comment)
  5. Follow the readme instruction available in above zip file.
  6. Upload the compiled program.

Open Bluetooth setting in my phone , unpair esp32 device from my old paired list. Rescan for new device then click on the my esp32 device ... Here m the miracle happened .... THE PIN CODE AUTHENTICATION APPEARED .... to pair my Bluetooth esp32 device....

Thanks for all brilliant people who saved my hard work done by providing this solution.

Regards
Harpreet Singh

@chegewara
Copy link
Contributor

Thanks for sharing @HarpreetHeera
As you said, you are using arduino-esp32 v1.0.1, which is very old version and probably at the time it was compiled option i mentioned earlier was not implemented in esp-idf, but glad you achieved what you are looking for.

@HarpreetHeera
Copy link

Thanks for sharing @HarpreetHeera
As you said, you are using arduino-esp32 v1.0.1, which is very old version and probably at the time it was compiled option i mentioned earlier was not implemented in esp-idf, but glad you achieved what you are looking for.

Thanks Chegewara ...
for your support and valuable response.
Have a great time.

@choichangjun
Copy link

choichangjun commented Feb 6, 2020

Hi guys. I found some code and I uploaded my repository.
come and try my code. it might be worked !
It should be Arduino IDF and ESP-IDF installed
No need to downgrade version
https://github.com/choichangjun/ESP32_arduino

@Flashbulbtech
Copy link

Hi guys. I found some code and I uploaded my repository.
come and try my code. it might be worked !
It should be Arduino IDF and ESP-IDF installed
No need to downgrade version
https://github.com/choichangjun/ESP32_arduino

Its wonderfully working. Thanks

@chegewara
Copy link
Contributor

https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/Arduino/security/StaticPIN/StaticPIN.ino

https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLESecurity.cpp#L67

Its here over a year, and its working, just for some reasons is not updated in arduino-essp32.

BTW this issue was about PIN in classic BT, not BLE

@HarpreetHeera
Copy link

Thanks Chegewara,
Now we have working pin key authentication in latest version of Arduino-Esp32.

Thanks for your efforts. Great to know. Now we are able to do more stuff on latest release .

Thanks again.

@HorstBaerbel
Copy link

HorstBaerbel commented Feb 20, 2020

So... I've tried Bluetooth classic serial on the ESP32 and pairing does not work for me with Ubuntu 19.10. The ESP32 always connects and directly disconnects again. Is this the same problem? What can I do about it?

Only option is to use arduino as component.

What does that mean?

@Vish1998
Copy link

Thanks Chegewara,
Now we have working pin key authentication in latest version of Arduino-Esp32.
Thanks for your efforts. Great to know. Now we are able to do more stuff on latest release .
Thanks again.

sir, can you please provide me the code to set password for esp-32 classic Bluetooth.

@HarpreetHeera
Copy link

Thanks Chegewara,
Now we have working pin key authentication in latest version of Arduino-Esp32.
Thanks for your efforts. Great to know. Now we are able to do more stuff on latest release .
Thanks again.

sir, can you please provide me the code to set password for esp-32 classic Bluetooth.

What specific problem are you facing? Need little explanation.

@Vish1998
Copy link

Thanks Chegewara,
Now we have working pin key authentication in latest version of Arduino-Esp32.
Thanks for your efforts. Great to know. Now we are able to do more stuff on latest release .
Thanks again.

sir, can you please provide me the code to set password for esp-32 classic Bluetooth.

What specific problem are you facing? Need little explanation.

I am unable to set a paring password for esp32 board. The board is automatically getting connected to mobile phone without asking for any passkey.

@Vish1998
Copy link

I am in need of help regarding setting passkey for ESP-32 classic Bluetooth please somebody help me out.

@chegewara
Copy link
Contributor

I am in need of help regarding setting passkey for ESP-32 classic Bluetooth please somebody help me out.

You need to use arduino as component and to change some settings in bluetooth menuconfig or rebuild bluetooth library in esp-idf with new settings and replace the one in arduino.

@Luis-Ferreira
Copy link

Hi,I´m also needing to set a passkey to classic Bluetooth .Use arduino as a component?How can we do that?I´m learning ,please help!Thanks.

@chegewara
Copy link
Contributor

@Luis-Ferreira
Copy link

https://github.com/espressif/arduino-esp32/blob/master/docs/esp-idf_component.md

Thanks for the answer.But is it possible to make it easier?How can a simple thing like this give so much work.I don´t know how to do it .Can you help?

@Vish1998
Copy link

https://github.com/espressif/arduino-esp32/blob/master/docs/esp-idf_component.md

Thanks for the answer.But is it possible to make it easier?How can a simple thing like this give so much work.I don´t know how to do it .Can you help?

I am also in need of it very much. Please help me out.

@HarpreetHeera
Copy link

If you are still not able to figure out with latest update.
Then try this.

#1458 (comment)

@Luis-Ferreira
Copy link

If you are still not able to figure out with latest update.
Then try this.

#1458 (comment)

Thanks for reply ,but I´m designing a commercial product with possible future updates so I can´t depend on older releases of arduino.I want something that I can work in the future .

@severinbeauvais
Copy link

severinbeauvais commented Feb 15, 2021

This is part of the solution:

  //
  // init Bluetooth
  //
  SerialBT.enableSSP();
  SerialBT.setPin("123456");
  if (!SerialBT.begin("MY_ESP32_BT")) {
    Serial.println("Bluetooth init failed!");
    while (true) {
      delay(1000); // don't proceed, loop forever
    }
  }
  Serial.println("Bluetooth initialized!");

I haven't figured out how to sync the code between device and phone... The code displayed on the phone is not as set above, and pairing fails.

Anyone?

@severinbeauvais
Copy link

I found this but it's not quite working either...
https://github.com/choichangjun/ESP32_arduino/blob/master/ESP32_Arduino_paring_Key.ino

@severinbeauvais
Copy link

severinbeauvais commented Feb 15, 2021

https://github.com/h2zero/NimBLE-Arduino/blob/master/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino

This is BLE not BT Classic. But thanks! I may use it anyway... :)

PS Needs NimBLE-Arduino library. See https://github.com/h2zero/NimBLE-Arduino

@ingsoc
Copy link

ingsoc commented Apr 15, 2021

Is this ever going to be addressed for BlueTooth Serial ?

Not being able to set a pass code makes it not usable for a large number of applications :(

@ingsoc
Copy link

ingsoc commented Apr 20, 2021

Bump

1 similar comment
@jbjbjb1
Copy link

jbjbjb1 commented Apr 22, 2021

Bump

@VojtechBartoska VojtechBartoska added the Area: BT&Wifi BT & Wifi related issues label Apr 22, 2021
@podaen
Copy link

podaen commented Apr 27, 2021

I want to setup a pin too. Did you tried this for an incomming connection on classic bluetooth over the AT-command.

Documentation AT-commands

@podaen
Copy link

podaen commented Apr 27, 2021

Sorry, It's not the latest version.

I want to setup a pin too. Did you tried this for an incomming connection on classic bluetooth over the AT-command.

Documentation AT-commands

This is...

Documentation AT-commands

@podaen
Copy link

podaen commented Apr 28, 2021

I could not access the AT-command over serial monitor in the Arduino IDE. It could maybe be possible by using the UART pins of the bluetooth. To do that you need to config ESP-IDF with python.

So I followed the instruction here and it worked.

@podaen
Copy link

podaen commented Apr 28, 2021

And I reflash the firmware with 2.1 too.

@ingsoc
Copy link

ingsoc commented Apr 28, 2021

@podaen Hi, Could you provide a few more detail on how you managed to achieve this ?

Cheers

@VojtechBartoska VojtechBartoska added the Status: In Progress ⚠️ Issue is in progress label Apr 28, 2021
@podaen
Copy link

podaen commented Apr 29, 2021

The one I flashed doesn't solve the issue here. Just for you to know. Anyway you can downloaded the "downoad tool" and "bin file" from espressif server, unzip it and direct the tool to the bin files. I flashed it on byte 0x1000, 0x8000 and 0x10000. It could be different from ESP to ESP. Google is your friend.

@podaen
Copy link

podaen commented May 2, 2021

I found a way to set a fix pin (for what I have test it now) with the last SDK. 

I did set the SPP (serial port protocol) to true in the menuconfig with python, but it can be already enabled default. I am not sure, after a lot of flashing and reconfiguration. The Arduino precompiled code does support SPP also. 

I test it on multiple devices and it worked but now I found out it doesn't  work with ios like HC05.

Fix pin python code

@podaen
Copy link

podaen commented May 4, 2021

note: In the sdkconfig files the secure simple pairing (SPP) needs to be NOT set. The arduino sdkconfig file that's generated is set for other reasons and can not be edit. So it cannot be done by this libary or any other libary on this type of bluetooth connecting without addapting other sdk files.

@VojtechBartoska VojtechBartoska self-assigned this May 6, 2021
@podaen
Copy link

podaen commented May 6, 2021

In my eyes secure simple pairing is interesting when you have the capibility too enter a key in both devices. I could be wrong... I m connecting with an android to esp without screen or keyboard.

@alfonso18martin
Copy link

alguien lo pudo hacer????.... el codigo pin

@SuGlider
Copy link
Collaborator

@alfonso18martin

Try calling setPin() before begin().

void setup() {
  Serial.begin(115200);
  SerialBT.setPin(pin);    // setPin() shall come before begin()
  SerialBT.begin("ESPBT", true); 
  Serial.println("The device started in master mode, make sure remote BT device is on!");
  
  connected = SerialBT.connect(address);
  
  if(connected) {
    Serial.println("Connected Succesfully!");
  } else {
    while(!SerialBT.connected(10000)) {
      Serial.println("Failed to connect. Make sure remote device is available and in range, then restart app."); 
    }
  }
}

@VojtechBartoska VojtechBartoska removed the Status: To be implemented Selected for Development label Apr 6, 2022
@PilnyTomas
Copy link
Contributor

@alfonso18martin

Try calling setPin() before begin().

void setup() {
  Serial.begin(115200);
  SerialBT.setPin(pin);    // setPin() shall come before begin()
  SerialBT.begin("ESPBT", true); 
  Serial.println("The device started in master mode, make sure remote BT device is on!");
  
  connected = SerialBT.connect(address);
  
  if(connected) {
    Serial.println("Connected Succesfully!");
  } else {
    while(!SerialBT.connected(10000)) {
      Serial.println("Failed to connect. Make sure remote device is available and in range, then restart app."); 
    }
  }
}

setPin is checking to make sure it was called after the begin
https://github.com/espressif/arduino-esp32/blob/855f5261913c74e9f4f99fc0de184c847cc4db59/libraries/BluetoothSerial/src/BluetoothSerial.cpp#L915C1-L915C1

@RMU56
Copy link

RMU56 commented Dec 21, 2023

Hardware:

Board: ESP-WROOM-32 Core Installation/update date: 01/JUN/2018 IDE name: Arduino IDE Flash Frequency: 80Mhz Upload Speed: 921600

Description:

I am using the SerialToSerialBT example. I am able to scan and discover the Bluetooth device from my smartphone. But the pairing is without any security/passcode. It simply pairs immediately. How to make the pairing using PIN/Passkey entry?

Sketch:

#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  delay(5000);
  Serial.println("Starting..");
  SerialBT.begin("MyESP32"); //Bluetooth device name
  Serial.println("The device started, now you can pair it with bluetooth!");
  
}

void loop() {
  if (Serial.available()) {
    SerialBT.write(Serial.read());
  }
  if (SerialBT.available()) {
    Serial.write(SerialBT.read());
  }
  delay(20);
}

Debug Messages:

Starting..
The device started, now you can pair it with bluetooth!

I have successfully connected using password 123456 and sending continuous data 0 to 9 in loop and can visible in BLE scanner app in R mode. You can only Read data if your connection is successful.
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#define SERVICE_UUID "0000FFE0-0000-1000-8000-00805F9B34FB"
#define CHARACTERISTIC_UUID "0000FFE1-0000-1000-8000-00805F9B34FB"

class MySecurity : public BLESecurityCallbacks {
uint32_t onPassKeyRequest() {
ESP_LOGI(LOG_TAG, "PassKeyRequest");
return 123456;
}

void onPassKeyNotify(uint32_t pass_key) {
ESP_LOGI(LOG_TAG, "The passkey Notify number:%d", pass_key);
}

bool onConfirmPIN(uint32_t pass_key) {
ESP_LOGI(LOG_TAG, "The passkey YES/NO number:%d", pass_key);
vTaskDelay(5000);
return true;
}

bool onSecurityRequest() {
ESP_LOGI(LOG_TAG, "SecurityRequest");
return true;
}

void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) {
ESP_LOGI(LOG_TAG, "Starting BLE work!");
}
};

class MyCallbacks : public BLECharacteristicCallbacks {
void onRead(BLECharacteristic *pCharacteristic) {
if (pCharacteristic->getValue().length() > 0) {
Serial.println("Read request received!");
// You can add your custom read handling code here
}
}
};

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;

int counter = 0;

void setup() {
Serial.begin(115200);

BLEDevice::init("ESP32");

BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);

BLEDevice::setSecurityCallbacks(new MySecurity());

pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE);
pCharacteristic->setValue("Hello World");
pCharacteristic->setCallbacks(new MyCallbacks());
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
BLESecurity *pSecurity = new BLESecurity();
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint32_t passkey = 123456;
uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE;
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND);
pSecurity->setCapability(ESP_IO_CAP_OUT);
pSecurity->setKeySize(16);
esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t));
pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
Serial.println("Characteristic defined! Now you can read it on your phone!");
}

void loop() {
// Increment the counter from 0 to 9
pCharacteristic->setValue(String(counter).c_str());
pCharacteristic->notify();

Serial.print("Sending value: ");
Serial.println(counter);

delay(1000); // Adjust the delay based on your application requirements

// Reset counter when it reaches 9
if (counter == 9) {
counter = 0;
} else {
counter++;
}

delay(2000);
}

@Rob58329
Copy link
Contributor

Rob58329 commented Jan 28, 2025

PS. If anyone want's to know how to list and/or remove/delete a BLE Bond/Pair in Arduino, example code is shown below:

// works on ESP32(NodeMCU-32S) and ESP32-S3 and ESP32-C3 
// works for both "BLEDevice::createServer();" and "BLEDevice::createClient();"
// works using "github.com/espressif/arduino-esp32" as at 19Jan25

// #define USE_ALTERNATIVE_SETUP // or not

#ifdef USE_ALTERNATIVE_SETUP
  #include <BLEDevice.h>
#else
  #include "nvs_flash.h"    
  #include "esp_bt.h"        
  #include "esp_gap_ble_api.h"
  #include "esp_bt_main.h"
#endif

void setup() {
  Serial.begin(115200); delay(3000);
  #ifdef USE_ALTERNATIVE_SETUP
    Serial.println("\nBLEDevice::init");
    BLEDevice::init("ESP-BLE");
  #else
    Serial.println("\nBLE Bonded_Devices_List_setup");
    Bonded_Devices_List_setup();
  #endif
  show_bonded_devices();
  Serial.println("\nCommands: 'd' = show_bonded_devices(),  'e' = remove_all_bonded_devices()");
}

void loop() {
  while (Serial.available()) {
    char c=Serial.read();
    if (c>=32) Serial.write(c); else Serial.println();
    if (c=='d') show_bonded_devices();
    if (c=='e') remove_all_bonded_devices();
  }
}

char bda_str[18];
char *bda2str(const uint8_t *bda) {
  sprintf(bda_str, "%02x:%02x:%02x:%02x:%02x:%02x", bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
  return bda_str;
}

void show_bonded_devices() {
  int dev_num = esp_ble_get_bond_device_num();
  esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num);
  esp_ble_get_bond_device_list(&dev_num, dev_list);
  Serial.printf("\nBonded devices number: %d\n", dev_num);
  for (int i = 0; i < dev_num; i++) {Serial.printf("Found bonded device #%d = %s\n", i+1, bda2str(dev_list[i].bd_addr));}
  free(dev_list);
}

void remove_all_bonded_devices() {
  Serial.println("\nRemoving all bonded devices...");
  int dev_num = esp_ble_get_bond_device_num();
  esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num);
  esp_ble_get_bond_device_list(&dev_num, dev_list);
  for (int i = 0; i < dev_num; i++) esp_ble_remove_bond_device(dev_list[i].bd_addr);
  free(dev_list);
}

#ifndef USE_ALTERNATIVE_SETUP // ********************
void Bonded_Devices_List_setup() {
  esp_err_t ret;

  // Initialize NVS.
  ret = nvs_flash_init();
  if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      ret = nvs_flash_init();
  }
  Serial.printf("Initialize NVS=%i\n",!ret);
  
  Serial.printf("esp_bt_controller_mem_release=%i\n",!esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); // unsure if this is necessary!?

  esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  ret = esp_bt_controller_init(&bt_cfg);
  if (ret) {Serial.printf("%s init controller failed: %s", __func__, esp_err_to_name(ret)); return;}
  Serial.printf("esp_bt_controller_init=%i\n",!ret);
   
  ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
  if (ret) {Serial.printf("%s enable controller failed: %s", __func__, esp_err_to_name(ret)); return;}
  Serial.printf("esp_bt_controller_enable=%i\n",!ret);

  ret = esp_bluedroid_init();
  if (ret) {Serial.printf("%s init bluetooth failed: %s", __func__, esp_err_to_name(ret)); return;}
  Serial.printf("esp_bluedroid_init=%i\n",!ret);
        
  ret = esp_bluedroid_enable();
  if (ret) {Serial.printf("%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret)); return;}
  Serial.printf("esp_bluedroid_enable=%i\n",!ret);
}
#endif // ********************

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: BT&Wifi BT & Wifi related issues
Projects
None yet
Development

No branches or pull requests