Merge branch 'develop' of https://github.com/bluekitchen/btstack into develop

This commit is contained in:
Milanka Ringwald 2016-03-30 15:05:38 +02:00
commit 185c7bdad7
4 changed files with 53 additions and 124 deletions

View File

@ -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(&current_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(&current_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(&current_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);
}

View File

@ -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;

View File

@ -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
}

View File

@ -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];