Skip to content
Permalink
Browse files

Bluetooth: Add possibility to pass a user_data to conn_tx_cb_t

This allows setting a custom pointer to be passed back to the complete
callback at expense of increasing the buffers in 4 bytes.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  • Loading branch information...
Vudentz authored and jhedberg committed May 21, 2019
1 parent a3bea88 commit b65fe62719eea65c474309e2b7017eed7aef94c2
@@ -744,7 +744,7 @@ ssize_t bt_gatt_attr_read_cpf(struct bt_conn *conn,
*
* @param conn Connection object.
*/
typedef void (*bt_gatt_complete_func_t) (struct bt_conn *conn);
typedef void (*bt_gatt_complete_func_t) (struct bt_conn *conn, void *user_data);

/** @brief Notify attribute value change with callback.
*
@@ -757,10 +757,13 @@ typedef void (*bt_gatt_complete_func_t) (struct bt_conn *conn);
* @param data Pointer to Attribute data.
* @param len Attribute value length.
* @param func Notification value callback.
* @param user_data User data to be passed back to the callback.
*
* @return 0 in case of success or negative value in case of error.
*/
int bt_gatt_notify_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *data, u16_t len,
bt_gatt_complete_func_t func);
bt_gatt_complete_func_t func, void *user_data);

/** @brief Notify attribute value change.
*
@@ -778,12 +781,14 @@ int bt_gatt_notify_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
* @param attr Characteristic or Characteristic Value attribute.
* @param data Pointer to Attribute data.
* @param len Attribute value length.
*
* @return 0 in case of success or negative value in case of error.
*/
static inline int bt_gatt_notify(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
const void *data, u16_t len)
{
return bt_gatt_notify_cb(conn, attr, data, len, NULL);
return bt_gatt_notify_cb(conn, attr, data, len, NULL, NULL);
}

/** @typedef bt_gatt_indicate_func_t
@@ -1106,12 +1111,14 @@ int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params);
* @param length Data length.
* @param sign Whether to sign data
* @param func Transmission complete callback.
* @param user_data User data to be passed back to callback.
*
* @return 0 in case of success or negative value in case of error.
*/
int bt_gatt_write_without_response_cb(struct bt_conn *conn, u16_t handle,
const void *data, u16_t length,
bool sign, bt_gatt_complete_func_t func);
bool sign, bt_gatt_complete_func_t func,
void *user_data);

/** @brief Write Attribute Value by handle without response
*
@@ -1131,7 +1138,7 @@ static inline int bt_gatt_write_without_response(struct bt_conn *conn,
u16_t length, bool sign)
{
return bt_gatt_write_without_response_cb(conn, handle, data, length,
sign, NULL);
sign, NULL, NULL);
}

struct bt_gatt_subscribe_params;
@@ -13,9 +13,6 @@ CONFIG_MCUMGR_SMP_BT=y
#CONFIG_MCUMGR_SMP_SHELL=y
#CONFIG_MCUMGR_SMP_UART=y

# Bluetooth support requires a net_buf user_data size >= 7.
CONFIG_NET_BUF_USER_DATA_SIZE=7

# Enable flash operations.
CONFIG_FLASH=y

@@ -16,9 +16,6 @@ CONFIG_MCUMGR_SMP_BT=y
CONFIG_MCUMGR_SMP_SHELL=y
#CONFIG_MCUMGR_SMP_UART=y

# Bluetooth support requires a net_buf user_data size >= 7.
CONFIG_NET_BUF_USER_DATA_SIZE=7

# Enable flash operations.
CONFIG_FLASH=y

@@ -23,9 +23,6 @@ CONFIG_MCUMGR_SMP_UART=y
# Disable Bluetooth unused features
CONFIG_BT_GATT_READ_MULTIPLE=n

# Bluetooth support requires a net_buf user_data size >= 7.
CONFIG_NET_BUF_USER_DATA_SIZE=7

# Enable flash operations.
CONFIG_FLASH=y

@@ -121,7 +121,7 @@ static struct bt_att *att_get(struct bt_conn *conn)
return CONTAINER_OF(chan, struct bt_att, chan);
}

static void att_cfm_sent(struct bt_conn *conn)
static void att_cfm_sent(struct bt_conn *conn, void *user_data)
{
struct bt_att *att = att_get(conn);

@@ -134,7 +134,7 @@ static void att_cfm_sent(struct bt_conn *conn)
k_sem_give(&att->tx_sem);
}

static void att_rsp_sent(struct bt_conn *conn)
static void att_rsp_sent(struct bt_conn *conn, void *user_data)
{
struct bt_att *att = att_get(conn);

@@ -147,7 +147,7 @@ static void att_rsp_sent(struct bt_conn *conn)
k_sem_give(&att->tx_sem);
}

static void att_req_sent(struct bt_conn *conn)
static void att_req_sent(struct bt_conn *conn, void *user_data)
{
struct bt_att *att = att_get(conn);

@@ -161,7 +161,7 @@ static void att_req_sent(struct bt_conn *conn)
}
}

static void att_pdu_sent(struct bt_conn *conn)
static void att_pdu_sent(struct bt_conn *conn, void *user_data)
{
struct bt_att *att = att_get(conn);

@@ -206,7 +206,7 @@ static void send_err_rsp(struct bt_conn *conn, u8_t req, u16_t handle,
rsp->handle = sys_cpu_to_le16(handle);
rsp->error = err;

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, att_rsp_sent, NULL);
}

static u8_t att_mtu_req(struct bt_att *att, struct net_buf *buf)
@@ -240,7 +240,7 @@ static u8_t att_mtu_req(struct bt_att *att, struct net_buf *buf)
rsp = net_buf_add(pdu, sizeof(*rsp));
rsp->mtu = sys_cpu_to_le16(mtu_server);

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, pdu, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, pdu, att_rsp_sent, NULL);

/* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part F] page 484:
*
@@ -282,7 +282,7 @@ static int att_send_req(struct bt_att *att, struct bt_att_req *req)

/* Keep a reference for resending in case of an error */
bt_l2cap_send_cb(att->chan.chan.conn, BT_L2CAP_CID_ATT,
net_buf_ref(req->buf), att_cb(req->buf));
net_buf_ref(req->buf), att_cb(req->buf), NULL);

return 0;
}
@@ -484,7 +484,7 @@ static u8_t att_find_info_rsp(struct bt_att *att, u16_t start_handle,
return 0;
}

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent, NULL);

return 0;
}
@@ -613,7 +613,7 @@ static u8_t att_find_type_rsp(struct bt_att *att, u16_t start_handle,
return 0;
}

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent, NULL);

return 0;
}
@@ -827,7 +827,7 @@ static u8_t att_read_type_rsp(struct bt_att *att, struct bt_uuid *uuid,
return 0;
}

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent, NULL);

return 0;
}
@@ -950,7 +950,7 @@ static u8_t att_read_rsp(struct bt_att *att, u8_t op, u8_t rsp, u16_t handle,
return 0;
}

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent, NULL);

return 0;
}
@@ -1028,7 +1028,7 @@ static u8_t att_read_mult_req(struct bt_att *att, struct net_buf *buf)
}
}

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent, NULL);

return 0;
}
@@ -1133,7 +1133,7 @@ static u8_t att_read_group_rsp(struct bt_att *att, struct bt_uuid *uuid,
return 0;
}

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent, NULL);

return 0;
}
@@ -1276,7 +1276,7 @@ static u8_t att_write_rsp(struct bt_conn *conn, u8_t req, u8_t rsp,

if (data.buf) {
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf,
att_rsp_sent);
att_rsp_sent, NULL);
}

return 0;
@@ -1400,7 +1400,7 @@ static u8_t att_prep_write_rsp(struct bt_att *att, u16_t handle, u16_t offset,
net_buf_add(data.buf, len);
memcpy(rsp->value, value, len);

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, data.buf, att_rsp_sent, NULL);

return 0;
}
@@ -1463,7 +1463,7 @@ static u8_t att_exec_write_rsp(struct bt_att *att, u8_t flags)
return BT_ATT_ERR_UNLIKELY;
}

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, att_rsp_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, att_rsp_sent, NULL);

return 0;
}
@@ -1732,7 +1732,7 @@ static u8_t att_indicate(struct bt_att *att, struct net_buf *buf)
return 0;
}

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, att_cfm_sent);
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, att_cfm_sent, NULL);

return 0;
}
@@ -2133,7 +2133,7 @@ static void bt_att_encrypt_change(struct bt_l2cap_chan *chan,

/* Resend buffer */
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, att->req->buf,
att_cb(att->req->buf));
att_cb(att->req->buf), NULL);
att->req->buf = NULL;
}
#endif /* CONFIG_BT_SMP */
@@ -2194,7 +2194,8 @@ u16_t bt_att_get_mtu(struct bt_conn *conn)
return att->chan.tx.mtu;
}

int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb)
int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb,
void *user_data)
{
struct bt_att *att;
struct bt_att_hdr *hdr;
@@ -2233,7 +2234,8 @@ int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb)
}
}

bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, cb ? cb : att_cb(buf));
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, cb ? cb : att_cb(buf),
user_data);

return 0;
}
@@ -242,7 +242,8 @@ struct net_buf *bt_att_create_pdu(struct bt_conn *conn, u8_t op,
size_t len);

/* Send ATT PDU over a connection */
int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb);
int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb,
void *user_data);

/* Send ATT Request over a connection */
int bt_att_req_send(struct bt_conn *conn, struct bt_att_req *req);
@@ -68,11 +68,7 @@ const struct bt_conn_auth_cb *bt_auth;
static struct bt_conn conns[CONFIG_BT_MAX_CONN];
static struct bt_conn_cb *callback_list;

struct conn_tx_cb {
bt_conn_tx_cb_t cb;
};

#define conn_tx(buf) ((struct conn_tx_cb *)net_buf_user_data(buf))
#define conn_tx(buf) ((struct bt_conn_tx_data *)net_buf_user_data(buf))

static struct bt_conn_tx conn_tx[CONFIG_BT_CONN_TX_MAX];
static sys_slist_t free_tx = SYS_SLIST_STATIC_INIT(&free_tx);
@@ -1152,9 +1148,10 @@ void bt_conn_recv(struct bt_conn *conn, struct net_buf *buf, u8_t flags)
}

int bt_conn_send_cb(struct bt_conn *conn, struct net_buf *buf,
bt_conn_tx_cb_t cb)
bt_conn_tx_cb_t cb, void *user_data)
{
BT_DBG("conn handle %u buf len %u cb %p", conn->handle, buf->len, cb);
BT_DBG("conn handle %u buf len %u cb %p user_data %p", conn->handle,
buf->len, cb, user_data);

if (conn->state != BT_CONN_CONNECTED) {
BT_ERR("not connected!");
@@ -1163,14 +1160,16 @@ int bt_conn_send_cb(struct bt_conn *conn, struct net_buf *buf,
}

conn_tx(buf)->cb = cb;
conn_tx(buf)->user_data = user_data;

net_buf_put(&conn->tx_queue, buf);
return 0;
}

static void tx_free(struct bt_conn_tx *tx)
{
tx->cb = NULL;
tx->data.cb = NULL;
tx->data.user_data = NULL;
sys_slist_prepend(&free_tx, &tx->node);
}

@@ -1181,8 +1180,9 @@ void bt_conn_notify_tx(struct bt_conn *conn)
BT_DBG("conn %p", conn);

while ((tx = k_fifo_get(&conn->tx_notify, K_NO_WAIT))) {
if (tx->cb) {
tx->cb(conn);
BT_DBG("cb %p user_data %p", tx->data.cb, tx->data.user_data);
if (tx->data.cb) {
tx->data.cb(conn, tx->data.user_data);
}

tx_free(tx);
@@ -1205,17 +1205,21 @@ static void notify_tx(void)
}
}

static sys_snode_t *add_pending_tx(struct bt_conn *conn, bt_conn_tx_cb_t cb)
static sys_snode_t *add_pending_tx(struct bt_conn *conn, bt_conn_tx_cb_t cb,
void *user_data)
{
struct bt_conn_tx *tx;
sys_snode_t *node;
unsigned int key;

BT_DBG("conn %p cb %p", conn, cb);
BT_DBG("conn %p cb %p user_data %p", conn, cb, user_data);

__ASSERT(!sys_slist_is_empty(&free_tx), "No free conn TX contexts");

node = sys_slist_get_not_empty(&free_tx);
CONTAINER_OF(node, struct bt_conn_tx, node)->cb = cb;
tx = CONTAINER_OF(node, struct bt_conn_tx, node);
tx->data.cb = cb;
tx->data.user_data = user_data;

key = irq_lock();
sys_slist_append(&conn->tx_pending, node);
@@ -1239,7 +1243,6 @@ static bool send_frag(struct bt_conn *conn, struct net_buf *buf, u8_t flags,
bool always_consume)
{
struct bt_hci_acl_hdr *hdr;
bt_conn_tx_cb_t cb;
sys_snode_t *node;
int err;

@@ -1261,10 +1264,10 @@ static bool send_frag(struct bt_conn *conn, struct net_buf *buf, u8_t flags,
hdr->handle = sys_cpu_to_le16(bt_acl_handle_pack(conn->handle, flags));
hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr));

cb = conn_tx(buf)->cb;
bt_buf_set_type(buf, BT_BUF_ACL_OUT);
/* Add to pending, it must be done before bt_buf_set_type */
node = add_pending_tx(conn, conn_tx(buf)->cb, conn_tx(buf)->user_data);

node = add_pending_tx(conn, cb);
bt_buf_set_type(buf, BT_BUF_ACL_OUT);

err = bt_send(buf);
if (err) {
@@ -1312,6 +1315,7 @@ static struct net_buf *create_frag(struct bt_conn *conn, struct net_buf *buf)

/* Fragments never have a TX completion callback */
conn_tx(frag)->cb = NULL;
conn_tx(frag)->user_data = NULL;

frag_len = MIN(conn_mtu(conn), net_buf_tailroom(frag));

0 comments on commit b65fe62

Please sign in to comment.
You can’t perform that action at this time.