adapt hci_transport_t to directly sub-class data_source_t

This commit is contained in:
matthias.ringwald 2009-06-06 19:52:36 +00:00
parent 94ab26f8d1
commit bb96ef8cd9
6 changed files with 43 additions and 45 deletions

View File

@ -1,16 +1,11 @@
/* new todo file for BTstack */
REFACTOR
- implement data_source
- single fd per data_source
- implement run_loop
- adapt current BT implementation to use new run_loop
NEW FUNCTIONALITY
- implement single connection event-driven socket server
- socket fd in data_source can be temp. replaced by actual connection fd
IMPROVE
- make data_source_t opaque: data_source_set_fd, data_source_set_cb
- implement TimerSource
- implement some kind of noitfy mechanism between multiple units
- make SocketServer object-oriented

View File

@ -9,16 +9,16 @@
#pragma once
#include <stdint.h>
#include "run_loop.h"
typedef struct {
data_source_t ds;
int (*open)(void *transport_config);
int (*close)();
int (*send_cmd_packet)(uint8_t *packet, int size);
int (*send_acl_packet)(uint8_t *packet, int size);
void (*register_event_packet_handler)(void (*handler)(uint8_t *packet, int size));
void (*register_acl_packet_handler) (void (*handler)(uint8_t *packet, int size));
int (*get_fd)(); // <-- only used for select(..) call
int (*handle_data)(); // -- to be called when select( .. ) returns for the fd
const char * (*get_transport_name)();
} hci_transport_t;

View File

@ -22,10 +22,12 @@ typedef enum {
H4_W4_ACL_PAYLOAD
} H4_STATE;
// single instance
static hci_transport_t * hci_transport_h4 = NULL;
static void dummy_handler(uint8_t *packet, int size);
static hci_uart_config_t *hci_uart_config;
static int fd;
static void (*event_packet_handler)(uint8_t *packet, int size) = dummy_handler;
static void (*acl_packet_handler) (uint8_t *packet, int size) = dummy_handler;
@ -41,7 +43,7 @@ static uint8_t hci_packet[400]; // bigger than largest packet
static int h4_open(void *transport_config){
hci_uart_config = (hci_uart_config_t*) transport_config;
struct termios toptions;
fd = open(hci_uart_config->device_name, O_RDWR | O_NOCTTY | O_NDELAY);
int fd = open(hci_uart_config->device_name, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror("init_serialport: Unable to open port ");
perror(hci_uart_config->device_name);
@ -98,6 +100,9 @@ static int h4_open(void *transport_config){
return -1;
}
// set up data_source
hci_transport_h4->ds.fd = fd;
// init state machine
bytes_to_read = 1;
h4_state = H4_W4_PACKET_TYPE;
@ -107,11 +112,14 @@ static int h4_open(void *transport_config){
}
static int h4_close(){
close(fd);
close(hci_transport_h4->ds.fd);
hci_transport_h4->ds.fd = 0;
return 0;
}
static int h4_send_cmd_packet(uint8_t *packet, int size){
if (hci_transport_h4->ds.fd == 0) return -1;
printf("CMD: ");
hexdump(packet, size);
@ -120,9 +128,9 @@ static int h4_send_cmd_packet(uint8_t *packet, int size){
hci_dump_packet( (uint8_t) packet_type, 0, packet, size);
write(fd, &packet_type, 1);
write(hci_transport_h4->ds.fd, &packet_type, 1);
while (size > 0) {
int bytes_written = write(fd, data, size);
int bytes_written = write(hci_transport_h4->ds.fd, data, size);
if (bytes_written < 0) {
return bytes_written;
}
@ -133,6 +141,8 @@ static int h4_send_cmd_packet(uint8_t *packet, int size){
}
static int h4_send_acl_packet(uint8_t *packet, int size){
if (hci_transport_h4->ds.fd == 0) return -1;
printf("ACL> ");
hexdump(packet, size);
@ -141,9 +151,9 @@ static int h4_send_acl_packet(uint8_t *packet, int size){
hci_dump_packet( (uint8_t) packet_type, 0, packet, size);
write(fd, &packet_type, 1);
write(hci_transport_h4->ds.fd, &packet_type, 1);
while (size > 0) {
int bytes_written = write(fd, data, size);
int bytes_written = write(hci_transport_h4->ds.fd, data, size);
if (bytes_written < 0) {
return bytes_written;
}
@ -161,13 +171,11 @@ static void h4_register_acl_packet_handler (void (*handler)(uint8_t *packet,
acl_packet_handler = handler;
}
static int h4_get_fd() {
return fd;
}
static int h4_handle_data() {
if (hci_transport_h4->ds.fd == 0) return -1;
// read up to bytes_to_read data in
int bytes_read = read(fd, &hci_packet[read_pos], bytes_to_read);
int bytes_read = read(hci_transport_h4->ds.fd, &hci_packet[read_pos], bytes_to_read);
if (bytes_read < 0) {
return bytes_read;
}
@ -233,15 +241,19 @@ static const char * h4_get_transport_name(){
static void dummy_handler(uint8_t *packet, int size){
}
// single instance
hci_transport_t hci_transport_h4 = {
h4_open,
h4_close,
h4_send_cmd_packet,
h4_send_acl_packet,
h4_register_event_packet_handler,
h4_register_acl_packet_handler,
h4_get_fd,
h4_handle_data,
h4_get_transport_name
};
// get h4 singleton
hci_transport_t * hci_transport_h4_instance() {
if (hci_transport_h4 == NULL) {
hci_transport_h4 = malloc( sizeof(hci_transport_t));
hci_transport_h4->ds.fd = 0;
hci_transport_h4->ds.process = h4_handle_data;
hci_transport_h4->open = h4_open;
hci_transport_h4->close = h4_close;
hci_transport_h4->send_cmd_packet = h4_send_cmd_packet;
hci_transport_h4->send_acl_packet = h4_send_acl_packet;
hci_transport_h4->register_event_packet_handler = h4_register_event_packet_handler;
hci_transport_h4->register_acl_packet_handler = h4_register_acl_packet_handler;
hci_transport_h4->get_transport_name = h4_get_transport_name;
}
return hci_transport_h4;
}

View File

@ -32,4 +32,4 @@
#define HCI_EVENT_PACKET 0x04
extern hci_transport_t hci_transport_h4;
extern hci_transport_t * hci_transport_h4_instance();

View File

@ -109,11 +109,6 @@ void acl_handler(uint8_t *packet, int size){
}
}
int transport_run_loop_cb(data_source_t * ds, int ready){
transport->handle_data();
return 0;
}
int main (int argc, const char * argv[]) {
bt_control_t * control = NULL;
@ -145,7 +140,7 @@ int main (int argc, const char * argv[]) {
hci_dump_open("/tmp/hci_dump.pklg", HCI_DUMP_PACKETLOGGER);
// H4 UART
transport = &hci_transport_h4;
transport = hci_transport_h4_instance();
// init HCI
hci_init(transport, &config, control);
@ -163,10 +158,7 @@ int main (int argc, const char * argv[]) {
hci_run();
// configure run loop
data_source_t hci_transport;
hci_transport.fd = transport->get_fd();
hci_transport.process = &transport_run_loop_cb;
run_loop_add(&hci_transport);
run_loop_add( (data_source_t *) transport);
// go!
run_loop_execute();

View File

@ -49,7 +49,6 @@ int run_loop_remove(data_source_t *ds){
void run_loop_execute() {
fd_set descriptors;
data_source_t *ds;
int highest;
while (1) {
// collect FDs
FD_ZERO(&descriptors);
@ -63,7 +62,7 @@ void run_loop_execute() {
}
}
// wait for ready FDs
select( highest+1, &descriptors, NULL, NULL, NULL);
select( highest_fd+1 , &descriptors, NULL, NULL, NULL);
// process input
for (ds = the_run_loop; ds != NULL ; ds = ds->next){