All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mgmtops: Fix adding UUID when EBUSY error is returned
@ 2012-06-10 19:50 Szymon Janc
  2012-06-11  9:40 ` Johan Hedberg
  0 siblings, 1 reply; 3+ messages in thread
From: Szymon Janc @ 2012-06-10 19:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

MGMT_ADDP_UUID may return EBUSY error (when adding UUID triggered COD
change) and UUID should be send to kernel one more time in such case.
---
 plugins/mgmtops.c |   63 ++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 20 deletions(-)

diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index a196b1f..ee42de0 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -825,28 +825,16 @@ static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
 		memcpy(uuid128, uuid, sizeof(*uuid));
 }
 
-static int mgmt_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint)
+static int send_uuid(int index, uuid_t *uuid, uint8_t svc_hint)
 {
 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_add_uuid)];
 	struct mgmt_hdr *hdr = (void *) buf;
 	struct mgmt_cp_add_uuid *cp = (void *) &buf[sizeof(*hdr)];
-	struct controller_info *info = &controllers[index];
 	uuid_t uuid128;
 	uint128_t uint128;
 
 	DBG("index %d", index);
 
-	if (info->pending_uuid) {
-		struct pending_uuid *pending = g_new0(struct pending_uuid, 1);
-
-		memcpy(&pending->uuid, uuid, sizeof(*uuid));
-		pending->svc_hint = svc_hint;
-
-		info->pending_uuids = g_slist_append(info->pending_uuids,
-								pending);
-		return 0;
-	}
-
 	uuid_to_uuid128(&uuid128, uuid);
 
 	memset(buf, 0, sizeof(buf));
@@ -859,9 +847,25 @@ static int mgmt_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint)
 
 	cp->svc_hint = svc_hint;
 
-	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
+	return write(mgmt_sock, buf, sizeof(buf));
+}
+
+static int mgmt_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint)
+{
+	struct controller_info *info = &controllers[index];
+	struct pending_uuid *pending;
+
+	DBG("index %d", index);
+
+	if (!info->pending_uuid && send_uuid(index, uuid, svc_hint) < 0)
 		return -errno;
 
+	pending = g_new0(struct pending_uuid, 1);
+
+	memcpy(&pending->uuid, uuid, sizeof(*uuid));
+	pending->svc_hint = svc_hint;
+
+	info->pending_uuids = g_slist_append(info->pending_uuids, pending);
 	info->pending_uuid = TRUE;
 
 	return 0;
@@ -1278,7 +1282,7 @@ static void mgmt_add_uuid_complete(int sk, uint16_t index, void *buf,
 	struct controller_info *info;
 	struct pending_uuid *pending;
 
-	DBG("add_uuid complete");
+	DBG("index %d", index);
 
 	if (index > max_index) {
 		error("Unexpected index %u in add_uuid_complete event", index);
@@ -1287,9 +1291,13 @@ static void mgmt_add_uuid_complete(int sk, uint16_t index, void *buf,
 
 	info = &controllers[index];
 
-	info->pending_uuid = FALSE;
+	pending = info->pending_uuids->data;
+	info->pending_uuids = g_slist_remove(info->pending_uuids, pending);
+	g_free(pending);
 
 	if (g_slist_length(info->pending_uuids) == 0) {
+		info->pending_uuid = FALSE;
+
 		if (info->pending_class) {
 			info->pending_class = FALSE;
 			mgmt_set_dev_class(index, info->major, info->minor);
@@ -1305,10 +1313,7 @@ static void mgmt_add_uuid_complete(int sk, uint16_t index, void *buf,
 
 	pending = info->pending_uuids->data;
 
-	mgmt_add_uuid(index, &pending->uuid, pending->svc_hint);
-
-	info->pending_uuids = g_slist_remove(info->pending_uuids, pending);
-	g_free(pending);
+	send_uuid(index, &pending->uuid, pending->svc_hint);
 }
 
 static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
@@ -1434,6 +1439,20 @@ static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
 	}
 }
 
+static void mgmt_add_uuid_resend(int sk, uint16_t index)
+{
+	struct controller_info *info;
+	struct pending_uuid *pending;
+
+	DBG("index %d", index);
+
+	info = &controllers[index];
+
+	pending = info->pending_uuids->data;
+
+	send_uuid(index, &pending->uuid, pending->svc_hint);
+}
+
 static void mgmt_cmd_status(int sk, uint16_t index, void *buf, size_t len)
 {
 	struct mgmt_ev_cmd_status *ev = buf;
@@ -1460,6 +1479,10 @@ static void mgmt_cmd_status(int sk, uint16_t index, void *buf, size_t len)
 	case MGMT_OP_READ_LOCAL_OOB_DATA:
 		read_local_oob_data_failed(sk, index);
 		break;
+	case MGMT_OP_ADD_UUID:
+		if (ev->status == MGMT_STATUS_BUSY)
+			mgmt_add_uuid_resend(sk, index);
+		break;
 	}
 }
 
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] mgmtops: Fix adding UUID when EBUSY error is returned
  2012-06-10 19:50 [PATCH] mgmtops: Fix adding UUID when EBUSY error is returned Szymon Janc
@ 2012-06-11  9:40 ` Johan Hedberg
  2012-06-11 20:18   ` Szymon Janc
  0 siblings, 1 reply; 3+ messages in thread
From: Johan Hedberg @ 2012-06-11  9:40 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Sun, Jun 10, 2012, Szymon Janc wrote:
> +static void mgmt_add_uuid_resend(int sk, uint16_t index)
> +{
> +	struct controller_info *info;
> +	struct pending_uuid *pending;
> +
> +	DBG("index %d", index);
> +
> +	info = &controllers[index];
> +
> +	pending = info->pending_uuids->data;
> +
> +	send_uuid(index, &pending->uuid, pending->svc_hint);
> +}
> +
>  static void mgmt_cmd_status(int sk, uint16_t index, void *buf, size_t len)
>  {
>  	struct mgmt_ev_cmd_status *ev = buf;
> @@ -1460,6 +1479,10 @@ static void mgmt_cmd_status(int sk, uint16_t index, void *buf, size_t len)
>  	case MGMT_OP_READ_LOCAL_OOB_DATA:
>  		read_local_oob_data_failed(sk, index);
>  		break;
> +	case MGMT_OP_ADD_UUID:
> +		if (ev->status == MGMT_STATUS_BUSY)
> +			mgmt_add_uuid_resend(sk, index);
> +		break;
>  	}
>  }

It's there a risk that this ends up in an infinite loop if the kernel is
in some state where it always keeps sending STATUS_BUSY? Would it make
sense to add a counter for retries and give up after 5 or 10 attempts?
Would it also make sense to add a small delay before resending the
command?

Johan

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] mgmtops: Fix adding UUID when EBUSY error is returned
  2012-06-11  9:40 ` Johan Hedberg
@ 2012-06-11 20:18   ` Szymon Janc
  0 siblings, 0 replies; 3+ messages in thread
From: Szymon Janc @ 2012-06-11 20:18 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth

Hi Johan,

On Monday 11 June 2012 11:40:11 Johan Hedberg wrote:
> It's there a risk that this ends up in an infinite loop if the kernel is
> in some state where it always keeps sending STATUS_BUSY? Would it make
> sense to add a counter for retries and give up after 5 or 10 attempts?

That would meant host didn't get command complete for set COD command (meaning 
something else is badly broken), but I guess adding counter 'just in case' 
wouldn't hurt much.

> Would it also make sense to add a small delay before resending the
> command?

I'm not sure up to how long can setting COD take, on my pc it takes <100ms for 
`hciconfig hci0 class 0x540100` with USB dongle. Does g_timeout_add with 
timeout ~50ms make sense?

-- 
Szymon K. Janc
szymon@janc.net.pl


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-06-11 20:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-10 19:50 [PATCH] mgmtops: Fix adding UUID when EBUSY error is returned Szymon Janc
2012-06-11  9:40 ` Johan Hedberg
2012-06-11 20:18   ` Szymon Janc

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.