| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-S3 | ESP32-S31 |
|---|
BLE Peripheral Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example creates GATT server and then starts advertising, waiting to be connected to a GATT client.
It uses ESP32's Bluetooth controller and NimBLE stack based BLE host.
This example aims at understanding GATT database configuration, handling GATT reads and writes, handling subscribe events, understanding advertisement and SMP related NimBLE APIs.
It also demonstrates security features of NimBLE stack. SMP parameters like I/O capabilities of device, Bonding flag, MITM protection flag and Secure Connection only mode, Enabling Link Encryption etc., can be configured through menuconfig options.
For RPA feature (currently Host based privacy feature is supported), use API ble_hs_pvcy_rpa_config to enable/disable host based privacy, own_addr_type needs to be set to BLE_ADDR_RANDOM to use this feature. Please include ble_hs_pvcy.h while using this API. As ble_hs_pvcy_rpa_config configures host privacy and sets address in controller, it is necessary to call this API after host-controller are synced (e.g. in bleprph_on_sync callback).
To test this demo, any BLE scanner app can be used.
Note :
- To install the dependency packages needed, please refer to the top level README file.
How to Use Example
Before project configuration and build, be sure to set the correct chip target using:
idf.py set-target <chip_name>
Configure the project
Open the project configuration menu:
idf.py menuconfig
In the Example Configuration menu:
- Select I/O capabilities of device from
Example Configuration --> I/O Capability, default isJust_works. - Enable/Disable other security related parameters
Bonding, MITM option, secure connection(SM SC). - Optional: enable static passkey support via
Component config -> Bluetooth -> NimBLE -> Enable support for Static Passkey.
Static passkey mode is useful for demos where you want to avoid interactive passkey entry.
When enabled, the example calls ble_sm_configure_static_passkey(456789, true) and NimBLE
automatically injects the passkey during pairing. Update the passkey in
examples/bluetooth/nimble/bleprph/main/main.c if you want a different value.
Both devices must use the same 6-digit passkey, and you should only use a fixed
passkey for development or controlled environments.
Build and Flash
Run idf.py -p PORT flash monitor to build, flash and monitor the project.
(To exit the serial monitor, type Ctrl-].)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
Example Output
There is this console output when bleprph starts advertising, connects, and a peer subscribes / writes / reads a characteristic:
I (...) NimBLE_BLE_PRPH: BLE Host Task Started
I (...) NimBLE: Device Address:
I (...) NimBLE: xx:xx:xx:xx:xx:xx
I (...) NimBLE:
I (...) NimBLE: GAP procedure initiated: advertise;
I (...) NimBLE: disc_mode=2
I (...) NimBLE: adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
I (...) NimBLE:
I (...) NimBLE: connection established; status=0
I (...) NimBLE: handle=0 ... conn_itvl=40 conn_latency=0 supervision_timeout=256 encrypted=0 authenticated=0 bonded=0
I (...) NimBLE:
I (...) NimBLE: subscribe event; conn_handle=0 attr_handle=<notify_attr> reason=1 prevn=0 curn=1 previ=0 curi=0
I (...) NimBLE: subscribe event; conn_handle=0 attr_handle=<rw_attr> reason=1 prevn=0 curn=1 previ=0 curi=0
I (...) NimBLE: Characteristic write; conn_handle=0 attr_handle=<rw_attr>
I (...) NimBLE: Notification/Indication scheduled for all subscribed peers.
I (...) NimBLE: GATT procedure initiated: notify;
I (...) NimBLE: att_handle=<rw_attr>
I (...) NimBLE: Characteristic read by NimBLE stack; attr_handle=<rw_attr>
I (...) NimBLE: notify_tx event; conn_handle=0 attr_handle=<rw_attr> status=0 is_indication=0
I (...) NimBLE: Characteristic read; conn_handle=0 attr_handle=<rw_attr>
If pairing / passkey options are enabled in menuconfig, additional security-related logs
(PASSKEY_ACTION_EVENT, encryption updates, and bonding/authentication fields) are also expected.
Note
- NVS support is not yet integrated to bonding. So, for now, bonding is not persistent across reboot.
The following configuration flags can be adjusted to significantly reduce RAM usage in your ESP-IDF project while retaining basic BLE functionality.
| Config Option | Old → New Value | RAM Saved (Bytes) |
|---|---|---|
| CONFIG_BT_NIMBLE_SM_SC | y → n | 2016 |
| CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION | y → n | 32 |
| CONFIG_BT_NIMBLE_GATT_MAX_PROCS | 4 → 2 | 112 |
| CONFIG_BT_NIMBLE_MAX_CONNECTIONS | 3 → 1 | 480 |
| CONFIG_BT_NIMBLE_MAX_BONDS | 3 → 1 | 448 |
| CONFIG_BT_NIMBLE_MAX_CCCDS | 8 → 1 | 112 |
| CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT | y → n | 256 |
| CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT | 30 → 15 | 240 |
| CONFIG_BT_NIMBLE_SECURITY_ENABLE | y → n | 2048 |
| CONFIG_SPI_FLASH_ROM_IMPL | n → y | 9804 |
| CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP | y → n | 8 |
| CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP | y → n | 132 |
| CONFIG_SPI_FLASH_SUPPORT_GD_CHIP | y → n | 640 |
| CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP | y → n | 0 |
| CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP | y → n | 132 |
| CONFIG_SPI_FLASH_SUPPORT_TH_CHIP | y → n | 128 |
| CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE | y → n | 696 |
| CONFIG_VFS_SUPPORT_TERMIOS | y → n | 424 |
| CONFIG_VFS_SUPPORT_IO | y → n | 3000 |
| CONFIG_COMPILER_OPTIMIZATION_SIZE | n → y | 8912 |
| CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE | n → y | 8456 |
| CONFIG_ESP_COEX_SW_COEXIST_ENABLE | y → n | 896 |
| CONFIG_LOG_DEFAULT_LEVEL_NONE | n → y | 2568 |
Troubleshooting
For any technical queries, please open an issue on GitHub. We will get back to you soon.