/** configure MTU operation complete */
void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB* p_clcb,
tBTA_GATTC_OP_CMPL* p_data) {
+ GATT_CONFIGURE_MTU_OP_CB cb = p_clcb->p_q_cmd->api_mtu.mtu_cb;
+ void* my_cb_data = p_clcb->p_q_cmd->api_mtu.mtu_cb_data;
tBTA_GATTC cb_data;
osi_free_and_reset((void**)&p_clcb->p_q_cmd);
cb_data.cfg_mtu.status = p_data->status;
cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu;
+ if (cb) {
+ cb(p_clcb->bta_conn_id, p_data->status, my_cb_data);
+ }
+
(*p_clcb->p_rcb->p_cback)(BTA_GATTC_CFG_MTU_EVT, &cb_data);
}
bta_sys_sendmsg(p_buf);
}
+void BTA_GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu,
+ GATT_CONFIGURE_MTU_OP_CB callback, void* cb_data) {
+ tBTA_GATTC_API_CFG_MTU* p_buf =
+ (tBTA_GATTC_API_CFG_MTU*)osi_malloc(sizeof(tBTA_GATTC_API_CFG_MTU));
+
+ p_buf->hdr.event = BTA_GATTC_API_CFG_MTU_EVT;
+ p_buf->hdr.layer_specific = conn_id;
+ p_buf->mtu = mtu;
+ p_buf->mtu_cb = callback;
+ p_buf->mtu_cb_data = cb_data;
+
+ bta_sys_sendmsg(p_buf);
+}
/*******************************************************************************
*
typedef struct {
BT_HDR hdr;
uint16_t mtu;
+ GATT_CONFIGURE_MTU_OP_CB mtu_cb;
+ void* mtu_cb_data;
} tBTA_GATTC_API_CFG_MTU;
typedef struct {
constexpr uint8_t GATT_READ_DESC = 2;
constexpr uint8_t GATT_WRITE_CHAR = 3;
constexpr uint8_t GATT_WRITE_DESC = 4;
+constexpr uint8_t GATT_CONFIG_MTU = 5;
struct gatt_read_op_data {
GATT_READ_OP_CB cb;
}
}
+struct gatt_configure_mtu_op_data {
+ GATT_CONFIGURE_MTU_OP_CB cb;
+ void* cb_data;
+};
+
+void BtaGattQueue::gatt_configure_mtu_op_finished(uint16_t conn_id,
+ tGATT_STATUS status,
+ void* data) {
+ gatt_configure_mtu_op_data* tmp = (gatt_configure_mtu_op_data*)data;
+ GATT_CONFIGURE_MTU_OP_CB tmp_cb = tmp->cb;
+ void* tmp_cb_data = tmp->cb_data;
+
+ osi_free(data);
+
+ mark_as_not_executing(conn_id);
+ gatt_execute_next_op(conn_id);
+
+ if (tmp_cb) {
+ tmp_cb(conn_id, status, tmp_cb_data);
+ return;
+ }
+}
+
void BtaGattQueue::gatt_execute_next_op(uint16_t conn_id) {
APPL_TRACE_DEBUG("%s: conn_id=0x%x", __func__, conn_id);
if (gatt_op_queue.empty()) {
data->cb_data = op.write_cb_data;
BTA_GATTC_WriteCharDescr(conn_id, op.handle, std::move(op.value),
GATT_AUTH_REQ_NONE, gatt_write_op_finished, data);
+ } else if (op.type == GATT_CONFIG_MTU) {
+ gatt_configure_mtu_op_data* data =
+ (gatt_configure_mtu_op_data*)osi_malloc(sizeof(gatt_configure_mtu_op_data));
+ data->cb = op.mtu_cb;
+ data->cb_data = op.mtu_cb_data;
+ BTA_GATTC_ConfigureMTU(conn_id, static_cast<uint16_t>(op.value[0] |
+ (op.value[1] << 8)),
+ gatt_configure_mtu_op_finished, data);
}
gatt_ops.pop_front();
.value = std::move(value)});
gatt_execute_next_op(conn_id);
}
+
+void BtaGattQueue::ConfigureMtu(uint16_t conn_id, uint16_t mtu) {
+ LOG(INFO) << __func__ << ", mtu: " << static_cast<int>(mtu);
+ std::vector<uint8_t> value = {static_cast<uint8_t>(mtu & 0xff),
+ static_cast<uint8_t>(mtu >> 8)};
+ gatt_op_queue[conn_id].push_back({.type = GATT_CONFIG_MTU,
+ .value = std::move(value)});
+ gatt_execute_next_op(conn_id);
+}
void* data);
typedef void (*GATT_WRITE_OP_CB)(uint16_t conn_id, tGATT_STATUS status,
uint16_t handle, void* data);
+typedef void (*GATT_CONFIGURE_MTU_OP_CB)(uint16_t conn_id, tGATT_STATUS status,
+ void* data);
/*******************************************************************************
*
*
******************************************************************************/
extern void BTA_GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu);
+extern void BTA_GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu,
+ GATT_CONFIGURE_MTU_OP_CB callback,
+ void* cb_data);
/*******************************************************************************
* BTA GATT Server API
std::vector<uint8_t> value,
tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
void* cb_data);
+ static void ConfigureMtu(uint16_t conn_id, uint16_t mtu);
/* Holds pending GATT operations */
struct gatt_operation {
void* read_cb_data;
GATT_WRITE_OP_CB write_cb;
void* write_cb_data;
+ GATT_CONFIGURE_MTU_OP_CB mtu_cb;
+ void* mtu_cb_data;
/* write-specific fields */
tGATT_WRITE_TYPE write_type;
uint8_t* value, void* data);
static void gatt_write_op_finished(uint16_t conn_id, tGATT_STATUS status,
uint16_t handle, void* data);
+ static void gatt_configure_mtu_op_finished(uint16_t conn_id,
+ tGATT_STATUS status, void* data);
// maps connection id to operations waiting for execution
static std::unordered_map<uint16_t, std::list<gatt_operation>> gatt_op_queue;
static bt_status_t btif_gattc_configure_mtu(int conn_id, int mtu) {
CHECK_BTGATT_INIT();
return do_in_jni_thread(
- Bind(base::IgnoreResult(&BTA_GATTC_ConfigureMTU), conn_id, mtu));
+ Bind(base::IgnoreResult(
+ static_cast<void (*)(uint16_t,uint16_t)>(&BTA_GATTC_ConfigureMTU)),
+ conn_id, mtu));
}
static void btif_gattc_conn_parameter_update_impl(