mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-22 06:41:17 +00:00
prepare socket_server and hci for client/server use
This commit is contained in:
parent
9265f5e24d
commit
498571813b
@ -340,6 +340,10 @@ int hci_send_acl_packet(uint8_t *packet, int size){
|
||||
return hci_stack.hci_transport->send_acl_packet(packet, size);
|
||||
}
|
||||
|
||||
int hci_send_cmd_packet(uint8_t *packet, int size){
|
||||
hci_stack.num_cmd_packets--;
|
||||
return hci_stack.hci_transport->send_cmd_packet(packet, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* pre: numcmds >= 0 - it's allowed to send a command to the controller
|
||||
@ -411,7 +415,5 @@ int hci_send_cmd(hci_cmd_t *cmd, ...){
|
||||
};
|
||||
va_end(argptr);
|
||||
hci_cmd_buffer[2] = pos - 3;
|
||||
// send packet
|
||||
hci_stack.num_cmd_packets--;
|
||||
return hci_stack.hci_transport->send_cmd_packet(hci_cmd_buffer, pos);
|
||||
return hci_send_cmd_packet(hci_cmd_buffer, pos);
|
||||
}
|
@ -176,6 +176,7 @@ void hexdump(void *data, int size);
|
||||
|
||||
// create and send hci command packet based on a template and a list of parameters
|
||||
int hci_send_cmd(hci_cmd_t *cmd, ...);
|
||||
int hci_send_cmd_packet(uint8_t *packet, int size);
|
||||
|
||||
// send ACL packet
|
||||
int hci_send_acl_packet(uint8_t *packet, int size);
|
||||
|
@ -50,7 +50,7 @@ void run_loop_execute() {
|
||||
|
||||
// process input
|
||||
data_source_t *next;
|
||||
for (ds = (data_source_t *) the_run_loop; ds != NULL ; ds = (data_source_t *) ds->item.next){
|
||||
for (ds = (data_source_t *) the_run_loop; ds != NULL ; ds = next){
|
||||
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)) {
|
||||
ds->process(ds, FD_ISSET(ds->fd, &descriptors));
|
||||
|
@ -38,15 +38,15 @@ typedef enum {
|
||||
} SOCKET_STATE;
|
||||
|
||||
typedef struct connection {
|
||||
data_source_t ds;
|
||||
struct connection * next;
|
||||
data_source_t ds; // used for run loop
|
||||
linked_item_t item; // used for connection list
|
||||
SOCKET_STATE state;
|
||||
uint16_t bytes_read;
|
||||
uint16_t bytes_to_read;
|
||||
char buffer[3+3+255]; // max HCI CMD + packet_header
|
||||
uint8_t buffer[3+3+255]; // max HCI CMD + packet_header
|
||||
} connection_t;
|
||||
|
||||
connection_t *connections = NULL;
|
||||
linked_list_t connections = NULL;
|
||||
|
||||
static char test_buffer[DATA_BUF_SIZE];
|
||||
|
||||
@ -63,21 +63,24 @@ int socket_server_set_non_blocking(int fd)
|
||||
return err;
|
||||
}
|
||||
|
||||
void socket_server_free_connection(connection_t *conn){
|
||||
// remove from run_loop
|
||||
run_loop_remove(&conn->ds);
|
||||
|
||||
// and from connection list
|
||||
linked_list_remove(&connections, &conn->item);
|
||||
|
||||
// destroy
|
||||
free(conn);
|
||||
}
|
||||
|
||||
static int socket_server_echo_process(struct data_source *ds, int ready) {
|
||||
int bytes_read = read(ds->fd, test_buffer, DATA_BUF_SIZE);
|
||||
|
||||
// connection closed by client?
|
||||
if (bytes_read < 0){
|
||||
|
||||
// emit signal
|
||||
|
||||
// remove from run_loop
|
||||
// @note: run_loop_execute must be prepared for this
|
||||
run_loop_remove(ds);
|
||||
|
||||
// destroy
|
||||
free(ds);
|
||||
|
||||
if (bytes_read <= 0){
|
||||
// free
|
||||
socket_server_free_connection( linked_item_get_user(&ds->item));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -87,13 +90,14 @@ static int socket_server_echo_process(struct data_source *ds, int ready) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int socket_server_connection_process(struct data_source *ds, int ready) {
|
||||
int socket_server_connection_process(struct data_source *ds, int ready) {
|
||||
connection_t *conn = (connection_t *) ds;
|
||||
int bytes_read = read(ds->fd, &conn->buffer[conn->bytes_read],
|
||||
sizeof(packet_header_t) - conn->bytes_read);
|
||||
if (bytes_read <= 0){
|
||||
//
|
||||
// free
|
||||
socket_server_free_connection( linked_item_get_user(&ds->item));
|
||||
return 0;
|
||||
}
|
||||
conn->bytes_read += bytes_read;
|
||||
conn->bytes_to_read -= bytes_read;
|
||||
@ -103,11 +107,20 @@ static int socket_server_connection_process(struct data_source *ds, int ready) {
|
||||
switch (conn->state){
|
||||
case SOCKET_W4_HEADER:
|
||||
conn->state = SOCKET_W4_DATA;
|
||||
conn->bytes_to_read = READ_BT_16( conn->buffer, 0);
|
||||
conn->bytes_to_read = READ_BT_16( conn->buffer, 0) + sizeof(packet_header_t);
|
||||
break;
|
||||
case SOCKET_W4_DATA:
|
||||
// process packet !!!
|
||||
|
||||
switch (conn->buffer[2]){
|
||||
case HCI_COMMAND_DATA_PACKET:
|
||||
hci_send_cmd_packet(&conn->buffer[3], READ_BT_16( conn->buffer, 0));
|
||||
break;
|
||||
case HCI_ACL_DATA_PACKET:
|
||||
hci_send_acl_packet(&conn->buffer[3], READ_BT_16( conn->buffer, 0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// wait for next packet
|
||||
conn->state = SOCKET_W4_HEADER;
|
||||
@ -117,7 +130,29 @@ static int socket_server_connection_process(struct data_source *ds, int ready) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int socket_server_send_packet_all(uint8_t type, uint8_t *packet, uint16_t size){
|
||||
uint8_t length[2];
|
||||
bt_store_16( (uint8_t *) &length, 0, size);
|
||||
connection_t *next;
|
||||
connection_t *it;
|
||||
for (it = (connection_t *) connections; it != NULL ; it = next){
|
||||
next = (connection_t *) it->item.next; // cache pointer to next connection_t to allow for removal
|
||||
write(it->ds.fd, &length, 2);
|
||||
write(it->ds.fd, &type, 1);
|
||||
write(it->ds.fd, packet, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int socket_server_send_event_all(uint8_t *packet, uint16_t size){
|
||||
return socket_server_send_packet_all( HCI_EVENT_PACKET, packet, size);
|
||||
}
|
||||
|
||||
int socket_server_send_acl_all(uint8_t *packet, uint16_t size){
|
||||
return socket_server_send_packet_all( HCI_ACL_DATA_PACKET, packet, size);
|
||||
}
|
||||
|
||||
|
||||
static int socket_server_accept(struct data_source *socket_ds, int ready) {
|
||||
|
||||
@ -141,14 +176,15 @@ static int socket_server_accept(struct data_source *socket_ds, int ready) {
|
||||
}
|
||||
// non-blocking ?
|
||||
// socket_server_set_non_blocking(ds->fd);
|
||||
|
||||
// store reference to this connection
|
||||
conn->next = NULL;
|
||||
connections = conn;
|
||||
|
||||
|
||||
// add this socket to the run_loop
|
||||
linked_item_set_user( &conn->ds.item, conn);
|
||||
run_loop_add( &conn->ds );
|
||||
|
||||
// and the connection list
|
||||
linked_item_set_user( &conn->item, conn);
|
||||
linked_list_add( &connections, &conn->item);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -161,7 +197,7 @@ data_source_t * socket_server_create_tcp(int port){
|
||||
|
||||
// create data_source_t
|
||||
data_source_t *ds = malloc( sizeof(data_source_t));
|
||||
if (ds == NULL) return ds;
|
||||
if (ds == NULL) return NULL;
|
||||
ds->fd = 0;
|
||||
ds->process = socket_server_accept;
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "run_loop.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* create socket data_source for tcp socket
|
||||
@ -23,3 +24,9 @@ data_source_t * socket_server_create_unix(char *path);
|
||||
* @todo: hack callback to allow data reception - replace with better architecture
|
||||
*/
|
||||
void socket_server_register_process_callback( int (*process_callback)(struct data_source *ds, int ready) );
|
||||
|
||||
int socket_server_send_event_all(uint8_t *packet, uint16_t size);
|
||||
int socket_server_send_acl_all(uint8_t *packet, uint16_t size);
|
||||
|
||||
// send ACL packet
|
||||
int hci_send_acl_packet(uint8_t *packet, int size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user