automatic turn off Bluetooth after 1 minutes idle

This commit is contained in:
matthias.ringwald 2009-08-09 20:18:34 +00:00
parent ee091cf1fd
commit 555971d7f5
5 changed files with 53 additions and 5 deletions

View File

@ -3,7 +3,6 @@
Last milestone reached: Restart client app without restarting BTdaemon possible
NEXT:
- automatic turn off Bluetooth after X minutes idle
- turn off Bluetooth on ctrl-c
- automatic start/stop of BTdaemon
- start BTdaemon by client lib

View File

@ -34,9 +34,18 @@
#include "hci_transport_usb.h"
#endif
#define DAEMON_NO_CONNECTION_TIMEOUT 60
static hci_transport_t * transport;
static hci_uart_config_t config;
static timer_t timeout;
static void daemon_no_connections_timeout(){
printf("No connection for %u secondes -> POWER OFF\n", DAEMON_NO_CONNECTION_TIMEOUT);
hci_power_control( HCI_POWER_OFF);
}
static int btstack_command_handler(connection_t *connection, uint8_t *packet, uint16_t size){
// BTstack Commands
hci_dump_packet( HCI_COMMAND_DATA_PACKET, 1, packet, size);
@ -86,8 +95,22 @@ static int daemon_client_handler(connection_t *connection, uint16_t packet_type,
l2cap_send_internal(channel, data, length);
break;
case DAEMON_EVENT_PACKET:
switch (data[0]) {
case DAEMON_CONNECTION_CLOSED:
l2cap_close_channels_for_connection(connection);
break;
case DAEMON_NR_CONNECTIONS_CHANGED:
// printf("Nr Connections changed, new %u\n", data[1]);
if (data[1]) {
run_loop_remove_timer(&timeout);
} else {
run_loop_set_timer(&timeout, DAEMON_NO_CONNECTION_TIMEOUT);
run_loop_add_timer(&timeout);
}
default:
break;
}
// only one event so far: client connection died
l2cap_close_channels_for_connection(connection);
break;
}
return 0;
@ -123,7 +146,9 @@ int main (int argc, const char * argv[]){
// init L2CAP
l2cap_init();
timeout.process = daemon_no_connections_timeout;
// @TODO: make choice of socket server configurable (TCP and/or Unix Domain Socket)
// @TODO: make port and/or socket configurable per config.h

View File

@ -72,7 +72,7 @@
#define HCI_EVENT_DATA_BUFFER_OVERFLOW 0x1A
#define HCI_EVENT_MAX_SLOTS_CHANGED 0x1B
#define HCI_EVENT_READ_CLOCK_OFFSET_COMPLETE 0x1C
#define NECTEVENT_ION_PACKET_TYPE_CHANGED 0x1D
#define HCI_EVENT_PACKET_TYPE_CHANGED 0x1D
#define HCI_EVENT_INQUIRY_RESULT_WITH_RSSI 0x22
#define HCI_EVENT_VENDOR_SPECIFIC 0xFF
@ -90,6 +90,12 @@
#define HCI_EVENT_L2CAP_TIMEOUT_CHECK 0x84
// data: event(8)
#define DAEMON_CONNECTION_CLOSED 0xc0
// data: event(8), nr_connections(8)
#define DAEMON_NR_CONNECTIONS_CHANGED 0xc1
#define COMMAND_COMPLETE_EVENT(event,cmd) ( event[0] == HCI_EVENT_COMMAND_COMPLETE && READ_BT_16(event,3) == cmd.opcode)
#define IS_COMMAND(packet, command) (READ_BT_16(packet,0) == command.opcode)

View File

@ -36,6 +36,7 @@
// extension for client/server communication
#define L2CAP_DATA_PACKET 0x05
#define DAEMON_EVENT_PACKET 0x06
typedef struct {

View File

@ -114,15 +114,31 @@ connection_t * socket_connection_register_new_connection(int fd){
return conn;
}
void static socket_connection_emit_nr_connections(){
linked_item_t *it;
uint8_t nr_connections = 0;
for (it = (linked_item_t *) connections; it != NULL ; it = it->next, nr_connections++);
uint8_t event[2];
event[0] = DAEMON_NR_CONNECTIONS_CHANGED;
event[1] = nr_connections;
(*socket_connection_packet_callback)(NULL, DAEMON_EVENT_PACKET, 0, (uint8_t *) &event, 2);
// printf("Nr connections changed,.. new %u\n", nr_connections);
}
int socket_connection_hci_process(struct data_source *ds) {
connection_t *conn = (connection_t *) ds;
int bytes_read = read(ds->fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read);
if (bytes_read <= 0){
// connection broken (no particular channel, no date yet)
(*socket_connection_packet_callback)(conn, DAEMON_EVENT_PACKET, 0, NULL, 0);
uint8_t event[1];
event[0] = DAEMON_CONNECTION_CLOSED;
(*socket_connection_packet_callback)(conn, DAEMON_EVENT_PACKET, 0, (uint8_t *) &event, 1);
// free connection
socket_connection_free_connection(linked_item_get_user(&ds->item));
socket_connection_emit_nr_connections();
return 0;
}
conn->bytes_read += bytes_read;
@ -161,6 +177,7 @@ static int socket_connection_accept(struct data_source *socket_ds) {
printf("socket_connection_accept new connection %u\n", fd);
socket_connection_register_new_connection(fd);
socket_connection_emit_nr_connections();
return 0;
}