diff --git a/include/btstack/run_loop.h b/include/btstack/run_loop.h index 2c7b36d64..f0c881038 100644 --- a/include/btstack/run_loop.h +++ b/include/btstack/run_loop.h @@ -93,6 +93,12 @@ int run_loop_remove_data_source(data_source_t *dataSource); // execute configured run_loop void run_loop_execute(void); +// hack to fix HCI timer handling +#ifdef EMBEDDED +uint32_t embedded_get_ticks(void); +uint32_t embedded_ticks_for_ms(uint32_t time_in_ms); +#endif + #if defined __cplusplus } #endif diff --git a/src/hci.c b/src/hci.c index 87ebae69b..41cb66574 100644 --- a/src/hci.c +++ b/src/hci.c @@ -76,27 +76,33 @@ hci_connection_t * connection_for_handle(hci_con_handle_t con_handle){ return NULL; } -#ifdef HAVE_TIME static void hci_connection_timeout_handler(timer_source_t *timer){ hci_connection_t * connection = linked_item_get_user(&timer->item); +#ifdef HAVE_TIME struct timeval tv; gettimeofday(&tv, NULL); if (tv.tv_sec >= connection->timestamp.tv_sec + HCI_CONNECTION_TIMEOUT_MS/1000) { // connections might be timed out hci_emit_l2cap_check_timeout(connection); - run_loop_set_timer(timer, HCI_CONNECTION_TIMEOUT_MS); - } else { - // next timeout check at - timer->timeout.tv_sec = connection->timestamp.tv_sec + HCI_CONNECTION_TIMEOUT_MS/1000; } +#endif +#ifdef EMBEDDED + if (embedded_get_ticks() > connection->timestamp + embedded_ticks_for_ms(HCI_CONNECTION_TIMEOUT_MS)){ + // connections might be timed out + hci_emit_l2cap_check_timeout(connection); + } +#endif + run_loop_set_timer(timer, HCI_CONNECTION_TIMEOUT_MS); run_loop_add_timer(timer); } -#endif static void hci_connection_timestamp(hci_connection_t *connection){ #ifdef HAVE_TIME gettimeofday(&connection->timestamp, NULL); #endif +#ifdef EMBEDDED + connection->timestamp = embedded_get_ticks(); +#endif } /** @@ -110,11 +116,9 @@ static hci_connection_t * create_connection_for_addr(bd_addr_t addr){ BD_ADDR_COPY(conn->address, addr); conn->con_handle = 0xffff; conn->authentication_flags = AUTH_FLAGS_NONE; -#ifdef HAVE_TIME linked_item_set_user(&conn->timeout.item, conn); conn->timeout.process = hci_connection_timeout_handler; hci_connection_timestamp(conn); -#endif conn->acl_recombination_length = 0; conn->acl_recombination_pos = 0; conn->num_acl_packets_sent = 0; @@ -340,9 +344,8 @@ static void hci_shutdown_connection(hci_connection_t *conn){ // cancel all l2cap connections hci_emit_disconnection_complete(conn->con_handle, 0x16); // terminated by local host -#ifdef HAVE_TIME run_loop_remove_timer(&conn->timeout); -#endif + linked_list_remove(&hci_stack.connections, (linked_item_t *) conn); btstack_memory_hci_connection_free( conn ); @@ -438,11 +441,10 @@ static void event_handler(uint8_t *packet, int size){ conn->state = OPEN; conn->con_handle = READ_BT_16(packet, 3); -#ifdef HAVE_TIME - gettimeofday(&conn->timestamp, NULL); + // restart timer run_loop_set_timer(&conn->timeout, HCI_CONNECTION_TIMEOUT_MS); run_loop_add_timer(&conn->timeout); -#endif + log_info("New connection: handle %u, ", conn->con_handle); print_bd_addr( conn->address ); log_info("\n"); diff --git a/src/hci.h b/src/hci.h index e645aac57..b29465058 100644 --- a/src/hci.h +++ b/src/hci.h @@ -194,13 +194,17 @@ typedef struct { // errands hci_authentication_flags_t authentication_flags; + + timer_source_t timeout; #ifdef HAVE_TIME // timer - timer_source_t timeout; struct timeval timestamp; #endif - +#ifdef EMBEDDED + uint32_t timeout; // timeout in system ticks +#endif + // ACL packet recombination uint8_t acl_recombination_buffer[4 + HCI_ACL_3DH5_SIZE]; uint16_t acl_recombination_pos; diff --git a/src/run_loop_embedded.c b/src/run_loop_embedded.c index bd8818536..da84121b2 100644 --- a/src/run_loop_embedded.c +++ b/src/run_loop_embedded.c @@ -145,9 +145,17 @@ static void embedded_tick_handler(void){ system_ticks++; } +uint32_t embedded_get_ticks(void){ + return system_ticks; +} + +uint32_t embedded_ticks_for_ms(uint32_t time_in_ms){ + return delta_ms / hal_tick_get_tick_period_in_ms() +} + // set timer void run_loop_set_timer(timer_source_t *ts, uint32_t timeout_in_ms){ - uint32_t ticks = timeout_in_ms / hal_tick_get_tick_period_in_ms(); + uint32_t ticks = embedded_ticks_for_ms(timeout_in_ms); if (ticks == 0) ticks++; ts->timeout = system_ticks + ticks; }