From 92e8d913329bac525c898948c5b922785bf8b9ca Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 9 Feb 2017 11:27:23 +0200 Subject: [PATCH 1/5] Bluetooth: GATT: Fix not updating previous node When iterating to the subscriptions to be removed the code has to keep a reference to the previous node but it case the subscription matches but doesn't need to be removed it doesn't update the prev node which may corrupt the list in case the next node end up being removed. Change-Id: Ic5448f01bf78d293f93b9a7078a0147385ea1d23 Signed-off-by: Luiz Augusto von Dentz --- subsys/bluetooth/host/gatt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 643c6a31d1f..9f08dbd995a 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -765,6 +765,7 @@ static void remove_subscriptions(struct bt_conn *conn) gatt_subscription_remove(conn, prev, params); } else { update_subscription(conn, params); + prev = node; } } } From fb3317b7a1a91122bc2d288cd9c700fa5e7e55fb Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 9 Feb 2017 22:25:56 +0100 Subject: [PATCH 2/5] Bluetooth: Fix not clearing signaled flag for conn_change signal From k_poll_signal_init() documentation: The poll signal contains a 'signaled' field that, when set by k_poll_signal(), stays set until the user sets it back to 0. It thus has to be reset by the user before being passed again to k_poll() or k_poll() will consider it being signaled, and will return immediately. Change-Id: I55daac92dd6293ac653fd7fa0f907b0b7fd99d65 Signed-off-by: Szymon Janc --- subsys/bluetooth/host/conn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index d3011b87b65..b2f922f2e3e 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1026,6 +1026,7 @@ int bt_conn_prepare_events(struct k_poll_event events[]) BT_DBG(""); + conn_change.signaled = 0; k_poll_event_init(&events[ev_count++], K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &conn_change); From 6c995a50536d7c8c6f4753358f15c22bf848456c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 10 Feb 2017 08:49:19 +0200 Subject: [PATCH 3/5] Bluetooth: Fix missing connection cleanup in some scenarios If the TX thread is not in k_poll() when conn->state gets set to DISCONNECTED and a dummy buffer is pushed to conn->tx_queue the bt_conn_prepare_events() function would have failed to add the connection to the poll list for cleanup. To ensure the cleanup always happens introduce a new flag that indicates that a cleanup must happen. The extra benefit of the flag is that we no-longer need a dummy buffer, but can simply use the conn_change signal to wake up the TX thread. Change-Id: I369584d305261ab3666b931c786daff9d131d228 Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/conn.c | 48 +++++++++++++++++---------- subsys/bluetooth/host/conn_internal.h | 1 + 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index b2f922f2e3e..5b9c6af14f0 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1020,6 +1020,25 @@ static bool send_buf(struct bt_conn *conn, struct net_buf *buf) static struct k_poll_signal conn_change = K_POLL_SIGNAL_INITIALIZER(); +static void conn_cleanup(struct bt_conn *conn) +{ + struct net_buf *buf; + + /* Give back any allocated buffers */ + while ((buf = net_buf_get(&conn->tx_queue, K_NO_WAIT))) { + net_buf_unref(buf); + } + + BT_ASSERT(!conn->pending_pkts); + + bt_conn_reset_rx_state(conn); + + /* Release the reference we took for the very first + * state transition. + */ + bt_conn_unref(conn); +} + int bt_conn_prepare_events(struct k_poll_event events[]) { int i, ev_count = 0; @@ -1037,6 +1056,12 @@ int bt_conn_prepare_events(struct k_poll_event events[]) continue; } + if (conn->state == BT_CONN_DISCONNECTED && + atomic_test_and_clear_bit(conn->flags, BT_CONN_CLEANUP)) { + conn_cleanup(conn); + continue; + } + if (conn->state != BT_CONN_CONNECTED) { continue; } @@ -1059,23 +1084,10 @@ void bt_conn_process_tx(struct bt_conn *conn) BT_DBG("conn %p", conn); - if (conn->state != BT_CONN_CONNECTED) { + if (conn->state == BT_CONN_DISCONNECTED && + atomic_test_and_clear_bit(conn->flags, BT_CONN_CLEANUP)) { BT_DBG("handle %u disconnected - cleaning up", conn->handle); - - /* Give back any allocated buffers */ - while ((buf = net_buf_get(&conn->tx_queue, K_NO_WAIT))) { - net_buf_unref(buf); - } - - BT_ASSERT(!conn->pending_pkts); - - bt_conn_reset_rx_state(conn); - - /* Release the reference we took for the very first - * state transition. - */ - bt_conn_unref(conn); - + conn_cleanup(conn); return; } @@ -1171,8 +1183,8 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) k_delayed_work_cancel(&conn->le.update_work); } - net_buf_put(&conn->tx_queue, - bt_conn_create_pdu(NULL, 0)); + atomic_set_bit(conn->flags, BT_CONN_CLEANUP); + k_poll_signal(&conn_change, 0); /* The last ref will be dropped by the tx_thread */ } else if (old_state == BT_CONN_CONNECT) { /* conn->err will be set in this case */ diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index dd1a9e01913..aec5925e423 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -23,6 +23,7 @@ enum { BT_CONN_BR_PAIRING, /* BR connection in pairing context */ BT_CONN_BR_NOBOND, /* SSP no bond pairing tracker */ BT_CONN_BR_PAIRING_INITIATOR, /* local host starts authentication */ + BT_CONN_CLEANUP, /* Disconnected, pending cleanup */ /* Total number of flags - must be at the end of the enum */ BT_CONN_NUM_FLAGS, From 40f91b7105f510b9defe93ea33fbd68e29e5984d Mon Sep 17 00:00:00 2001 From: Arun Jagadish Date: Wed, 8 Feb 2017 18:52:12 +0530 Subject: [PATCH 4/5] Bluetooth: AVDTP: Moving structures to headerfile Moving AVDTP structure - bt_avdtp_req,to header file. Change-Id: I6e3bbc9e5b45ae7009cc5d94ae50a08b0490f4fa Signed-off-by: Arun Jagadish --- subsys/bluetooth/host/avdtp.c | 10 ---------- subsys/bluetooth/host/avdtp_internal.h | 13 +++++++++++++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/subsys/bluetooth/host/avdtp.c b/subsys/bluetooth/host/avdtp.c index ad34c0b51fc..193f0cce2e1 100644 --- a/subsys/bluetooth/host/avdtp.c +++ b/subsys/bluetooth/host/avdtp.c @@ -38,20 +38,10 @@ #define AVDTP_GET_PKT_TYPE(hdr) ((hdr & 0x0c) >> AVDTP_PKT_POSITION) #define AVDTP_GET_SIG_ID(s) (s & AVDTP_SIGID_MASK) -typedef int (*bt_avdtp_func_t)(struct bt_avdtp *session, - struct bt_avdtp_req *req); - static struct bt_avdtp_event_cb *event_cb; static struct bt_avdtp_seid_lsep *lseps; -struct bt_avdtp_req { - uint8_t signal_id; - uint8_t transaction_id; - bt_avdtp_func_t func; - struct k_delayed_work timeout_work; -}; - #define AVDTP_CHAN(_ch) CONTAINER_OF(_ch, struct bt_avdtp, br_chan.chan) #define AVDTP_KWORK(_work) CONTAINER_OF(_work, struct bt_avdtp_req,\ diff --git a/subsys/bluetooth/host/avdtp_internal.h b/subsys/bluetooth/host/avdtp_internal.h index 7f8ae396ea5..0733cfddd80 100644 --- a/subsys/bluetooth/host/avdtp_internal.h +++ b/subsys/bluetooth/host/avdtp_internal.h @@ -87,6 +87,19 @@ #define BT_AVDTP_MIN_SEID 0x01 #define BT_AVDTP_MAX_SEID 0x3E +struct bt_avdtp; +struct bt_avdtp_req; + +typedef int (*bt_avdtp_func_t)(struct bt_avdtp *session, + struct bt_avdtp_req *req); + +struct bt_avdtp_req { + uint8_t signal_id; + uint8_t transaction_id; + bt_avdtp_func_t func; + struct k_delayed_work timeout_work; +}; + struct bt_avdtp_single_sig_hdr { uint8_t hdr; uint8_t signal_id; From 6545aa3f5266237c8a47eaade53b90730782a375 Mon Sep 17 00:00:00 2001 From: Prasanna Karthik Date: Thu, 9 Feb 2017 16:18:48 -0800 Subject: [PATCH 5/5] Bluetooth: nble: Catch and handle non-zero fn_index Avoid multiple breaks and gracefully catch non-zero values of fn_index Change-Id: I1cf7b271b8478e63af2da1f40b4caceb63d7ce90 Signed-off-by: Prasanna Karthik --- drivers/bluetooth/nble/rpc_deserialize.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/nble/rpc_deserialize.c b/drivers/bluetooth/nble/rpc_deserialize.c index 8bb0f5374c0..29ef88cbbbf 100644 --- a/drivers/bluetooth/nble/rpc_deserialize.c +++ b/drivers/bluetooth/nble/rpc_deserialize.c @@ -557,8 +557,9 @@ static void deserialize_control(uint8_t fn_index, struct net_buf *buf) rpc_init_cb(struct_data.version, true); } break; - break; + default: panic(-1); + break; } }