From 80481634582e15c7c460914efc60ffe3b11673d5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 29 Jun 2014 19:13:12 +0200 Subject: [PATCH] core: Use kernel background scanning if available --- src/adapter.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/adapter.c b/src/adapter.c index b34cf484e..de528e320 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -1187,6 +1187,14 @@ static void trigger_passive_scanning(struct btd_adapter *adapter) adapter->passive_scan_timeout = 0; } + /* + * When the kernel background scanning is available, there is + * no need to start any discovery. The kernel will keep scanning + * as long as devices are in its auto-connection list. + */ + if (kernel_bg_scan) + return; + /* * If any client is running a discovery right now, then do not * even try to start passive scanning. @@ -1227,6 +1235,14 @@ static void stop_passive_scanning_complete(uint8_t status, uint16_t length, DBG("status 0x%02x (%s)", status, mgmt_errstr(status)); + /* + * When the kernel background scanning is available, there is + * no need to stop any discovery. The kernel will handle the + * auto-connection by itself. + */ + if (kernel_bg_scan) + return; + dev = adapter->connect_le; adapter->connect_le = NULL; @@ -3040,6 +3056,25 @@ int adapter_connect_list_add(struct btd_adapter *adapter, DBG("%s added to %s's connect_list", device_get_path(device), adapter->system_name); + if (kernel_bg_scan) { + struct mgmt_cp_add_device cp; + const bdaddr_t *bdaddr; + uint8_t bdaddr_type; + + bdaddr = device_get_address(device); + bdaddr_type = btd_device_get_bdaddr_type(device); + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.addr.bdaddr, bdaddr); + cp.addr.type = bdaddr_type; + cp.action = 0x01; + + if (mgmt_send(adapter->mgmt, MGMT_OP_ADD_DEVICE, + adapter->dev_id, sizeof(cp), &cp, + NULL, NULL, NULL) > 0) + return 0; + } + done: if (!(adapter->current_settings & MGMT_SETTING_POWERED)) return 0; @@ -3070,6 +3105,24 @@ void adapter_connect_list_remove(struct btd_adapter *adapter, DBG("%s removed from %s's connect_list", device_get_path(device), adapter->system_name); + if (kernel_bg_scan) { + struct mgmt_cp_remove_device cp; + const bdaddr_t *bdaddr; + uint8_t bdaddr_type; + + bdaddr = device_get_address(device); + bdaddr_type = btd_device_get_bdaddr_type(device); + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.addr.bdaddr, bdaddr); + cp.addr.type = bdaddr_type; + + if (mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_DEVICE, + adapter->dev_id, sizeof(cp), &cp, + NULL, NULL, NULL) > 0) + return; + } + if (!adapter->connect_list) { stop_passive_scanning(adapter); return; @@ -6406,6 +6459,37 @@ static void unpaired_callback(uint16_t index, uint16_t length, device_set_unpaired(device, ev->addr.type); } +static void clear_devices_complete(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + if (status != MGMT_STATUS_SUCCESS) { + error("Failed to clear devices: %s (0x%02x)", + mgmt_errstr(status), status); + return; + } +} + +static int clear_devices(struct btd_adapter *adapter) +{ + struct mgmt_cp_remove_device cp; + + if (!kernel_bg_scan) + return 0; + + memset(&cp, 0, sizeof(cp)); + + DBG("sending clear devices command for index %u", adapter->dev_id); + + if (mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_DEVICE, + adapter->dev_id, sizeof(cp), &cp, + clear_devices_complete, adapter, NULL) > 0) + return 0; + + error("Failed to clear devices for index %u", adapter->dev_id); + + return -EIO; +} + static void read_info_complete(uint8_t status, uint16_t length, const void *param, void *user_data) { @@ -6449,6 +6533,7 @@ static void read_info_complete(uint8_t status, uint16_t length, adapter->current_settings = btohs(rp->current_settings); clear_uuids(adapter); + clear_devices(adapter); err = adapter_register(adapter); if (err < 0) { -- 2.47.3