hfp: verify hfp role when looking up connection by bd_addr, sco, or acl handle

This commit is contained in:
Matthias Ringwald 2018-09-24 16:38:56 +02:00
parent 9119d792f4
commit 405014fb5c
4 changed files with 27 additions and 19 deletions

View File

@ -292,36 +292,36 @@ hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){
return NULL;
}
hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){
hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t hfp_role){
btstack_linked_list_iterator_t it;
btstack_linked_list_iterator_init(&it, hfp_get_connections());
while (btstack_linked_list_iterator_has_next(&it)){
hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
if (memcmp(hfp_connection->remote_addr, bd_addr, 6) == 0) {
if (memcmp(hfp_connection->remote_addr, bd_addr, 6) == 0 && hfp_connection->local_role == hfp_role) {
return hfp_connection;
}
}
return NULL;
}
hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle){
hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle, hfp_role_t hfp_role){
btstack_linked_list_iterator_t it;
btstack_linked_list_iterator_init(&it, hfp_get_connections());
while (btstack_linked_list_iterator_has_next(&it)){
hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
if (hfp_connection->sco_handle == handle){
if (hfp_connection->sco_handle == handle && hfp_connection->local_role == hfp_role){
return hfp_connection;
}
}
return NULL;
}
hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle){
hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle, hfp_role_t hfp_role){
btstack_linked_list_iterator_t it;
btstack_linked_list_iterator_init(&it, hfp_get_connections());
while (btstack_linked_list_iterator_has_next(&it)){
hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
if (hfp_connection->acl_handle == handle){
if (hfp_connection->acl_handle == handle && hfp_connection->local_role == hfp_role){
return hfp_connection;
}
}
@ -377,7 +377,7 @@ static void remove_hfp_connection_context(hfp_connection_t * hfp_connection){
}
static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t local_role){
hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr, local_role);
if (hfp_connection) return hfp_connection;
hfp_connection = create_hfp_connection_context();
memcpy(hfp_connection->remote_addr, bd_addr, 6);
@ -565,7 +565,7 @@ static void hfp_handle_failed_sco_connection(uint8_t status){
}
void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){
UNUSED(channel); // ok: no channel
bd_addr_t event_addr;
@ -582,7 +582,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
case 0: // SCO
case 2: // eSCO
hci_event_connection_request_get_bd_addr(packet, event_addr);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
if (!hfp_connection) break;
log_info("hf accept sco\n");
hfp_connection->hf_accept_sco = 1;
@ -605,7 +605,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
hci_event_synchronous_connection_complete_get_bd_addr(packet, event_addr);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
if (!hfp_connection) {
log_error("HFP: connection does not exist for remote with addr %s.", bd_addr_to_str(event_addr));
return;
@ -645,7 +645,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
" rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle,
bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
if (!hfp_connection) {
log_error("SCO link created, hfp_connection for address %s not found.", bd_addr_to_str(event_addr));
@ -666,7 +666,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
case HCI_EVENT_DISCONNECTION_COMPLETE:
handle = little_endian_read_16(packet,3);
hfp_connection = get_hfp_connection_context_for_sco_handle(handle);
hfp_connection = get_hfp_connection_context_for_sco_handle(handle, local_role);
if (!hfp_connection) break;
@ -728,7 +728,7 @@ void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *pac
rfcomm_event_channel_opened_get_bd_addr(packet, event_addr);
status = rfcomm_event_channel_opened_get_status(packet);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return;
if (status) {

View File

@ -652,7 +652,7 @@ void hfp_set_hf_run_for_context(void (*callbcack)(hfp_connection_t * hfp_connect
void hfp_init(void);
void hfp_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t service_uuid, int rfcomm_channel_nr, const char * name);
void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role);
void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role);
void hfp_emit_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, uint8_t value);
void hfp_emit_simple_event(hfp_connection_t * hfp_connection, uint8_t event_subtype);
@ -660,9 +660,9 @@ void hfp_emit_string_event(hfp_connection_t * hfp_connection, uint8_t event_subt
void hfp_emit_slc_connection_event(hfp_connection_t * hfp_connection, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr);
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);
hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle);
hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle);
hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t hfp_role);
hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle, hfp_role_t hfp_role);
hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle, hfp_role_t hfp_role);
btstack_linked_list_t * hfp_get_connections(void);
void hfp_parse(hfp_connection_t * connection, uint8_t byte, int isHandsFree);

View File

@ -2071,6 +2071,10 @@ static void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
hfp_run();
}
static void 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);
}
void hfp_ag_init_codecs(int codecs_nr, 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);
@ -2108,7 +2112,7 @@ void hfp_ag_init(uint16_t rfcomm_channel_nr){
hfp_init();
hci_event_callback_registration.callback = &hfp_handle_hci_event;
hci_event_callback_registration.callback = &hci_event_packet_handler;
hci_add_event_handler(&hci_event_callback_registration);
rfcomm_register_service(&rfcomm_packet_handler, rfcomm_channel_nr, 0xffff);

View File

@ -1108,10 +1108,14 @@ static void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
hfp_run();
}
static void 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_HF);
}
void hfp_hf_init(uint16_t rfcomm_channel_nr){
hfp_init();
hci_event_callback_registration.callback = &hfp_handle_hci_event;
hci_event_callback_registration.callback = &hci_event_packet_handler;
hci_add_event_handler(&hci_event_callback_registration);
rfcomm_register_service(rfcomm_packet_handler, rfcomm_channel_nr, 0xffff);