mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 04:20:20 +00:00
add codec exchanged into event
This commit is contained in:
parent
08b456cdc6
commit
6a7f44bd8d
@ -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
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user