mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-19 06:40:54 +00:00
add, track, and handle btstack_set_disoverable
This commit is contained in:
parent
bc2af4fc4b
commit
381fbed89a
29
TODO.txt
29
TODO.txt
@ -12,25 +12,16 @@
|
||||
2010-xxxx: Release 0.2 - revions xxx
|
||||
- limit size of /tmp/hci_dump.pklg to 1000 packets (max 1 MB)
|
||||
- power handling: handle power changes in all states, receive and handle power notifications, keep track of individual clients
|
||||
- fixed bugs in cocoa run loop implementation
|
||||
- automate scan enable management: hci_set_discoverable(bool) sets inquiry scan, page scan is always active
|
||||
|
||||
NEXT:
|
||||
- DONE: provide per client information: connection, power mode
|
||||
- DONE: fix bug with run_loop_cocoa, after client disconnects
|
||||
|
||||
- power handling
|
||||
- DONE: add wake() to bt_control.h: OFF<->ON<->SLEEP (SLEEP -> OFF is possible)
|
||||
- DONE: check if Bluetooth module can be woken up instantly with BlueTool on Broadcom chipsets -> yes
|
||||
- check if Bluetooth module can be woken up instantly with BlueTool on CSR chipsets
|
||||
- check apps for sleep mode compatibility - see what happens on ACTIVATED event
|
||||
- Keyboard
|
||||
- Mouse
|
||||
- WeBe++
|
||||
- WiiMote example
|
||||
- BTstackManager
|
||||
|
||||
- automate scan enable management
|
||||
- provide new "set discoverable (on/off)" command and store in per client information
|
||||
- keep track of page scan enable -> active if l2cap services exist
|
||||
- check apps for sleep mode/reactivated compatibility - see what happens on ACTIVATED event
|
||||
- WiiMote example
|
||||
- BTstackManager
|
||||
- Keyboard
|
||||
- Mouse
|
||||
- WeBe++
|
||||
|
||||
- clean up components
|
||||
- consolidate iOS code in port_ios.m (bt_control_iphone.m, platform_iphone.m)
|
||||
@ -39,15 +30,13 @@ NEXT:
|
||||
- add control of status bar icon to bt_control.h, too.
|
||||
- decide on configure flags
|
||||
- dynamic link BTdaemon against libBTstack.dylist
|
||||
|
||||
|
||||
- decide what to do with the CocoaTouch code. Options:
|
||||
- do nothing (potential problem with multiple dylibs in same process)
|
||||
- add it to libBTstack.dylib
|
||||
- provide a libBTstackCocoaTouch.dylib (less memory usage)
|
||||
|
||||
|
||||
- move RFCOMM code into BTdaemon
|
||||
- have a look at External Accessory interface by Apple - it's quite similar in function to BTstack
|
||||
|
||||
- HCI CMD packet is limited to 1024 bytes payload. SDP records could be larger than that. Options:
|
||||
- provide a way to transfer SDP records in segments
|
||||
|
@ -118,9 +118,12 @@ extern "C" {
|
||||
// data: system bluetooth on/off (bool)
|
||||
#define BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED 0x64
|
||||
|
||||
// data: event (8), len(8), status (8) == 0, address (48), name (1984 = 248 bytes)
|
||||
// data: event (8), len(8), status (8) == 0, address (48), name (1984 bits = 248 bytes)
|
||||
#define BTSTACK_EVENT_REMOTE_NAME_CACHED 0x65
|
||||
|
||||
// data: discoverable enabled (bool)
|
||||
#define BTSTACK_EVENT_DISCOVERABLE_ENABLED 0x66
|
||||
|
||||
// data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16)
|
||||
#define L2CAP_EVENT_CHANNEL_OPENED 0x70
|
||||
|
||||
|
63
src/daemon.c
63
src/daemon.c
@ -89,30 +89,30 @@ typedef struct {
|
||||
|
||||
} client_state_t;
|
||||
|
||||
static hci_transport_t * transport;
|
||||
static hci_uart_config_t config;
|
||||
|
||||
static timer_source_t timeout;
|
||||
static uint8_t timeout_active = 0;
|
||||
|
||||
static int power_management_sleep = 0;
|
||||
|
||||
#pragma mark prototypes
|
||||
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state);
|
||||
static void (*bluetooth_status_handler)(BLUETOOTH_STATE state) = dummy_bluetooth_status_handler;
|
||||
|
||||
static linked_list_t clients = NULL; // list of connected clients
|
||||
static client_state_t * client_for_connection(connection_t *connection);
|
||||
static int clients_requires_power_on();
|
||||
|
||||
static int clients_require_power_on();
|
||||
static int clients_require_discoverable();
|
||||
static void start_power_off_timer();
|
||||
static void stop_power_off_timer();
|
||||
|
||||
#pragma mark globals
|
||||
static hci_transport_t * transport;
|
||||
static hci_uart_config_t config;
|
||||
static timer_source_t timeout;
|
||||
static uint8_t timeout_active = 0;
|
||||
static int power_management_sleep = 0;
|
||||
static linked_list_t clients = NULL; // list of connected clients
|
||||
static void (*bluetooth_status_handler)(BLUETOOTH_STATE state) = dummy_bluetooth_status_handler;
|
||||
|
||||
|
||||
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state){
|
||||
printf("Bluetooth status: %u\n", state);
|
||||
};
|
||||
|
||||
static void daemon_no_connections_timeout(){
|
||||
if (clients_requires_power_on()) return; // false alarm :)
|
||||
if (clients_require_power_on()) return; // false alarm :)
|
||||
printf("No active client connection for %u seconds -> POWER OFF\n", DAEMON_NO_ACTIVE_CLIENT_TIMEOUT/1000);
|
||||
hci_power_control(HCI_POWER_OFF);
|
||||
}
|
||||
@ -140,7 +140,7 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
||||
if (!client) break;
|
||||
client->power_mode = packet[3];
|
||||
// handle merged state
|
||||
if (!clients_requires_power_on()){
|
||||
if (!clients_require_power_on()){
|
||||
start_power_off_timer();
|
||||
} else if (!power_management_sleep) {
|
||||
stop_power_off_timer();
|
||||
@ -153,7 +153,9 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
||||
#ifdef USE_BLUETOOL
|
||||
case BTSTACK_SET_SYSTEM_BLUETOOTH_ENABLED:
|
||||
iphone_system_bt_set_enabled(packet[3]);
|
||||
// fall through .. :)
|
||||
hci_emit_system_bluetooth_enabled(iphone_system_bt_enabled());
|
||||
break;
|
||||
|
||||
case BTSTACK_GET_SYSTEM_BLUETOOTH_ENABLED:
|
||||
hci_emit_system_bluetooth_enabled(iphone_system_bt_enabled());
|
||||
break;
|
||||
@ -163,6 +165,14 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
||||
hci_emit_system_bluetooth_enabled(0);
|
||||
break;
|
||||
#endif
|
||||
case BTSTACK_SET_DISCOVERABLE:
|
||||
// track client discoverable requests
|
||||
client = client_for_connection(connection);
|
||||
if (!client) break;
|
||||
client->discoverable = packet[3];
|
||||
// merge state
|
||||
hci_discoverable_control(clients_require_discoverable());
|
||||
break;
|
||||
case L2CAP_CREATE_CHANNEL_MTU:
|
||||
bt_flip_addr(addr, &packet[3]);
|
||||
psm = READ_BT_16(packet, 9);
|
||||
@ -252,8 +262,10 @@ static int daemon_client_handler(connection_t *connection, uint16_t packet_type,
|
||||
if (!client) break;
|
||||
linked_list_remove(&clients, (linked_item_t *) client);
|
||||
free(client);
|
||||
printf("Client connection closed. clients_requires_power_on()=%u\n",clients_requires_power_on());
|
||||
if (!clients_requires_power_on()){
|
||||
// update discoverable mode
|
||||
hci_discoverable_control(clients_require_discoverable());
|
||||
// start power off, if last active client
|
||||
if (!clients_require_power_on()){
|
||||
start_power_off_timer();
|
||||
}
|
||||
break;
|
||||
@ -333,7 +345,7 @@ static void power_notification_callback(POWER_NOTIFICATION_t notification){
|
||||
case POWER_WILL_WAKE_UP:
|
||||
// assume that all clients use Bluetooth -> if connection, start Bluetooth
|
||||
power_management_sleep = 0;
|
||||
if (clients_requires_power_on()) {
|
||||
if (clients_require_power_on()) {
|
||||
hci_power_control(HCI_POWER_ON);
|
||||
}
|
||||
break;
|
||||
@ -528,7 +540,7 @@ static client_state_t * client_for_connection(connection_t *connection) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int clients_requires_power_on(){
|
||||
static int clients_require_power_on(){
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) clients; it ; it = it->next){
|
||||
client_state_t * client_state = (client_state_t *) it;
|
||||
@ -538,3 +550,14 @@ static int clients_requires_power_on(){
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clients_require_discoverable(){
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) clients; it ; it = it->next){
|
||||
client_state_t * client_state = (client_state_t *) it;
|
||||
if (client_state->discoverable) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
25
src/hci.c
25
src/hci.c
@ -344,6 +344,9 @@ static void event_handler(uint8_t *packet, int size){
|
||||
log_dbg("hci_read_buffer_size: size %u, count %u\n", hci_stack.acl_data_packet_length, hci_stack.total_num_acl_packets);
|
||||
}
|
||||
}
|
||||
if (COMMAND_COMPLETE_EVENT(packet, hci_write_scan_enable)){
|
||||
hci_emit_discoverable_enabled(hci_stack.discoverable);
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS:
|
||||
@ -758,6 +761,18 @@ int hci_power_control(HCI_POWER_MODE power_mode){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hci_discoverable_control(uint8_t enable){
|
||||
if (enable) enable = 1; // normalize argument
|
||||
|
||||
if (hci_stack.discoverable == enable){
|
||||
hci_emit_discoverable_enabled(hci_stack.discoverable);
|
||||
return;
|
||||
}
|
||||
|
||||
hci_send_cmd(&hci_write_scan_enable, 2 | enable); // 1 = inq scan, 2 = page scan
|
||||
hci_stack.discoverable = enable;
|
||||
}
|
||||
|
||||
void hci_run(){
|
||||
|
||||
if (hci_stack.num_cmd_packets == 0) {
|
||||
@ -1026,3 +1041,13 @@ void hci_emit_remote_name_cached(bd_addr_t *addr, device_name_t *name){
|
||||
hci_dump_packet(HCI_EVENT_PACKET, 0, event, len);
|
||||
hci_stack.packet_handler(HCI_EVENT_PACKET, event, len);
|
||||
}
|
||||
|
||||
void hci_emit_discoverable_enabled(uint8_t enabled){
|
||||
uint8_t len = 3;
|
||||
uint8_t event[len];
|
||||
event[0] = BTSTACK_EVENT_DISCOVERABLE_ENABLED;
|
||||
event[1] = len - 2;
|
||||
event[2] = enabled;
|
||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, len);
|
||||
hci_stack.packet_handler(HCI_EVENT_PACKET, event, len);
|
||||
}
|
||||
|
@ -89,6 +89,9 @@ extern "C" {
|
||||
// set system Bluetooth state
|
||||
#define BTSTACK_SET_SYSTEM_BLUETOOTH_ENABLED 0x06
|
||||
|
||||
// enable inquiry scan for this client
|
||||
#define BTSTACK_SET_DISCOVERABLE 0x07
|
||||
|
||||
// create l2cap channel: @param bd_addr(48), psm (16)
|
||||
#define L2CAP_CREATE_CHANNEL 0x20
|
||||
|
||||
@ -223,6 +226,9 @@ typedef struct {
|
||||
uint8_t substate;
|
||||
uint8_t cmds_ready;
|
||||
|
||||
/* */
|
||||
uint8_t discoverable;
|
||||
|
||||
} hci_stack_t;
|
||||
|
||||
// create and send hci command packets based on a template and a list of parameters
|
||||
@ -268,6 +274,7 @@ void hci_emit_hci_open_failed();
|
||||
void hci_emit_btstack_version();
|
||||
void hci_emit_system_bluetooth_enabled(uint8_t enabled);
|
||||
void hci_emit_remote_name_cached(bd_addr_t *addr, device_name_t *name);
|
||||
void hci_emit_discoverable_enabled(uint8_t enabled);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user