If you try to connect your smartphone to the ESP32 using Bluetooth,
you will see the following additional information in the log.
W (340623) BT_HCI: hcif conn complete: hdl 0x80, st 0x0
W (340703) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 8000
W (340903) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 32000
W (341003) BT_L2CAP: L2CAP - rcvd conn req for unknown PSM: 23
W (341013) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 8000
W (341383) BT_APPL: new conn_srvc id:19, app_id:0
W (341393) BT_BTC: AVRC not Init, not using it.
W (344593) BT_HCI: hci cmd send: sniff: hdl 0x80, intv(400 800)
W (344613) BT_HCI: hcif mode change: hdl 0x80, mode 2, intv 800, status 0x0
I (344613) BT APP: gap_handler event: 13
W (344673) BT_HCI: hci cmd send: unsniff: hdl 0x80
W (345183) BT_HCI: hcif mode change: hdl 0x80, mode 0, intv 0, status 0x0
I (345193) BT APP: gap_handler event: 13
W (348383) BT_HCI: hci cmd send: sniff: hdl 0x80, intv(400 800)
W (348403) BT_HCI: hcif mode change: hdl 0x80, mode 2, intv 800, status 0x0
I (348413) BT APP: gap_handler event: 13
W (91153) BT_HCI: hcif conn complete: hdl 0x80, st 0x0
W (91243) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 8000
W (91433) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 32000
W (91533) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 8000
W (91543) BT_L2CAP: L2CAP - rcvd conn req for unknown PSM: 23
I (91543) BT APP: a2d_handler event: 0
I (91623) BT APP: a2d_handler event: 2
I (91623) BT APP: a2d_handler event: 5
W (91793) BT_APPL: new conn_srvc id:19, app_id:0
I (91803) BT APP: a2d_handler event: 0
W (91803) BT_BTC: AVRC not Init, not using it.
W (95003) BT_HCI: hci cmd send: sniff: hdl 0x80, intv(400 800)
W (95013) BT_HCI: hcif mode change: hdl 0x80, mode 2, intv 800, status 0x0
I (95013) BT APP: gap_handler event: 13
W (95123) BT_HCI: hci cmd send: unsniff: hdl 0x80
W (95173) BT_HCI: hcif mode change: hdl 0x80, mode 0, intv 0, status 0x0
I (95173) BT APP: gap_handler event: 13
W (98373) BT_HCI: hci cmd send: sniff: hdl 0x80, intv(400 800)
W (98393) BT_HCI: hcif mode change: hdl 0x80, mode 2, intv 800, status 0x0
I (98403) BT APP: gap_handler event: 13
First, your phone is now able to connect to the ESP32 over
Bluetooth. Second, there are some more events, specifically four
events sent to the a2d_handler()
and three events sent to the
gap_handler()
.
Look at the gap_handler()
event number 13 first. That is the
ESP_BT_GAP_MODE_CHG_EVT
event. Since you are being sent these
events, implement some very rudimentary code to “handle” them. For
now, all the handler does is to print something a little more
descriptive to the log, rather than actually doing anything with the
event.
static void gap_handler(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *params)
{
switch (event) {
case ESP_BT_GAP_CONFIG_EIR_DATA_EVT:
ESP_LOGI(tag, "gap_handler event: ESP_BT_GAP_CONFIG_EIR_DATA_EVT");
break;
case ESP_BT_GAP_MODE_CHG_EVT:
ESP_LOGI(tag, "gap_handler event: ESP_BT_GAP_MODE_CHG_EVT");
break;
default:
ESP_LOGI(tag, "gap_handler event: %d", event);
break;
}
}
Run the code again and connect to the ESP32 using Bluetooth to see the
following log messages:
I (1153) BT APP: Successfully enabled Bluetooth Controller
I (1163) BT APP: Successfully initialized Bluedroid stack
I (1223) BT APP: Successfully enabled Bluedroid stack
I (1233) BT APP: Successfully set the discoverability and connectability mode
I (1243) BT APP: Successfully registered callback function
W (1243) BT_BTC: A2DP Enable without AVRC
I (1253) BT APP: gap_handler event: ESP_BT_GAP_CONFIG_EIR_DATA_EVT
I (1293) BT APP: Successfully initialized A2DP sink
I (1293) BT APP: Successfully registered A2D handler function
W (91153) BT_HCI: hcif conn complete: hdl 0x80, st 0x0
W (91243) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 8000
W (91433) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 32000
W (91533) BT_HCI: hcif link supv_to changed: hdl 0x80, supv_to 8000
W (91543) BT_L2CAP: L2CAP - rcvd conn req for unknown PSM: 23
I (91543) BT APP: a2d_handler event: 0
I (91623) BT APP: a2d_handler event: 2
I (91623) BT APP: a2d_handler event: 5
W (91793) BT_APPL: new conn_srvc id:19, app_id:0
I (91803) BT APP: a2d_handler event: 0
W (91803) BT_BTC: AVRC not Init, not using it.
W (95003) BT_HCI: hci cmd send: sniff: hdl 0x80, intv(400 800)
W (95013) BT_HCI: hcif mode change: hdl 0x80, mode 2, intv 800, status 0x0
I (95013) BT APP: gap_handler event: ESP_BT_GAP_MODE_CHG_EVT
W (95123) BT_HCI: hci cmd send: unsniff: hdl 0x80
W (95173) BT_HCI: hcif mode change: hdl 0x80, mode 0, intv 0, status 0x0
I (95173) BT APP: gap_handler event: ESP_BT_GAP_MODE_CHG_EVT
W (98373) BT_HCI: hci cmd send: sniff: hdl 0x80, intv(400 800)
W (98393) BT_HCI: hcif mode change: hdl 0x80, mode 2, intv 800, status 0x0
I (98403) BT APP: gap_handler event: ESP_BT_GAP_MODE_CHG_EVT
That seems a bit more descriptive than event 10 and event 13. However,
you still really don’t know the details of the events. Fortunately,
the handler function also receives a pointer to a set of parameters of
type esp_bt_gap_cb_param_t
. In the documentation you can see that
each event has an associated parameter structure. For the first event
in the log, ESP_BT_GAP_CONFIG_EIR_DATA_EVT
, there is a parameter
struct called config_eir_data_param
. Within this struct, there are
three public members: stat
, eir_type_num
, and eir_type
. Update
the handler function to print the values of these parameters to the
monitor log.
/* Static function definitions */
static void gap_handler(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *params)
{
switch (event) {
case ESP_BT_GAP_CONFIG_EIR_DATA_EVT:
ESP_LOGI(tag, "gap_handler event: ESP_BT_GAP_CONFIG_EIR_DATA_EVT");
ESP_LOGI(tag, "params->config_eir_data.stat: %d", params->config_eir_data.stat);
uint8_t eir_type_num = params->config_eir_data.eir_type_num;
ESP_LOGI(tag, "params->config_eir_data.eir_type_num: %d", eir_type_num);
for (uint8_t i = 0; i < eir_type_num; i++) {
ESP_LOGI(tag, "params->config_eir_data.eir_type[%d]: %d", i, params->config_eir_data.eir_type[i]);
}
break;
case ESP_BT_GAP_MODE_CHG_EVT:
ESP_LOGI(tag, "gap_handler event: ESP_BT_GAP_MODE_CHG_EVT");
break;
default:
ESP_LOGI(tag, "gap_handler event: %d", event);
break;
}
}
In an nutshell, you first print out the stat
integer, then you loop
through the array of eir_type
and print each of its values as
well. Since there may be a variable number of eir_type
items in the
array, you loop over the array eir_type_num
times. When you run this
code on the ESP32 board, you’ll see the following information in the log.
I (1253) BT APP: gap_handler event: ESP_BT_GAP_CONFIG_EIR_DATA_EVT
I (1253) BT APP: params->config_eir_data.stat: 0
I (1263) BT APP: params->config_eir_data.eir_type_num: 4
I (1263) BT APP: params->config_eir_data.eir_type[0]: 9
I (1273) BT APP: params->config_eir_data.eir_type[1]: 3
I (1283) BT APP: params->config_eir_data.eir_type[2]: 5
I (1283) BT APP: params->config_eir_data.eir_type[3]: 7
I (1293) BT APP: Successfully initialized A2DP sink
I (1293) BT APP: Successfully registered A2D handler function
Interesting! First of all, the stat
integer seems to be 0. By
looking that up in the documentation, you see that this refers to the
first item in the enum esp_bt_status_t
, which is
ESP_BT_STATUS_SUCCESS
. That sounds promising. You can also see in
the documentation that they call out two status enums that seem
important, ESP_BT_STATUS_SUCCESS
, or enum 0, which you’ve already
seen, and ESP_BT_STATUS_EIR_TOO_LARGE
, which is the last enum at
number 20. Update the code to include these two cases for easier
readability of the log messages
/* Static function definitions */
static void gap_handler(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *params)
{
switch (event) {
case ESP_BT_GAP_CONFIG_EIR_DATA_EVT:
ESP_LOGI(tag, "gap_handler event: ESP_BT_GAP_CONFIG_EIR_DATA_EVT");
esp_bt_status_t stat = params->config_eir_data.stat;
if (stat == ESP_BT_STATUS_SUCCESS) {
ESP_LOGI(tag, "params->config_eir_data.stat: ESP_BT_STATUS_SUCCESS");
} else if (stat == ESP_BT_STATUS_EIR_TOO_LARGE) {
ESP_LOGI(tag, "params->config_eir_data.stat: ESP_BT_STATUS_EIR_TOO_LARGE");
} else {
ESP_LOGI(tag, "params->config_eir_data.stat: %d", stat);
}
uint8_t eir_type_num = params->config_eir_data.eir_type_num;
ESP_LOGI(tag, "params->config_eir_data.eir_type_num: %d", eir_type_num);
for (uint8_t i = 0; i < eir_type_num; i++) {
ESP_LOGI(tag, "params->config_eir_data.eir_type[%d]: %d", i, params->config_eir_data.eir_type[i]);
}
break;
case ESP_BT_GAP_MODE_CHG_EVT:
ESP_LOGI(tag, "gap_handler event: ESP_BT_GAP_MODE_CHG_EVT");
break;
default:
ESP_LOGI(tag, "gap_handler event: %d", event);
break;
}
}
This doesn’t change anything in the running of the code, but simply
makes the log messages a bit more informative. When you run that again
on the ESP32 you’ll see the following output:
I (1293) BT APP: gap_handler event: ESP_BT_GAP_CONFIG_EIR_DATA_EVT
I (1293) BT APP: params->config_eir_data.stat: ESP_BT_STATUS_SUCCESS
I (1303) BT APP: params->config_eir_data.eir_type_num: 4
I (1313) BT APP: params->config_eir_data.eir_type[0]: 9
I (1313) BT APP: params->config_eir_data.eir_type[1]: 3
I (1323) BT APP: params->config_eir_data.eir_type[2]: 5
I (1323) BT APP: params->config_eir_data.eir_type[3]: 7
I (1333) BT APP: Successfully initialized A2DP sink
I (1253) BT APP: gap_handler event: ESP_BT_GAP_CONFIG_EIR_DATA_EVT
I (1253) BT APP: params->config_eir_data.stat: ESP_BT_STATUS_SUCCESS
I (1263) BT APP: params->config_eir_data.eir_type_num: 4
I (1263) BT APP: params->config_eir_data.eir_type[0]: 9
I (1273) BT APP: params->config_eir_data.eir_type[1]: 3
I (1283) BT APP: params->config_eir_data.eir_type[2]: 5
I (1283) BT APP: params->config_eir_data.eir_type[3]: 7
I (1293) BT APP: Successfully initialized A2DP sink
I (1293) BT APP: Successfully registered A2D handler function