add codec exchanged into event

This commit is contained in:
Milanka Ringwald 2016-06-29 17:12:36 +02:00
parent 08b456cdc6
commit 6a7f44bd8d
6 changed files with 97 additions and 29 deletions

View File

@ -915,10 +915,12 @@ typedef uint8_t sm_key_t[16];
/** HFP Subevent */
/**
* @format 11H
* @format 11HB1
* @param subevent_code
* @param status 0 == OK
* @param con_handle
* @param bd_addr
* @param negotiated_codec
*/
#define HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED 0x01
@ -929,10 +931,12 @@ typedef uint8_t sm_key_t[16];
#define HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED 0x02
/**
* @format 11H
* @format 11HB1
* @param subevent_code
* @param status 0 == OK
* @param handle
* @param bd_addr
* @param negotiated_codec
*/
#define HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED 0x03
@ -975,9 +979,10 @@ typedef uint8_t sm_key_t[16];
#define HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR 0x08
/**
* @format 11
* @format 111
* @param subevent_code
* @param status
* @param negotiated_codec
*/
#define HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE 0x09

View File

@ -2739,6 +2739,24 @@ static inline uint8_t hfp_subevent_service_level_connection_established_get_stat
static inline hci_con_handle_t hfp_subevent_service_level_connection_established_get_con_handle(const uint8_t * event){
return little_endian_read_16(event, 4);
}
/**
* @brief Get field bd_addr from event HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED
* @param event packet
* @param Pointer to storage for bd_addr
* @note: btstack_type B
*/
static inline void hfp_subevent_service_level_connection_established_get_bd_addr(const uint8_t * event, bd_addr_t bd_addr){
reverse_bd_addr(&event[6], bd_addr);
}
/**
* @brief Get field negotiated_codec from event HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED
* @param event packet
* @return negotiated_codec
* @note: btstack_type 1
*/
static inline uint8_t hfp_subevent_service_level_connection_established_get_negotiated_codec(const uint8_t * event){
return event[12];
}
/**
@ -2759,6 +2777,24 @@ static inline uint8_t hfp_subevent_audio_connection_established_get_status(const
static inline hci_con_handle_t hfp_subevent_audio_connection_established_get_handle(const uint8_t * event){
return little_endian_read_16(event, 4);
}
/**
* @brief Get field bd_addr from event HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED
* @param event packet
* @param Pointer to storage for bd_addr
* @note: btstack_type B
*/
static inline void hfp_subevent_audio_connection_established_get_bd_addr(const uint8_t * event, bd_addr_t bd_addr){
reverse_bd_addr(&event[6], bd_addr);
}
/**
* @brief Get field negotiated_codec from event HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED
* @param event packet
* @return negotiated_codec
* @note: btstack_type 1
*/
static inline uint8_t hfp_subevent_audio_connection_established_get_negotiated_codec(const uint8_t * event){
return event[12];
}
/**
@ -2846,6 +2882,15 @@ static inline uint8_t hfp_subevent_extended_audio_gateway_error_get_error(const
static inline uint8_t hfp_subevent_codecs_connection_complete_get_status(const uint8_t * event){
return event[3];
}
/**
* @brief Get field negotiated_codec from event HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE
* @param event packet
* @return negotiated_codec
* @note: btstack_type 1
*/
static inline uint8_t hfp_subevent_codecs_connection_complete_get_negotiated_codec(const uint8_t * event){
return event[4];
}

View File

@ -129,7 +129,7 @@ int send_str_over_rfcomm(uint16_t cid, char * command){
return 1;
}
int hfp_supports_codec(uint8_t codec, int codecs_nr, uint16_t * codecs){
int hfp_supports_codec(uint8_t codec, int codecs_nr, uint8_t * codecs){
int i;
for (i = 0; i < codecs_nr; i++){
if (codecs[i] == codec) return 1;
@ -203,6 +203,17 @@ void hfp_emit_simple_event(btstack_packet_handler_t callback, uint8_t event_subt
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
void hfp_emit_codec_event(btstack_packet_handler_t callback, uint8_t status, uint8_t codec){
if (!callback) return;
uint8_t event[5];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
event[2] = HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE;
event[3] = status; // status 0 == OK
event[4] = codec;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
void hfp_emit_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t value){
if (!callback) return;
uint8_t event[4];
@ -213,14 +224,19 @@ void hfp_emit_event(btstack_packet_handler_t callback, uint8_t event_subtype, ui
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
void hfp_emit_connection_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t status, hci_con_handle_t con_handle){
void hfp_emit_connection_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr, uint8_t codec){
if (!callback) return;
uint8_t event[6];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
event[2] = event_subtype;
event[3] = status; // status 0 == OK
little_endian_store_16(event, 4, con_handle);
uint8_t event[13];
int pos = 0;
event[pos++] = HCI_EVENT_HFP_META;
event[pos++] = sizeof(event) - 2;
event[pos++] = event_subtype;
event[pos++] = status; // status 0 == OK
little_endian_store_16(event, pos, con_handle);
pos += 2;
reverse_bd_addr(addr,&event[pos]);
pos += 6;
event[pos] = codec;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
@ -291,7 +307,7 @@ void hfp_reset_context_flags(hfp_connection_t * hfp_connection){
// establish codecs hfp_connection
hfp_connection->suggested_codec = 0;
hfp_connection->negotiated_codec = 0;
hfp_connection->negotiated_codec = HFP_CODEC_CVSD;
hfp_connection->codec_confirmed = 0;
hfp_connection->establish_audio_connection = 0;
@ -327,7 +343,6 @@ static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t b
hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
if (hfp_connection) return hfp_connection;
hfp_connection = create_hfp_connection_context();
printf("created hfp_connection for address %s\n", bd_addr_to_str(bd_addr));
memcpy(hfp_connection->remote_addr, bd_addr, 6);
return hfp_connection;
}
@ -510,17 +525,17 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
rfcomm_event_channel_opened_get_bd_addr(packet, event_addr);
status = rfcomm_event_channel_opened_get_status(packet);
// printf("RFCOMM_EVENT_CHANNEL_OPENED packet_handler adddr %s, status %u\n", bd_addr_to_str(event_addr), status);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return;
if (status) {
hfp_emit_connection_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, status, rfcomm_event_channel_opened_get_con_handle(packet));
hfp_emit_connection_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr, hfp_connection->negotiated_codec);
remove_hfp_connection_context(hfp_connection);
} else {
hfp_connection->acl_handle = rfcomm_event_channel_opened_get_con_handle(packet);
hfp_connection->rfcomm_cid = rfcomm_event_channel_opened_get_rfcomm_cid(packet);
bd_addr_copy(hfp_connection->remote_addr, event_addr);
// uint16_t mtu = rfcomm_event_channel_opened_get_max_frame_size(packet);
// printf("RFCOMM channel open succeeded. hfp_connection %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", hfp_connection, hfp_connection->rfcomm_cid, mtu);
@ -608,7 +623,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
hfp_connection->sco_handle = sco_handle;
hfp_connection->establish_audio_connection = 0;
hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
hfp_emit_connection_event(hfp_callback, HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED, packet[2], sco_handle);
hfp_emit_connection_event(hfp_callback, HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED, packet[2], sco_handle, event_addr, hfp_connection->negotiated_codec);
break;
}

View File

@ -489,7 +489,7 @@ typedef struct hfp_connection {
// TODO: rename into hf_codecs_nr
int remote_codecs_nr;
uint16_t remote_codecs[HFP_MAX_INDICATOR_DESC_SIZE];
uint8_t remote_codecs[HFP_MAX_INDICATOR_DESC_SIZE];
int ag_indicators_nr;
hfp_ag_indicator_t ag_indicators[HFP_MAX_INDICATOR_DESC_SIZE];
@ -628,7 +628,8 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
void hfp_emit_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t value);
void hfp_emit_simple_event(btstack_packet_handler_t callback, uint8_t event_subtype);
void hfp_emit_string_event(btstack_packet_handler_t callback, uint8_t event_subtype, const char * value);
void hfp_emit_connection_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t status, hci_con_handle_t con_handle);
void hfp_emit_connection_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr, uint8_t codec);
void hfp_emit_codec_event(btstack_packet_handler_t callback, uint8_t status, uint8_t codec);
hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid);
hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr);
@ -644,7 +645,7 @@ void hfp_reset_context_flags(hfp_connection_t * connection);
void hfp_release_audio_connection(hfp_connection_t * connection);
void hfp_setup_synchronous_connection(hfp_connection_t * connection);
int hfp_supports_codec(uint8_t codec, int codecs_nr, uint16_t * codecs);
int hfp_supports_codec(uint8_t codec, int codecs_nr, uint8_t * codecs);
const char * hfp_hf_feature(int index);
const char * hfp_ag_feature(int index);

View File

@ -519,8 +519,8 @@ static int hfp_ag_set_response_and_hold(uint16_t cid, int state){
}
static uint8_t hfp_ag_suggest_codec(hfp_connection_t *hfp_connection){
if (hfp_supports_codec(HFP_CODEC_MSBC, hfp_codecs_nr, (uint16_t *)hfp_codecs)){
if (hfp_supports_codec(HFP_CODEC_MSBC, hfp_connection->remote_codecs_nr, (uint16_t *)(hfp_connection->remote_codecs))){
if (hfp_supports_codec(HFP_CODEC_MSBC, hfp_codecs_nr, hfp_codecs)){
if (hfp_supports_codec(HFP_CODEC_MSBC, hfp_connection->remote_codecs_nr, hfp_connection->remote_codecs)){
return HFP_CODEC_MSBC;
}
}
@ -587,7 +587,7 @@ static int codecs_exchange_state_machine(hfp_connection_t * hfp_connection){
}
hfp_connection->negotiated_codec = hfp_connection->codec_confirmed;
hfp_connection->codecs_state = HFP_CODECS_EXCHANGED;
hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0);
hfp_emit_codec_event(hfp_callback, 0, hfp_connection->negotiated_codec);
hfp_ag_ok(hfp_connection->rfcomm_cid);
return 1;
default:
@ -610,7 +610,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_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_init_link_settings(hfp_connection);

View File

@ -515,8 +515,8 @@ static int codecs_exchange_state_machine(hfp_connection_t * hfp_connection){
hfp_hf_cmd_trigger_codec_connection_setup(hfp_connection->rfcomm_cid);
break;
case HFP_CMD_AG_SUGGESTED_CODEC:
if (hfp_supports_codec(hfp_connection->suggested_codec, hfp_codecs_nr, (uint16_t *)hfp_codecs)){
case HFP_CMD_AG_SUGGESTED_CODEC:{
if (hfp_supports_codec(hfp_connection->suggested_codec, hfp_codecs_nr, hfp_codecs)){
hfp_connection->codec_confirmed = hfp_connection->suggested_codec;
hfp_connection->ok_pending = 1;
hfp_connection->codecs_state = HFP_CODECS_HF_CONFIRMED_CODEC;
@ -531,7 +531,7 @@ static int codecs_exchange_state_machine(hfp_connection_t * hfp_connection){
}
break;
}
default:
break;
}
@ -828,7 +828,8 @@ 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_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_init_link_settings(hfp_connection);
// restore volume settings
hfp_connection->speaker_gain = hfp_hf_speaker_gain;
@ -936,7 +937,8 @@ static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){
break;
case HFP_CODECS_HF_CONFIRMED_CODEC:
hfp_connection->codecs_state = HFP_CODECS_EXCHANGED;
hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0);
hfp_connection->negotiated_codec = hfp_connection->suggested_codec;
hfp_emit_codec_event(hfp_callback, 0, hfp_connection->negotiated_codec);
break;
default:
break;