Bluetooth: GATT: Add bt_gatt_write_response_cb
This adds bt_gatt_write_response_cb works similarly to bt_gatt_notify_cb which can take a callback to be called when the PDU is considered transmitted over the air. Note: This can also be used to disable the ATT flow control which would blocks sending multiple commands without wainting their transmissions. Fixes #11558 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
c01535c735
commit
a779705f16
4 changed files with 53 additions and 23 deletions
|
@ -697,7 +697,7 @@ ssize_t bt_gatt_attr_read_cpf(struct bt_conn *conn,
|
|||
*
|
||||
* @param conn Connection object.
|
||||
*/
|
||||
typedef void (*bt_gatt_notify_complete_func_t) (struct bt_conn *conn);
|
||||
typedef void (*bt_gatt_complete_func_t) (struct bt_conn *conn);
|
||||
|
||||
/** @brief Notify attribute value change with callback.
|
||||
*
|
||||
|
@ -713,7 +713,7 @@ typedef void (*bt_gatt_notify_complete_func_t) (struct bt_conn *conn);
|
|||
*/
|
||||
int bt_gatt_notify_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
const void *data, u16_t len,
|
||||
bt_gatt_notify_complete_func_t func);
|
||||
bt_gatt_complete_func_t func);
|
||||
|
||||
/** @brief Notify attribute value change.
|
||||
*
|
||||
|
@ -999,6 +999,30 @@ struct bt_gatt_write_params {
|
|||
*/
|
||||
int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params);
|
||||
|
||||
/** @brief Write Attribute Value by handle without response with callback.
|
||||
*
|
||||
* This function works in the same way as @ref bt_gatt_write_without_response.
|
||||
* With the addition that after sending the write the callback function will be
|
||||
* called.
|
||||
*
|
||||
* Note: By using a callback it also disable the internal flow control
|
||||
* which would prevent sending multiple commands without wainting their
|
||||
* transmissions to complete, so if that is required the caller shall not
|
||||
* submit more data until the callback is called.
|
||||
*
|
||||
* @param conn Connection object.
|
||||
* @param handle Attribute handle.
|
||||
* @param data Data to be written.
|
||||
* @param length Data length.
|
||||
* @param sign Whether to sign data
|
||||
* @param func Transmission complete 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);
|
||||
|
||||
/** @brief Write Attribute Value by handle without response
|
||||
*
|
||||
* This procedure write the attribute value without requiring an
|
||||
|
@ -1012,9 +1036,13 @@ int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params);
|
|||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_gatt_write_without_response(struct bt_conn *conn, u16_t handle,
|
||||
const void *data, u16_t length,
|
||||
bool sign);
|
||||
static inline int bt_gatt_write_without_response(struct bt_conn *conn,
|
||||
u16_t handle, const void *data,
|
||||
u16_t length, bool sign)
|
||||
{
|
||||
return bt_gatt_write_without_response_cb(conn, handle, data, length,
|
||||
sign, NULL);
|
||||
}
|
||||
|
||||
struct bt_gatt_subscribe_params;
|
||||
|
||||
|
|
|
@ -2191,7 +2191,7 @@ 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)
|
||||
int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb)
|
||||
{
|
||||
struct bt_att *att;
|
||||
struct bt_att_hdr *hdr;
|
||||
|
@ -2205,12 +2205,15 @@ int bt_att_send(struct bt_conn *conn, struct net_buf *buf)
|
|||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
/* Don't use tx_sem if caller has set it own callback */
|
||||
if (!cb) {
|
||||
k_sem_take(&att->tx_sem, K_FOREVER);
|
||||
if (!att_is_connected(att)) {
|
||||
BT_WARN("Disconnected");
|
||||
k_sem_give(&att->tx_sem);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
}
|
||||
|
||||
hdr = (void *)buf->data;
|
||||
|
||||
|
@ -2227,7 +2230,7 @@ int bt_att_send(struct bt_conn *conn, struct net_buf *buf)
|
|||
}
|
||||
}
|
||||
|
||||
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, att_cb(buf));
|
||||
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, cb ? cb : att_cb(buf));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -242,7 +242,7 @@ 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);
|
||||
int bt_att_send(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb);
|
||||
|
||||
/* Send ATT Request over a connection */
|
||||
int bt_att_req_send(struct bt_conn *conn, struct bt_att_req *req);
|
||||
|
|
|
@ -774,14 +774,14 @@ struct notify_data {
|
|||
int err;
|
||||
u16_t type;
|
||||
const struct bt_gatt_attr *attr;
|
||||
bt_gatt_notify_complete_func_t func;
|
||||
bt_gatt_complete_func_t func;
|
||||
const void *data;
|
||||
u16_t len;
|
||||
struct bt_gatt_indicate_params *params;
|
||||
};
|
||||
|
||||
static int gatt_notify(struct bt_conn *conn, u16_t handle, const void *data,
|
||||
size_t len, bt_gatt_notify_complete_func_t cb)
|
||||
size_t len, bt_gatt_complete_func_t cb)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
struct bt_att_notify *nfy;
|
||||
|
@ -800,9 +800,7 @@ static int gatt_notify(struct bt_conn *conn, u16_t handle, const void *data,
|
|||
net_buf_add(buf, len);
|
||||
memcpy(nfy->value, data, len);
|
||||
|
||||
bt_l2cap_send_cb(conn, BT_L2CAP_CID_ATT, buf, cb);
|
||||
|
||||
return 0;
|
||||
return bt_att_send(conn, buf, cb);
|
||||
}
|
||||
|
||||
static void gatt_indicate_rsp(struct bt_conn *conn, u8_t err,
|
||||
|
@ -828,7 +826,7 @@ static int gatt_send(struct bt_conn *conn, struct net_buf *buf,
|
|||
|
||||
err = bt_att_req_send(conn, req);
|
||||
} else {
|
||||
err = bt_att_send(conn, buf);
|
||||
err = bt_att_send(conn, buf, NULL);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
|
@ -977,7 +975,7 @@ static u8_t notify_cb(const struct bt_gatt_attr *attr, void *user_data)
|
|||
|
||||
int bt_gatt_notify_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
const void *data, u16_t len,
|
||||
bt_gatt_notify_complete_func_t func)
|
||||
bt_gatt_complete_func_t func)
|
||||
{
|
||||
struct notify_data nfy;
|
||||
|
||||
|
@ -2089,8 +2087,9 @@ static void gatt_write_rsp(struct bt_conn *conn, u8_t err, const void *pdu,
|
|||
params->func(conn, err, params);
|
||||
}
|
||||
|
||||
int bt_gatt_write_without_response(struct bt_conn *conn, u16_t handle,
|
||||
const void *data, u16_t length, bool sign)
|
||||
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)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
struct bt_att_write_cmd *cmd;
|
||||
|
@ -2127,7 +2126,7 @@ int bt_gatt_write_without_response(struct bt_conn *conn, u16_t handle,
|
|||
|
||||
BT_DBG("handle 0x%04x length %u", handle, length);
|
||||
|
||||
return gatt_send(conn, buf, NULL, NULL, NULL);
|
||||
return bt_att_send(conn, buf, func);
|
||||
}
|
||||
|
||||
static int gatt_exec_write(struct bt_conn *conn,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue