mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-22 06:41:17 +00:00
add, track, and handle btstack_set_disoverable
This commit is contained in:
parent
bc2af4fc4b
commit
381fbed89a
21
TODO.txt
21
TODO.txt
@ -12,25 +12,16 @@
|
|||||||
2010-xxxx: Release 0.2 - revions xxx
|
2010-xxxx: Release 0.2 - revions xxx
|
||||||
- limit size of /tmp/hci_dump.pklg to 1000 packets (max 1 MB)
|
- 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
|
- 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:
|
NEXT:
|
||||||
- DONE: provide per client information: connection, power mode
|
- check apps for sleep mode/reactivated compatibility - see what happens on ACTIVATED event
|
||||||
- DONE: fix bug with run_loop_cocoa, after client disconnects
|
- WiiMote example
|
||||||
|
- BTstackManager
|
||||||
- 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
|
- Keyboard
|
||||||
- Mouse
|
- Mouse
|
||||||
- WeBe++
|
- 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
|
|
||||||
|
|
||||||
- clean up components
|
- clean up components
|
||||||
- consolidate iOS code in port_ios.m (bt_control_iphone.m, platform_iphone.m)
|
- consolidate iOS code in port_ios.m (bt_control_iphone.m, platform_iphone.m)
|
||||||
@ -45,9 +36,7 @@ NEXT:
|
|||||||
- add it to libBTstack.dylib
|
- add it to libBTstack.dylib
|
||||||
- provide a libBTstackCocoaTouch.dylib (less memory usage)
|
- provide a libBTstackCocoaTouch.dylib (less memory usage)
|
||||||
|
|
||||||
|
|
||||||
- move RFCOMM code into BTdaemon
|
- 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:
|
- 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
|
- provide a way to transfer SDP records in segments
|
||||||
|
@ -118,9 +118,12 @@ extern "C" {
|
|||||||
// data: system bluetooth on/off (bool)
|
// data: system bluetooth on/off (bool)
|
||||||
#define BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED 0x64
|
#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
|
#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)
|
// 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
|
#define L2CAP_EVENT_CHANNEL_OPENED 0x70
|
||||||
|
|
||||||
|
63
src/daemon.c
63
src/daemon.c
@ -89,30 +89,30 @@ typedef struct {
|
|||||||
|
|
||||||
} client_state_t;
|
} client_state_t;
|
||||||
|
|
||||||
static hci_transport_t * transport;
|
#pragma mark prototypes
|
||||||
static hci_uart_config_t config;
|
|
||||||
|
|
||||||
static timer_source_t timeout;
|
|
||||||
static uint8_t timeout_active = 0;
|
|
||||||
|
|
||||||
static int power_management_sleep = 0;
|
|
||||||
|
|
||||||
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state);
|
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 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 start_power_off_timer();
|
||||||
static void stop_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){
|
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state){
|
||||||
printf("Bluetooth status: %u\n", state);
|
printf("Bluetooth status: %u\n", state);
|
||||||
};
|
};
|
||||||
|
|
||||||
static void daemon_no_connections_timeout(){
|
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);
|
printf("No active client connection for %u seconds -> POWER OFF\n", DAEMON_NO_ACTIVE_CLIENT_TIMEOUT/1000);
|
||||||
hci_power_control(HCI_POWER_OFF);
|
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;
|
if (!client) break;
|
||||||
client->power_mode = packet[3];
|
client->power_mode = packet[3];
|
||||||
// handle merged state
|
// handle merged state
|
||||||
if (!clients_requires_power_on()){
|
if (!clients_require_power_on()){
|
||||||
start_power_off_timer();
|
start_power_off_timer();
|
||||||
} else if (!power_management_sleep) {
|
} else if (!power_management_sleep) {
|
||||||
stop_power_off_timer();
|
stop_power_off_timer();
|
||||||
@ -153,7 +153,9 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
|||||||
#ifdef USE_BLUETOOL
|
#ifdef USE_BLUETOOL
|
||||||
case BTSTACK_SET_SYSTEM_BLUETOOTH_ENABLED:
|
case BTSTACK_SET_SYSTEM_BLUETOOTH_ENABLED:
|
||||||
iphone_system_bt_set_enabled(packet[3]);
|
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:
|
case BTSTACK_GET_SYSTEM_BLUETOOTH_ENABLED:
|
||||||
hci_emit_system_bluetooth_enabled(iphone_system_bt_enabled());
|
hci_emit_system_bluetooth_enabled(iphone_system_bt_enabled());
|
||||||
break;
|
break;
|
||||||
@ -163,6 +165,14 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
|||||||
hci_emit_system_bluetooth_enabled(0);
|
hci_emit_system_bluetooth_enabled(0);
|
||||||
break;
|
break;
|
||||||
#endif
|
#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:
|
case L2CAP_CREATE_CHANNEL_MTU:
|
||||||
bt_flip_addr(addr, &packet[3]);
|
bt_flip_addr(addr, &packet[3]);
|
||||||
psm = READ_BT_16(packet, 9);
|
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;
|
if (!client) break;
|
||||||
linked_list_remove(&clients, (linked_item_t *) client);
|
linked_list_remove(&clients, (linked_item_t *) client);
|
||||||
free(client);
|
free(client);
|
||||||
printf("Client connection closed. clients_requires_power_on()=%u\n",clients_requires_power_on());
|
// update discoverable mode
|
||||||
if (!clients_requires_power_on()){
|
hci_discoverable_control(clients_require_discoverable());
|
||||||
|
// start power off, if last active client
|
||||||
|
if (!clients_require_power_on()){
|
||||||
start_power_off_timer();
|
start_power_off_timer();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -333,7 +345,7 @@ static void power_notification_callback(POWER_NOTIFICATION_t notification){
|
|||||||
case POWER_WILL_WAKE_UP:
|
case POWER_WILL_WAKE_UP:
|
||||||
// assume that all clients use Bluetooth -> if connection, start Bluetooth
|
// assume that all clients use Bluetooth -> if connection, start Bluetooth
|
||||||
power_management_sleep = 0;
|
power_management_sleep = 0;
|
||||||
if (clients_requires_power_on()) {
|
if (clients_require_power_on()) {
|
||||||
hci_power_control(HCI_POWER_ON);
|
hci_power_control(HCI_POWER_ON);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -528,7 +540,7 @@ static client_state_t * client_for_connection(connection_t *connection) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clients_requires_power_on(){
|
static int clients_require_power_on(){
|
||||||
linked_item_t *it;
|
linked_item_t *it;
|
||||||
for (it = (linked_item_t *) clients; it ; it = it->next){
|
for (it = (linked_item_t *) clients; it ; it = it->next){
|
||||||
client_state_t * client_state = (client_state_t *) it;
|
client_state_t * client_state = (client_state_t *) it;
|
||||||
@ -538,3 +550,14 @@ static int clients_requires_power_on(){
|
|||||||
}
|
}
|
||||||
return 0;
|
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);
|
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;
|
break;
|
||||||
|
|
||||||
case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS:
|
case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS:
|
||||||
@ -758,6 +761,18 @@ int hci_power_control(HCI_POWER_MODE power_mode){
|
|||||||
return 0;
|
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(){
|
void hci_run(){
|
||||||
|
|
||||||
if (hci_stack.num_cmd_packets == 0) {
|
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_dump_packet(HCI_EVENT_PACKET, 0, event, len);
|
||||||
hci_stack.packet_handler(HCI_EVENT_PACKET, 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
|
// set system Bluetooth state
|
||||||
#define BTSTACK_SET_SYSTEM_BLUETOOTH_ENABLED 0x06
|
#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)
|
// create l2cap channel: @param bd_addr(48), psm (16)
|
||||||
#define L2CAP_CREATE_CHANNEL 0x20
|
#define L2CAP_CREATE_CHANNEL 0x20
|
||||||
|
|
||||||
@ -223,6 +226,9 @@ typedef struct {
|
|||||||
uint8_t substate;
|
uint8_t substate;
|
||||||
uint8_t cmds_ready;
|
uint8_t cmds_ready;
|
||||||
|
|
||||||
|
/* */
|
||||||
|
uint8_t discoverable;
|
||||||
|
|
||||||
} hci_stack_t;
|
} hci_stack_t;
|
||||||
|
|
||||||
// create and send hci command packets based on a template and a list of parameters
|
// 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_btstack_version();
|
||||||
void hci_emit_system_bluetooth_enabled(uint8_t enabled);
|
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_remote_name_cached(bd_addr_t *addr, device_name_t *name);
|
||||||
|
void hci_emit_discoverable_enabled(uint8_t enabled);
|
||||||
|
|
||||||
#if defined __cplusplus
|
#if defined __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user