mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-15 14:42:31 +00:00
hfp: extract hfp_handle_rfcomm_event from hfp_handle_hci_event, register hci handler in hf/ag
This commit is contained in:
parent
225dff0411
commit
279501658e
@ -109,8 +109,6 @@ static btstack_packet_handler_t hfp_ag_rfcomm_packet_handler;
|
||||
|
||||
static void (*hfp_hf_run_for_context)(hfp_connection_t * hfp_connection);
|
||||
|
||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
|
||||
static hfp_connection_t * sco_establishment_active;
|
||||
|
||||
const char * hfp_hf_feature(int index){
|
||||
@ -564,15 +562,15 @@ 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, hfp_role_t local_role){
|
||||
void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
UNUSED(channel); // ok: no channel
|
||||
|
||||
bd_addr_t event_addr;
|
||||
uint16_t rfcomm_cid, handle;
|
||||
hci_con_handle_t handle;
|
||||
hfp_connection_t * hfp_connection = NULL;
|
||||
uint8_t status;
|
||||
|
||||
log_debug("HFP packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
|
||||
log_debug("HFP HCI event handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
|
||||
|
||||
switch (hci_event_packet_get_type(packet)) {
|
||||
|
||||
@ -593,60 +591,6 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
}
|
||||
break;
|
||||
|
||||
case RFCOMM_EVENT_INCOMING_CONNECTION:
|
||||
// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
|
||||
rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr);
|
||||
hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr, local_role);
|
||||
if (!hfp_connection){
|
||||
log_info("hfp: no memory to accept incoming connection - decline");
|
||||
rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet));
|
||||
return;
|
||||
}
|
||||
if (hfp_connection->state != HFP_IDLE) {
|
||||
log_error("hfp: incoming connection but state != HFP_IDLE");
|
||||
return;
|
||||
}
|
||||
|
||||
hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
|
||||
hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
|
||||
// printf("RFCOMM channel %u requested for %s\n", hfp_connection->rfcomm_cid, bd_addr_to_str(hfp_connection->remote_addr));
|
||||
rfcomm_accept_connection(hfp_connection->rfcomm_cid);
|
||||
break;
|
||||
|
||||
case RFCOMM_EVENT_CHANNEL_OPENED:
|
||||
// data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
|
||||
|
||||
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);
|
||||
if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return;
|
||||
|
||||
if (status) {
|
||||
hfp_emit_slc_connection_event(hfp_connection, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr);
|
||||
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);
|
||||
|
||||
switch (hfp_connection->state){
|
||||
case HFP_W4_RFCOMM_CONNECTED:
|
||||
hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
|
||||
break;
|
||||
case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
|
||||
hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
|
||||
// printf("Shutting down RFCOMM.\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVENT_COMMAND_STATUS:
|
||||
if (hci_event_command_status_get_command_opcode(packet) == hci_setup_synchronous_connection.opcode) {
|
||||
status = hci_event_command_status_get_status(packet);
|
||||
@ -717,23 +661,6 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
break;
|
||||
}
|
||||
|
||||
case RFCOMM_EVENT_CHANNEL_CLOSED:
|
||||
if (local_role > 1){
|
||||
log_error("hfp_handle_hci_event role %x", local_role);
|
||||
}
|
||||
rfcomm_cid = little_endian_read_16(packet,2);
|
||||
hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
|
||||
if (!hfp_connection) break;
|
||||
if (hfp_connection->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
|
||||
hfp_connection->state = HFP_IDLE;
|
||||
hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid, local_role);
|
||||
break;
|
||||
}
|
||||
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
|
||||
remove_hfp_connection_context(hfp_connection);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
handle = little_endian_read_16(packet,3);
|
||||
hfp_connection = get_hfp_connection_context_for_sco_handle(handle);
|
||||
@ -760,6 +687,90 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
}
|
||||
}
|
||||
|
||||
void hfp_handle_rfcomm_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;
|
||||
uint16_t rfcomm_cid;
|
||||
hfp_connection_t * hfp_connection = NULL;
|
||||
uint8_t status;
|
||||
|
||||
log_debug("HFP packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
|
||||
|
||||
switch (hci_event_packet_get_type(packet)) {
|
||||
|
||||
case RFCOMM_EVENT_INCOMING_CONNECTION:
|
||||
// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
|
||||
rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr);
|
||||
hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr, local_role);
|
||||
if (!hfp_connection){
|
||||
log_info("hfp: no memory to accept incoming connection - decline");
|
||||
rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet));
|
||||
return;
|
||||
}
|
||||
if (hfp_connection->state != HFP_IDLE) {
|
||||
log_error("hfp: incoming connection but state != HFP_IDLE");
|
||||
return;
|
||||
}
|
||||
|
||||
hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
|
||||
hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
|
||||
// printf("RFCOMM channel %u requested for %s\n", hfp_connection->rfcomm_cid, bd_addr_to_str(hfp_connection->remote_addr));
|
||||
rfcomm_accept_connection(hfp_connection->rfcomm_cid);
|
||||
break;
|
||||
|
||||
case RFCOMM_EVENT_CHANNEL_OPENED:
|
||||
// data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
|
||||
|
||||
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);
|
||||
if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return;
|
||||
|
||||
if (status) {
|
||||
hfp_emit_slc_connection_event(hfp_connection, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr);
|
||||
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);
|
||||
|
||||
switch (hfp_connection->state){
|
||||
case HFP_W4_RFCOMM_CONNECTED:
|
||||
hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
|
||||
break;
|
||||
case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
|
||||
hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
|
||||
// printf("Shutting down RFCOMM.\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
|
||||
}
|
||||
break;
|
||||
|
||||
case RFCOMM_EVENT_CHANNEL_CLOSED:
|
||||
rfcomm_cid = little_endian_read_16(packet,2);
|
||||
hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
|
||||
if (!hfp_connection) break;
|
||||
if (hfp_connection->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
|
||||
hfp_connection->state = HFP_IDLE;
|
||||
hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid, local_role);
|
||||
break;
|
||||
}
|
||||
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
|
||||
remove_hfp_connection_context(hfp_connection);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// translates command string into hfp_command_t CMD
|
||||
static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){
|
||||
int offset = isHandsFree ? 0 : 2;
|
||||
@ -1505,11 +1516,5 @@ void hfp_set_hf_run_for_context(void (*callback)(hfp_connection_t * hfp_connecti
|
||||
hfp_hf_run_for_context = callback;
|
||||
}
|
||||
|
||||
static void 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_INVALID);
|
||||
}
|
||||
|
||||
void hfp_init(void){
|
||||
hci_event_callback_registration.callback = &packet_handler;
|
||||
hci_add_event_handler(&hci_event_callback_registration);
|
||||
}
|
||||
|
@ -652,7 +652,8 @@ 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, hfp_role_t local_role);
|
||||
void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
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);
|
||||
void hfp_emit_string_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, const char * value);
|
||||
|
@ -81,6 +81,8 @@ void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr);
|
||||
int get_hfp_ag_indicators_nr(hfp_connection_t * context);
|
||||
hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context);
|
||||
|
||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
|
||||
// gobals
|
||||
static const char default_hfp_ag_service_name[] = "Voice gateway";
|
||||
|
||||
@ -2032,7 +2034,7 @@ static void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
|
||||
hfp_run_for_context(get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid));
|
||||
return;
|
||||
}
|
||||
hfp_handle_hci_event(packet_type, channel, packet, size, HFP_ROLE_AG);
|
||||
hfp_handle_rfcomm_event(packet_type, channel, packet, size, HFP_ROLE_AG);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -2075,9 +2077,15 @@ void hfp_ag_init_call_hold_services(int call_hold_services_nr, const char * call
|
||||
|
||||
|
||||
void hfp_ag_init(uint16_t rfcomm_channel_nr){
|
||||
|
||||
hfp_init();
|
||||
|
||||
hci_event_callback_registration.callback = &hfp_handle_hci_event;
|
||||
hci_add_event_handler(&hci_event_callback_registration);
|
||||
|
||||
rfcomm_register_service(&rfcomm_packet_handler, rfcomm_channel_nr, 0xffff);
|
||||
|
||||
// used to set packet handler for outgoing rfcomm connections - could be handled by emitting an event to us
|
||||
hfp_set_ag_rfcomm_packet_handler(&rfcomm_packet_handler);
|
||||
|
||||
hfp_ag_response_and_hold_active = 0;
|
||||
|
@ -66,6 +66,8 @@
|
||||
#include "hci_dump.h"
|
||||
#include "l2cap.h"
|
||||
|
||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
|
||||
static const char default_hfp_hf_service_name[] = "Hands-Free unit";
|
||||
static uint16_t hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
|
||||
static uint8_t hfp_codecs_nr = 0;
|
||||
@ -1099,7 +1101,7 @@ static void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
|
||||
hfp_run_for_context(get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid));
|
||||
return;
|
||||
}
|
||||
hfp_handle_hci_event(packet_type, channel, packet, size, HFP_ROLE_HF);
|
||||
hfp_handle_rfcomm_event(packet_type, channel, packet, size, HFP_ROLE_HF);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1110,8 +1112,14 @@ static void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
|
||||
void hfp_hf_init(uint16_t rfcomm_channel_nr){
|
||||
hfp_init();
|
||||
|
||||
hci_event_callback_registration.callback = &hfp_handle_hci_event;
|
||||
hci_add_event_handler(&hci_event_callback_registration);
|
||||
|
||||
rfcomm_register_service(rfcomm_packet_handler, rfcomm_channel_nr, 0xffff);
|
||||
|
||||
// used to set packet handler for outgoing rfcomm connections - could be handled by emitting an event to us
|
||||
hfp_set_hf_rfcomm_packet_handler(&rfcomm_packet_handler);
|
||||
|
||||
hfp_set_hf_run_for_context(hfp_run_for_context);
|
||||
|
||||
hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
|
||||
|
Loading…
x
Reference in New Issue
Block a user