mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(bluedroid): Update LC3-SWB support in bluedroid
- Update LC3 in btc and bta, update AT - Update LC3 in SCO frame transfer and examples - improve lc3 transfer speed - Fix some encoding and decoding bugs - Rename the functions and macros to fit both msbc and lc3 - Add config dependency - Add migration guides for bluetooth-classic - change the statement of "Wide Band Speech" to "Wideband Speech" to fit HFPv1.10
This commit is contained in:
@@ -238,13 +238,21 @@ config BT_HFP_USE_EXTERNAL_CODEC
|
||||
for new design.
|
||||
|
||||
config BT_HFP_WBS_ENABLE
|
||||
bool "Wide Band Speech"
|
||||
bool "Wideband Speech"
|
||||
depends on BT_HFP_ENABLE && BT_HFP_AUDIO_DATA_PATH_HCI
|
||||
default y
|
||||
help
|
||||
This enables Wide Band Speech. Should disable it when SCO data path is PCM.
|
||||
This enables Wideband Speech. Should disable it when SCO data path is PCM.
|
||||
Otherwise there will be no data transmitted via GPIOs.
|
||||
|
||||
config BT_HFP_LC3_ENABLE
|
||||
bool "Super Wideband Speech (LC3-SWB)"
|
||||
depends on BT_HFP_ENABLE && BT_HFP_WBS_ENABLE && BT_HFP_USE_EXTERNAL_CODEC
|
||||
default n
|
||||
help
|
||||
Enable HFP 1.9 LC3-SWB codec negotiation support.
|
||||
Requires Wideband Speech (codec negotiation) to be enabled.
|
||||
|
||||
menuconfig BT_HID_ENABLED
|
||||
bool "Classic BT HID"
|
||||
depends on BT_CLASSIC_ENABLED
|
||||
|
||||
@@ -160,6 +160,32 @@ esp_err_t esp_hf_ag_audio_disconnect(esp_bd_addr_t remote_addr)
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_hf_ag_set_codec(esp_bd_addr_t remote_bda, esp_hf_codec_mode_t mode)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (remote_bda == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (mode > ESP_HF_CODEC_LC3) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_SET_CODEC_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
memcpy(&arg.set_codec.remote_addr, remote_bda, sizeof(esp_bd_addr_t));
|
||||
arg.set_codec.mode = mode;
|
||||
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL);
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_hf_ag_vra_control(esp_bd_addr_t remote_addr, esp_hf_vr_state_t value)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -61,10 +61,11 @@ typedef enum
|
||||
ESP_HF_ATA_RESPONSE_EVT, /*!< Answer an Incoming Call */
|
||||
ESP_HF_CHUP_RESPONSE_EVT, /*!< Reject an Incoming Call */
|
||||
ESP_HF_DIAL_EVT, /*!< Originate an outgoing call with specific number or dial the last number */
|
||||
ESP_HF_WBS_RESPONSE_EVT, /*!< Codec Status */
|
||||
ESP_HF_WBS_RESPONSE_EVT, /*!< Result of esp_hf_ag_set_codec() */
|
||||
ESP_HF_BCS_RESPONSE_EVT, /*!< Final Codec Choice */
|
||||
ESP_HF_PKT_STAT_NUMS_GET_EVT, /*!< Request number of packet different status */
|
||||
ESP_HF_PROF_STATE_EVT, /*!< Indicate HF init or deinit complete */
|
||||
ESP_HF_BAC_RESPONSE_EVT, /*!< Peer codec capabilities from AT+BAC */
|
||||
} esp_hf_cb_event_t;
|
||||
|
||||
/// Dial type of ESP_HF_DIAL_EVT
|
||||
@@ -210,15 +211,24 @@ typedef union
|
||||
*/
|
||||
struct hf_wbs_rep_param {
|
||||
esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */
|
||||
esp_hf_wbs_config_t codec; /*!< codec mode CVSD or mSBC */
|
||||
esp_hf_codec_mode_t codec; /*!< Requested codec CVSD, mSBC or LC3 */
|
||||
esp_bt_status_t status; /*!< ESP_BT_STATUS_SUCCESS or FAIL */
|
||||
} wbs_rep; /*!< AG callback param of ESP_HF_WBS_RESPONSE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_BAC_RESPONSE_EVT
|
||||
*/
|
||||
struct hf_bac_rep_param {
|
||||
esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */
|
||||
uint16_t peer_codecs; /*!< Bitmap: ESP_HF_CODEC_CAP_CVSD | MSBC | LC3 */
|
||||
} bac_rep; /*!< AG callback param of ESP_HF_BAC_RESPONSE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_HF_BCS_RESPONSE_EVT
|
||||
*/
|
||||
struct hf_bcs_rep_param {
|
||||
esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */
|
||||
esp_hf_wbs_config_t mode; /*!< codec mode CVSD or mSBC */
|
||||
esp_hf_codec_mode_t mode; /*!< Final negotiated codec mode CVSD, mSBC or LC3 */
|
||||
} bcs_rep; /*!< AG callback param of ESP_HF_BCS_RESPONSE_EVT */
|
||||
|
||||
/**
|
||||
@@ -371,6 +381,26 @@ esp_err_t esp_hf_ag_audio_connect(esp_bd_addr_t remote_bda);
|
||||
*/
|
||||
esp_err_t esp_hf_ag_audio_disconnect(esp_bd_addr_t remote_bda);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Set preferred codec for subsequent SCO connections with a remote HF.
|
||||
* Should be called after receiving ESP_HF_BAC_RESPONSE_EVT to know peer capabilities.
|
||||
* Result is reported via ESP_HF_WBS_RESPONSE_EVT.
|
||||
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
|
||||
*
|
||||
* @param[in] remote_bda: remote bluetooth HFP client device address
|
||||
* @param[in] mode: ESP_HF_CODEC_CVSD, ESP_HF_CODEC_MSBC, ESP_HF_CODEC_LC3,
|
||||
* or ESP_HF_CODEC_NONE to reset to stack default
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: request sent to lower layer
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled or SLC not connected
|
||||
* - ESP_ERR_INVALID_ARG: invalid codec mode or address
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_hf_ag_set_codec(esp_bd_addr_t remote_bda, esp_hf_codec_mode_t mode);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Response of Volume Recognition Command(AT+VRA) from HFP client.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -35,6 +35,7 @@ typedef enum {
|
||||
ESP_HF_CLIENT_AUDIO_STATE_CONNECTING, /*!< audio connection has been initiated */
|
||||
ESP_HF_CLIENT_AUDIO_STATE_CONNECTED, /*!< audio connection is established */
|
||||
ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, /*!< mSBC audio connection is established */
|
||||
ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_LC3, /*!< LC3-SWB audio connection is established */
|
||||
} esp_hf_client_audio_state_t;
|
||||
|
||||
/// in-band ring tone state
|
||||
@@ -67,6 +68,9 @@ typedef struct {
|
||||
#define ESP_HF_CLIENT_PEER_FEAT_HF_IND 0x400 /*!< HF Indicators */
|
||||
#define ESP_HF_CLIENT_PEER_FEAT_ESCO_S4 0x800 /*!< eSCO S4 Setting Supported */
|
||||
|
||||
/* HFP 1.9 - local HF feature, maps to SDP SupportedFeatures bit 8 */
|
||||
#define ESP_HF_CLIENT_FEAT_SWB 0x00010000 /*!< Super Wideband Speech */
|
||||
|
||||
/* CHLD feature masks of AG */
|
||||
#define ESP_HF_CLIENT_CHLD_FEAT_REL 0x01 /*!< 0 Release waiting call or held calls */
|
||||
#define ESP_HF_CLIENT_CHLD_FEAT_REL_ACC 0x02 /*!< 1 Release active calls and accept other waiting or held call */
|
||||
|
||||
@@ -47,8 +47,9 @@ typedef enum {
|
||||
typedef enum {
|
||||
ESP_HF_AUDIO_STATE_DISCONNECTED = 0, /*!< audio connection released */
|
||||
ESP_HF_AUDIO_STATE_CONNECTING, /*!< audio connection has been initiated */
|
||||
ESP_HF_AUDIO_STATE_CONNECTED, /*!< audio connection is established */
|
||||
ESP_HF_AUDIO_STATE_CONNECTED, /*!< CVSD audio connection is established */
|
||||
ESP_HF_AUDIO_STATE_CONNECTED_MSBC, /*!< mSBC audio connection is established */
|
||||
ESP_HF_AUDIO_STATE_CONNECTED_LC3, /*!< LC3-SWB audio connection is established */
|
||||
} esp_hf_audio_state_t;
|
||||
|
||||
/// Bluetooth HFP audio volume type
|
||||
@@ -179,13 +180,32 @@ typedef enum {
|
||||
ESP_HF_CALL_WAITING_ACTIVE, /*!< active call waiting */
|
||||
} esp_hf_call_waiting_status_t;
|
||||
|
||||
/* WBS codec setting */
|
||||
/* codec setting - values match HFP Codec ID in AT+BAC/+BCS (Appendix B) */
|
||||
typedef enum
|
||||
{
|
||||
ESP_HF_WBS_NONE, /*!< No Wideband Speech (WBS) codec support */
|
||||
ESP_HF_WBS_NO, /*!< Wideband Speech (WBS) codec is not enabled */
|
||||
ESP_HF_WBS_YES /*!< Wideband Speech (WBS) codec is enabled */
|
||||
}esp_hf_wbs_config_t;
|
||||
ESP_HF_CODEC_NONE = 0, /*!< No codec negotiated */
|
||||
ESP_HF_CODEC_CVSD = 1, /*!< Narrowband Speech (CVSD) */
|
||||
ESP_HF_CODEC_MSBC = 2, /*!< Wideband Speech (mSBC) */
|
||||
ESP_HF_CODEC_LC3 = 3 /*!< Super Wideband Speech (LC3-SWB) */
|
||||
} esp_hf_codec_mode_t;
|
||||
|
||||
/*!< @deprecated Renamed to ESP_HF_CODEC_NONE */
|
||||
#define ESP_HF_WBS_NONE (ESP_HF_CODEC_NONE) /*!< No Wideband Speech (WBS) codec support */
|
||||
|
||||
/*!< @deprecated Renamed to ESP_HF_CODEC_CVSD */
|
||||
#define ESP_HF_WBS_NO (ESP_HF_CODEC_CVSD) /*!< Wideband Speech (WBS) codec is not enabled */
|
||||
|
||||
/*!< @deprecated Renamed to ESP_HF_CODEC_MSBC */
|
||||
#define ESP_HF_WBS_YES (ESP_HF_CODEC_MSBC) /*!< Wideband Speech (WBS) codec is enabled */
|
||||
|
||||
/*!< @deprecated esp_hf_wbs_config_t is changed to esp_hf_codec_mode_t */
|
||||
typedef esp_hf_codec_mode_t esp_hf_wbs_config_t;
|
||||
|
||||
|
||||
/** @brief Codec capability bitmap for AT+BAC, matches BTA_AG_CODEC_* flags */
|
||||
#define ESP_HF_CODEC_CAP_CVSD (1u << (ESP_HF_CODEC_CVSD - 1)) /*!< 0x01 */
|
||||
#define ESP_HF_CODEC_CAP_MSBC (1u << (ESP_HF_CODEC_MSBC - 1)) /*!< 0x02 */
|
||||
#define ESP_HF_CODEC_CAP_LC3 (1u << (ESP_HF_CODEC_LC3 - 1)) /*!< 0x04 */
|
||||
|
||||
/// Bluetooth HFP RFCOMM connection and service level connection status
|
||||
typedef enum {
|
||||
@@ -261,6 +281,17 @@ typedef enum {
|
||||
#define ESP_HF_MSBC_BITPOOL 26 /*!< mSBC bitpool */
|
||||
/* frame size after mSBC encoded */
|
||||
#define ESP_HF_MSBC_ENCODED_FRAME_SIZE 57 /*!< mSBC frame size */
|
||||
#define ESP_HF_MSBC_SAMPLING_RATE_HZ 16000 /*!< mSBC PCM sampling rate */
|
||||
#define ESP_HF_MSBC_H2_HEADER_LEN 2 /*!< H2 sync header length */
|
||||
#define ESP_HF_MSBC_ENCODED_FRAME_SIZE_WITH_H2 (ESP_HF_MSBC_ENCODED_FRAME_SIZE + ESP_HF_MSBC_H2_HEADER_LEN)
|
||||
|
||||
/* Since HFP uses a fixed set of LC3-SWB codec parameters (HFP 1.9 Table 6.15) */
|
||||
#define ESP_HF_LC3_SAMPLING_RATE_HZ 32000 /*!< LC3-SWB PCM sampling rate */
|
||||
#define ESP_HF_LC3_FRAME_DURATION_US 7500 /*!< LC3-SWB frame duration */
|
||||
#define ESP_HF_LC3_ENCODED_FRAME_SIZE 58 /*!< LC3 payload size (excl. H2 header) */
|
||||
#define ESP_HF_LC3_H2_HEADER_LEN 2 /*!< H2 sync header length */
|
||||
#define ESP_HF_LC3_ENCODED_FRAME_SIZE_WITH_H2 (ESP_HF_LC3_ENCODED_FRAME_SIZE + ESP_HF_LC3_H2_HEADER_LEN)
|
||||
#define ESP_HF_LC3_BITRATE_BPS 61867 /*!< Resulting bit rate (excl. H2 header) */
|
||||
|
||||
/**
|
||||
* @brief HFP audio buffer
|
||||
|
||||
@@ -805,7 +805,8 @@ void bta_ag_setcodec(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||
/* Check if the requested codec type is valid */
|
||||
if((codec_type != BTA_AG_CODEC_NONE) &&
|
||||
(codec_type != BTA_AG_CODEC_CVSD) &&
|
||||
(codec_type != BTA_AG_CODEC_MSBC)) {
|
||||
(codec_type != BTA_AG_CODEC_MSBC) &&
|
||||
(codec_type != BTA_AG_CODEC_LC3)) {
|
||||
val.hdr.status = BTA_AG_FAIL_RESOURCES;
|
||||
APPL_TRACE_ERROR("%s error: unsupported codec type %d", __func__, codec_type);
|
||||
if (bta_ag_cb.p_cback) {
|
||||
|
||||
@@ -355,7 +355,7 @@ void BTA_AgCiData(UINT16 handle)
|
||||
*******************************************************************************/
|
||||
void BTA_AgAudioBuffAlloc(UINT16 size, UINT8 **pp_buff, UINT8 **pp_data)
|
||||
{
|
||||
/* reserve 1 byte at last, when the size is mSBC frame size (57), then we got a buffer that can hold 60 bytes data */
|
||||
/* reserve trailing space for H2 header and optional eSCO padding (mSBC: 57+2+1=60, LC3: 58+2=60) */
|
||||
BT_HDR *p_buf= (BT_HDR *)osi_calloc(sizeof(BT_HDR) + BTA_AG_BUFF_OFFSET_MIN + BTA_AG_H2_HEADER_LEN + size + 1);
|
||||
if (p_buf != NULL) {
|
||||
/* mSBC offset is large than CVSD, so this is also work in CVSD air mode */
|
||||
|
||||
@@ -694,6 +694,10 @@ static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB *p_scb, char *p_s)
|
||||
retval |= BTA_AG_CODEC_MSBC;
|
||||
break;
|
||||
|
||||
case UUID_CODEC_LC3:
|
||||
retval |= BTA_AG_CODEC_LC3;
|
||||
break;
|
||||
|
||||
default:
|
||||
APPL_TRACE_ERROR("Unknown Codec UUID(%d) received", uuid_codec);
|
||||
break;
|
||||
@@ -707,6 +711,32 @@ static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB *p_scb, char *p_s)
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ag_select_sco_codec_from_peer
|
||||
**
|
||||
** Description Select preferred SCO codec from peer capabilities (LC3 > mSBC > CVSD).
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_ag_select_sco_codec_from_peer(tBTA_AG_SCB *p_scb)
|
||||
{
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
if (p_scb->peer_codecs & BTA_AG_CODEC_LC3) {
|
||||
p_scb->sco_codec = BTA_AG_CODEC_LC3;
|
||||
APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to LC3");
|
||||
} else
|
||||
#endif
|
||||
if (p_scb->peer_codecs & BTA_AG_CODEC_MSBC) {
|
||||
p_scb->sco_codec = BTA_AG_CODEC_MSBC;
|
||||
APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to MSBC");
|
||||
} else {
|
||||
p_scb->sco_codec = BTA_AG_CODEC_CVSD;
|
||||
APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to CVSD");
|
||||
}
|
||||
}
|
||||
#endif /* #if (BTM_WBS_INCLUDED == TRUE ) */
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -1167,13 +1197,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
|
||||
p_scb->peer_codecs = bta_ag_parse_bac(p_scb, p_arg);
|
||||
p_scb->codec_updated = TRUE;
|
||||
|
||||
if (p_scb->peer_codecs & BTA_AG_CODEC_MSBC) {
|
||||
p_scb->sco_codec = UUID_CODEC_MSBC;
|
||||
APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to MSBC");
|
||||
} else {
|
||||
p_scb->sco_codec = UUID_CODEC_CVSD;
|
||||
APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to CVSD");
|
||||
}
|
||||
bta_ag_select_sco_codec_from_peer(p_scb);
|
||||
/* The above logic sets the stack preferred codec based on local and peer codec
|
||||
capabilities. This can be overridden by the application depending on its preference
|
||||
using the bta_ag_setcodec API. We send the peer_codecs to the application. */
|
||||
@@ -1204,6 +1228,10 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
|
||||
codec_type = BTA_AG_CODEC_MSBC;
|
||||
break;
|
||||
|
||||
case UUID_CODEC_LC3:
|
||||
codec_type = BTA_AG_CODEC_LC3;
|
||||
break;
|
||||
|
||||
default:
|
||||
APPL_TRACE_ERROR("Unknown codec_uuid %d", int_arg);
|
||||
codec_type = 0xFFFF;
|
||||
@@ -1675,6 +1703,10 @@ void bta_ag_send_bcs(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||
codec_uuid = UUID_CODEC_MSBC;
|
||||
break;
|
||||
|
||||
case BTA_AG_CODEC_LC3:
|
||||
codec_uuid = UUID_CODEC_LC3;
|
||||
break;
|
||||
|
||||
default:
|
||||
APPL_TRACE_ERROR("bta_ag_send_bcs: unknown codec %d, use CVSD", p_scb->sco_codec);
|
||||
codec_uuid = UUID_CODEC_CVSD;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "bta_ag_int.h"
|
||||
#include "bta/bta_api.h"
|
||||
#include "bta/bta_sys.h"
|
||||
#include "common/bt_target.h"
|
||||
#include "bta/bta_ag_api.h"
|
||||
#include "bta/bta_ag_co.h"
|
||||
#include "bta/utl.h"
|
||||
@@ -286,7 +287,11 @@ const tBTA_AG_ST_TBL bta_ag_st_tbl[] =
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
const uint16_t bta_ag_version = HFP_VERSION_1_9;
|
||||
#else
|
||||
const uint16_t bta_ag_version = HFP_VERSION_1_8;
|
||||
#endif
|
||||
/* AG control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_AG_CB bta_ag_cb;
|
||||
|
||||
@@ -129,6 +129,22 @@ static const tBTM_ESCO_PARAMS bta_ag_esco_params[BTA_AG_NUM_CODECS] =
|
||||
BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */
|
||||
}
|
||||
};
|
||||
|
||||
static BOOLEAN bta_ag_is_transparent_codec(tBTM_SCO_CODEC_TYPE codec)
|
||||
{
|
||||
return (codec == BTM_SCO_CODEC_MSBC || codec == BTM_SCO_CODEC_LC3);
|
||||
}
|
||||
|
||||
static UINT32 bta_ag_sco_get_pcm_rate(tBTM_SCO_CODEC_TYPE codec)
|
||||
{
|
||||
if (codec == BTM_SCO_CODEC_LC3) {
|
||||
return BTA_HFP_SCO_SAMP_RATE_32K;
|
||||
}
|
||||
if (codec == BTM_SCO_CODEC_MSBC) {
|
||||
return BTA_HFP_SCO_SAMP_RATE_16K;
|
||||
}
|
||||
return BTA_HFP_SCO_SAMP_RATE_8K;
|
||||
}
|
||||
#else
|
||||
#define BTA_AG_NUM_CODECS 2
|
||||
#define BTA_AG_ESCO_SETTING_IDX_CVSD 0 /* eSCO setting for CVSD S3 */
|
||||
@@ -282,24 +298,33 @@ static void bta_ag_sco_disc_cback(UINT16 sco_idx)
|
||||
|
||||
#if (BTM_WBS_INCLUDED == TRUE )
|
||||
/* Restore settings */
|
||||
if(bta_ag_cb.sco.p_curr_scb->inuse_codec == BTA_AG_CODEC_MSBC)
|
||||
if (bta_ag_is_transparent_codec(bta_ag_cb.sco.p_curr_scb->inuse_codec))
|
||||
{
|
||||
/* set_sco_codec(BTM_SCO_CODEC_NONE); we should get a close */
|
||||
BTM_WriteVoiceSettings (BTM_VOICE_SETTING_CVSD);
|
||||
|
||||
/* If SCO open was initiated by AG and failed for mSBC, then attempt
|
||||
mSBC with T1 settings i.e. 'Safe Settings'. If this fails, then switch to CVSD */
|
||||
/* If SCO open was initiated by AG and failed for mSBC/LC3, then attempt
|
||||
transparent codec with T1 settings i.e. 'Safe Settings'. If this fails,
|
||||
fall back to mSBC (from LC3) or CVSD. */
|
||||
if (bta_ag_sco_is_opening (bta_ag_cb.sco.p_curr_scb))
|
||||
{
|
||||
if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2)
|
||||
{
|
||||
APPL_TRACE_DEBUG("Fallback to mSBC T1 settings");
|
||||
APPL_TRACE_DEBUG("Fallback to transparent codec T1 settings");
|
||||
bta_ag_cb.sco.p_curr_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T1;
|
||||
}
|
||||
else
|
||||
{
|
||||
APPL_TRACE_DEBUG("Fallback to CVSD settings");
|
||||
bta_ag_cb.sco.p_curr_scb->codec_fallback = TRUE;
|
||||
if (bta_ag_cb.sco.p_curr_scb->inuse_codec == BTA_AG_CODEC_LC3 &&
|
||||
(bta_ag_cb.sco.p_curr_scb->peer_codecs & BTA_AG_CODEC_MSBC)) {
|
||||
APPL_TRACE_DEBUG("Fallback from LC3 to mSBC");
|
||||
bta_ag_cb.sco.p_curr_scb->sco_codec = BTA_AG_CODEC_MSBC;
|
||||
bta_ag_cb.sco.p_curr_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
|
||||
bta_ag_cb.sco.p_curr_scb->codec_updated = TRUE;
|
||||
} else {
|
||||
APPL_TRACE_DEBUG("Fallback to CVSD settings");
|
||||
bta_ag_cb.sco.p_curr_scb->codec_fallback = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -482,7 +507,11 @@ static UINT16 bta_ag_sco_get_frame_size(tBTA_AG_SCB *p_scb)
|
||||
frame_size = p_scb->out_pkt_len;
|
||||
break;
|
||||
case BTM_SCO_AIR_MODE_TRANSPNT:
|
||||
frame_size = BTA_AG_MSBC_FRAME_SIZE;
|
||||
if (p_scb->inuse_codec == BTA_AG_CODEC_LC3) {
|
||||
frame_size = BTA_AG_LC3_FRAME_PAYLOAD_SIZE;
|
||||
} else {
|
||||
frame_size = BTA_AG_MSBC_FRAME_PAYLOAD_SIZE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -555,9 +584,9 @@ static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig)
|
||||
|
||||
#if (BTM_WBS_INCLUDED == TRUE)
|
||||
|
||||
if ((p_scb->sco_codec == BTM_SCO_CODEC_MSBC) && !p_scb->codec_fallback && !p_scb->retry_with_sco_only)
|
||||
if (bta_ag_is_transparent_codec(p_scb->sco_codec) && !p_scb->codec_fallback && !p_scb->retry_with_sco_only)
|
||||
{
|
||||
esco_codec = BTM_SCO_CODEC_MSBC;
|
||||
esco_codec = p_scb->sco_codec;
|
||||
}
|
||||
if (p_scb->codec_fallback)
|
||||
{
|
||||
@@ -566,8 +595,8 @@ static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig)
|
||||
p_scb->codec_updated = TRUE;
|
||||
}
|
||||
/* If WBS included, use CVSD by default, index is 0 for CVSD by initialization */
|
||||
/* If eSCO codec is mSBC, index is T2 or T1 */
|
||||
if (esco_codec == BTM_SCO_CODEC_MSBC)
|
||||
/* If eSCO codec is mSBC or LC3, index is T2 or T1 */
|
||||
if (bta_ag_is_transparent_codec(esco_codec))
|
||||
{
|
||||
if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2)
|
||||
{
|
||||
@@ -625,12 +654,12 @@ static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig)
|
||||
||!((params.packet_types & ~(BTM_ESCO_LINK_ONLY_MASK | BTM_SCO_LINK_ONLY_MASK)) ^ BTA_AG_NO_EDR_ESCO))
|
||||
{
|
||||
#if (BTM_WBS_INCLUDED == TRUE)
|
||||
if (esco_codec != BTA_AG_CODEC_MSBC)
|
||||
if (!bta_ag_is_transparent_codec(esco_codec))
|
||||
{
|
||||
p_scb->retry_with_sco_only = TRUE;
|
||||
APPL_TRACE_API("Setting retry_with_sco_only to TRUE");
|
||||
}
|
||||
else /* Do not use SCO when using mSBC */
|
||||
else /* Do not use SCO when using mSBC or LC3 */
|
||||
{
|
||||
p_scb->retry_with_sco_only = FALSE;
|
||||
APPL_TRACE_API("Setting retry_with_sco_only to FALSE");
|
||||
@@ -661,7 +690,7 @@ static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig)
|
||||
|
||||
/* This setting may not be necessary */
|
||||
/* To be verified with stable 2049 boards */
|
||||
if (esco_codec == BTA_AG_CODEC_MSBC)
|
||||
if (bta_ag_is_transparent_codec(esco_codec))
|
||||
BTM_WriteVoiceSettings(BTM_VOICE_SETTING_TRANS);
|
||||
else
|
||||
BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD);
|
||||
@@ -675,13 +704,12 @@ static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig)
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||
#if (BTM_WBS_INCLUDED == TRUE)
|
||||
if (esco_codec == BTA_AG_CODEC_MSBC) {
|
||||
pcm_sample_rate = BTA_HFP_SCO_SAMP_RATE_16K;
|
||||
} else
|
||||
#endif
|
||||
pcm_sample_rate = bta_ag_sco_get_pcm_rate(esco_codec);
|
||||
#else
|
||||
{
|
||||
pcm_sample_rate = BTA_HFP_SCO_SAMP_RATE_8K;
|
||||
}
|
||||
#endif
|
||||
sco_route = bta_ag_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, p_scb->app_id);
|
||||
#endif
|
||||
|
||||
@@ -730,7 +758,7 @@ static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig)
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_ag_attempt_msbc_safe_settings(tBTA_AG_SCB *p_scb)
|
||||
{
|
||||
if (p_scb->svc_conn && p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
|
||||
if (p_scb->svc_conn && bta_ag_is_transparent_codec(p_scb->sco_codec) &&
|
||||
p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1)
|
||||
return TRUE;
|
||||
else
|
||||
@@ -791,6 +819,7 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB *p_scb)
|
||||
bta_ag_send_bcs(p_scb, NULL);
|
||||
|
||||
/* Start timer to handle timeout */
|
||||
bta_sys_stop_timer(&p_scb->cn_timer);
|
||||
p_scb->cn_timer.p_cback = (TIMER_CBACK*)&bta_ag_cn_timer_cback;
|
||||
p_scb->cn_timer.param = (UINT32)p_scb;
|
||||
bta_sys_start_timer(&p_scb->cn_timer, 0, BTA_AG_CODEC_NEGO_TIMEOUT);
|
||||
@@ -1588,7 +1617,9 @@ void bta_ag_sco_conn_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||
|
||||
#if (BTM_WBS_INCLUDED == TRUE)
|
||||
/* call app callback */
|
||||
if (p_scb->sco_codec == BTA_AG_CODEC_MSBC) {
|
||||
if (p_scb->inuse_codec == BTA_AG_CODEC_LC3) {
|
||||
bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_LC3_OPEN_EVT);
|
||||
} else if (p_scb->inuse_codec == BTA_AG_CODEC_MSBC) {
|
||||
bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_MSBC_OPEN_EVT);
|
||||
} else {
|
||||
bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
|
||||
@@ -1905,24 +1936,43 @@ static void bta_ag_sco_data_send_cvsd(tBTA_AG_SCB *p_scb, BT_HDR *p_buf)
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ag_sco_data_send_msbc
|
||||
** Function bta_ag_sco_transparent_air_pad
|
||||
**
|
||||
** Description Process SCO data of mSBC air mode
|
||||
** Description Padding bytes after H2 + codec payload to fill eSCO packet.
|
||||
**
|
||||
** Returns Number of padding bytes
|
||||
**
|
||||
*******************************************************************************/
|
||||
static UINT8 bta_ag_sco_transparent_air_pad(UINT16 frame_payload_size, UINT16 out_pkt_len)
|
||||
{
|
||||
UINT16 air_len = frame_payload_size + BTA_AG_H2_HEADER_LEN;
|
||||
if (out_pkt_len > air_len) {
|
||||
return (UINT8)(out_pkt_len - air_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ag_sco_data_send_transparent
|
||||
**
|
||||
** Description Process SCO data of transparent air mode (mSBC or LC3-SWB)
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_ag_sco_data_send_msbc(tBTA_AG_SCB *p_scb, BT_HDR *p_buf)
|
||||
static void bta_ag_sco_data_send_transparent(tBTA_AG_SCB *p_scb, BT_HDR *p_buf, UINT16 frame_payload_size)
|
||||
{
|
||||
UINT16 out_pkt_len = p_scb->out_pkt_len;
|
||||
if (p_buf->len == BTA_AG_MSBC_FRAME_SIZE && p_buf->offset >= BTA_AG_BUFF_OFFSET_MIN + BTA_AG_H2_HEADER_LEN) {
|
||||
UINT8 air_pad = bta_ag_sco_transparent_air_pad(frame_payload_size, out_pkt_len);
|
||||
|
||||
if (p_buf->len == frame_payload_size && p_buf->offset >= BTA_AG_BUFF_OFFSET_MIN + BTA_AG_H2_HEADER_LEN) {
|
||||
/* add H2 header */
|
||||
p_buf->offset -= BTA_AG_H2_HEADER_LEN;
|
||||
UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
bta_ag_h2_header((UINT16 *)p_data);
|
||||
/* add header len, add addition one bytes, the len is BTA_AG_SCO_OUT_PKT_LEN_2EV3 now */
|
||||
p_buf->len += BTA_AG_H2_HEADER_LEN + 1;
|
||||
p_buf->len += BTA_AG_H2_HEADER_LEN + air_pad;
|
||||
|
||||
if (out_pkt_len == BTA_AG_SCO_OUT_PKT_LEN_2EV3) {
|
||||
/* mSBC frame can be send directly */
|
||||
@@ -1950,8 +2000,8 @@ static void bta_ag_sco_data_send_msbc(tBTA_AG_SCB *p_scb, BT_HDR *p_buf)
|
||||
APPL_TRACE_WARNING("%s, invalid out pkt len: %d", __FUNCTION__, out_pkt_len);
|
||||
}
|
||||
}
|
||||
else if (p_buf->len != 0 && p_buf->len % BTA_AG_MSBC_FRAME_SIZE == 0) {
|
||||
/* multiple mSBC frame in the buffer, or just one but offset is too small */
|
||||
else if (p_buf->len != 0 && p_buf->len % frame_payload_size == 0) {
|
||||
/* multiple mSBC or LC3-SWB frame in the buffer, or just one but offset is too small */
|
||||
UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
UINT16 total_len = p_buf->len;
|
||||
if (out_pkt_len == BTA_AG_SCO_OUT_PKT_LEN_2EV3) {
|
||||
@@ -1966,9 +2016,9 @@ static void bta_ag_sco_data_send_msbc(tBTA_AG_SCB *p_scb, BT_HDR *p_buf)
|
||||
UINT8 *p_data2 = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
|
||||
bta_ag_h2_header((UINT16 *)p_data2);
|
||||
p_data2 += BTA_AG_H2_HEADER_LEN;
|
||||
memcpy(p_data2, p_data, BTA_AG_MSBC_FRAME_SIZE);
|
||||
p_data += BTA_AG_MSBC_FRAME_SIZE;
|
||||
total_len -= BTA_AG_MSBC_FRAME_SIZE;
|
||||
memcpy(p_data2, p_data, frame_payload_size);
|
||||
p_data += frame_payload_size;
|
||||
total_len -= frame_payload_size;
|
||||
bta_ag_write_sco_data(p_scb, p_buf2, NULL);
|
||||
}
|
||||
}
|
||||
@@ -2001,7 +2051,7 @@ static void bta_ag_sco_data_send_msbc(tBTA_AG_SCB *p_scb, BT_HDR *p_buf)
|
||||
p_buf3->offset = BTA_AG_BUFF_OFFSET_MIN;
|
||||
p_buf3->len = BTA_AG_SCO_OUT_PKT_LEN_EV3;
|
||||
UINT8 *p_data3 = (UINT8 *)(p_buf3 + 1) + p_buf3->offset;
|
||||
UINT16 rem_payload = BTA_AG_MSBC_FRAME_SIZE - (BTA_AG_SCO_OUT_PKT_LEN_EV3 - BTA_AG_H2_HEADER_LEN);
|
||||
UINT16 rem_payload = frame_payload_size - (BTA_AG_SCO_OUT_PKT_LEN_EV3 - BTA_AG_H2_HEADER_LEN);
|
||||
memcpy(p_data3, p_data, rem_payload);
|
||||
p_data += rem_payload;
|
||||
total_len -= rem_payload;
|
||||
@@ -2014,7 +2064,7 @@ static void bta_ag_sco_data_send_msbc(tBTA_AG_SCB *p_scb, BT_HDR *p_buf)
|
||||
osi_free(p_buf);
|
||||
}
|
||||
else {
|
||||
APPL_TRACE_WARNING("%s, unaccepted data len: %d", __FUNCTION__, p_buf->len);
|
||||
APPL_TRACE_WARNING("%s, unaccepted data len: %d (frame %d)", __FUNCTION__, p_buf->len, frame_payload_size);
|
||||
osi_free(p_buf);
|
||||
}
|
||||
}
|
||||
@@ -2048,7 +2098,11 @@ void bta_ag_sco_data_send(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||
bta_ag_sco_data_send_cvsd(p_scb, p_buf);
|
||||
break;
|
||||
case BTM_SCO_AIR_MODE_TRANSPNT:
|
||||
bta_ag_sco_data_send_msbc(p_scb, p_buf);
|
||||
if (p_scb->inuse_codec == BTA_AG_CODEC_LC3) {
|
||||
bta_ag_sco_data_send_transparent(p_scb, p_buf, BTA_AG_LC3_FRAME_PAYLOAD_SIZE);
|
||||
} else {
|
||||
bta_ag_sco_data_send_transparent(p_scb, p_buf, BTA_AG_MSBC_FRAME_PAYLOAD_SIZE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
osi_free(p_buf);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "bta_ag_int.h"
|
||||
#include "common/bt_target.h"
|
||||
#include "bta/bta_ag_api.h"
|
||||
#include "bta/bta_sys.h"
|
||||
#include "bta/bta_ag_api.h"
|
||||
@@ -161,7 +162,11 @@ BOOLEAN bta_ag_add_record(UINT16 service_uuid, char *p_service_name, UINT8 scn,
|
||||
/* add profile descriptor list */
|
||||
if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE) {
|
||||
profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
version = HFP_VERSION_1_9;
|
||||
#else
|
||||
version = HFP_VERSION_1_8;
|
||||
#endif
|
||||
} else {
|
||||
profile_uuid = UUID_SERVCLASS_HEADSET;
|
||||
version = HSP_VERSION_1_2;
|
||||
@@ -188,6 +193,11 @@ BOOLEAN bta_ag_add_record(UINT16 service_uuid, char *p_service_name, UINT8 scn,
|
||||
if (codec_supported) {
|
||||
features |= 0x0020;
|
||||
}
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
if (codec_supported) {
|
||||
features |= 0x0100; /* SWB supported in SDP */
|
||||
}
|
||||
#endif
|
||||
UINT16_TO_BE_FIELD(buf, features);
|
||||
result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 2, buf);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#define HFP_VERSION_1_6 0x0106
|
||||
#define HFP_VERSION_1_7 0x0107
|
||||
#define HFP_VERSION_1_8 0x0108
|
||||
#define HFP_VERSION_1_9 0x0109
|
||||
|
||||
#define HSP_VERSION_1_0 0x0100
|
||||
#define HSP_VERSION_1_2 0x0102
|
||||
@@ -102,7 +103,9 @@
|
||||
/* mSBC H2 header length */
|
||||
#define BTA_AG_H2_HEADER_LEN 2
|
||||
/* mSBC frame size not include H1/H2 header */
|
||||
#define BTA_AG_MSBC_FRAME_SIZE 57
|
||||
#define BTA_AG_MSBC_FRAME_PAYLOAD_SIZE 57
|
||||
#define BTA_AG_LC3_FRAME_PAYLOAD_SIZE 58
|
||||
#define BTA_AG_LC3_VOHCI_FRAME_SIZE 60
|
||||
/* max user data len of sco packet type EV3 */
|
||||
#define BTA_AG_SCO_OUT_PKT_LEN_EV3 30
|
||||
/* max user data len of sco packet type 2-EV3 */
|
||||
|
||||
@@ -63,6 +63,7 @@ static const uint8_t bta_hf_client_cb_data_size[] = {
|
||||
sizeof(tBTA_HF_CLIENT_VAL), // #define BTA_HF_CLIENT_RING_INDICATION 21
|
||||
0, // #define BTA_HF_CLIENT_DISABLE_EVT 22
|
||||
sizeof(tBTA_SCO_PKT_STAT_NUMS), // #define BTA_HF_CLIENT_PKT_STAT_NUMS_GET_EVT 23
|
||||
sizeof(tBTA_HF_CLIENT_AUDIO_STAT), // #define BTA_HF_CLIENT_AUDIO_LC3_OPEN_EVT 24
|
||||
};
|
||||
/*****************************************************************************
|
||||
** External Function Declarations
|
||||
@@ -368,7 +369,7 @@ void BTA_HfClientAudioBuffAlloc(UINT16 size, UINT8 **pp_buff, UINT8 **pp_data)
|
||||
return;
|
||||
}
|
||||
|
||||
/* reserve 1 byte at last, when the size is mSBC frame size (57), then we got a buffer that can hold 60 bytes data */
|
||||
/* reserve trailing space for H2 header and optional eSCO padding (mSBC: 57+2+1=60, LC3: 58+2=60) */
|
||||
p_buf = (BT_HDR *)osi_calloc(sizeof(BT_HDR) + BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_H2_HEADER_LEN + size + 1);
|
||||
if (p_buf != NULL) {
|
||||
/* mSBC offset is large than CVSD, so this is work in CVSD air mode */
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include "bta/bta_hf_client_api.h"
|
||||
#include "bta_hf_client_int.h"
|
||||
#include "common/bt_target.h"
|
||||
#include "stack/sdpdefs.h"
|
||||
#include "stack/port_api.h"
|
||||
#include "osi/allocator.h"
|
||||
|
||||
@@ -488,14 +490,49 @@ static void bta_hf_client_handle_ciev(UINT32 index, UINT32 value)
|
||||
}
|
||||
}
|
||||
|
||||
static tBTM_SCO_CODEC_TYPE bta_hf_client_hfp_codec_id_to_btm(UINT32 hfp_codec_id)
|
||||
{
|
||||
switch (hfp_codec_id) {
|
||||
case UUID_CODEC_MSBC:
|
||||
return BTM_SCO_CODEC_MSBC;
|
||||
case UUID_CODEC_LC3:
|
||||
return BTM_SCO_CODEC_LC3;
|
||||
case UUID_CODEC_CVSD:
|
||||
return BTM_SCO_CODEC_CVSD;
|
||||
default:
|
||||
/* Accept BTM bitmask values for backward compatibility */
|
||||
if (hfp_codec_id == BTM_SCO_CODEC_MSBC || hfp_codec_id == BTM_SCO_CODEC_LC3 ||
|
||||
hfp_codec_id == BTM_SCO_CODEC_CVSD) {
|
||||
return (tBTM_SCO_CODEC_TYPE)hfp_codec_id;
|
||||
}
|
||||
return BTM_SCO_CODEC_CVSD;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT32 bta_hf_client_btm_codec_to_hfp_id(tBTM_SCO_CODEC_TYPE btm_codec)
|
||||
{
|
||||
switch (btm_codec) {
|
||||
case BTM_SCO_CODEC_MSBC:
|
||||
return UUID_CODEC_MSBC;
|
||||
case BTM_SCO_CODEC_LC3:
|
||||
return UUID_CODEC_LC3;
|
||||
case BTM_SCO_CODEC_CVSD:
|
||||
default:
|
||||
return UUID_CODEC_CVSD;
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_hf_client_handle_bcs(UINT32 codec)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s %u", __FUNCTION__, codec);
|
||||
tBTM_SCO_CODEC_TYPE btm_codec = bta_hf_client_hfp_codec_id_to_btm(codec);
|
||||
|
||||
if (codec == BTM_SCO_CODEC_CVSD ||
|
||||
(codec == BTM_SCO_CODEC_MSBC && bta_hf_client_cb.msbc_enabled == TRUE)) {
|
||||
bta_hf_client_cb.scb.negotiated_codec = codec;
|
||||
bta_hf_client_send_at_bcs(codec);
|
||||
APPL_TRACE_DEBUG("%s hfp_id %u btm_codec %u", __FUNCTION__, codec, btm_codec);
|
||||
|
||||
if (btm_codec == BTM_SCO_CODEC_CVSD ||
|
||||
(btm_codec == BTM_SCO_CODEC_MSBC && bta_hf_client_cb.msbc_enabled == TRUE) ||
|
||||
(btm_codec == BTM_SCO_CODEC_LC3 && bta_hf_client_cb.lc3_enabled == TRUE)) {
|
||||
bta_hf_client_cb.scb.negotiated_codec = btm_codec;
|
||||
bta_hf_client_send_at_bcs(btm_codec);
|
||||
} else {
|
||||
bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
|
||||
bta_hf_client_send_at_bac();
|
||||
@@ -1427,7 +1464,8 @@ void bta_hf_client_send_at_brsf(void)
|
||||
|
||||
APPL_TRACE_DEBUG("%s", __FUNCTION__);
|
||||
|
||||
at_len = snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN, "AT+BRSF=%u\r", bta_hf_client_cb.scb.features);
|
||||
at_len = snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN, "AT+BRSF=%u\r",
|
||||
bta_hf_client_cb.scb.features & BTA_HF_CLIENT_BRSF_FEAT_SPEC);
|
||||
|
||||
at_len = MIN(at_len, BTA_HF_CLIENT_AT_MAX_LEN - 1);
|
||||
if (at_len < 0) {
|
||||
@@ -1446,6 +1484,11 @@ void bta_hf_client_send_at_bac(void)
|
||||
|
||||
APPL_TRACE_DEBUG("%s", __FUNCTION__);
|
||||
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
if (bta_hf_client_cb.lc3_enabled && bta_hf_client_cb.msbc_enabled) {
|
||||
buf = "AT+BAC=1,2,3\r";
|
||||
} else
|
||||
#endif
|
||||
if (bta_hf_client_cb.msbc_enabled) {
|
||||
buf = "AT+BAC=1,2\r";
|
||||
} else {
|
||||
@@ -1465,7 +1508,8 @@ void bta_hf_client_send_at_bcs(UINT32 codec)
|
||||
return;
|
||||
}
|
||||
|
||||
at_len = snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN, "AT+BCS=%u\r", codec);
|
||||
at_len = snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN, "AT+BCS=%u\r",
|
||||
bta_hf_client_btm_codec_to_hfp_id((tBTM_SCO_CODEC_TYPE)codec));
|
||||
|
||||
at_len = MIN(at_len, BTA_HF_CLIENT_AT_MAX_LEN - 1);
|
||||
if (at_len < 0) {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "common/bt_defs.h"
|
||||
#include "common/bt_target.h"
|
||||
#include "bta/bta_api.h"
|
||||
#include "bta/bta_sys.h"
|
||||
#include "bta/bta_hf_client_api.h"
|
||||
@@ -251,7 +252,11 @@ const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
|
||||
bta_hf_client_st_closing
|
||||
};
|
||||
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
const int bta_hf_client_version = HFP_HF_VERSION_1_9;
|
||||
#else
|
||||
const int bta_hf_client_version = HFP_HF_VERSION_1_7;
|
||||
#endif
|
||||
|
||||
/* HF Client control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
@@ -460,6 +465,16 @@ static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
|
||||
bta_hf_client_cb.msbc_enabled = FALSE;
|
||||
}
|
||||
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
if (bta_hf_client_version >= HFP_HF_VERSION_1_9) {
|
||||
bta_hf_client_cb.lc3_enabled = TRUE;
|
||||
} else {
|
||||
bta_hf_client_cb.lc3_enabled = FALSE;
|
||||
}
|
||||
#else
|
||||
bta_hf_client_cb.lc3_enabled = FALSE;
|
||||
#endif
|
||||
|
||||
bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
|
||||
|
||||
/* set same setting as AG does */
|
||||
|
||||
@@ -43,6 +43,22 @@ static BOOLEAN s_bta_hf_client_bqb_esco_s1_flag = false;
|
||||
#define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S3 1 /* eSCO setting for CVSD S3 */
|
||||
#define BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2 2 /* eSCO setting for mSBC T2 */
|
||||
#define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4 3 /* eSCO setting for CVSD S4 */
|
||||
|
||||
static BOOLEAN bta_hf_client_is_transparent_codec(tBTM_SCO_CODEC_TYPE codec)
|
||||
{
|
||||
return (codec == BTM_SCO_CODEC_MSBC || codec == BTM_SCO_CODEC_LC3);
|
||||
}
|
||||
|
||||
static UINT32 bta_hf_client_sco_get_pcm_rate(tBTM_SCO_CODEC_TYPE codec)
|
||||
{
|
||||
if (codec == BTM_SCO_CODEC_LC3) {
|
||||
return BTA_HFP_SCO_SAMP_RATE_32K;
|
||||
}
|
||||
if (codec == BTM_SCO_CODEC_MSBC) {
|
||||
return BTA_HFP_SCO_SAMP_RATE_16K;
|
||||
}
|
||||
return BTA_HFP_SCO_SAMP_RATE_8K;
|
||||
}
|
||||
#define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S1 4 /* eSCO setting for CVSD S1 */
|
||||
|
||||
static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = {
|
||||
@@ -197,7 +213,11 @@ static UINT16 bta_hf_client_sco_get_frame_size(void)
|
||||
frame_size = bta_hf_client_cb.scb.out_pkt_len;
|
||||
break;
|
||||
case BTM_SCO_AIR_MODE_TRANSPNT:
|
||||
frame_size = BTA_HF_CLIENT_MSBC_FRAME_SIZE;
|
||||
if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_LC3) {
|
||||
frame_size = BTA_HF_CLIENT_LC3_FRAME_SIZE;
|
||||
} else {
|
||||
frame_size = BTA_HF_CLIENT_MSBC_FRAME_SIZE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -291,7 +311,7 @@ static void bta_hf_client_sco_conn_rsp(tBTM_ESCO_CONN_REQ_EVT_DATA *p_data)
|
||||
index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S1;
|
||||
}
|
||||
#endif /* BT_HF_CLIENT_BQB_INCLUDED */
|
||||
} else if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) {
|
||||
} else if (bta_hf_client_is_transparent_codec(bta_hf_client_cb.scb.negotiated_codec)) {
|
||||
index = BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2;
|
||||
}
|
||||
}
|
||||
@@ -302,7 +322,7 @@ static void bta_hf_client_sco_conn_rsp(tBTM_ESCO_CONN_REQ_EVT_DATA *p_data)
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||
bta_hf_client_co_audio_state(bta_hf_client_cb.scb.sco_idx, SCO_STATE_SETUP, 0);
|
||||
pcm_sample_rate = BTA_HFP_SCO_SAMP_RATE_8K;
|
||||
pcm_sample_rate = bta_hf_client_sco_get_pcm_rate(bta_hf_client_cb.scb.negotiated_codec);
|
||||
|
||||
/* initialize SCO setup, no voice setting for AG, data rate <==> sample rate */
|
||||
BTM_ConfigScoPath(bta_hf_client_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, 0),
|
||||
@@ -460,25 +480,34 @@ static void bta_hf_client_sco_data_send_cvsd(BT_HDR *p_buf, UINT16 out_pkt_len)
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 bta_hf_client_sco_transparent_air_pad(UINT16 frame_payload_size, UINT16 out_pkt_len)
|
||||
{
|
||||
UINT16 air_len = frame_payload_size + BTA_HF_CLIENT_H2_HEADER_LEN;
|
||||
if (out_pkt_len > air_len) {
|
||||
return (UINT8)(out_pkt_len - air_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hf_client_sco_data_send_msbc
|
||||
** Function bta_hf_client_sco_data_send_transparent
|
||||
**
|
||||
** Description Process SCO data of mSBC air mode
|
||||
** Description Process SCO data of transparent air mode (mSBC or LC3-SWB)
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_hf_client_sco_data_send_msbc(BT_HDR *p_buf, UINT16 out_pkt_len)
|
||||
static void bta_hf_client_sco_data_send_transparent(BT_HDR *p_buf, UINT16 out_pkt_len, UINT16 frame_payload_size)
|
||||
{
|
||||
if (p_buf->len == BTA_HF_CLIENT_MSBC_FRAME_SIZE && p_buf->offset >= BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_H2_HEADER_LEN) {
|
||||
/* add H2 header */
|
||||
UINT8 air_pad = bta_hf_client_sco_transparent_air_pad(frame_payload_size, out_pkt_len);
|
||||
|
||||
if (p_buf->len == frame_payload_size && p_buf->offset >= BTA_HF_CLIENT_BUFF_OFFSET_MIN + BTA_HF_CLIENT_H2_HEADER_LEN) {
|
||||
p_buf->offset -= BTA_HF_CLIENT_H2_HEADER_LEN;
|
||||
UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
bta_hf_client_h2_header((UINT16 *)p_data);
|
||||
/* add header len, add addition one bytes, the len is BTA_HF_CLIENT_SCO_OUT_PKT_LEN_2EV3 now */
|
||||
p_buf->len += BTA_HF_CLIENT_H2_HEADER_LEN + 1;
|
||||
p_buf->len += BTA_HF_CLIENT_H2_HEADER_LEN + air_pad;
|
||||
|
||||
if (out_pkt_len == BTA_HF_CLIENT_SCO_OUT_PKT_LEN_2EV3) {
|
||||
/* mSBC frame can be send directly */
|
||||
@@ -506,8 +535,7 @@ static void bta_hf_client_sco_data_send_msbc(BT_HDR *p_buf, UINT16 out_pkt_len)
|
||||
APPL_TRACE_WARNING("%s, invalid out pkt len: %d", __FUNCTION__, out_pkt_len);
|
||||
}
|
||||
}
|
||||
else if (p_buf->len != 0 && p_buf->len % BTA_HF_CLIENT_MSBC_FRAME_SIZE == 0) {
|
||||
/* multiple mSBC frame in the buffer, or just one but offset is too small */
|
||||
else if (p_buf->len != 0 && p_buf->len % frame_payload_size == 0) {
|
||||
UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
UINT16 total_len = p_buf->len;
|
||||
if (out_pkt_len == BTA_HF_CLIENT_SCO_OUT_PKT_LEN_2EV3) {
|
||||
@@ -522,9 +550,9 @@ static void bta_hf_client_sco_data_send_msbc(BT_HDR *p_buf, UINT16 out_pkt_len)
|
||||
UINT8 *p_data2 = (UINT8 *)(p_buf2 + 1) + p_buf2->offset;
|
||||
bta_hf_client_h2_header((UINT16 *)p_data2);
|
||||
p_data2 += BTA_HF_CLIENT_H2_HEADER_LEN;
|
||||
memcpy(p_data2, p_data, BTA_HF_CLIENT_MSBC_FRAME_SIZE);
|
||||
p_data += BTA_HF_CLIENT_MSBC_FRAME_SIZE;
|
||||
total_len -= BTA_HF_CLIENT_MSBC_FRAME_SIZE;
|
||||
memcpy(p_data2, p_data, frame_payload_size);
|
||||
p_data += frame_payload_size;
|
||||
total_len -= frame_payload_size;
|
||||
bta_hf_client_write_sco_data(p_buf2, NULL);
|
||||
}
|
||||
}
|
||||
@@ -557,7 +585,7 @@ static void bta_hf_client_sco_data_send_msbc(BT_HDR *p_buf, UINT16 out_pkt_len)
|
||||
p_buf3->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN;
|
||||
p_buf3->len = BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
|
||||
UINT8 *p_data3 = (UINT8 *)(p_buf3 + 1) + p_buf3->offset;
|
||||
UINT16 rem_payload = BTA_HF_CLIENT_MSBC_FRAME_SIZE - (BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3 - BTA_HF_CLIENT_H2_HEADER_LEN);
|
||||
UINT16 rem_payload = frame_payload_size - (BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3 - BTA_HF_CLIENT_H2_HEADER_LEN);
|
||||
memcpy(p_data3, p_data, rem_payload);
|
||||
p_data += rem_payload;
|
||||
total_len -= rem_payload;
|
||||
@@ -570,7 +598,7 @@ static void bta_hf_client_sco_data_send_msbc(BT_HDR *p_buf, UINT16 out_pkt_len)
|
||||
osi_free(p_buf);
|
||||
}
|
||||
else {
|
||||
APPL_TRACE_WARNING("%s, unaccepted data len: %d", __FUNCTION__, p_buf->len);
|
||||
APPL_TRACE_WARNING("%s, unaccepted data len: %d (frame %d)", __FUNCTION__, p_buf->len, frame_payload_size);
|
||||
osi_free(p_buf);
|
||||
}
|
||||
}
|
||||
@@ -604,7 +632,11 @@ void bta_hf_client_sco_data_send(tBTA_HF_CLIENT_DATA *p_data)
|
||||
bta_hf_client_sco_data_send_cvsd(p_buf, out_pkt_len);
|
||||
break;
|
||||
case BTM_SCO_AIR_MODE_TRANSPNT:
|
||||
bta_hf_client_sco_data_send_msbc(p_buf, out_pkt_len);
|
||||
if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_LC3) {
|
||||
bta_hf_client_sco_data_send_transparent(p_buf, out_pkt_len, BTA_HF_CLIENT_LC3_FRAME_SIZE);
|
||||
} else {
|
||||
bta_hf_client_sco_data_send_transparent(p_buf, out_pkt_len, BTA_HF_CLIENT_MSBC_FRAME_SIZE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
osi_free(p_buf);
|
||||
@@ -778,7 +810,7 @@ static void bta_hf_client_sco_create(BOOLEAN is_orig)
|
||||
(bta_hf_client_cb.scb.peer_features & BTA_HF_CLIENT_PEER_ESCO_S4)) {
|
||||
index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4;
|
||||
}
|
||||
} else if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) {
|
||||
} else if (bta_hf_client_is_transparent_codec(bta_hf_client_cb.scb.negotiated_codec)) {
|
||||
index = BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2;
|
||||
}
|
||||
params = bta_hf_client_esco_params[index];
|
||||
@@ -810,7 +842,7 @@ static void bta_hf_client_sco_create(BOOLEAN is_orig)
|
||||
/* Allow any platform specific pre-SCO set up to take place */
|
||||
bta_hf_client_co_audio_state(bta_hf_client_cb.scb.sco_idx, SCO_STATE_SETUP, 0);
|
||||
|
||||
pcm_sample_rate = BTA_HFP_SCO_SAMP_RATE_8K;
|
||||
pcm_sample_rate = bta_hf_client_sco_get_pcm_rate(bta_hf_client_cb.scb.negotiated_codec);
|
||||
sco_route = bta_hf_client_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, 0);
|
||||
|
||||
/* initialize SCO setup, no voice setting for AG, data rate <==> sample rate */
|
||||
@@ -1165,7 +1197,9 @@ void bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA *p_data)
|
||||
bta_hf_client_cb.scb.out_pkt_len, BTA_HF_CLIENT_CI_SCO_DATA_EVT);
|
||||
#endif
|
||||
|
||||
if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) {
|
||||
if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_LC3) {
|
||||
bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_LC3_OPEN_EVT);
|
||||
} else if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) {
|
||||
bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT);
|
||||
} else {
|
||||
bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_OPEN_EVT);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "bta/bta_api.h"
|
||||
#include "common/bt_target.h"
|
||||
#include "bta/bta_sys.h"
|
||||
#include "common/bt_defs.h"
|
||||
#include "bta/bta_hf_client_api.h"
|
||||
@@ -114,7 +115,11 @@ BOOLEAN bta_hf_client_add_record(char *p_service_name, UINT8 scn,
|
||||
|
||||
/* add profile descriptor list */
|
||||
profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
version = HFP_VERSION_1_9;
|
||||
#else
|
||||
version = HFP_VERSION_1_8;
|
||||
#endif
|
||||
|
||||
result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);
|
||||
|
||||
@@ -150,6 +155,12 @@ BOOLEAN bta_hf_client_add_record(char *p_service_name, UINT8 scn,
|
||||
sdp_features |= 0x0020;
|
||||
}
|
||||
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
if (features & BTA_HF_CLIENT_FEAT_SWB) {
|
||||
sdp_features |= 0x0100; /* SWB supported in SDP */
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT16_TO_BE_FIELD(buf, sdp_features);
|
||||
result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 2, buf);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define HFP_VERSION_1_6 0x0106
|
||||
#define HFP_VERSION_1_7 0x0107
|
||||
#define HFP_VERSION_1_8 0x0108
|
||||
#define HFP_VERSION_1_9 0x0109
|
||||
|
||||
/* RFCOMM MTU SIZE */
|
||||
#define BTA_HF_CLIENT_MTU 256
|
||||
@@ -39,6 +40,13 @@
|
||||
#define BTA_HF_CLIENT_ACP 0 /* accepted connection */
|
||||
#define BTA_HF_CLIENT_INT 1 /* initiating connection */
|
||||
|
||||
/* feature mask that matches spec */
|
||||
#define BTA_HF_CLIENT_BRSF_FEAT_SPEC (BTA_HF_CLIENT_FEAT_ECNR | BTA_HF_CLIENT_FEAT_3WAY | \
|
||||
BTA_HF_CLIENT_FEAT_CLI | BTA_HF_CLIENT_FEAT_VREC | \
|
||||
BTA_HF_CLIENT_FEAT_VOL | BTA_HF_CLIENT_FEAT_ECS | \
|
||||
BTA_HF_CLIENT_FEAT_ECC | BTA_HF_CLIENT_FEAT_CODEC | \
|
||||
BTA_HF_CLIENT_FEAT_HF_IND | BTA_HF_CLIENT_FEAT_ESCO_S4)
|
||||
|
||||
/* Timer to wait for retry in case of collision */
|
||||
#ifndef BTA_HF_CLIENT_COLLISION_TIMER
|
||||
#define BTA_HF_CLIENT_COLLISION_TIMER 2411
|
||||
@@ -51,6 +59,8 @@
|
||||
#define BTA_HF_CLIENT_H2_HEADER_LEN 2
|
||||
/* mSBC frame size not include H1/H2 header */
|
||||
#define BTA_HF_CLIENT_MSBC_FRAME_SIZE 57
|
||||
#define BTA_HF_CLIENT_LC3_FRAME_SIZE 58
|
||||
#define BTA_HF_CLIENT_LC3_VOHCI_FRAME_SIZE 60
|
||||
/* max user data len of sco packet type EV3 */
|
||||
#define BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3 30
|
||||
/* max user data len of sco packet type 2-EV3 */
|
||||
@@ -209,6 +219,7 @@ typedef struct {
|
||||
UINT8 scn;
|
||||
tBTA_HF_CLIENT_CBACK *p_cback; /* application callback */
|
||||
BOOLEAN msbc_enabled;
|
||||
BOOLEAN lc3_enabled;
|
||||
} tBTA_HF_CLIENT_CB;
|
||||
|
||||
/*****************************************************************************
|
||||
|
||||
@@ -92,6 +92,7 @@ typedef UINT16 tBTA_AG_CHLD_FEAT;
|
||||
#define BTA_AG_CODEC_NONE BTM_SCO_CODEC_NONE
|
||||
#define BTA_AG_CODEC_CVSD BTM_SCO_CODEC_CVSD /* CVSD */
|
||||
#define BTA_AG_CODEC_MSBC BTM_SCO_CODEC_MSBC /* mSBC */
|
||||
#define BTA_AG_CODEC_LC3 BTM_SCO_CODEC_LC3 /* LC3-SWB */
|
||||
typedef UINT16 tBTA_AG_PEER_CODEC;
|
||||
|
||||
/* AG parse mode */
|
||||
@@ -159,6 +160,7 @@ typedef UINT8 tBTA_AG_RES;
|
||||
#define BTA_AG_AUDIO_MSBC_OPEN_EVT 32 /* Audio connection with mSBC codec open */
|
||||
|
||||
#define BTA_AG_PKT_NUMS_GET_EVT 33 /* AG packet status nums */
|
||||
#define BTA_AG_AUDIO_LC3_OPEN_EVT 34 /* Audio connection with LC3-SWB codec open */
|
||||
|
||||
/* Values below are for HFP only */
|
||||
#define BTA_AG_AT_A_EVT 10 /* Answer a incoming call */
|
||||
@@ -363,7 +365,8 @@ typedef struct
|
||||
tBTA_AG_CHLD_FEAT chld_feat;
|
||||
} tBTA_AG_CONN;
|
||||
|
||||
/* data associated with BTA_AG_AUDIO_OPEN_EVT, BTA_AG_AUDIO_CLOSE_EVT or BTA_AG_AUDIO_MSBC_OPEN_EVT */
|
||||
/* data associated with BTA_AG_AUDIO_OPEN_EVT, BTA_AG_AUDIO_CLOSE_EVT, */
|
||||
/* BTA_AG_AUDIO_MSBC_OPEN_EVT or BTA_AG_AUDIO_LC3_OPEN_EVT */
|
||||
typedef struct
|
||||
{
|
||||
tBTA_AG_HDR hdr;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
/* Hands-Free unit(HF) version */
|
||||
#define HFP_HF_VERSION_1_6 0x0106 /* v1.6 */
|
||||
#define HFP_HF_VERSION_1_7 0x0107 /* v1.7 */
|
||||
#define HFP_HF_VERSION_1_9 0x0109 /* v1.9 */
|
||||
|
||||
/* HFP peer (AG) features*/
|
||||
#define BTA_HF_CLIENT_PEER_FEAT_3WAY 0x00000001 /* Three-way calling */
|
||||
@@ -66,6 +67,9 @@ typedef UINT16 tBTA_HF_CLIENT_PEER_FEAT;
|
||||
#define BTA_HF_CLIENT_FEAT_HF_IND 0x00000100 /* HF indicators */
|
||||
#define BTA_HF_CLIENT_FEAT_ESCO_S4 0x00000200 /* eSCO S4 Setting Supported */
|
||||
|
||||
/* Proprietary features: using 31 ~ 16 bits, AT+BRSF bit 12 ~ 31 are reserved by spec */
|
||||
#define BTA_HF_CLIENT_FEAT_SWB 0x00010000 /* Super Wideband Speech */
|
||||
|
||||
/* HFP HF extended call handling - masks not related to any spec */
|
||||
#define BTA_HF_CLIENT_CHLD_REL 0x00000001 /* 0 Release waiting call or held calls */
|
||||
#define BTA_HF_CLIENT_CHLD_REL_ACC 0x00000002 /* 1 Release active calls and accept other (waiting or held) cal */
|
||||
@@ -114,6 +118,7 @@ typedef UINT8 tBTA_HF_CLIENT_AT_RESULT_TYPE;
|
||||
#define BTA_HF_CLIENT_RING_INDICATION 21 /* HF Client ring indication */
|
||||
#define BTA_HF_CLIENT_DISABLE_EVT 22 /* HF Client disabled */
|
||||
#define BTA_HF_CLIENT_PKT_STAT_NUMS_GET_EVT 23 /* HF Client packet status nums */
|
||||
#define BTA_HF_CLIENT_AUDIO_LC3_OPEN_EVT 24 /* Audio connection with LC3-SWB codec open */
|
||||
|
||||
typedef UINT8 tBTA_HF_CLIENT_EVT;
|
||||
|
||||
@@ -188,7 +193,7 @@ typedef struct {
|
||||
tBTA_HF_CLIENT_CHLD_FEAT chld_feat;
|
||||
} tBTA_HF_CLIENT_CONN;
|
||||
|
||||
/* data associated with BTA_HF_CLIENT_AUDIO_XXX_EVT */
|
||||
/* data associated with BTA_HF_CLIENT_AUDIO_XXX_EVT (OPEN/MSBC/LC3/CLOSE) */
|
||||
typedef struct {
|
||||
tBTA_HF_CLIENT_HDR hdr;
|
||||
UINT16 preferred_frame_size;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define BTA_HFP_CODEC_NONE BTM_SCO_CODEC_NONE
|
||||
#define BTA_HFP_CODEC_CVSD BTM_SCO_CODEC_CVSD /* CVSD */
|
||||
#define BTA_HFP_CODEC_MSBC BTM_SCO_CODEC_MSBC /* mSBC */
|
||||
#define BTA_HFP_CODEC_LC3 BTM_SCO_CODEC_LC3 /* LC3-SWB */
|
||||
|
||||
typedef UINT16 tBTA_HFP_PEER_CODEC;
|
||||
|
||||
@@ -25,6 +26,7 @@ typedef UINT8 tBTA_HFP_SCO_CODEC_TYPE;
|
||||
|
||||
#define BTA_HFP_SCO_SAMP_RATE_8K 8000
|
||||
#define BTA_HFP_SCO_SAMP_RATE_16K 16000
|
||||
#define BTA_HFP_SCO_SAMP_RATE_32K 32000
|
||||
|
||||
/* SCO codec information */
|
||||
typedef struct {
|
||||
|
||||
@@ -307,7 +307,7 @@ static void bta_ag_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad
|
||||
*length = (UINT8)frame_len;
|
||||
}
|
||||
|
||||
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
|
||||
// PLC_INCLUDED will be set to TRUE when enabling Wideband Speech
|
||||
#if (PLC_INCLUDED == TRUE)
|
||||
switch(status) {
|
||||
case OI_OK:
|
||||
|
||||
@@ -106,7 +106,7 @@ hf_local_param_t *hf_local_param_ptr = NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* wide band synchronous */
|
||||
/* Wideband synchronous */
|
||||
#ifndef BTC_HF_WBS_PREFERRED
|
||||
#define BTC_HF_WBS_PREFERRED TRUE
|
||||
#endif
|
||||
@@ -203,6 +203,38 @@ static BOOLEAN is_connected(int idx, bt_bdaddr_t *bd_addr)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static esp_hf_codec_mode_t btc_hf_bta_codec_to_esp(tBTA_AG_PEER_CODEC codec)
|
||||
{
|
||||
if (codec == BTA_AG_CODEC_NONE) {
|
||||
return ESP_HF_CODEC_NONE;
|
||||
}
|
||||
if (codec & BTA_AG_CODEC_LC3) {
|
||||
return ESP_HF_CODEC_LC3;
|
||||
}
|
||||
if (codec & BTA_AG_CODEC_MSBC) {
|
||||
return ESP_HF_CODEC_MSBC;
|
||||
}
|
||||
if (codec & BTA_AG_CODEC_CVSD) {
|
||||
return ESP_HF_CODEC_CVSD;
|
||||
}
|
||||
return ESP_HF_CODEC_NONE;
|
||||
}
|
||||
|
||||
static tBTA_AG_PEER_CODEC btc_hf_esp_codec_to_bta(esp_hf_codec_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case ESP_HF_CODEC_CVSD:
|
||||
return BTA_AG_CODEC_CVSD;
|
||||
case ESP_HF_CODEC_MSBC:
|
||||
return BTA_AG_CODEC_MSBC;
|
||||
case ESP_HF_CODEC_LC3:
|
||||
return BTA_AG_CODEC_LC3;
|
||||
case ESP_HF_CODEC_NONE:
|
||||
default:
|
||||
return BTA_AG_CODEC_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static int btc_hf_latest_connected_idx(void)
|
||||
{
|
||||
struct timespec now, conn_time_delta;
|
||||
@@ -265,7 +297,8 @@ static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *param)
|
||||
else if (BTA_AG_CONN_EVT == event) {
|
||||
param_len = sizeof(tBTA_AG_CONN);
|
||||
}
|
||||
else if ((BTA_AG_AUDIO_OPEN_EVT == event) || (BTA_AG_AUDIO_CLOSE_EVT == event) || (BTA_AG_AUDIO_MSBC_OPEN_EVT == event)) {
|
||||
else if ((BTA_AG_AUDIO_OPEN_EVT == event) || (BTA_AG_AUDIO_CLOSE_EVT == event) ||
|
||||
(BTA_AG_AUDIO_MSBC_OPEN_EVT == event) || (BTA_AG_AUDIO_LC3_OPEN_EVT == event)) {
|
||||
param_len = sizeof(tBTA_AG_AUDIO_STAT);
|
||||
}
|
||||
else if (param) {
|
||||
@@ -465,6 +498,22 @@ bt_status_t btc_hf_disconnect(bt_bdaddr_t *bd_addr)
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
|
||||
bt_status_t btc_hf_set_codec(bt_bdaddr_t *bd_addr, esp_hf_codec_mode_t mode)
|
||||
{
|
||||
int idx = btc_hf_idx_by_bdaddr(bd_addr);
|
||||
if ((idx < 0) || (idx >= BTC_HF_NUM_CB) || !hf_local_param.initialized) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
/* AT+BAC may arrive before SLC_CONNECTED; allow CONNECTED or SLC_CONNECTED */
|
||||
if (!is_connected(idx, bd_addr)) {
|
||||
BTIF_TRACE_WARNING("%s: HF AG not connected", __FUNCTION__);
|
||||
return BT_STATUS_NOT_READY;
|
||||
}
|
||||
|
||||
BTA_AgSetCodec(hf_local_param.btc_hf_cb[idx].handle, btc_hf_esp_codec_to_bta(mode));
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bt_status_t btc_hf_connect_audio(bt_bdaddr_t *bd_addr)
|
||||
{
|
||||
int idx = btc_hf_idx_by_bdaddr(bd_addr);
|
||||
@@ -1299,6 +1348,12 @@ void btc_hf_call_handler(btc_msg_t *msg)
|
||||
break;
|
||||
}
|
||||
|
||||
case BTC_HF_SET_CODEC_EVT:
|
||||
{
|
||||
btc_hf_set_codec(&arg->set_codec.remote_addr, arg->set_codec.mode);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BTC_TRACE_WARNING("%s : unhandled event: %d\n", __FUNCTION__, msg->act);
|
||||
}
|
||||
@@ -1454,6 +1509,20 @@ void btc_hf_cb_handler(btc_msg_t *msg)
|
||||
} while (0);
|
||||
break;
|
||||
}
|
||||
case BTA_AG_AUDIO_LC3_OPEN_EVT:
|
||||
{
|
||||
idx = p_data->hdr.handle - 1;
|
||||
CHECK_HF_IDX(idx);
|
||||
do {
|
||||
param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTED_LC3;
|
||||
memcpy(param.audio_stat.remote_addr, &hf_local_param.btc_hf_cb[idx].connected_bda,sizeof(esp_bd_addr_t));
|
||||
hf_local_param.btc_hf_cb[idx].sync_conn_hdl = p_data->hdr.sync_conn_handle;
|
||||
param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
|
||||
param.audio_stat.preferred_frame_size = p_data->audio_stat.preferred_frame_size;
|
||||
btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m);
|
||||
} while (0);
|
||||
break;
|
||||
}
|
||||
case BTA_AG_AUDIO_CLOSE_EVT:
|
||||
{
|
||||
idx = p_data->hdr.handle - 1;
|
||||
@@ -1641,18 +1710,24 @@ void btc_hf_cb_handler(btc_msg_t *msg)
|
||||
CHECK_HF_IDX(idx);
|
||||
BTC_TRACE_DEBUG("AG Bitmap of peer-codecs %d", p_data->val.num);
|
||||
#if (BTM_WBS_INCLUDED == TRUE)
|
||||
/* If the peer supports mSBC and the BTC preferred codec is also mSBC, then
|
||||
** we should set the BTA AG Codec to mSBC. This would trigger a +BCS to mSBC at the time
|
||||
** of SCO connection establishment */
|
||||
/* Default stack preference; application may override in ESP_HF_BAC_RESPONSE_EVT */
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
if (p_data->val.num & BTA_AG_CODEC_LC3) {
|
||||
BTC_TRACE_DEBUG("%s btc_hf override-Preferred Codec to LC3", __FUNCTION__);
|
||||
BTA_AgSetCodec(hf_local_param.btc_hf_cb[idx].handle, BTA_AG_CODEC_LC3);
|
||||
} else
|
||||
#endif
|
||||
if ((btc_conf_hf_force_wbs == TRUE) && (p_data->val.num & BTA_AG_CODEC_MSBC)) {
|
||||
BTC_TRACE_DEBUG("%s btc_hf override-Preferred Codec to MSBC", __FUNCTION__);
|
||||
BTA_AgSetCodec(hf_local_param.btc_hf_cb[idx].handle,BTA_AG_CODEC_MSBC);
|
||||
}
|
||||
else {
|
||||
BTA_AgSetCodec(hf_local_param.btc_hf_cb[idx].handle, BTA_AG_CODEC_MSBC);
|
||||
} else {
|
||||
BTC_TRACE_DEBUG("%s btc_hf override-Preferred Codec to CVSD", __FUNCTION__);
|
||||
BTA_AgSetCodec(hf_local_param.btc_hf_cb[idx].handle,BTA_AG_CODEC_CVSD);
|
||||
BTA_AgSetCodec(hf_local_param.btc_hf_cb[idx].handle, BTA_AG_CODEC_CVSD);
|
||||
}
|
||||
#endif
|
||||
memcpy(param.bac_rep.remote_addr, &hf_local_param.btc_hf_cb[idx].connected_bda, sizeof(esp_bd_addr_t));
|
||||
param.bac_rep.peer_codecs = p_data->val.num;
|
||||
btc_hf_cb_to_app(ESP_HF_BAC_RESPONSE_EVT, ¶m);
|
||||
break;
|
||||
}
|
||||
#if (BTM_WBS_INCLUDED == TRUE)
|
||||
@@ -1661,9 +1736,11 @@ void btc_hf_cb_handler(btc_msg_t *msg)
|
||||
idx = p_data->hdr.handle - 1;
|
||||
CHECK_HF_IDX(idx);
|
||||
do {
|
||||
BTC_TRACE_DEBUG("Set codec status %d codec %d 1=CVSD 2=MSBC", p_data->val.hdr.status, p_data->val.num);
|
||||
memcpy(param.wbs_rep.remote_addr, &hf_local_param.btc_hf_cb[idx].connected_bda,sizeof(esp_bd_addr_t));
|
||||
param.wbs_rep.codec = p_data->val.num;
|
||||
BTC_TRACE_DEBUG("Set codec status %d codec %d", p_data->val.hdr.status, p_data->val.num);
|
||||
memcpy(param.wbs_rep.remote_addr, &hf_local_param.btc_hf_cb[idx].connected_bda, sizeof(esp_bd_addr_t));
|
||||
param.wbs_rep.status = (p_data->val.hdr.status == BTA_AG_SUCCESS) ?
|
||||
ESP_BT_STATUS_SUCCESS : ESP_BT_STATUS_FAIL;
|
||||
param.wbs_rep.codec = btc_hf_bta_codec_to_esp(p_data->val.num);
|
||||
btc_hf_cb_to_app(ESP_HF_WBS_RESPONSE_EVT, ¶m);
|
||||
} while (0);
|
||||
break;
|
||||
@@ -1674,10 +1751,9 @@ void btc_hf_cb_handler(btc_msg_t *msg)
|
||||
idx = p_data->hdr.handle - 1;
|
||||
CHECK_HF_IDX(idx);
|
||||
do {
|
||||
BTC_TRACE_DEBUG("AG final seleded codec is %d 1=CVSD 2=MSBC", p_data->val.num);
|
||||
memcpy(param.bcs_rep.remote_addr, &hf_local_param.btc_hf_cb[idx].connected_bda,sizeof(esp_bd_addr_t));
|
||||
param.bcs_rep.mode = p_data->val.num;
|
||||
/* No ESP_HF_WBS_NONE case, because HFP 1.6 supported device can send BCS */
|
||||
BTC_TRACE_DEBUG("AG final selected codec is %d", p_data->val.num);
|
||||
memcpy(param.bcs_rep.remote_addr, &hf_local_param.btc_hf_cb[idx].connected_bda, sizeof(esp_bd_addr_t));
|
||||
param.bcs_rep.mode = btc_hf_bta_codec_to_esp(p_data->val.num);
|
||||
btc_hf_cb_to_app(ESP_HF_BCS_RESPONSE_EVT, ¶m);
|
||||
} while (0);
|
||||
break;
|
||||
|
||||
@@ -433,7 +433,7 @@ static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN
|
||||
*length = (UINT8)frame_len;
|
||||
}
|
||||
|
||||
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
|
||||
// PLC_INCLUDED will be set to TRUE when enabling Wideband Speech
|
||||
#if (PLC_INCLUDED == TRUE)
|
||||
switch(status){
|
||||
case OI_OK:
|
||||
@@ -534,18 +534,21 @@ void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
|
||||
}
|
||||
p_new_buf->offset = 0;
|
||||
UINT8 *p_data = (UINT8 *)(p_new_buf + 1) + p_new_buf->offset;
|
||||
UINT16 data_len = BTM_MSBC_FRAME_SIZE;
|
||||
memcpy(p_data, bta_hf_client_co_cb.rx_half_msbc_data, BTM_MSBC_FRAME_SIZE / 2);
|
||||
memcpy(p_data + BTM_MSBC_FRAME_SIZE / 2, p, pkt_size);
|
||||
osi_free(p_buf);
|
||||
if (BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p_data)) {
|
||||
/* H2 header sync word found, skip */
|
||||
p_data += 2;
|
||||
data_len -= 2;
|
||||
}
|
||||
else if (!bta_hf_client_co_cb.is_bad_frame){
|
||||
/* not a bad frame, assume as H1 header */
|
||||
p_data += 1;
|
||||
data_len -= 1;
|
||||
}
|
||||
btc_hf_client_audio_data_cb_to_app((uint8_t *)p_new_buf, (uint8_t *)p_data, BTM_MSBC_FRAME_SIZE, bta_hf_client_co_cb.is_bad_frame);
|
||||
btc_hf_client_audio_data_cb_to_app((uint8_t *)p_new_buf, (uint8_t *)p_data, data_len, bta_hf_client_co_cb.is_bad_frame);
|
||||
bta_hf_client_co_cb.is_bad_frame = false;
|
||||
memset(bta_hf_client_co_cb.rx_half_msbc_data, 0, BTM_MSBC_FRAME_SIZE / 2);
|
||||
}
|
||||
@@ -555,15 +558,18 @@ void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
|
||||
if (pkt_size > BTM_MSBC_FRAME_SIZE) {
|
||||
pkt_size = BTM_MSBC_FRAME_SIZE;
|
||||
}
|
||||
UINT16 data_len = pkt_size;
|
||||
if (BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p)) {
|
||||
/* H2 header sync word found, skip */
|
||||
p += 2;
|
||||
data_len -= 2;
|
||||
}
|
||||
else if (!bta_hf_client_co_cb.is_bad_frame){
|
||||
/* not a bad frame, assume as H1 header */
|
||||
p += 1;
|
||||
data_len -= 1;
|
||||
}
|
||||
btc_hf_client_audio_data_cb_to_app((uint8_t *)p_buf, (uint8_t *)p, pkt_size, bta_hf_client_co_cb.is_bad_frame);
|
||||
btc_hf_client_audio_data_cb_to_app((uint8_t *)p_buf, (uint8_t *)p, data_len, bta_hf_client_co_cb.is_bad_frame);
|
||||
bta_hf_client_co_cb.is_bad_frame = false;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -78,7 +78,12 @@ void bta_hf_client_bqb_esco_s4_ctrl(BOOLEAN enable)
|
||||
/************************************************************************************
|
||||
** Static variables
|
||||
************************************************************************************/
|
||||
const int btc_hf_client_version = HFP_HF_VERSION_1_7;
|
||||
const int btc_hf_client_version =
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
HFP_HF_VERSION_1_9;
|
||||
#else
|
||||
HFP_HF_VERSION_1_7;
|
||||
#endif
|
||||
|
||||
#if HFP_DYNAMIC_MEMORY == FALSE
|
||||
static hf_client_local_param_t hf_client_local_param;
|
||||
@@ -796,6 +801,9 @@ bt_status_t btc_hf_client_execute_service(BOOLEAN b_enable)
|
||||
/* Enable and register with BTA-HFClient */
|
||||
BTA_HfClientEnable(bte_hf_client_evt);
|
||||
hf_client_local_param.btc_hf_client_features = BTC_HF_CLIENT_FEATURES;
|
||||
#if UC_BT_HFP_LC3_ENABLE
|
||||
hf_client_local_param.btc_hf_client_features |= BTA_HF_CLIENT_FEAT_SWB;
|
||||
#endif
|
||||
if (btc_hf_client_version >= HFP_HF_VERSION_1_7)
|
||||
{
|
||||
hf_client_local_param.btc_hf_client_features |= BTA_HF_CLIENT_FEAT_ESCO_S4;
|
||||
@@ -1114,6 +1122,17 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
|
||||
btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m);
|
||||
} while (0);
|
||||
break;
|
||||
case BTA_HF_CLIENT_AUDIO_LC3_OPEN_EVT:
|
||||
do {
|
||||
param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_LC3;
|
||||
memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda,
|
||||
sizeof(esp_bd_addr_t));
|
||||
hf_client_local_param.btc_hf_client_cb.sync_conn_hdl = p_data->hdr.sync_conn_handle;
|
||||
param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
|
||||
param.audio_stat.preferred_frame_size = p_data->audio_stat.preferred_frame_size;
|
||||
btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m);
|
||||
} while (0);
|
||||
break;
|
||||
case BTA_HF_CLIENT_AUDIO_CLOSE_EVT:
|
||||
do {
|
||||
param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_DISCONNECTED;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -57,7 +57,8 @@ typedef enum
|
||||
//REG
|
||||
BTC_HF_REGISTER_DATA_CALLBACK_EVT,
|
||||
BTC_HF_REGISTER_AUDIO_DATA_CALLBACK_EVT,
|
||||
BTC_HF_REQUEST_PKT_STAT_EVT
|
||||
BTC_HF_REQUEST_PKT_STAT_EVT,
|
||||
BTC_HF_SET_CODEC_EVT
|
||||
} btc_hf_act_t;
|
||||
|
||||
/* btc_hf_args_t */
|
||||
@@ -190,6 +191,12 @@ typedef union
|
||||
UINT16 sync_conn_handle;
|
||||
} pkt_sync_hd;
|
||||
|
||||
// BTC_HF_SET_CODEC_EVT
|
||||
struct ag_set_codec_param {
|
||||
bt_bdaddr_t remote_addr;
|
||||
esp_hf_codec_mode_t mode;
|
||||
} set_codec;
|
||||
|
||||
} btc_hf_args_t;
|
||||
|
||||
/************************************************************************************
|
||||
|
||||
@@ -805,13 +805,20 @@
|
||||
#define UC_BT_HFP_AUDIO_DATA_PATH_HCI FALSE
|
||||
#endif
|
||||
|
||||
//Wide Band Speech
|
||||
//Wideband Speech
|
||||
#ifdef CONFIG_BT_HFP_WBS_ENABLE
|
||||
#define UC_BT_HFP_WBS_ENABLE CONFIG_BT_HFP_WBS_ENABLE
|
||||
#else
|
||||
#define UC_BT_HFP_WBS_ENABLE FALSE
|
||||
#endif
|
||||
|
||||
//Super Wideband Speech (LC3-SWB)
|
||||
#ifdef CONFIG_BT_HFP_LC3_ENABLE
|
||||
#define UC_BT_HFP_LC3_ENABLE CONFIG_BT_HFP_LC3_ENABLE
|
||||
#else
|
||||
#define UC_BT_HFP_LC3_ENABLE FALSE
|
||||
#endif
|
||||
|
||||
/**********************************************************
|
||||
* Memory reference
|
||||
**********************************************************/
|
||||
|
||||
@@ -1221,6 +1221,20 @@
|
||||
#define BTM_MSBC_FRAME_DATA_SIZE 57
|
||||
#endif
|
||||
|
||||
/* LC3-SWB eSCO air frame (H2 + payload); same 60-byte eSCO packet as mSBC */
|
||||
#ifndef BTM_LC3_FRAME_SIZE
|
||||
#define BTM_LC3_FRAME_SIZE 60
|
||||
#endif
|
||||
|
||||
#ifndef BTM_LC3_FRAME_DATA_SIZE
|
||||
#define BTM_LC3_FRAME_DATA_SIZE 58
|
||||
#endif
|
||||
|
||||
/* Transparent wideband air frame size (mSBC and LC3-SWB) */
|
||||
#ifndef BTM_HFP_TRANSPARENT_FRAME_SIZE
|
||||
#define BTM_HFP_TRANSPARENT_FRAME_SIZE BTM_MSBC_FRAME_SIZE
|
||||
#endif
|
||||
|
||||
/* The size in bytes of the BTM inquiry database. 5 As Default */
|
||||
#ifndef BTM_INQ_DB_SIZE
|
||||
#define BTM_INQ_DB_SIZE 5
|
||||
|
||||
@@ -1116,6 +1116,7 @@ typedef UINT8 tBTM_SCO_ROUTE_TYPE;
|
||||
#define BTM_SCO_CODEC_NONE 0x0000
|
||||
#define BTM_SCO_CODEC_CVSD 0x0001
|
||||
#define BTM_SCO_CODEC_MSBC 0x0002
|
||||
#define BTM_SCO_CODEC_LC3 0x0004
|
||||
typedef UINT16 tBTM_SCO_CODEC_TYPE;
|
||||
|
||||
|
||||
|
||||
@@ -279,6 +279,7 @@
|
||||
#if (BTM_WBS_INCLUDED == TRUE)
|
||||
#define UUID_CODEC_CVSD 0x0001 /* CVSD */
|
||||
#define UUID_CODEC_MSBC 0x0002 /* mSBC */
|
||||
#define UUID_CODEC_LC3 0x0003 /* LC3-SWB */
|
||||
#endif
|
||||
|
||||
/* Define all the 'Descriptor Type' values.
|
||||
@@ -308,7 +309,7 @@
|
||||
#define LANG_ID_CODE_ENGLISH ((UINT16) 0x656e) /* "en" */
|
||||
#define LANG_ID_CHAR_ENCODE_UTF8 ((UINT16) 0x006a) /* UTF-8 */
|
||||
|
||||
/* Constants used for display purposes only. These define ovelapping attribute values */
|
||||
/* Constants used for display purposes only. These define overlapping attribute values */
|
||||
#define ATTR_ID_VERS_OR_GRP_OR_DRELNUM_OR_IPSUB_OR_SPECID 0x0200
|
||||
#define ATTR_ID_VEND_ID_OR_SERVICE_DB_STATE_OR_PARSE_VER 0x0201
|
||||
#define ATTR_ID_PROD_ID_OR_HID_DEV_SUBCLASS 0x0202
|
||||
|
||||
Reference in New Issue
Block a user