From: Arman Uguray <armansito@chromium.org>
To: linux-bluetooth@vger.kernel.org
Cc: Arman Uguray <armansito@chromium.org>
Subject: [PATCH BlueZ v1 1/4] shared/att: Drop the connection is a request is received while one is pending.
Date: Mon, 6 Oct 2014 14:01:41 -0700 [thread overview]
Message-ID: <1412629304-3391-2-git-send-email-armansito@chromium.org> (raw)
In-Reply-To: <1412629304-3391-1-git-send-email-armansito@chromium.org>
With this patch, when bt_att is being used for the server role, it now makes
sure that a second request drops the connection unless a response for a previous
request has been sent.
---
src/shared/att.c | 101 +++++++++++++++++++++++++++++++++----------------------
1 file changed, 61 insertions(+), 40 deletions(-)
diff --git a/src/shared/att.c b/src/shared/att.c
index de35aef..96f34a3 100644
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -64,6 +64,8 @@ struct bt_att {
bool in_disconn;
bool need_disconn_cleanup;
+ bool in_req; /* There's a pending incoming request */
+
uint8_t *buf;
uint16_t mtu;
@@ -460,6 +462,9 @@ static bool can_write_data(struct io *io, void *user_data)
case ATT_OP_TYPE_IND:
att->pending_ind = op;
break;
+ case ATT_OP_TYPE_RSP:
+ /* Set in_req to false to indicate that no request is pending */
+ att->in_req = false;
default:
destroy_att_send_op(op);
return true;
@@ -604,6 +609,46 @@ static void handle_notify(struct bt_att *att, uint8_t opcode, uint8_t *pdu,
bt_att_unref(att);
}
+static void disconn_handler(void *data, void *user_data)
+{
+ struct att_disconn *disconn = data;
+
+ if (disconn->removed)
+ return;
+
+ if (disconn->callback)
+ disconn->callback(disconn->user_data);
+}
+
+static bool disconnect_cb(struct io *io, void *user_data)
+{
+ struct bt_att *att = user_data;
+
+ io_destroy(att->io);
+ att->io = NULL;
+
+ util_debug(att->debug_callback, att->debug_data,
+ "Physical link disconnected");
+
+ bt_att_ref(att);
+ att->in_disconn = true;
+ queue_foreach(att->disconn_list, disconn_handler, NULL);
+ att->in_disconn = false;
+
+ if (att->need_disconn_cleanup) {
+ queue_remove_all(att->disconn_list, match_disconn_removed, NULL,
+ destroy_att_disconn);
+ att->need_disconn_cleanup = false;
+ }
+
+ bt_att_cancel_all(att);
+ bt_att_unregister_all(att);
+
+ bt_att_unref(att);
+
+ return false;
+}
+
static bool can_read_data(struct io *io, void *user_data)
{
struct bt_att *att = user_data;
@@ -635,6 +680,22 @@ static bool can_read_data(struct io *io, void *user_data)
util_debug(att->debug_callback, att->debug_data,
"ATT opcode cannot be handled: 0x%02x", opcode);
break;
+ case ATT_OP_TYPE_REQ:
+ /* If a request is currently pending, then the sequential
+ * protocol was violated. Disconnect the bearer and notify the
+ * upper-layer.
+ */
+ if (att->in_req) {
+ util_debug(att->debug_callback, att->debug_data,
+ "Received request while another is "
+ "pending: 0x%02x", opcode);
+ disconnect_cb(att->io, att);
+ return false;
+ }
+
+ att->in_req = true;
+
+ /* Fall through to the next case */
default:
/* For all other opcodes notify the upper layer of the PDU and
* let them act on it.
@@ -648,46 +709,6 @@ static bool can_read_data(struct io *io, void *user_data)
return true;
}
-static void disconn_handler(void *data, void *user_data)
-{
- struct att_disconn *disconn = data;
-
- if (disconn->removed)
- return;
-
- if (disconn->callback)
- disconn->callback(disconn->user_data);
-}
-
-static bool disconnect_cb(struct io *io, void *user_data)
-{
- struct bt_att *att = user_data;
-
- io_destroy(att->io);
- att->io = NULL;
-
- util_debug(att->debug_callback, att->debug_data,
- "Physical link disconnected");
-
- bt_att_ref(att);
- att->in_disconn = true;
- queue_foreach(att->disconn_list, disconn_handler, NULL);
- att->in_disconn = false;
-
- if (att->need_disconn_cleanup) {
- queue_remove_all(att->disconn_list, match_disconn_removed, NULL,
- destroy_att_disconn);
- att->need_disconn_cleanup = false;
- }
-
- bt_att_cancel_all(att);
- bt_att_unregister_all(att);
-
- bt_att_unref(att);
-
- return false;
-}
-
struct bt_att *bt_att_new(int fd)
{
struct bt_att *att;
--
2.1.0.rc2.206.gedb03e5
next prev parent reply other threads:[~2014-10-06 21:01 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-06 21:01 [PATCH BlueZ v1 0/5] Introduce shared/gatt-server Arman Uguray
2014-10-06 21:01 ` Arman Uguray [this message]
2014-10-06 21:01 ` [PATCH BlueZ v1 2/4] shared/gatt-server: " Arman Uguray
2014-10-09 8:18 ` Marcin Kraglak
2014-10-06 21:01 ` [PATCH BlueZ v1 3/4] shared/gatt-server: Support Exchange MTU request Arman Uguray
2014-10-06 21:01 ` [PATCH BlueZ v1 4/4] shared/gatt-server: Support Read By Group Type request Arman Uguray
2014-10-09 8:24 ` Luiz Augusto von Dentz
2014-10-13 20:57 ` Arman Uguray
2014-10-08 15:14 ` [PATCH BlueZ v1 0/5] Introduce shared/gatt-server Arman Uguray
2014-10-09 8:29 ` Luiz Augusto von Dentz
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=1412629304-3391-2-git-send-email-armansito@chromium.org \
--to=armansito@chromium.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox