From bddf039736393c06f8cf732c9b259ddd0df35ed1 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 19 Dec 2016 18:02:41 +0100 Subject: [PATCH] Bluetooth: Make BR/EDR discovery be limited only by time If more inquiry results were received during discovery than fits in storage results with lowest RSSI will be skipped. This is to improve API usefulness in busy environments where results with low RSSI (likely more far away than high RSSI) could consume provided result space, Change-Id: I1e9ca901b693f608d58575916809e8bd8bfe710f Signed-off-by: Szymon Janc --- include/bluetooth/bluetooth.h | 4 ++- subsys/bluetooth/host/hci_core.c | 51 ++++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/include/bluetooth/bluetooth.h b/include/bluetooth/bluetooth.h index c03232057f0..9a035cbcb1a 100644 --- a/include/bluetooth/bluetooth.h +++ b/include/bluetooth/bluetooth.h @@ -330,7 +330,9 @@ struct bt_br_discovery_param { * * Start BR/EDR discovery (inquiry) and provide results through the specified * callback. When bt_br_discovery_cb_t is called it indicates that discovery - * has completed. + * has completed. If more inquiry results were received during session than + * fits in provided result storage, only ones with highest RSSI will be + * reported. * * @param param Discovery parameters. * @param results Storage for discovery results. diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index afb44fe31d4..b1be61eb05a 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1655,10 +1655,11 @@ static void inquiry_complete(struct net_buf *buf) report_discovery_results(); } -static struct bt_br_discovery_result *get_result_slot(const bt_addr_t *addr) +static struct bt_br_discovery_result *get_result_slot(const bt_addr_t *addr, + int8_t rssi) { + struct bt_br_discovery_result *result = NULL; size_t i; - int err; /* check if already present in results */ for (i = 0; i < discovery_results_count; i++) { @@ -1674,17 +1675,33 @@ static struct bt_br_discovery_result *get_result_slot(const bt_addr_t *addr) return &discovery_results[discovery_results_count++]; } - BT_WARN("Got more Inquiry results than requested"); - - err = bt_hci_cmd_send_sync(BT_HCI_OP_INQUIRY_CANCEL, NULL, NULL); - if (err) { - BT_ERR("Failed to cancel discovery (%d)", err); + /* ignore if invalid RSSI */ + if (rssi == 0xff) { return NULL; } - report_discovery_results(); + /* + * Pick slot with smallest RSSI that is smaller then passed RSSI + * TODO handle TX if present + */ + for (i = 0; i < discovery_results_size; i++) { + if (discovery_results[i].rssi > rssi) { + continue; + } - return NULL; + if (!result || result->rssi > discovery_results[i].rssi) { + result = &discovery_results[i]; + } + } + + if (result) { + BT_DBG("Reusing slot (old %s rssi %d dBm)", + bt_addr_str(&result->addr), result->rssi); + + bt_addr_copy(&result->addr, addr); + } + + return result; } static void inquiry_result_with_rssi(struct net_buf *buf) @@ -1705,7 +1722,7 @@ static void inquiry_result_with_rssi(struct net_buf *buf) BT_DBG("%s rssi %d dBm", bt_addr_str(&evt->addr), evt->rssi); - result = get_result_slot(&evt->addr); + result = get_result_slot(&evt->addr, evt->rssi); if (!result) { return; } @@ -1717,6 +1734,9 @@ static void inquiry_result_with_rssi(struct net_buf *buf) memcpy(result->cod, evt->cod, 3); result->rssi = evt->rssi; + /* we could reuse slot so make sure EIR is cleared */ + memset(result->eir, 0, sizeof(result->eir)); + /* * Get next report iteration by moving pointer to right offset * in buf according to spec 4.2, Vol 2, Part E, 7.7.33. @@ -1737,7 +1757,7 @@ static void extended_inquiry_result(struct net_buf *buf) BT_DBG("%s rssi %d dBm", bt_addr_str(&evt->addr), evt->rssi); - result = get_result_slot(&evt->addr); + result = get_result_slot(&evt->addr, evt->rssi); if (!result) { return; } @@ -1760,7 +1780,7 @@ static void remote_name_request_complete(struct net_buf *buf) uint8_t *eir; int i; - result = get_result_slot(&evt->bdaddr); + result = get_result_slot(&evt->bdaddr, 0xff); if (!result) { return; } @@ -4049,8 +4069,7 @@ struct net_buf *bt_buf_get_acl(void) #endif /* CONFIG_BLUETOOTH_HOST_BUFFERS */ #if defined(CONFIG_BLUETOOTH_BREDR) -static int br_start_inquiry(const struct bt_br_discovery_param *param, - size_t num_rsp) +static int br_start_inquiry(const struct bt_br_discovery_param *param) { const uint8_t iac[3] = { 0x33, 0x8b, 0x9e }; struct bt_hci_op_inquiry *cp; @@ -4064,7 +4083,7 @@ static int br_start_inquiry(const struct bt_br_discovery_param *param, cp = net_buf_add(buf, sizeof(*cp)); cp->length = param->length; - cp->num_rsp = num_rsp; + cp->num_rsp = 0xff; /* we limit discovery only by time */ memcpy(cp->lap, iac, 3); if (param->limited) { @@ -4104,7 +4123,7 @@ int bt_br_discovery_start(const struct bt_br_discovery_param *param, return -EALREADY; } - err = br_start_inquiry(param, cnt); + err = br_start_inquiry(param); if (err) { return err; }