mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-25 18:35:17 +00:00
Merge branch 'develop' of https://github.com/bluekitchen/btstack into develop
This commit is contained in:
commit
185c7bdad7
@ -51,17 +51,18 @@
|
||||
#else
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static void btstack_run_loop_posix_dump_timer(void);
|
||||
static int btstack_run_loop_posix_timeval_compare(struct timeval *a, struct timeval *b);
|
||||
static int btstack_run_loop_posix_timer_compare(btstack_timer_source_t *a, btstack_timer_source_t *b);
|
||||
|
||||
// the run loop
|
||||
static btstack_linked_list_t data_sources;
|
||||
static int data_sources_modified;
|
||||
static btstack_linked_list_t timers;
|
||||
// start time. tv_usec = 0
|
||||
static struct timeval init_tv;
|
||||
|
||||
/**
|
||||
@ -88,17 +89,18 @@ static int btstack_run_loop_posix_remove_data_source(btstack_data_source_t *ds){
|
||||
static void btstack_run_loop_posix_add_timer(btstack_timer_source_t *ts){
|
||||
btstack_linked_item_t *it;
|
||||
for (it = (btstack_linked_item_t *) &timers; it->next ; it = it->next){
|
||||
if ((btstack_timer_source_t *) it->next == ts){
|
||||
btstack_timer_source_t * next = (btstack_timer_source_t *) it->next;
|
||||
if (next == ts){
|
||||
log_error( "btstack_run_loop_timer_add error: timer to add already in list!");
|
||||
return;
|
||||
}
|
||||
if (btstack_run_loop_posix_timer_compare( (btstack_timer_source_t *) it->next, ts) > 0) {
|
||||
if (next->timeout > ts->timeout) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ts->item.next = it->next;
|
||||
it->next = (btstack_linked_item_t *) ts;
|
||||
// log_info("Added timer %x at %u\n", (int) ts, (unsigned int) ts->timeout.tv_sec);
|
||||
log_debug("Added timer %p at %u\n", ts, ts->timeout);
|
||||
// btstack_run_loop_posix_dump_timer();
|
||||
}
|
||||
|
||||
@ -116,7 +118,7 @@ static void btstack_run_loop_posix_dump_timer(void){
|
||||
int i = 0;
|
||||
for (it = (btstack_linked_item_t *) timers; it ; it = it->next){
|
||||
btstack_timer_source_t *ts = (btstack_timer_source_t*) it;
|
||||
log_info("timer %u, timeout %u\n", i, (unsigned int) ts->timeout.tv_sec);
|
||||
log_info("timer %u, timeout %u\n", i, ts->timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,6 +130,17 @@ static void btstack_run_loop_posix_disable_data_source_callbacks(btstack_data_so
|
||||
ds->flags &= ~callback_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Queries the current time in ms since start
|
||||
*/
|
||||
static uint32_t btstack_run_loop_posix_get_time_ms(void){
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
uint32_t time_ms = ((tv.tv_sec - init_tv.tv_sec) * 1000) + (tv.tv_usec / 1000);
|
||||
log_info("btstack_run_loop_posix_get_time_ms: %u <- %u / %u", time_ms, (int) tv.tv_sec, (int) tv.tv_usec);
|
||||
return time_ms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute run_loop
|
||||
*/
|
||||
@ -136,16 +149,16 @@ static void btstack_run_loop_posix_execute(void) {
|
||||
fd_set descriptors_write;
|
||||
|
||||
btstack_timer_source_t *ts;
|
||||
struct timeval current_tv;
|
||||
struct timeval next_tv;
|
||||
struct timeval *timeout;
|
||||
btstack_linked_list_iterator_t it;
|
||||
|
||||
struct timeval * timeout;
|
||||
struct timeval tv;
|
||||
uint32_t now_ms;
|
||||
|
||||
while (1) {
|
||||
// collect FDs
|
||||
FD_ZERO(&descriptors_read);
|
||||
FD_ZERO(&descriptors_write);
|
||||
int highest_fd = 0;
|
||||
int highest_fd = -1;
|
||||
btstack_linked_list_iterator_init(&it, &data_sources);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
btstack_data_source_t *ds = (btstack_data_source_t*) btstack_linked_list_iterator_next(&it);
|
||||
@ -155,65 +168,57 @@ static void btstack_run_loop_posix_execute(void) {
|
||||
if (ds->fd > highest_fd) {
|
||||
highest_fd = ds->fd;
|
||||
}
|
||||
log_debug("btstack_run_loop_execute adding fd %u for read", ds->fd);
|
||||
}
|
||||
if (ds->flags & DATA_SOURCE_CALLBACK_WRITE){
|
||||
FD_SET(ds->fd, &descriptors_write);
|
||||
if (ds->fd > highest_fd) {
|
||||
highest_fd = ds->fd;
|
||||
}
|
||||
log_debug("btstack_run_loop_execute adding fd %u for write", ds->fd);
|
||||
}
|
||||
}
|
||||
|
||||
// get next timeout
|
||||
// pre: 0 <= tv_usec < 1000000
|
||||
timeout = NULL;
|
||||
if (timers) {
|
||||
gettimeofday(¤t_tv, NULL);
|
||||
ts = (btstack_timer_source_t *) timers;
|
||||
next_tv.tv_usec = ts->timeout.tv_usec - current_tv.tv_usec;
|
||||
next_tv.tv_sec = ts->timeout.tv_sec - current_tv.tv_sec;
|
||||
while (next_tv.tv_usec < 0){
|
||||
next_tv.tv_usec += 1000000;
|
||||
next_tv.tv_sec--;
|
||||
timeout = &tv;
|
||||
now_ms = btstack_run_loop_posix_get_time_ms();
|
||||
int delta = ts->timeout - now_ms;
|
||||
if (delta < 0){
|
||||
delta = 0;
|
||||
}
|
||||
if (next_tv.tv_sec < 0){
|
||||
next_tv.tv_sec = 0;
|
||||
next_tv.tv_usec = 0;
|
||||
}
|
||||
timeout = &next_tv;
|
||||
tv.tv_sec = delta / 1000;
|
||||
tv.tv_usec = (delta - (tv.tv_sec * 1000)) * 1000;
|
||||
log_debug("btstack_run_loop_execute next timeout in %u ms", delta);
|
||||
}
|
||||
|
||||
// wait for ready FDs
|
||||
select( highest_fd+1 , &descriptors_read, &descriptors_write, NULL, timeout);
|
||||
|
||||
// process data sources very carefully
|
||||
// bt_control.close() triggered from a client can remove a different data source
|
||||
|
||||
// log_info("btstack_run_loop_posix_execute: before ds check\n");
|
||||
|
||||
data_sources_modified = 0;
|
||||
btstack_linked_list_iterator_init(&it, &data_sources);
|
||||
while (btstack_linked_list_iterator_has_next(&it) && !data_sources_modified){
|
||||
btstack_data_source_t *ds = (btstack_data_source_t*) btstack_linked_list_iterator_next(&it);
|
||||
// log_info("btstack_run_loop_posix_execute: check %x with fd %u\n", (int) ds, ds->fd);
|
||||
log_debug("btstack_run_loop_posix_execute: check %x with fd %u\n", (int) ds, ds->fd);
|
||||
if (FD_ISSET(ds->fd, &descriptors_read)) {
|
||||
// log_info("btstack_run_loop_posix_execute: process read %x with fd %u\n", (int) ds, ds->fd);
|
||||
log_debug("btstack_run_loop_posix_execute: process read %x with fd %u\n", (int) ds, ds->fd);
|
||||
ds->process(ds, DATA_SOURCE_CALLBACK_READ);
|
||||
}
|
||||
if (FD_ISSET(ds->fd, &descriptors_write)) {
|
||||
// log_info("btstack_run_loop_posix_execute: process write %x with fd %u\n", (int) ds, ds->fd);
|
||||
log_debug("btstack_run_loop_posix_execute: process write %x with fd %u\n", (int) ds, ds->fd);
|
||||
ds->process(ds, DATA_SOURCE_CALLBACK_WRITE);
|
||||
}
|
||||
}
|
||||
// log_info("btstack_run_loop_posix_execute: after ds check\n");
|
||||
log_debug("btstack_run_loop_posix_execute: after ds check\n");
|
||||
|
||||
// process timers
|
||||
// pre: 0 <= tv_usec < 1000000
|
||||
while (timers) {
|
||||
gettimeofday(¤t_tv, NULL);
|
||||
ts = (btstack_timer_source_t *) timers;
|
||||
if (ts->timeout.tv_sec > current_tv.tv_sec) break;
|
||||
if (ts->timeout.tv_sec == current_tv.tv_sec && ts->timeout.tv_usec > current_tv.tv_usec) break;
|
||||
// log_info("btstack_run_loop_posix_execute: process times %x\n", (int) ts);
|
||||
if (ts->timeout > now_ms) break;
|
||||
log_debug("btstack_run_loop_posix_execute: process timer %p\n", ts);
|
||||
|
||||
// remove timer before processing it to allow handler to re-register with run loop
|
||||
btstack_run_loop_remove_timer(ts);
|
||||
@ -224,63 +229,18 @@ static void btstack_run_loop_posix_execute(void) {
|
||||
|
||||
// set timer
|
||||
static void btstack_run_loop_posix_set_timer(btstack_timer_source_t *a, uint32_t timeout_in_ms){
|
||||
gettimeofday(&a->timeout, NULL);
|
||||
a->timeout.tv_sec += timeout_in_ms / 1000;
|
||||
a->timeout.tv_usec += (timeout_in_ms % 1000) * 1000;
|
||||
if (a->timeout.tv_usec > 1000000) {
|
||||
a->timeout.tv_usec -= 1000000;
|
||||
a->timeout.tv_sec++;
|
||||
}
|
||||
}
|
||||
|
||||
// compare timers - NULL is assumed to be before the Big Bang
|
||||
// pre: 0 <= tv_usec < 1000000
|
||||
static int btstack_run_loop_posix_timeval_compare(struct timeval *a, struct timeval *b){
|
||||
if (!a && !b) return 0;
|
||||
if (!a) return -1;
|
||||
if (!b) return 1;
|
||||
|
||||
if (a->tv_sec < b->tv_sec) {
|
||||
return -1;
|
||||
}
|
||||
if (a->tv_sec > b->tv_sec) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (a->tv_usec < b->tv_usec) {
|
||||
return -1;
|
||||
}
|
||||
if (a->tv_usec > b->tv_usec) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// compare timers - NULL is assumed to be before the Big Bang
|
||||
// pre: 0 <= tv_usec < 1000000
|
||||
static int btstack_run_loop_posix_timer_compare(btstack_timer_source_t *a, btstack_timer_source_t *b){
|
||||
if (!a && !b) return 0;
|
||||
if (!a) return -1;
|
||||
if (!b) return 1;
|
||||
return btstack_run_loop_posix_timeval_compare(&a->timeout, &b->timeout);
|
||||
uint32_t time_ms = btstack_run_loop_posix_get_time_ms();
|
||||
a->timeout = time_ms + timeout_in_ms;
|
||||
log_info("btstack_run_loop_posix_set_timer to %u ms (now %u, timeout %u)", a->timeout, time_ms, timeout_in_ms);
|
||||
}
|
||||
|
||||
static void btstack_run_loop_posix_init(void){
|
||||
data_sources = NULL;
|
||||
timers = NULL;
|
||||
// just assume that we started at tv_usec == 0
|
||||
gettimeofday(&init_tv, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Queries the current time in ms since start
|
||||
*/
|
||||
static uint32_t btstack_run_loop_posix_get_time_ms(void){
|
||||
struct timeval current_tv;
|
||||
gettimeofday(¤t_tv, NULL);
|
||||
return (current_tv.tv_sec - init_tv.tv_sec) * 1000
|
||||
+ (current_tv.tv_usec - init_tv.tv_usec) / 1000;
|
||||
init_tv.tv_usec = 0;
|
||||
log_debug("btstack_run_loop_posix_init at %u/%u", (int) init_tv.tv_sec, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,10 +50,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef HAVE_POSIX_TIME
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -81,12 +77,8 @@ typedef struct btstack_data_source {
|
||||
|
||||
typedef struct btstack_timer_source {
|
||||
btstack_linked_item_t item;
|
||||
#ifdef HAVE_POSIX_TIME
|
||||
struct timeval timeout; // <-- next timeout
|
||||
#endif
|
||||
#if defined(HAVE_EMBEDDED_TICK) || defined(HAVE_EMBEDDED_TIME_MS)
|
||||
uint32_t timeout; // timeout in system ticks (HAVE_EMBEDDED_TICK) or millis (HAVE_EMBEDDED_TIME_MS)
|
||||
#endif
|
||||
// timeout in system ticks (HAVE_EMBEDDED_TICK) or milliseconds (HAVE_EMBEDDED_TIME_MS)
|
||||
uint32_t timeout;
|
||||
// will be called when timer fired
|
||||
void (*process)(struct btstack_timer_source *ts);
|
||||
void * context;
|
||||
|
19
src/hci.c
19
src/hci.c
@ -207,38 +207,23 @@ hci_connection_t * hci_connection_for_bd_addr_and_type(bd_addr_t addr, bd_addr_
|
||||
|
||||
static void hci_connection_timeout_handler(btstack_timer_source_t *timer){
|
||||
hci_connection_t * connection = (hci_connection_t *) btstack_run_loop_get_timer_context(timer);
|
||||
#ifdef HAVE_POSIX_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);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_EMBEDDED_TICK
|
||||
if (btstack_run_loop_embedded_get_ticks() > connection->timestamp + btstack_run_loop_embedded_ticks_for_ms(HCI_CONNECTION_TIMEOUT_MS)){
|
||||
// connections might be timed out
|
||||
hci_emit_l2cap_check_timeout(connection);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_EMBEDDED_TIME_MS
|
||||
#else
|
||||
if (btstack_run_loop_get_time_ms() > connection->timestamp + HCI_CONNECTION_TIMEOUT_MS){
|
||||
// connections might be timed out
|
||||
hci_emit_l2cap_check_timeout(connection);
|
||||
}
|
||||
#endif
|
||||
btstack_run_loop_set_timer(timer, HCI_CONNECTION_TIMEOUT_MS);
|
||||
btstack_run_loop_add_timer(timer);
|
||||
}
|
||||
|
||||
static void hci_connection_timestamp(hci_connection_t *connection){
|
||||
#ifdef HAVE_POSIX_TIME
|
||||
gettimeofday(&connection->timestamp, NULL);
|
||||
#endif
|
||||
#ifdef HAVE_EMBEDDED_TICK
|
||||
connection->timestamp = btstack_run_loop_embedded_get_ticks();
|
||||
#endif
|
||||
#ifdef HAVE_EMBEDDED_TIME_MS
|
||||
#else
|
||||
connection->timestamp = btstack_run_loop_get_time_ms();
|
||||
#endif
|
||||
}
|
||||
|
12
src/hci.h
12
src/hci.h
@ -386,16 +386,8 @@ typedef struct {
|
||||
|
||||
btstack_timer_source_t timeout;
|
||||
|
||||
#ifdef HAVE_POSIX_TIME
|
||||
// timer
|
||||
struct timeval timestamp;
|
||||
#endif
|
||||
#ifdef HAVE_EMBEDDED_TICK
|
||||
uint32_t timestamp; // timestamp in system ticks
|
||||
#endif
|
||||
#ifdef HAVE_EMBEDDED_TIME_MS
|
||||
uint32_t timestamp; // timestamp in ms
|
||||
#endif
|
||||
// timeout in system ticks (HAVE_EMBEDDED_TICK) or milliseconds (HAVE_EMBEDDED_TIME_MS)
|
||||
uint32_t timestamp;
|
||||
|
||||
// ACL packet recombination - PRE_BUFFER + ACL Header + ACL payload
|
||||
uint8_t acl_recombination_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + 4 + HCI_ACL_BUFFER_SIZE];
|
||||
|
Loading…
x
Reference in New Issue
Block a user