mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-15 12:39:51 +00:00
hfp: support CC256x assisted hfp
This commit is contained in:
parent
49ed206d42
commit
3721a23546
@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
|
||||
---
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
CC256x: With ENABLE_CC256X_ASSISTED_HFP, HFP enables WBS codec on demand and configures PCM/I2S interface for 8kH/16kHz
|
||||
|
||||
## Release v1.2.1
|
||||
|
||||
### Fixed
|
||||
|
@ -81,6 +81,7 @@ ENABLE_LOG_DEBUG | Enable log_debug messages
|
||||
ENABLE_LOG_ERROR | Enable log_error messages
|
||||
ENABLE_LOG_INFO | Enable log_info messages
|
||||
ENABLE_SCO_OVER_HCI | Enable SCO over HCI for chipsets (if supported)
|
||||
ENABLE_SCO_OVER_PCM | Enable SCO ofer PCM/I2S for chipsets (if supported)
|
||||
ENABLE_HFP_WIDE_BAND_SPEECH | Enable support for mSBC codec used in HFP profile for Wide-Band Speech
|
||||
ENBALE_LE_PERIPHERAL | Enable support for LE Peripheral Role in HCI and Security Manager
|
||||
ENBALE_LE_CENTRAL | Enable support for LE Central Role in HCI and Security Manager
|
||||
@ -96,6 +97,7 @@ ENABLE_CROSS_TRANSPORT_KEY_DERIVATION | Enable Cross-Transport Key Derivation (C
|
||||
ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE | Enable L2CAP Enhanced Retransmission Mode. Mandatory for AVRCP Browsing
|
||||
ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL | Enable HCI Controller to Host Flow Control, see below
|
||||
ENABLE_ATT_DELAYED_RESPONSE | Enable support for delayed ATT operations, see [GATT Server](profiles/#sec:GATTServerProfile)
|
||||
ENABLE_CC256X_ASSISTED_HFP | Enable support for Assisted HFP mode in CC256x Controller, requires ENABLE_SCO_OVER_PCM
|
||||
ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND | Enable workaround for bug in CC256x Flow Control during baud rate change, see chipset docs.
|
||||
ENABLE_CYPRESS_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND | Enable workaround for bug in CYW2070x Flow Control during baud rate change, similar to CC256x.
|
||||
ENABLE_LE_LIMIT_ACL_FRAGMENT_BY_MAX_OCTETS | Force HCI to fragment ACL-LE packets to fit into over-the-air packet
|
||||
|
@ -59,6 +59,10 @@
|
||||
#include "hci_dump.h"
|
||||
#include "l2cap.h"
|
||||
|
||||
#if defined(ENABLE_CC256X_ASSISTED_HFP) && !defined(ENABLE_SCO_OVER_PCM)
|
||||
#error "Assisted HFP is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM"
|
||||
#endif
|
||||
|
||||
#define HFP_HF_FEATURES_SIZE 10
|
||||
#define HFP_AG_FEATURES_SIZE 12
|
||||
|
||||
@ -690,6 +694,9 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
} else {
|
||||
hfp_connection->hf_accept_sco = 1;
|
||||
}
|
||||
#ifdef ENABLE_CC256X_ASSISTED_HFP
|
||||
hfp_cc256x_prepare_for_sco(hfp_connection);
|
||||
#endif
|
||||
log_info("hf accept sco %u\n", hfp_connection->hf_accept_sco);
|
||||
sco_establishment_active = hfp_connection;
|
||||
break;
|
||||
@ -778,6 +785,10 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
|
||||
if (!hfp_connection) break;
|
||||
|
||||
#ifdef ENABLE_CC256X_ASSISTED_HFP
|
||||
hfp_connection->cc256x_send_wbs_disassociate = true;
|
||||
#endif
|
||||
|
||||
hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID;
|
||||
hfp_connection->release_audio_connection = 0;
|
||||
hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
|
||||
@ -795,6 +806,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){
|
||||
UNUSED(packet_type);
|
||||
UNUSED(channel); // ok: no channel
|
||||
@ -1598,6 +1610,41 @@ void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){
|
||||
sco_voice_setting, hfp_link_settings[setting].retransmission_effort, packet_types);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CC256X_ASSISTED_HFP
|
||||
void hfp_cc256x_prepare_for_sco(hfp_connection_t * hfp_connection){
|
||||
hfp_connection->cc256x_send_write_codec_config = true;
|
||||
if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
|
||||
hfp_connection->cc256x_send_wbs_associate = true;
|
||||
}
|
||||
}
|
||||
|
||||
void hfp_cc256x_write_codec_config(hfp_connection_t * hfp_connection){
|
||||
uint32_t sample_rate_hz;
|
||||
uint16_t clock_rate_khz;
|
||||
if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
|
||||
clock_rate_khz = 512;
|
||||
sample_rate_hz = 16000;
|
||||
} else {
|
||||
clock_rate_khz = 256;
|
||||
sample_rate_hz = 8000;
|
||||
}
|
||||
uint8_t clock_direction = 0; // master
|
||||
uint16_t frame_sync_duty_cycle = 0; // i2s with 50%
|
||||
uint8_t frame_sync_edge = 1; // rising edge
|
||||
uint8_t frame_sync_polarity = 0; // active high
|
||||
uint8_t reserved = 0;
|
||||
uint16_t size = 16;
|
||||
uint16_t chan_1_offset = 1;
|
||||
uint16_t chan_2_offset = chan_1_offset + size;
|
||||
uint8_t out_edge = 1; // rising
|
||||
uint8_t in_edge = 0; // falling
|
||||
hci_send_cmd(&hci_ti_write_codec_config, clock_rate_khz, clock_direction, sample_rate_hz, frame_sync_duty_cycle,
|
||||
frame_sync_edge, frame_sync_polarity, reserved,
|
||||
size, chan_1_offset, out_edge, size, chan_1_offset, in_edge, reserved,
|
||||
size, chan_2_offset, out_edge, size, chan_2_offset, in_edge, reserved);
|
||||
}
|
||||
#endif
|
||||
|
||||
void hfp_set_hf_callback(btstack_packet_handler_t callback){
|
||||
hfp_hf_callback = callback;
|
||||
}
|
||||
|
@ -643,6 +643,12 @@ typedef struct hfp_connection {
|
||||
uint8_t bnip_type; // 0 == not set
|
||||
char bnip_number[25]; //
|
||||
|
||||
#ifdef ENABLE_CC256X_ASSISTED_HFP
|
||||
bool cc256x_send_write_codec_config;
|
||||
bool cc256x_send_wbs_associate;
|
||||
bool cc256x_send_wbs_disassociate;
|
||||
#endif
|
||||
|
||||
} hfp_connection_t;
|
||||
|
||||
// UTILS_START : TODO move to utils
|
||||
@ -701,6 +707,11 @@ const char * hfp_enhanced_call_status2str(uint16_t index);
|
||||
const char * hfp_enhanced_call_mode2str(uint16_t index);
|
||||
const char * hfp_enhanced_call_mpty2str(uint16_t index);
|
||||
|
||||
#ifdef ENABLE_CC256X_ASSISTED_HFP
|
||||
void hfp_cc256x_prepare_for_sco(hfp_connection_t * hfp_connection);
|
||||
void hfp_cc256x_write_codec_config(hfp_connection_t * hfp_connection);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set packet types for SCO connections
|
||||
* @param common single packet_types: HFP_SCO_PACKET_TYPES_*
|
||||
|
@ -555,9 +555,11 @@ static int codecs_exchange_state_machine(hfp_connection_t * hfp_connection){
|
||||
log_info("hfp: codec confirmed: %s", (hfp_connection->negotiated_codec == HFP_CODEC_MSBC) ? "mSBC" : "CVSD");
|
||||
hfp_ag_send_ok(hfp_connection->rfcomm_cid);
|
||||
// now, pick link settings
|
||||
|
||||
hfp_init_link_settings(hfp_connection, hfp_ag_esco_s4_supported(hfp_connection));
|
||||
return 1;
|
||||
#ifdef ENABLE_CC256X_ASSISTED_HFP
|
||||
hfp_cc256x_prepare_for_sco(hfp_connection);
|
||||
#endif
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1712,6 +1714,30 @@ static void hfp_ag_run_for_context(hfp_connection_t *hfp_connection){
|
||||
// during SDP query, RFCOMM CID is not set
|
||||
if (hfp_connection->rfcomm_cid == 0) return;
|
||||
|
||||
// assert command could be sent
|
||||
if (hci_can_send_command_packet_now() == 0) return;
|
||||
|
||||
#ifdef ENABLE_CC256X_ASSISTED_HFP
|
||||
// WBS Disassociate
|
||||
if (hfp_connection->cc256x_send_wbs_disassociate){
|
||||
hfp_connection->cc256x_send_wbs_disassociate = false;
|
||||
hci_send_cmd(&hci_ti_wbs_disassociate);
|
||||
return;
|
||||
}
|
||||
// Write Codec Config
|
||||
if (hfp_connection->cc256x_send_write_codec_config){
|
||||
hfp_connection->cc256x_send_write_codec_config = false;
|
||||
hfp_cc256x_write_codec_config(hfp_connection);
|
||||
return;
|
||||
}
|
||||
// WBS Associate
|
||||
if (hfp_connection->cc256x_send_wbs_associate){
|
||||
hfp_connection->cc256x_send_wbs_associate = false;
|
||||
hci_send_cmd(&hci_ti_wbs_associate, hfp_connection->acl_handle);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!rfcomm_can_send_packet_now(hfp_connection->rfcomm_cid)) {
|
||||
log_info("hfp_ag_run_for_context: request can send for 0x%02x", hfp_connection->rfcomm_cid);
|
||||
rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
|
||||
@ -2013,10 +2039,6 @@ static void hfp_ag_rfcomm_packet_handler(uint8_t packet_type, uint16_t channel,
|
||||
|
||||
static void hfp_ag_hci_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
hfp_handle_hci_event(packet_type, channel, packet, size, HFP_ROLE_AG);
|
||||
|
||||
// allow for sco established -> ring transition
|
||||
if (packet_type != HCI_EVENT_PACKET) return;
|
||||
if (hci_event_packet_get_type(packet) != HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE) return;
|
||||
hfp_ag_run();
|
||||
}
|
||||
|
||||
@ -2115,6 +2137,9 @@ static void hfp_ag_setup_audio_connection(hfp_connection_t * hfp_connection){
|
||||
hfp_connection->codecs_state = HFP_CODECS_EXCHANGED;
|
||||
// now, pick link settings
|
||||
hfp_init_link_settings(hfp_connection, hfp_ag_esco_s4_supported(hfp_connection));
|
||||
#ifdef ENABLE_CC256X_ASSISTED_HFP
|
||||
hfp_cc256x_prepare_for_sco(hfp_connection);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -544,7 +544,31 @@ static void hfp_hf_run_for_context(hfp_connection_t * hfp_connection){
|
||||
// during SDP query, RFCOMM CID is not set
|
||||
if (hfp_connection->rfcomm_cid == 0) return;
|
||||
|
||||
if (hfp_connection->hf_accept_sco && hci_can_send_command_packet_now()){
|
||||
// assert command could be sent
|
||||
if (hci_can_send_command_packet_now() == 0) return;
|
||||
|
||||
#ifdef ENABLE_CC256X_ASSISTED_HFP
|
||||
// WBS Disassociate
|
||||
if (hfp_connection->cc256x_send_wbs_disassociate){
|
||||
hfp_connection->cc256x_send_wbs_disassociate = false;
|
||||
hci_send_cmd(&hci_ti_wbs_disassociate);
|
||||
return;
|
||||
}
|
||||
// Write Codec Config
|
||||
if (hfp_connection->cc256x_send_write_codec_config){
|
||||
hfp_connection->cc256x_send_write_codec_config = false;
|
||||
hfp_cc256x_write_codec_config(hfp_connection);
|
||||
return;
|
||||
}
|
||||
// WBS Associate
|
||||
if (hfp_connection->cc256x_send_wbs_associate){
|
||||
hfp_connection->cc256x_send_wbs_associate = false;
|
||||
hci_send_cmd(&hci_ti_wbs_associate, hfp_connection->acl_handle);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (hfp_connection->hf_accept_sco){
|
||||
|
||||
bool eSCO = hfp_connection->hf_accept_sco == 2;
|
||||
hfp_connection->hf_accept_sco = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user