hfp: fix supported features of generated SDP records, add defines for missing features, drop negotiated codec from SLC and Audio connection events

This commit is contained in:
Matthias Ringwald 2016-07-26 21:34:12 +02:00
parent d76591ef8d
commit 4f84bf367b
7 changed files with 75 additions and 25 deletions

View File

@ -681,11 +681,24 @@ int btstack_main(int argc, const char * argv[]){
// L2CAP
l2cap_init();
uint16_t supported_features =
(1<<HFP_AGSF_ESCO_S4) |
(1<<HFP_AGSF_HF_INDICATORS) |
(1<<HFP_AGSF_CODEC_NEGOTIATION) |
(1<<HFP_AGSF_EXTENDED_ERROR_RESULT_CODES) |
(1<<HFP_AGSF_ENHANCED_CALL_CONTROL) |
(1<<HFP_AGSF_ENHANCED_CALL_STATUS) |
(1<<HFP_AGSF_ABILITY_TO_REJECT_A_CALL) |
(1<<HFP_AGSF_IN_BAND_RING_TONE) |
(1<<HFP_AGSF_VOICE_RECOGNITION_FUNCTION) |
(1<<HFP_AGSF_THREE_WAY_CALLING);
int wide_band_speech = 1;
// HFP
rfcomm_init();
hfp_ag_init(rfcomm_channel_nr);
hfp_ag_init_supported_features(0x3ef | (1<<HFP_AGSF_HF_INDICATORS) | (1<<HFP_AGSF_ESCO_S4));
hfp_ag_init_supported_features(supported_features);
hfp_ag_init_codecs(sizeof(codecs), codecs);
hfp_ag_init_ag_indicators(ag_indicators_nr, ag_indicators);
hfp_ag_init_hf_indicators(hf_indicators_nr, hf_indicators);
@ -697,7 +710,7 @@ int btstack_main(int argc, const char * argv[]){
// SDP Server
sdp_init();
memset(hfp_service_buffer, 0, sizeof(hfp_service_buffer));
hfp_ag_create_sdp_record( hfp_service_buffer, 0x10001, rfcomm_channel_nr, hfp_ag_service_name, 0, 0);
hfp_ag_create_sdp_record( hfp_service_buffer, 0x10001, rfcomm_channel_nr, hfp_ag_service_name, 0, supported_features, wide_band_speech);
printf("SDP service record size: %u\n", de_get_len( hfp_service_buffer));
sdp_register_service(hfp_service_buffer);

View File

@ -631,8 +631,16 @@ int btstack_main(int argc, const char * argv[]){
rfcomm_init();
sdp_init();
uint16_t hf_supported_features =
(1<<HFP_HFSF_ESCO_S4) |
(1<<HFP_HFSF_HF_INDICATORS) |
(1<<HFP_HFSF_CODEC_NEGOTIATION) |
(1<<HFP_HFSF_ENHANCED_CALL_STATUS) |
(1<<HFP_HFSF_REMOTE_VOLUME_CONTROL);
int wide_band_speech = 1;
hfp_hf_init(rfcomm_channel_nr);
hfp_hf_init_supported_features(438 | (1<<HFP_HFSF_CODEC_NEGOTIATION) |(1<<HFP_HFSF_ESCO_S4) | (1<<HFP_HFSF_EC_NR_FUNCTION));
hfp_hf_init_supported_features(hf_supported_features);
hfp_hf_init_hf_indicators(sizeof(indicators)/sizeof(uint16_t), indicators);
hfp_hf_init_codecs(sizeof(codecs), codecs);
@ -640,7 +648,7 @@ int btstack_main(int argc, const char * argv[]){
hci_register_sco_packet_handler(&packet_handler);
memset(hfp_service_buffer, 0, sizeof(hfp_service_buffer));
hfp_hf_create_sdp_record(hfp_service_buffer, 0x10001, rfcomm_channel_nr, hfp_hf_service_name, 0);
hfp_hf_create_sdp_record(hfp_service_buffer, 0x10001, rfcomm_channel_nr, hfp_hf_service_name, hf_supported_features, wide_band_speech);
printf("SDP service record size: %u\n", de_get_len(hfp_service_buffer));
sdp_register_service(hfp_service_buffer);
gap_set_class_of_device(0x200408);

View File

@ -66,12 +66,16 @@ extern "C" {
9: eSCO S4 (and T2) Settings Supported
10-31: Reserved for future definition
*/
#define HFP_HFSF_EC_NR_FUNCTION 0
#define HFP_HFSF_THREE_WAY_CALLING 1
#define HFP_HFSF_VOICE_RECOGNITION_FUNCTION 3
#define HFP_HFSF_CODEC_NEGOTIATION 7
#define HFP_HFSF_HF_INDICATORS 8
#define HFP_HFSF_ESCO_S4 9
#define HFP_HFSF_EC_NR_FUNCTION 0
#define HFP_HFSF_THREE_WAY_CALLING 1
#define HFP_HFSF_CLI_PRESENTATION_CAPABILITY 2
#define HFP_HFSF_VOICE_RECOGNITION_FUNCTION 3
#define HFP_HFSF_REMOTE_VOLUME_CONTROL 4
#define HFP_HFSF_ENHANCED_CALL_STATUS 5
#define HFP_HFSF_ENHANCED_CALL_CONTROL 6
#define HFP_HFSF_CODEC_NEGOTIATION 7
#define HFP_HFSF_HF_INDICATORS 8
#define HFP_HFSF_ESCO_S4 9
/* AG Supported Features:
0: Three-way calling
@ -88,13 +92,18 @@ extern "C" {
11: eSCO S4 (and T2) Settings Supported
12-31: Reserved for future definition
*/
#define HFP_AGSF_THREE_WAY_CALLING 0
#define HFP_AGSF_EC_NR_FUNCTION 1
#define HFP_AGSF_THREE_WAY_CALLING 0
#define HFP_AGSF_EC_NR_FUNCTION 1
#define HFP_AGSF_VOICE_RECOGNITION_FUNCTION 2
#define HFP_AGSF_IN_BAND_RING_TONE 3
#define HFP_AGSF_CODEC_NEGOTIATION 9
#define HFP_AGSF_HF_INDICATORS 10
#define HFP_AGSF_ESCO_S4 11
#define HFP_AGSF_IN_BAND_RING_TONE 3
#define HFP_AGSF_ATTACH_A_NUMBER_TO_A_VOICE_TAG 4
#define HFP_AGSF_ABILITY_TO_REJECT_A_CALL 5
#define HFP_AGSF_ENHANCED_CALL_STATUS 6
#define HFP_AGSF_ENHANCED_CALL_CONTROL 7
#define HFP_AGSF_EXTENDED_ERROR_RESULT_CODES 8
#define HFP_AGSF_CODEC_NEGOTIATION 9
#define HFP_AGSF_HF_INDICATORS 10
#define HFP_AGSF_ESCO_S4 11
#define HFP_DEFAULT_HF_SUPPORTED_FEATURES 0x0000
#define HFP_DEFAULT_AG_SUPPORTED_FEATURES 0x0009

View File

@ -180,7 +180,7 @@ static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){
return hf && ag;
}
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){
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 = default_hfp_ag_service_name;
}
@ -193,8 +193,17 @@ void hfp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle,
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"
//
uint16_t sdp_features = supported_features &0x1f;
if (supported_features & wide_band_speech){
sdp_features |= 1 << 5; // Wide band speech bit
}
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures
de_add_number(service, DE_UINT, DE_SIZE_16, supported_features);
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
}
static int hfp_ag_change_in_band_ring_tone_setting_cmd(uint16_t cid){
@ -611,7 +620,7 @@ static void hfp_init_link_settings(hfp_connection_t * hfp_connection){
static void hfp_ag_slc_established(hfp_connection_t * hfp_connection){
hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
hfp_emit_connection_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0, hfp_connection->acl_handle, hfp_connection->remote_addr, hfp_connection->negotiated_codec);
hfp_emit_connection_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0, hfp_connection->acl_handle, hfp_connection->remote_addr);
hfp_init_link_settings(hfp_connection);

View File

@ -67,8 +67,9 @@ typedef struct {
* @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);;
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);
/**
* @brief Set up HFP Audio Gateway (AG) device without additional supported features.

View File

@ -161,14 +161,23 @@ static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
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){
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 = default_hfp_hf_service_name;
}
hfp_create_sdp_record(service, service_record_handle, SDP_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"
//
uint16_t sdp_features = supported_features & 0x1f;
if (supported_features & wide_band_speech){
sdp_features |= 1 << 5; // Wide band speech bit
}
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures
de_add_number(service, DE_UINT, DE_SIZE_16, supported_features);
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
}
static int hfp_hf_cmd_exchange_supported_features(uint16_t cid){
@ -830,7 +839,7 @@ static void hfp_init_link_settings(hfp_connection_t * hfp_connection){
static void hfp_ag_slc_established(hfp_connection_t * hfp_connection){
hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
hfp_emit_connection_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0, hfp_connection->acl_handle, hfp_connection->remote_addr, hfp_connection->negotiated_codec);
hfp_emit_connection_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0, hfp_connection->acl_handle, hfp_connection->remote_addr);
hfp_init_link_settings(hfp_connection);
// restore volume settings
hfp_connection->speaker_gain = hfp_hf_speaker_gain;

View File

@ -61,8 +61,9 @@ extern "C" {
* @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);
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);
/**
* @brief Set up HFP Hands-Free (HF) device without additional supported features.