diff --git a/src/btstack_defines.h b/src/btstack_defines.h index 0621f09aa..55986afe0 100644 --- a/src/btstack_defines.h +++ b/src/btstack_defines.h @@ -294,6 +294,13 @@ // data: event(8) #define DAEMON_EVENT_HCI_PACKET_SENT 0x6C +// additional HCI events +/** + * @format B + * @param handle + */ +#define HCI_EVENT_SCO_CAN_SEND_NOW 0x6F + // L2CAP EVENTS /** diff --git a/src/hci.c b/src/hci.c index a193e75f2..3645bcc17 100644 --- a/src/hci.c +++ b/src/hci.c @@ -419,13 +419,19 @@ int hci_can_send_acl_packet_now(hci_con_handle_t con_handle){ } int hci_can_send_prepared_sco_packet_now(hci_con_handle_t con_handle){ - if (!hci_transport_can_send_prepared_packet_now(HCI_SCO_DATA_PACKET)) return 0; + if (!hci_transport_can_send_prepared_packet_now(HCI_SCO_DATA_PACKET)) { + hci_stack->sco_waiting_for_can_send_now = 1; + return 0; + } if (!hci_stack->synchronous_flow_control_enabled) return 1; return hci_number_free_sco_slots_for_handle(con_handle) > 0; } int hci_can_send_sco_packet_now(hci_con_handle_t con_handle){ - if (hci_stack->hci_packet_buffer_reserved) return 0; + if (hci_stack->hci_packet_buffer_reserved) { + hci_stack->sco_waiting_for_can_send_now = 1; + return 0; + } return hci_can_send_prepared_sco_packet_now(con_handle); } @@ -1424,7 +1430,7 @@ static void event_handler(uint8_t *packet, int size){ log_error("hci_number_completed_packets, more sco slots freed then sent."); conn->num_sco_packets_sent = 0; } - + hci_notify_sco_can_send_now(handle); } else { if (conn->num_acl_packets_sent >= num_packets){ conn->num_acl_packets_sent -= num_packets; @@ -2900,6 +2906,23 @@ static void hci_emit_acl_packet(uint8_t * packet, uint16_t size){ hci_stack->acl_packet_handler(HCI_ACL_DATA_PACKET, packet, size); } +static void hci_emit_sco_can_send_now(uint16_t handle){ + uint8_t event[4]; + event[0] = HCI_EVENT_SCO_CAN_SEND_NOW; + event[1] = 2; + little_endian_store_16(event, 2, handle); + hci_dump_packet(HCI_EVENT_PACKET, 1, event, sizeof(event)); + hci_stack->sco_packet_handler(HCI_EVENT_PACKET, handle, event, sizeof(event)); +} + +static void hci_notify_sco_can_send_now(uint16_t handle){ + // notify SCO sender if waiting + if (hci_stack->sco_waiting_for_can_send_now){ + hci_stack->sco_waiting_for_can_send_now = 0; + hci_emit_sco_can_send_now(handle); + } +} + void hci_emit_state(void){ log_info("BTSTACK_EVENT_STATE %u", hci_stack->state); uint8_t event[3]; diff --git a/src/hci.h b/src/hci.h index 05afbeda5..1f0b85735 100644 --- a/src/hci.h +++ b/src/hci.h @@ -525,6 +525,21 @@ typedef struct { /* link key db */ const btstack_link_key_db_t * link_key_db; + // list of existing baseband connections + btstack_linked_list_t connections; + + /* callback to L2CAP layer */ + void (*acl_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); + + /* callback for SCO data */ + void (*sco_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); + + /* callbacks for events */ + btstack_linked_list_t event_handlers; + + // hardware error callback + void (*hardware_error_callback)(void); + // basic configuration const char * local_name; uint32_t class_of_device; @@ -534,9 +549,6 @@ typedef struct { uint8_t ssp_authentication_requirement; uint8_t ssp_auto_accept; - // list of existing baseband connections - btstack_linked_list_t connections; - // single buffer for HCI packet assembly + additional prebuffer for H4 drivers uint8_t hci_packet_buffer_prefix[HCI_OUTGOING_PRE_BUFFER_SIZE]; uint8_t hci_packet_buffer[HCI_PACKET_BUFFER_SIZE]; // opcode (16), len(8) @@ -553,6 +565,7 @@ typedef struct { uint8_t synchronous_flow_control_enabled; uint8_t le_acl_packets_total_num; uint16_t le_data_packets_length; + uint8_t sco_waiting_for_can_send_now; /* local supported features */ uint8_t local_supported_features[8]; @@ -572,14 +585,6 @@ typedef struct { // usable packet types given acl_data_packet_length and HCI_ACL_BUFFER_SIZE uint16_t packet_types; - /* callback to L2CAP layer */ - void (*acl_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); - - /* callback for SCO data */ - void (*sco_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); - - /* callbacks for events */ - btstack_linked_list_t event_handlers; /* hci state machine */ HCI_STATE state; @@ -641,9 +646,6 @@ typedef struct { bd_addr_t custom_bd_addr; uint8_t custom_bd_addr_set; - // hardware error callback - void (*hardware_error_callback)(void); - } hci_stack_t; /**