hfp: add hfp_hf_create_sdp_record_with_codecs and hfp_hf_create_sdp_record_with_codecs

This commit is contained in:
Matthias Ringwald 2023-10-10 11:44:49 +02:00
parent 2eb5c29059
commit aa10b9cbee
5 changed files with 149 additions and 65 deletions

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- L2CAP: additional authorization_required param in l2cap_ecbm_register_service
- GATT Client: support GATT over Enhanced LE Bearer
- GATT Server: support GATT over Enhanced LE Bearer
- HFP: hfp_hf_create_sdp_record_with_codecs and hfp_hf_create_sdp_record_with_codecs
- HOG Device: emit HIDS_SUBEVENT_SET_REPORT
- HOG Device: provide report for GET REPORT operation via callback
- LE Device DB: le_device_db_dump dumps LTK

View File

@ -2613,13 +2613,11 @@ static void hfp_ag_hci_event_packet_handler(uint8_t packet_type, uint16_t channe
hfp_ag_run();
}
void hfp_ag_init_codecs(int codecs_nr, const uint8_t * codecs){
if (codecs_nr > HFP_MAX_NUM_CODECS){
log_error("hfp_init: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS);
return;
}
int i;
void hfp_ag_init_codecs(uint8_t codecs_nr, const uint8_t * codecs){
btstack_assert(codecs_nr <= HFP_MAX_NUM_CODECS);
hfp_ag_codecs_nr = codecs_nr;
uint8_t i;
for (i=0; i < codecs_nr; i++){
hfp_ag_codecs[i] = codecs[i];
}
@ -3220,42 +3218,71 @@ uint8_t hfp_ag_notify_incoming_call_waiting(hci_con_handle_t acl_handle){
hfp_ag_run_for_context(hfp_connection);
return ERROR_CODE_SUCCESS;
}
void hfp_ag_create_sdp_record_with_codecs(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr,
const char * name, uint8_t ability_to_reject_call, uint16_t supported_features,
uint8_t codecs_nr, const uint8_t * codecs){
if (!name){
name = hfp_ag_default_service_name;
}
hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, rfcomm_channel_nr, name);
void hfp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features, int wide_band_speech){
if (!name){
name = hfp_ag_default_service_name;
}
hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, rfcomm_channel_nr, name);
/*
* 0x01 Ability to reject a call
* 0x00 No ability to reject a call
*/
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0301); // Hands-Free Profile - Network
de_add_number(service, DE_UINT, DE_SIZE_8, ability_to_reject_call);
/*
* 0x01 Ability to reject a call
* 0x00 No ability to reject a call
*/
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0301); // Hands-Free Profile - Network
de_add_number(service, DE_UINT, DE_SIZE_8, ability_to_reject_call);
// Construct SupportedFeatures for SDP bitmap:
//
// "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values
// of the Bits 0 to 4 of the unsolicited result code +BRSF"
//
// Wide band speech (bit 5) requires Codec negotiation
//
uint16_t sdp_features = supported_features & 0x1f;
if ( (wide_band_speech == 1) && (supported_features & (1 << HFP_AGSF_CODEC_NEGOTIATION))){
sdp_features |= 1 << 5;
}
// Construct SupportedFeatures for SDP bitmap:
//
// "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values
// of the Bits 0 to 4 of the unsolicited result code +BRSF"
//
// Wide band speech (bit 5) and LC3-SWB (bit 8) require Codec negotiation
//
uint16_t sdp_features = supported_features & 0x1f;
if (supported_features & (1 << HFP_AGSF_ENHANCED_VOICE_RECOGNITION_STATUS)){
sdp_features |= 1 << 6;
}
if (supported_features & (1 << HFP_AGSF_VOICE_RECOGNITION_TEXT)){
sdp_features |= 1 << 7;
}
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
// codecs
if ((supported_features & (1 << HFP_HFSF_CODEC_NEGOTIATION)) != 0){
uint8_t i;
for (i=0;i<codecs_nr;i++){
switch (codecs[i]){
case HFP_CODEC_MSBC:
sdp_features |= 1 << 5;
break;
case HFP_CODEC_LC3_SWB:
sdp_features |= 1 << 8;
break;
}
}
}
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
}
void hfp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name,
uint8_t ability_to_reject_call, uint16_t supported_features, int wide_band_speech){
uint8_t codecs_nr;
const uint8_t * codecs;
const uint8_t wide_band_codecs[] = { HFP_CODEC_MSBC };
if (wide_band_speech == 0){
codecs_nr = 0;
codecs = NULL;
} else {
codecs_nr = 1;
codecs = wide_band_codecs;
}
hfp_ag_create_sdp_record_with_codecs(service, service_record_handle, rfcomm_channel_nr, name,
ability_to_reject_call, supported_features, codecs_nr, codecs);
}
void hfp_ag_register_packet_handler(btstack_packet_handler_t callback){

View File

@ -64,10 +64,13 @@ typedef struct {
* @param rfcomm_channel_nr
* @param name
* @param ability_to_reject_call
* @param suported_features 32-bit bitmap, see HFP_AGSF_* values in hfp.h
* @param wide_band_speech supported
* @param supported_features 32-bit bitmap, see HFP_AGSF_* values in hfp.h
* @param codecs_nr
* @param codecs
*/
void hfp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features, int wide_band_speech);
void hfp_ag_create_sdp_record_with_codecs(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr,
const char * name, uint8_t ability_to_reject_call, uint16_t supported_features,
uint8_t codecs_nr, const uint8_t * codecs);
/**
* @brief Set up HFP Audio Gateway (AG) device without additional supported features.
@ -80,7 +83,7 @@ void hfp_ag_init(uint8_t rfcomm_channel_nr);
* @param codecs_nr
* @param codecs
*/
void hfp_ag_init_codecs(int codecs_nr, const uint8_t * codecs);
void hfp_ag_init_codecs(uint8_t codecs_nr, const uint8_t * codecs);
/**
* @brief Set supported features.
@ -506,6 +509,18 @@ uint8_t hfp_ag_send_command_result_code(hci_con_handle_t acl_handle, bool ok);
*/
void hfp_ag_deinit(void);
/**
* @brief Create HFP Audio Gateway (AG) SDP service record.
* @deprecated Use hfp_ag_create_sdp_record_with_codecs instead
* @param service
* @param rfcomm_channel_nr
* @param name
* @param ability_to_reject_call
* @param suported_features 32-bit bitmap, see HFP_AGSF_* values in hfp.h
* @param wide_band_speech supported
*/
void hfp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features, int wide_band_speech);
/* API_END */
// testing

View File

@ -1566,11 +1566,11 @@ void hfp_hf_deinit(void){
(void) memset(hfp_hf_phone_number, 0, sizeof(hfp_hf_phone_number));
}
void hfp_hf_init_codecs(int codecs_nr, const uint8_t * codecs){
void hfp_hf_init_codecs(uint8_t codecs_nr, const uint8_t * codecs){
btstack_assert(codecs_nr <= HFP_MAX_NUM_CODECS);
hfp_hf_codecs_nr = codecs_nr;
int i;
uint8_t i;
for (i=0; i<codecs_nr; i++){
hfp_hf_codecs[i] = codecs[i];
}
@ -2269,34 +2269,62 @@ int hfp_hf_in_band_ringtone_active(hci_con_handle_t acl_handle){
return get_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE);
}
void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features, int wide_band_speech){
if (!name){
name = hfp_hf_default_service_name;
}
hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE, rfcomm_channel_nr, name);
void hfp_hf_create_sdp_record_with_codecs(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr,
const char * name, uint16_t supported_features, uint8_t codecs_nr, const uint8_t * codecs){
if (!name){
name = hfp_hf_default_service_name;
}
hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE, rfcomm_channel_nr, name);
// Construct SupportedFeatures for SDP bitmap:
//
// "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values
// of the Bits 0 to 4 of the unsolicited result code +BRSF"
//
// Wide band speech (bit 5) and LC3-SWB (bit 8) require Codec negotiation
//
uint16_t sdp_features = supported_features & 0x1f;
// Construct SupportedFeatures for SDP bitmap:
//
// "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values
// of the Bits 0 to 4 of the unsolicited result code +BRSF"
//
// Wide band speech (bit 5) requires Codec negotiation
//
uint16_t sdp_features = supported_features & 0x1f;
if ( (wide_band_speech != 0) && (supported_features & (1 << HFP_HFSF_CODEC_NEGOTIATION))){
sdp_features |= 1 << 5;
}
if (supported_features & (1 << HFP_HFSF_ENHANCED_VOICE_RECOGNITION_STATUS)){
sdp_features |= 1 << 6;
}
if (supported_features & (1 << HFP_HFSF_VOICE_RECOGNITION_TEXT)){
sdp_features |= 1 << 7;
}
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
// codecs
if ((supported_features & (1 << HFP_HFSF_CODEC_NEGOTIATION)) != 0){
uint8_t i;
for (i=0;i<codecs_nr;i++){
switch (codecs[i]){
case HFP_CODEC_MSBC:
sdp_features |= 1 << 5;
break;
case HFP_CODEC_LC3_SWB:
sdp_features |= 1 << 8;
break;
}
}
}
de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SUPPORTED_FEATURES);
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
}
// @deprecated, call new API
void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features, int wide_band_speech){
uint8_t codecs_nr;
const uint8_t * codecs;
const uint8_t wide_band_codecs[] = { HFP_CODEC_MSBC };
if (wide_band_speech == 0){
codecs_nr = 0;
codecs = NULL;
} else {
codecs_nr = 1;
codecs = wide_band_codecs;
}
hfp_hf_create_sdp_record_with_codecs(service, service_record_handle, rfcomm_channel_nr, name, supported_features, codecs_nr, codecs);
}
void hfp_hf_register_custom_at_command(hfp_custom_at_command_t * custom_at_command){

View File

@ -54,14 +54,16 @@ extern "C" {
/* API_START */
/**
* @brief Create HFP Hands-Free (HF) SDP service record.
* @brief Create HFP Hands-Free (HF) SDP service record.
* @param service
* @param rfcomm_channel_nr
* @param name
* @param suported_features 32-bit bitmap, see HFP_HFSF_* values in hfp.h
* @param wide_band_speech supported
* @param codecs_nr number of codecs in codecs argument
* @param codecs
*/
void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features, int wide_band_speech);
void hfp_hf_create_sdp_record_with_codecs(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr,
const char * name, uint16_t supported_features, uint8_t codecs_nr, const uint8_t * codecs);
/**
* @brief Set up HFP Hands-Free (HF) device without additional supported features.
@ -75,10 +77,10 @@ uint8_t hfp_hf_init(uint8_t rfcomm_channel_nr);
/**
* @brief Set codecs.
* @param codecs_nr
* @param codecs_nr number of codecs in codecs argument
* @param codecs
*/
void hfp_hf_init_codecs(int codecs_nr, const uint8_t * codecs);
void hfp_hf_init_codecs(uint8_t codecs_nr, const uint8_t * codecs);
/**
* @brief Set supported features.
@ -570,6 +572,17 @@ void hfp_hf_register_custom_at_command(hfp_custom_at_command_t * custom_at_comma
*/
void hfp_hf_deinit(void);
/**
* @brief Create HFP Hands-Free (HF) SDP service record.
* @deprecated Use hfp_hf_create_sdp_record_with_codecs instead
* @param service
* @param rfcomm_channel_nr
* @param name
* @param suported_features 32-bit bitmap, see HFP_HFSF_* values in hfp.h
* @param wide_band_speech supported
*/
void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features, int wide_band_speech);
/* API_END */
#if defined __cplusplus