All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ 3/3] shared/att: Auto retry if request fails
Date: Thu, 18 Jun 2015 18:01:53 +0300	[thread overview]
Message-ID: <1434639713-32167-3-git-send-email-luiz.dentz@gmail.com> (raw)
In-Reply-To: <1434639713-32167-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds auto retry logic to requests when a security error happen,
it will first attempt to elevate the security to match the requirement
and then retry sending the request once again.
---
 src/shared/att.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/src/shared/att.c b/src/shared/att.c
index f9a5817..e8be4cc 100644
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -576,6 +576,55 @@ static bool disconnect_cb(struct io *io, void *user_data)
 	return false;
 }
 
+static bool change_security(struct bt_att *att, uint8_t ecode)
+{
+	int security;
+
+	security = bt_att_get_security(att);
+	if (ecode == BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION &&
+					security < BT_ATT_SECURITY_MEDIUM)
+		security = BT_ATT_SECURITY_MEDIUM;
+	else if (ecode == BT_ATT_ERROR_AUTHENTICATION &&
+					security < BT_ATT_SECURITY_HIGH)
+		security = BT_ATT_SECURITY_HIGH;
+	else
+		return false;
+
+	return bt_att_set_security(att, security);
+}
+
+static bool handle_error_rsp(struct bt_att *att, uint8_t *pdu,
+					ssize_t pdu_len, uint8_t *opcode)
+{
+	const struct bt_att_pdu_error_rsp *rsp;
+	struct att_send_op *op = att->pending_req;
+
+	if (pdu_len != sizeof(*rsp)) {
+		*opcode = 0;
+		return false;
+	}
+
+	rsp = (void *) pdu;
+
+	*opcode = rsp->opcode;
+
+	/* Only try to change security on L2CAP */
+	if (!att->io_on_l2cap)
+		return false;
+
+	/* Attempt to change security */
+	if (!change_security(att, rsp->ecode))
+		return false;
+
+	util_debug(att->debug_callback, att->debug_data,
+						"Retrying operation %p", op);
+
+	att->pending_req = NULL;
+
+	/* Push operation back to request queue */
+	return queue_push_head(att->req_queue, op);
+}
+
 static void handle_rsp(struct bt_att *att, uint8_t opcode, uint8_t *pdu,
 								ssize_t pdu_len)
 {
@@ -601,10 +650,11 @@ static void handle_rsp(struct bt_att *att, uint8_t opcode, uint8_t *pdu,
 	 * the request is malformed, end the current request with failure.
 	 */
 	if (opcode == BT_ATT_OP_ERROR_RSP) {
-		if (pdu_len != 4)
-			goto fail;
-
-		req_opcode = pdu[0];
+		/* Return if error response cause a retry */
+		if (handle_error_rsp(att, pdu, pdu_len, &req_opcode)) {
+			wakeup_writer(att);
+			return;
+		}
 	} else if (!(req_opcode = get_req_opcode(opcode)))
 		goto fail;
 
-- 
2.1.0


      parent reply	other threads:[~2015-06-18 15:01 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-18 15:01 [PATCH BlueZ 1/3] unit/test-gatt: Fix /TP/GAR/CL/BV-04-C test Luiz Augusto von Dentz
2015-06-18 15:01 ` [PATCH BlueZ 2/3] unit/test-gatt: Fix /TP/GAR/CL/BV-07-C test Luiz Augusto von Dentz
2015-06-18 15:01 ` Luiz Augusto von Dentz [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1434639713-32167-3-git-send-email-luiz.dentz@gmail.com \
    --to=luiz.dentz@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.