This example is extended from NimBLE Beacon Example, and further introduces
1. How to advertise as a connectable peripheral device
2. How to capture GAP events and handle them
3. How to update connection parameters
It uses ESP32's Bluetooth controller and NimBLE host stack.
To test this demo, any BLE scanner application can be used.
## Try It Yourself
### Set Target
Before project configuration and build, be sure to set the correct chip target using:
``` shell
idf.py set-target <chip_name>
```
For example, if you're using ESP32, then input
``` Shell
idf.py set-target esp32
```
### Build and Flash
Run the following command to build, flash and monitor the project.
``` Shell
idf.py -p <PORT> flash monitor
```
For example, if the corresponding serial port is `/dev/ttyACM0`, then it goes
``` Shell
idf.py -p /dev/ttyACM0 flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects.
## Code Explained
### Overview
1. Initialize LED, NVS flash, NimBLE host stack and GAP service; configure NimBLE host stack and start NimBLE host task thread; wait for NimBLE host stack to sync with BLE controller
2. Set advertisement and scan response data, then configure advertising parameters and start advertising
3. On connect event
1. Turn on the LED on the dev board
2. Print out connection descriptions
3. Update connection parameters
4. On connection update event
1. Print out connection descriptions
5. On disconnect event
1. Turn off the LED on the dev board
2. Print out connection descriptions
### Entry Point & On Stack Sync
Please refer to the NimBLE Beacon Example for details.
### Start Advertising
There're some slight differences in this example when compared to NimBLE Beacon Example. First, in this example we are constructing a connectable peripheral, so connection mode is set to connectable, that is
``` C
static void start_advertising(void) {
...
/* Set non-connetable and general discoverable mode to be a beacon */
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
...
}
```
Also, to demonstrate advertising parameters settings, advertising interval parameters are modified to 500ms, and shown in scan response. Please note that the unit of advertising interval is 0.625ms.
And finally, when calling the advertising start API, a callback function `gap_event_handler` is passed as argument to receive GAP events. We'll talk about it in the next section.
When the device is connected to a peer device or a connection failed, a connect event will be passed to `gap_event_handler` by NimBLE host stack. We'll first check the connection status
- If succeeded
- Get connection descriptor by connection handle and print out
- Turn on the LED
- Try to update connection parameters
- If failed
- Re-start advertising
``` C
/* Connect event */
static int gap_event_handler(struct ble_gap_event *event, void *arg) {
/* Local variables */
int rc = 0;
struct ble_gap_conn_desc desc;
/* Handle different GAP event */
switch (event->type) {
/* Connect event */
case BLE_GAP_EVENT_CONNECT:
/* A new connection was established or a connection attempt failed. */
ESP_LOGE(TAG, "failed to find connection by handle, error code: %d",
rc);
return rc;
}
print_conn_desc(&desc);
return rc;
...
}
```
## Observation
If everything goes well, except for what we have seen in NimBLE Beacon example, you should be able to see LED turned on when device is connected, and see LED turned off on disconnection.
## Troubleshooting
For any technical queries, please file an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.