mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-23 11:43:24 +00:00
removed ready paramter from data_source callbacks, added timer management functions to run loop
This commit is contained in:
parent
75a8ec5e31
commit
7b22b9bc7d
@ -89,8 +89,7 @@ void event_handler(uint8_t *packet, uint16_t size){
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, const char * argv[]){
|
int main (int argc, const char * argv[]){
|
||||||
bt_open();
|
bt_open();
|
||||||
bt_register_event_packet_handler(event_handler);
|
bt_register_event_packet_handler(event_handler);
|
||||||
|
@ -30,9 +30,9 @@ typedef struct hci_transport_h4 {
|
|||||||
// single instance
|
// single instance
|
||||||
static hci_transport_h4_t * hci_transport_h4 = NULL;
|
static hci_transport_h4_t * hci_transport_h4 = NULL;
|
||||||
|
|
||||||
static int h4_process(struct data_source *ds, int ready);
|
static int h4_process(struct data_source *ds);
|
||||||
static void dummy_handler(uint8_t *packet, int size);
|
static void dummy_handler(uint8_t *packet, int size);
|
||||||
static hci_uart_config_t *hci_uart_config;
|
static hci_uart_config_t *hci_uart_config;
|
||||||
|
|
||||||
static void (*event_packet_handler)(uint8_t *packet, int size) = dummy_handler;
|
static void (*event_packet_handler)(uint8_t *packet, int size) = dummy_handler;
|
||||||
static void (*acl_packet_handler) (uint8_t *packet, int size) = dummy_handler;
|
static void (*acl_packet_handler) (uint8_t *packet, int size) = dummy_handler;
|
||||||
@ -110,7 +110,7 @@ static int h4_open(void *transport_config){
|
|||||||
if (!hci_transport_h4) return -1;
|
if (!hci_transport_h4) return -1;
|
||||||
hci_transport_h4->ds->fd = fd;
|
hci_transport_h4->ds->fd = fd;
|
||||||
hci_transport_h4->ds->process = h4_process;
|
hci_transport_h4->ds->process = h4_process;
|
||||||
run_loop_add(hci_transport_h4->ds);
|
run_loop_add_data_source(hci_transport_h4->ds);
|
||||||
|
|
||||||
// init state machine
|
// init state machine
|
||||||
bytes_to_read = 1;
|
bytes_to_read = 1;
|
||||||
@ -122,7 +122,7 @@ static int h4_open(void *transport_config){
|
|||||||
|
|
||||||
static int h4_close(){
|
static int h4_close(){
|
||||||
// first remove run loop handler
|
// first remove run loop handler
|
||||||
run_loop_remove(hci_transport_h4->ds);
|
run_loop_remove_data_source(hci_transport_h4->ds);
|
||||||
|
|
||||||
// close device
|
// close device
|
||||||
close(hci_transport_h4->ds->fd);
|
close(hci_transport_h4->ds->fd);
|
||||||
@ -181,7 +181,7 @@ static void h4_register_acl_packet_handler (void (*handler)(uint8_t *packet,
|
|||||||
acl_packet_handler = handler;
|
acl_packet_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int h4_process(struct data_source *ds, int ready) {
|
static int h4_process(struct data_source *ds) {
|
||||||
if (hci_transport_h4->ds->fd == 0) return -1;
|
if (hci_transport_h4->ds->fd == 0) return -1;
|
||||||
|
|
||||||
// read up to bytes_to_read data in
|
// read up to bytes_to_read data in
|
||||||
|
@ -9,22 +9,84 @@
|
|||||||
|
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
// the run loop
|
// the run loop
|
||||||
static linked_list_t the_run_loop = NULL;
|
static linked_list_t data_sources = NULL;
|
||||||
|
static linked_list_t timers = NULL;
|
||||||
|
|
||||||
|
// set timer
|
||||||
|
void run_loop_set_timer(timer_t *a, int timeout_in_seconds){
|
||||||
|
gettimeofday(&a->timeout, NULL);
|
||||||
|
a->timeout.tv_sec += timeout_in_seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare timers - NULL is assumed to be before the Big Bang
|
||||||
|
int run_loop_timer_compare(timer_t *a, timer_t *b){
|
||||||
|
|
||||||
|
if (!a || !b) return 0;
|
||||||
|
if (!a) return -1;
|
||||||
|
if (!b) return 1;
|
||||||
|
|
||||||
|
if (a->timeout.tv_sec < b->timeout.tv_sec) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a->timeout.tv_sec > b->timeout.tv_sec) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->timeout.tv_usec < b->timeout.tv_usec) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a->timeout.tv_usec > b->timeout.tv_usec) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add data_source to run_loop
|
* Add data_source to run_loop
|
||||||
*/
|
*/
|
||||||
void run_loop_add(data_source_t *ds){
|
void run_loop_add_data_source(data_source_t *ds){
|
||||||
linked_list_add(&the_run_loop, (linked_item_t *) ds);
|
linked_list_add(&data_sources, (linked_item_t *) ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove data_source from run loop
|
* Remove data_source from run loop
|
||||||
*/
|
*/
|
||||||
int run_loop_remove(data_source_t *ds){
|
int run_loop_remove_data_source(data_source_t *ds){
|
||||||
return linked_list_remove(&the_run_loop, (linked_item_t *) ds);
|
return linked_list_remove(&data_sources, (linked_item_t *) ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add timer to run_loop (keep list sorted)
|
||||||
|
*/
|
||||||
|
void run_loop_add_timer(timer_t *ts){
|
||||||
|
linked_item_t *it;
|
||||||
|
for (it = (linked_item_t *) &timers; it ; it = it->next){
|
||||||
|
if ( run_loop_timer_compare( (timer_t *) it->next, ts) >= 0) {
|
||||||
|
ts->item.next = it->next;
|
||||||
|
it->next = (linked_item_t *) ts;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove timer from run loop
|
||||||
|
*/
|
||||||
|
int run_loop_remove_timer(timer_t *ts){
|
||||||
|
return linked_list_remove(&timers, (linked_item_t *) ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_loop_timer_dump(){
|
||||||
|
linked_item_t *it;
|
||||||
|
int i = 0;
|
||||||
|
for (it = (linked_item_t *) timers; it ; it = it->next){
|
||||||
|
timer_t *ts = (timer_t*) it;
|
||||||
|
printf("timer %u, timeout %u\n", i, ts->timeout.tv_sec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,11 +95,13 @@ int run_loop_remove(data_source_t *ds){
|
|||||||
void run_loop_execute() {
|
void run_loop_execute() {
|
||||||
fd_set descriptors;
|
fd_set descriptors;
|
||||||
data_source_t *ds;
|
data_source_t *ds;
|
||||||
|
timer_t *ts;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// collect FDs
|
// collect FDs
|
||||||
FD_ZERO(&descriptors);
|
FD_ZERO(&descriptors);
|
||||||
int highest_fd = 0;
|
int highest_fd = 0;
|
||||||
for (ds = (data_source_t *) the_run_loop; ds ; ds = (data_source_t *) ds->item.next){
|
for (ds = (data_source_t *) data_sources; ds ; ds = (data_source_t *) ds->item.next){
|
||||||
if (ds->fd) {
|
if (ds->fd) {
|
||||||
FD_SET(ds->fd, &descriptors);
|
FD_SET(ds->fd, &descriptors);
|
||||||
if (ds->fd > highest_fd) {
|
if (ds->fd > highest_fd) {
|
||||||
@ -45,17 +109,24 @@ void run_loop_execute() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get next timeout
|
||||||
|
// ..
|
||||||
|
|
||||||
// wait for ready FDs
|
// wait for ready FDs
|
||||||
select( highest_fd+1 , &descriptors, NULL, NULL, NULL);
|
select( highest_fd+1 , &descriptors, NULL, NULL, NULL);
|
||||||
|
|
||||||
// process input
|
// process data sources
|
||||||
data_source_t *next;
|
data_source_t *next;
|
||||||
for (ds = (data_source_t *) the_run_loop; ds != NULL ; ds = next){
|
for (ds = (data_source_t *) data_sources; ds != NULL ; ds = next){
|
||||||
next = (data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself
|
next = (data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself
|
||||||
if (FD_ISSET(ds->fd, &descriptors)) {
|
if (FD_ISSET(ds->fd, &descriptors)) {
|
||||||
ds->process(ds, FD_ISSET(ds->fd, &descriptors));
|
ds->process(ds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process timers
|
||||||
|
// ..
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,16 +8,32 @@
|
|||||||
|
|
||||||
#include "linked_list.h"
|
#include "linked_list.h"
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
typedef struct data_source {
|
typedef struct data_source {
|
||||||
linked_item_t item;
|
linked_item_t item;
|
||||||
int fd; // <-- file descriptors to watch or 0
|
int fd; // <-- file descriptors to watch or 0
|
||||||
int (*process)(struct data_source *ds, int ready); // <-- do processing, @return: more to do
|
int (*process)(struct data_source *ds); // <-- do processing
|
||||||
} data_source_t;
|
} data_source_t;
|
||||||
|
|
||||||
typedef struct timer_source {
|
typedef struct timer {
|
||||||
struct timer_source *next;
|
linked_item_t item;
|
||||||
} timer_source_t;
|
struct timeval timeout; // <-- next timeout
|
||||||
|
int (*process)(struct timer *ts); // <-- do processing
|
||||||
|
} timer_t;
|
||||||
|
|
||||||
void run_loop_add(data_source_t *dataSource); // <-- add DataSource to RunLoop
|
// set timer based on current time
|
||||||
int run_loop_remove(data_source_t *dataSource); // <-- remove DataSource from RunLoop
|
void run_loop_set_timer(timer_t *a, int timeout_in_seconds);
|
||||||
void run_loop_execute(); // <-- execute configured RunLoop
|
|
||||||
|
// compare timers - NULL is assumed to be before the Big Bang
|
||||||
|
int run_loop_timer_compare(timer_t *a, timer_t *b);
|
||||||
|
|
||||||
|
void run_loop_add_data_source(data_source_t *dataSource); // <-- add DataSource to RunLoop
|
||||||
|
int run_loop_remove_data_source(data_source_t *dataSource); // <-- remove DataSource from RunLoop
|
||||||
|
|
||||||
|
void run_loop_add_timer(timer_t *timer); // <-- add Timer to RunLoop
|
||||||
|
int run_loop_remove_timer(timer_t *timer); // <-- remove Timer from RunLoop
|
||||||
|
|
||||||
|
void run_loop_timer_dump(); // debug
|
||||||
|
|
||||||
|
void run_loop_execute(); // <-- execute configured RunLoop
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#define DATA_BUF_SIZE 80
|
#define DATA_BUF_SIZE 80
|
||||||
|
|
||||||
/** prototypes */
|
/** prototypes */
|
||||||
static int socket_connection_hci_process(struct data_source *ds, int ready);
|
static int socket_connection_hci_process(struct data_source *ds);
|
||||||
static int socket_connection_dummy_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length);
|
static int socket_connection_dummy_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length);
|
||||||
|
|
||||||
/** globals */
|
/** globals */
|
||||||
@ -77,7 +77,7 @@ int socket_connection_set_non_blocking(int fd)
|
|||||||
|
|
||||||
void socket_connection_free_connection(connection_t *conn){
|
void socket_connection_free_connection(connection_t *conn){
|
||||||
// remove from run_loop
|
// remove from run_loop
|
||||||
run_loop_remove(&conn->ds);
|
run_loop_remove_data_source(&conn->ds);
|
||||||
|
|
||||||
// and from connection list
|
// and from connection list
|
||||||
linked_list_remove(&connections, &conn->item);
|
linked_list_remove(&connections, &conn->item);
|
||||||
@ -106,7 +106,7 @@ connection_t * socket_connection_register_new_connection(int fd){
|
|||||||
socket_connection_init_statemachine(conn);
|
socket_connection_init_statemachine(conn);
|
||||||
|
|
||||||
// add this socket to the run_loop
|
// add this socket to the run_loop
|
||||||
run_loop_add( &conn->ds );
|
run_loop_add_data_source( &conn->ds );
|
||||||
|
|
||||||
// and the connection list
|
// and the connection list
|
||||||
linked_list_add( &connections, &conn->item);
|
linked_list_add( &connections, &conn->item);
|
||||||
@ -114,7 +114,7 @@ connection_t * socket_connection_register_new_connection(int fd){
|
|||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
int socket_connection_hci_process(struct data_source *ds, int ready) {
|
int socket_connection_hci_process(struct data_source *ds) {
|
||||||
connection_t *conn = (connection_t *) ds;
|
connection_t *conn = (connection_t *) ds;
|
||||||
int bytes_read = read(ds->fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read);
|
int bytes_read = read(ds->fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read);
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ int socket_connection_hci_process(struct data_source *ds, int ready) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int socket_connection_accept(struct data_source *socket_ds, int ready) {
|
static int socket_connection_accept(struct data_source *socket_ds) {
|
||||||
|
|
||||||
/* New connection coming in! */
|
/* New connection coming in! */
|
||||||
int fd = accept(socket_ds->fd, NULL, NULL);
|
int fd = accept(socket_ds->fd, NULL, NULL);
|
||||||
@ -207,7 +207,7 @@ int socket_connection_create_tcp(int port){
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
run_loop_add(ds);
|
run_loop_add_data_source(ds);
|
||||||
|
|
||||||
printf ("Server up and running ...\n");
|
printf ("Server up and running ...\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -290,7 +290,7 @@ connection_t * socket_connection_open_tcp(){
|
|||||||
int socket_connection_close_tcp(connection_t * connection){
|
int socket_connection_close_tcp(connection_t * connection){
|
||||||
if (!connection) return -1;
|
if (!connection) return -1;
|
||||||
shutdown(connection->ds.fd, SHUT_RDWR);
|
shutdown(connection->ds.fd, SHUT_RDWR);
|
||||||
run_loop_remove(&connection->ds);
|
run_loop_remove_data_source(&connection->ds);
|
||||||
free( connection );
|
free( connection );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user