mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-02 07:20:16 +00:00
hci: improved sco tx scheduling (without flow control over UART)
This commit is contained in:
parent
28166e7187
commit
59c335756f
80
src/hci.c
80
src/hci.c
@ -2553,21 +2553,15 @@ static void event_handler(uint8_t *packet, int size){
|
|||||||
|
|
||||||
#ifdef ENABLE_CLASSIC
|
#ifdef ENABLE_CLASSIC
|
||||||
|
|
||||||
#define SCO_TX_AFTER_RX_MS 5
|
|
||||||
|
|
||||||
static void sco_tx_timeout_handler(btstack_timer_source_t * ts);
|
static void sco_tx_timeout_handler(btstack_timer_source_t * ts);
|
||||||
static void sco_schedule_tx(hci_connection_t * conn);
|
static void sco_schedule_tx(hci_connection_t * conn);
|
||||||
|
|
||||||
static void sco_tx_timeout_handler(btstack_timer_source_t * ts){
|
static void sco_tx_timeout_handler(btstack_timer_source_t * ts){
|
||||||
log_info("SCO TX Timeout");
|
log_debug("SCO TX Timeout");
|
||||||
hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) btstack_run_loop_get_timer_context(ts);
|
hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) btstack_run_loop_get_timer_context(ts);
|
||||||
hci_connection_t * conn = hci_connection_for_handle(con_handle);
|
hci_connection_t * conn = hci_connection_for_handle(con_handle);
|
||||||
if (!conn) return;
|
if (!conn) return;
|
||||||
|
|
||||||
// schedule next
|
|
||||||
sco_schedule_tx(conn);
|
|
||||||
conn->sco_tx_count++;
|
|
||||||
|
|
||||||
// trigger send
|
// trigger send
|
||||||
conn->sco_tx_ready = 1;
|
conn->sco_tx_ready = 1;
|
||||||
// extra packet if CVSD but SCO buffer is too short
|
// extra packet if CVSD but SCO buffer is too short
|
||||||
@ -2577,28 +2571,22 @@ static void sco_tx_timeout_handler(btstack_timer_source_t * ts){
|
|||||||
hci_notify_if_sco_can_send_now();
|
hci_notify_if_sco_can_send_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define SCO_TX_AFTER_RX_MS (6)
|
||||||
|
|
||||||
static void sco_schedule_tx(hci_connection_t * conn){
|
static void sco_schedule_tx(hci_connection_t * conn){
|
||||||
// find next time to send
|
|
||||||
uint32_t now = btstack_run_loop_get_time_ms();
|
uint32_t now = btstack_run_loop_get_time_ms();
|
||||||
uint32_t tx_ms;
|
uint32_t sco_tx_ms = conn->sco_rx_ms + SCO_TX_AFTER_RX_MS;
|
||||||
int time_delta_ms;
|
int time_delta_ms = sco_tx_ms - now;
|
||||||
while (1){
|
|
||||||
// packet delay: count(rx) - count(tx)
|
btstack_timer_source_t * timer = (conn->sco_rx_count & 1) ? &conn->timeout : &conn->timeout_sco;
|
||||||
int packet_offset = (int8_t) (conn->sco_tx_count - conn->sco_rx_count);
|
|
||||||
tx_ms = conn->sco_rx_ms + ((packet_offset * 15) >> 1) + SCO_TX_AFTER_RX_MS;
|
// log_error("SCO TX at %u in %u", (int) sco_tx_ms, time_delta_ms);
|
||||||
time_delta_ms = (int) (tx_ms - now);
|
btstack_run_loop_set_timer(timer, time_delta_ms);
|
||||||
if (time_delta_ms >= 3){
|
btstack_run_loop_set_timer_context(timer, (void *) (uintptr_t) conn->con_handle);
|
||||||
break;
|
btstack_run_loop_set_timer_handler(timer, &sco_tx_timeout_handler);
|
||||||
}
|
btstack_run_loop_add_timer(timer);
|
||||||
// skip packet
|
|
||||||
conn->sco_tx_count++;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
log_info("SCO TX at %u in %u", (int) tx_ms, time_delta_ms);
|
|
||||||
btstack_run_loop_set_timer(&conn->timeout, time_delta_ms);
|
|
||||||
btstack_run_loop_set_timer_context(&conn->timeout, (void *) (uintptr_t) conn->con_handle);
|
|
||||||
btstack_run_loop_set_timer_handler(&conn->timeout, &sco_tx_timeout_handler);
|
|
||||||
btstack_run_loop_add_timer(&conn->timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sco_handler(uint8_t * packet, uint16_t size){
|
static void sco_handler(uint8_t * packet, uint16_t size){
|
||||||
@ -2607,8 +2595,6 @@ static void sco_handler(uint8_t * packet, uint16_t size){
|
|||||||
hci_connection_t * conn = hci_connection_for_handle(con_handle);
|
hci_connection_t * conn = hci_connection_for_handle(con_handle);
|
||||||
if (!conn) return;
|
if (!conn) return;
|
||||||
|
|
||||||
int notify_sco = 0;
|
|
||||||
|
|
||||||
// CSR 8811 prefixes 60 byte SCO packet in transparent mode with 20 zero bytes -> skip first 20 payload bytes
|
// CSR 8811 prefixes 60 byte SCO packet in transparent mode with 20 zero bytes -> skip first 20 payload bytes
|
||||||
if (hci_stack->manufacturer == BLUETOOTH_COMPANY_ID_CAMBRIDGE_SILICON_RADIO){
|
if (hci_stack->manufacturer == BLUETOOTH_COMPANY_ID_CAMBRIDGE_SILICON_RADIO){
|
||||||
if (size == 83 && ((hci_stack->sco_voice_setting_active & 0x03) == 0x03)){
|
if (size == 83 && ((hci_stack->sco_voice_setting_active & 0x03) == 0x03)){
|
||||||
@ -2624,22 +2610,27 @@ static void sco_handler(uint8_t * packet, uint16_t size){
|
|||||||
// log_debug("sco flow %u, handle 0x%04x, packets sent %u, bytes send %u", hci_stack->synchronous_flow_control_enabled, (int) con_handle, conn->num_packets_sent, conn->num_sco_bytes_sent);
|
// log_debug("sco flow %u, handle 0x%04x, packets sent %u, bytes send %u", hci_stack->synchronous_flow_control_enabled, (int) con_handle, conn->num_packets_sent, conn->num_sco_bytes_sent);
|
||||||
if (hci_stack->synchronous_flow_control_enabled == 0){
|
if (hci_stack->synchronous_flow_control_enabled == 0){
|
||||||
uint32_t now = btstack_run_loop_get_time_ms();
|
uint32_t now = btstack_run_loop_get_time_ms();
|
||||||
if (conn->sco_rx_valid){
|
|
||||||
|
if (!conn->sco_rx_valid){
|
||||||
|
// ignore first 10 packets
|
||||||
conn->sco_rx_count++;
|
conn->sco_rx_count++;
|
||||||
// expected arrival timme
|
// log_debug("sco rx count %u", conn->sco_rx_count);
|
||||||
conn->sco_rx_ms += 7;
|
if (conn->sco_rx_count == 10) {
|
||||||
int delta = (int32_t) (now - conn->sco_rx_ms);
|
// use first timestamp as is and pretent it just started
|
||||||
if (delta <= 0){
|
conn->sco_rx_ms = now;
|
||||||
log_info("SCO NOW - EXP = %d, use +7 ms", delta);
|
conn->sco_rx_valid = 1;
|
||||||
} else {
|
conn->sco_rx_count = 0;
|
||||||
conn->sco_rx_ms++;
|
sco_schedule_tx(conn);
|
||||||
log_info("SCO NOW > EXP = %d, use +8 ms", delta);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// use first timestamp as is
|
// track expected arrival timme
|
||||||
conn->sco_rx_ms = now;
|
conn->sco_rx_count++;
|
||||||
conn->sco_rx_valid = 1;
|
conn->sco_rx_ms += 7;
|
||||||
log_info("SCO first rx");
|
int delta = (int32_t) (now - conn->sco_rx_ms);
|
||||||
|
if (delta > 0){
|
||||||
|
conn->sco_rx_ms++;
|
||||||
|
}
|
||||||
|
// log_debug("sco rx %u", conn->sco_rx_ms);
|
||||||
sco_schedule_tx(conn);
|
sco_schedule_tx(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2649,11 +2640,6 @@ static void sco_handler(uint8_t * packet, uint16_t size){
|
|||||||
hci_stack->sco_packet_handler(HCI_SCO_DATA_PACKET, 0, packet, size);
|
hci_stack->sco_packet_handler(HCI_SCO_DATA_PACKET, 0, packet, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify app if it can send again
|
|
||||||
if (notify_sco){
|
|
||||||
hci_notify_if_sco_can_send_now();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL
|
#ifdef ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL
|
||||||
conn->num_packets_completed++;
|
conn->num_packets_completed++;
|
||||||
hci_stack->host_completed_packets = 1;
|
hci_stack->host_completed_packets = 1;
|
||||||
|
@ -503,8 +503,8 @@ typedef struct {
|
|||||||
|
|
||||||
// generate sco can send now based on received packets, using timeout below
|
// generate sco can send now based on received packets, using timeout below
|
||||||
uint8_t sco_tx_ready;
|
uint8_t sco_tx_ready;
|
||||||
uint8_t sco_tx_count;
|
|
||||||
|
|
||||||
|
btstack_timer_source_t timeout_sco;
|
||||||
#endif /* ENABLE_CLASSIC */
|
#endif /* ENABLE_CLASSIC */
|
||||||
|
|
||||||
// errands
|
// errands
|
||||||
|
Loading…
x
Reference in New Issue
Block a user