Merge bluetooth branch into master

Some more Bluetooth fixes for 1.7.0-rc1.

----------------------------------------------------------------
Arun Jagadish (1):
      Bluetooth: AVDTP: Moving structures to headerfile

Johan Hedberg (1):
      Bluetooth: Fix missing connection cleanup in some scenarios

Luiz Augusto von Dentz (1):
      Bluetooth: GATT: Fix not updating previous node

Prasanna Karthik (1):
      Bluetooth: nble: Catch and handle non-zero fn_index

Szymon Janc (1):
      Bluetooth: Fix not clearing signaled flag for conn_change signal

 drivers/bluetooth/nble/rpc_deserialize.c |  3 +-
 subsys/bluetooth/host/avdtp.c            | 10 ----
 subsys/bluetooth/host/avdtp_internal.h   | 13 +++++
 subsys/bluetooth/host/conn.c             | 49 +++++++++++------
 subsys/bluetooth/host/conn_internal.h    |  1 +
 subsys/bluetooth/host/gatt.c             |  1 +
 6 files changed, 48 insertions(+), 29 deletions(-)

Change-Id: If1d53d9767d89080480ce5147156adeeb26565dc
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2017-02-10 18:03:15 +02:00
commit 01c821f56f
6 changed files with 48 additions and 29 deletions

View file

@ -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;
}
}

View file

@ -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,\

View file

@ -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;

View file

@ -1020,12 +1020,32 @@ 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;
BT_DBG("");
conn_change.signaled = 0;
k_poll_event_init(&events[ev_count++], K_POLL_TYPE_SIGNAL,
K_POLL_MODE_NOTIFY_ONLY, &conn_change);
@ -1036,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;
}
@ -1058,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;
}
@ -1170,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 */

View file

@ -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,

View file

@ -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;
}
}
}