forked from espressif/esp-idf
feat(bt/bluedroid): Add PBAP client sample code in hfp_hf example
This commit is contained in:
@@ -64,6 +64,18 @@ PCM Signal supports three configurations in menuconfig: PCM Role, PCM Polar and
|
|||||||
- The default configuration is `Stereo Mode`, you can change the PCM Channel mode in `menuconfig` path:
|
- The default configuration is `Stereo Mode`, you can change the PCM Channel mode in `menuconfig` path:
|
||||||
`Component config --> Bluetooth --> Controller Options --> PCM Signal Configurations --> PCM Signal Configurations: Role, Polar and Channel Mode(Stereo/Mono) --> Channel Mode(Stereo/Mono)`
|
`Component config --> Bluetooth --> Controller Options --> PCM Signal Configurations --> PCM Signal Configurations: Role, Polar and Channel Mode(Stereo/Mono) --> Channel Mode(Stereo/Mono)`
|
||||||
|
|
||||||
|
### Special Configurations for PBA Client
|
||||||
|
|
||||||
|
To use PBA Client function, we need to enable PBA Client in `menuconfig` path: `Component config --> Bluetooth --> Bluedroid Options --> Classic Bluetooth --> Classic BT PBA Client`, this example already enable PBA Client by `sdkconfig.defaults`.
|
||||||
|
|
||||||
|
Step to initialize PBA Client connection:
|
||||||
|
|
||||||
|
- Register user callback: `esp_pbac_register_callback(bt_app_pbac_cb)`
|
||||||
|
- Initialize PBA Client API: `esp_pbac_init()`
|
||||||
|
- Connect to peer device ...
|
||||||
|
- Call `esp_pbac_connect(peer_addr, supported_features, 0)`, this will initiate service discover and try to connect to PBA Server.
|
||||||
|
- After the operation done, whether success or not, we will receive a `ESP_PBAC_CONNECTION_STATE_EVT` event in user callback.
|
||||||
|
|
||||||
### Codec Choice
|
### Codec Choice
|
||||||
|
|
||||||
ESP32 supports two types of codec for HFP audio data: `CVSD` and `mSBC`.
|
ESP32 supports two types of codec for HFP audio data: `CVSD` and `mSBC`.
|
||||||
|
@@ -2,6 +2,7 @@ idf_component_register(SRCS "app_hf_msg_set.c"
|
|||||||
"bt_app_core.c"
|
"bt_app_core.c"
|
||||||
"bt_app_hf.c"
|
"bt_app_hf.c"
|
||||||
"gpio_pcm_config.c"
|
"gpio_pcm_config.c"
|
||||||
|
"bt_app_pbac.c"
|
||||||
"main.c"
|
"main.c"
|
||||||
PRIV_REQUIRES bt nvs_flash esp_driver_gpio console esp_ringbuf
|
PRIV_REQUIRES bt nvs_flash esp_driver_gpio console esp_ringbuf
|
||||||
INCLUDE_DIRS ".")
|
INCLUDE_DIRS ".")
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "esp_bt_device.h"
|
#include "esp_bt_device.h"
|
||||||
#include "esp_gap_bt_api.h"
|
#include "esp_gap_bt_api.h"
|
||||||
#include "esp_hf_client_api.h"
|
#include "esp_hf_client_api.h"
|
||||||
|
#include "esp_pbac_api.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
@@ -244,6 +245,9 @@ void bt_app_hf_client_cb(esp_hf_client_cb_event_t event, esp_hf_client_cb_param_
|
|||||||
param->conn_stat.peer_feat,
|
param->conn_stat.peer_feat,
|
||||||
param->conn_stat.chld_feat);
|
param->conn_stat.chld_feat);
|
||||||
memcpy(peer_addr,param->conn_stat.remote_bda,ESP_BD_ADDR_LEN);
|
memcpy(peer_addr,param->conn_stat.remote_bda,ESP_BD_ADDR_LEN);
|
||||||
|
if (param->conn_stat.state == ESP_HF_CLIENT_CONNECTION_STATE_SLC_CONNECTED) {
|
||||||
|
esp_pbac_connect(peer_addr);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_bt.h"
|
||||||
|
#include "esp_pbac_api.h"
|
||||||
|
#include "bt_app_core.h"
|
||||||
|
#include "bt_app_pbac.h"
|
||||||
|
|
||||||
|
#define BT_PBAC_TAG "BT_PBAC"
|
||||||
|
|
||||||
|
esp_pbac_conn_hdl_t pba_conn_handle;
|
||||||
|
|
||||||
|
void bt_app_pbac_cb(esp_pbac_event_t event, esp_pbac_param_t *param)
|
||||||
|
{
|
||||||
|
switch (event)
|
||||||
|
{
|
||||||
|
case ESP_PBAC_CONNECTION_STATE_EVT:
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "PBA client connection event, state: %s, reason: 0x%x", (param->conn_stat.connected ? "Connected" : "Disconnected"), param->conn_stat.reason);
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "Peer supported repositories: 0x%x, supported features: 0x%lx", param->conn_stat.peer_supported_repo, param->conn_stat.peer_supported_feat);
|
||||||
|
if (param->conn_stat.connected) {
|
||||||
|
pba_conn_handle = param->conn_stat.handle;
|
||||||
|
/* set phone book to "telecom" folder, just to test set phone book function */
|
||||||
|
esp_pbac_set_phone_book(pba_conn_handle, ESP_PBAC_SET_PHONE_BOOK_FLAGS_DOWN, "telecom");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ESP_PBAC_PULL_PHONE_BOOK_RESPONSE_EVT:
|
||||||
|
/* if multiple PBA connection, we should check param->pull_phone_book_rsp.handle */
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "PBA client pull phone book response, handle:%d, result: 0x%x", param->pull_phone_book_rsp.handle, param->pull_phone_book_rsp.result);
|
||||||
|
if (param->pull_phone_book_rsp.result == ESP_PBAC_SUCCESS && param->pull_phone_book_rsp.data_len > 0) {
|
||||||
|
printf("%.*s\n", param->pull_phone_book_rsp.data_len, param->pull_phone_book_rsp.data);
|
||||||
|
/* copy data to other buff before return, if phone book size is too large, it will be sent in multiple response event */
|
||||||
|
}
|
||||||
|
if (param->pull_phone_book_rsp.final) {
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "PBA client pull phone book final response");
|
||||||
|
/* pull phone book done, now we can perform other operation */
|
||||||
|
if (param->pull_phone_book_rsp.result == ESP_PBAC_SUCCESS && param->pull_phone_book_rsp.include_phone_book_size) {
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "Phone Book Size:%d", param->pull_phone_book_rsp.phone_book_size);
|
||||||
|
esp_pbac_pull_phone_book_app_param_t app_param = {0};
|
||||||
|
app_param.include_property_selector = 1;
|
||||||
|
/* property bit mask, filter out photo, refer to Phone Book Access Profile */
|
||||||
|
app_param.property_selector = 0xFFFFFFF7;
|
||||||
|
/* pull again, without 'max_list_count = 0', then we can get the entire phone book */
|
||||||
|
esp_pbac_pull_phone_book(pba_conn_handle, "telecom/pb.vcf", &app_param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ESP_PBAC_SET_PHONE_BOOK_RESPONSE_EVT:
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "PBA client set phone book response, handle:%d, result: 0x%x", param->set_phone_book_rsp.handle, param->set_phone_book_rsp.result);
|
||||||
|
/* done, set phone book response will always be a final response */
|
||||||
|
if (param->set_phone_book_rsp.result == ESP_PBAC_SUCCESS) {
|
||||||
|
esp_pbac_pull_phone_book_app_param_t app_param = {0};
|
||||||
|
app_param.include_max_list_count = 1;
|
||||||
|
/* set max_list_count to zero, then we can get phone book size in peer response */
|
||||||
|
app_param.max_list_count = 0;
|
||||||
|
/* pull phone book use a absolute path; if no app param, we can pass a NULL to API */
|
||||||
|
esp_pbac_pull_phone_book(pba_conn_handle, "telecom/pb.vcf", &app_param);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ESP_PBAC_PULL_VCARD_LISTING_RESPONSE_EVT:
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "PBA client pull vCard listing response, handle:%d, result: 0x%x", param->pull_vcard_listing_rsp.handle, param->pull_vcard_listing_rsp.result);
|
||||||
|
if (param->pull_vcard_listing_rsp.result == ESP_PBAC_SUCCESS) {
|
||||||
|
printf("%.*s\n", param->pull_vcard_listing_rsp.data_len, param->pull_vcard_listing_rsp.data);
|
||||||
|
}
|
||||||
|
if (param->pull_vcard_listing_rsp.final) {
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "PBA client pull vCard listing final response");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ESP_PBAC_PULL_VCARD_ENTRY_RESPONSE_EVT:
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "PBA client pull vCard entry response, handle:%d, result: 0x%x", param->pull_vcard_entry_rsp.handle, param->pull_vcard_entry_rsp.result);
|
||||||
|
if (param->pull_vcard_entry_rsp.result == ESP_PBAC_SUCCESS) {
|
||||||
|
printf("%.*s\n", param->pull_vcard_entry_rsp.data_len, param->pull_vcard_entry_rsp.data);
|
||||||
|
}
|
||||||
|
if (param->pull_vcard_entry_rsp.final) {
|
||||||
|
ESP_LOGI(BT_PBAC_TAG, "PBA client pull vCard entry final response");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_bt.h"
|
||||||
|
#include "esp_pbac_api.h"
|
||||||
|
|
||||||
|
void bt_app_pbac_cb(esp_pbac_event_t event, esp_pbac_param_t *param);
|
@@ -21,10 +21,12 @@
|
|||||||
#include "esp_bt_device.h"
|
#include "esp_bt_device.h"
|
||||||
#include "esp_gap_bt_api.h"
|
#include "esp_gap_bt_api.h"
|
||||||
#include "esp_hf_client_api.h"
|
#include "esp_hf_client_api.h"
|
||||||
|
#include "esp_pbac_api.h"
|
||||||
#include "bt_app_hf.h"
|
#include "bt_app_hf.h"
|
||||||
#include "gpio_pcm_config.h"
|
#include "gpio_pcm_config.h"
|
||||||
#include "esp_console.h"
|
#include "esp_console.h"
|
||||||
#include "app_hf_msg_set.h"
|
#include "app_hf_msg_set.h"
|
||||||
|
#include "bt_app_pbac.h"
|
||||||
|
|
||||||
esp_bd_addr_t peer_addr = {0};
|
esp_bd_addr_t peer_addr = {0};
|
||||||
static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
|
static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
|
||||||
@@ -251,6 +253,8 @@ static void bt_hf_client_hdl_stack_evt(uint16_t event, void *p_param)
|
|||||||
esp_bt_gap_register_callback(esp_bt_gap_cb);
|
esp_bt_gap_register_callback(esp_bt_gap_cb);
|
||||||
esp_hf_client_register_callback(bt_app_hf_client_cb);
|
esp_hf_client_register_callback(bt_app_hf_client_cb);
|
||||||
esp_hf_client_init();
|
esp_hf_client_init();
|
||||||
|
esp_pbac_register_callback(bt_app_pbac_cb);
|
||||||
|
esp_pbac_init();
|
||||||
|
|
||||||
#if (CONFIG_EXAMPLE_SSP_ENABLED == true)
|
#if (CONFIG_EXAMPLE_SSP_ENABLED == true)
|
||||||
/* Set default parameters for Secure Simple Pairing */
|
/* Set default parameters for Secure Simple Pairing */
|
||||||
|
@@ -8,3 +8,4 @@ CONFIG_BT_BLUEDROID_ENABLED=y
|
|||||||
CONFIG_BT_CLASSIC_ENABLED=y
|
CONFIG_BT_CLASSIC_ENABLED=y
|
||||||
CONFIG_BT_HFP_ENABLE=y
|
CONFIG_BT_HFP_ENABLE=y
|
||||||
CONFIG_BT_HFP_CLIENT_ENABLE=y
|
CONFIG_BT_HFP_CLIENT_ENABLE=y
|
||||||
|
CONFIG_BT_PBAC_ENABLED=y
|
||||||
|
Reference in New Issue
Block a user