Following patches improves handling of stop discovery in scenario of
big inflow of device found events.
v2:
* Fix confirm name callback
Lukasz Rymanowski (3):
android: Add tracking for pending confirm name command
android: Cancel all pending confirm name before stop discovery
android: Send confirm name request with mgmt_send
android/bluetooth.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 46 insertions(+), 4 deletions(-)
--
1.8.4
Hi Ćukasz,
On Monday 10 of March 2014 00:06:34 Lukasz Rymanowski wrote:
> Following patches improves handling of stop discovery in scenario of
> big inflow of device found events.
>
> v2:
> * Fix confirm name callback
>
> Lukasz Rymanowski (3):
> android: Add tracking for pending confirm name command
> android: Cancel all pending confirm name before stop discovery
> android: Send confirm name request with mgmt_send
>
> android/bluetooth.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 46 insertions(+), 4 deletions(-)
>
>
All patches applied, thanks.
--
Best regards,
Szymon Janc
If user wants to cancel discovery we should remove all the confirm name
requests from mgmt queues.
It is in order to make sure that stop discovery have a free way to
reach kernel.
This improves scenario when there is a big inflow of device found events and
mgmt queues become full of confirm name requests. In such case stop discovery
might stack in the queue.
---
android/bluetooth.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 60ca17d..9286c67 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2467,6 +2467,14 @@ static bool start_discovery(void)
return false;
}
+static void cancel_pending_confirm_name(gpointer data, gpointer user_data)
+{
+ struct device *dev = data;
+
+ mgmt_cancel(mgmt_if, dev->confirm_id);
+ dev->confirm_id = 0;
+}
+
static bool stop_discovery(void)
{
struct mgmt_cp_stop_discovery cp;
@@ -2481,6 +2489,9 @@ static bool stop_discovery(void)
DBG("type=0x%x", cp.type);
+ /* Lets drop all confirm name request as we don't need it anymore */
+ g_slist_foreach(cached_devices, cancel_pending_confirm_name, NULL);
+
if (mgmt_send(mgmt_if, MGMT_OP_STOP_DISCOVERY, adapter.index,
sizeof(cp), &cp, NULL, NULL, NULL) > 0)
return true;
--
1.8.4
This patch improves handling stop disvocery in scenarios when there is a big
inflow of device found events. In such case, number of confirm
name request might block mgmt queses and make stop discovery stack in the queue.
Even we cancel previous confirm name request, there is still possibility that
new incoming device found events produce confirm name request which will
might block stop discovery.
---
android/bluetooth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 9286c67..158eb2a 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -1061,7 +1061,7 @@ static unsigned int confirm_device_name(const bdaddr_t *addr, uint8_t addr_type,
if (!resolve_name)
cp.name_known = 1;
- res = mgmt_reply(mgmt_if, MGMT_OP_CONFIRM_NAME, adapter.index,
+ res = mgmt_send(mgmt_if, MGMT_OP_CONFIRM_NAME, adapter.index,
sizeof(cp), &cp, confirm_device_name_cb,
NULL, NULL);
if (!res)
--
1.8.4
---
android/bluetooth.c | 39 +++++++++++++++++++++++++++++++++++----
1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index ba4f14b..60ca17d 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -97,6 +97,8 @@ struct device {
GSList *uuids;
bool found; /* if device is found in current discovery session */
+ unsigned int confirm_id; /* mgtm command id if command pending */
+
};
struct browse_req {
@@ -318,6 +320,9 @@ static struct device *find_device(const bdaddr_t *bdaddr)
static void free_device(struct device *dev)
{
+ if (dev->confirm_id)
+ mgmt_cancel(mgmt_if, dev->confirm_id);
+
g_free(dev->name);
g_free(dev->friendly_name);
g_slist_free_full(dev->uuids, g_free);
@@ -1023,10 +1028,31 @@ static void mgmt_discovering_event(uint16_t index, uint16_t length,
HAL_EV_DISCOVERY_STATE_CHANGED, sizeof(cp), &cp);
}
-static void confirm_device_name(const bdaddr_t *addr, uint8_t addr_type,
+static void confirm_device_name_cb(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_confirm_name *rp = param;
+ struct device *dev;
+
+ DBG("Confirm name status: %s (0x%02x)", mgmt_errstr(status), status);
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size of confirm name response");
+ return;
+ }
+
+ dev = find_device(&rp->addr.bdaddr);
+ if (!dev)
+ return;
+
+ dev->confirm_id = 0;
+}
+
+static unsigned int confirm_device_name(const bdaddr_t *addr, uint8_t addr_type,
bool resolve_name)
{
struct mgmt_cp_confirm_name cp;
+ unsigned int res;
memset(&cp, 0, sizeof(cp));
bacpy(&cp.addr.bdaddr, addr);
@@ -1035,9 +1061,13 @@ static void confirm_device_name(const bdaddr_t *addr, uint8_t addr_type,
if (!resolve_name)
cp.name_known = 1;
- if (mgmt_reply(mgmt_if, MGMT_OP_CONFIRM_NAME, adapter.index,
- sizeof(cp), &cp, NULL, NULL, NULL) == 0)
+ res = mgmt_reply(mgmt_if, MGMT_OP_CONFIRM_NAME, adapter.index,
+ sizeof(cp), &cp, confirm_device_name_cb,
+ NULL, NULL);
+ if (!res)
error("Failed to send confirm name request");
+
+ return res;
}
static int fill_hal_prop(void *buf, uint8_t type, uint16_t len,
@@ -1205,7 +1235,8 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
info("Device %s needs name confirmation (resolve_name=%d)",
addr, resolve_name);
- confirm_device_name(bdaddr, bdaddr_type, resolve_name);
+ dev->confirm_id = confirm_device_name(bdaddr, bdaddr_type,
+ resolve_name);
}
}
--
1.8.4