Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8190200 authored by Jakub Pawłowski's avatar Jakub Pawłowski Committed by Gerrit Code Review
Browse files

Merge "GATT: Read Multiple Variable Length" into main

parents 45de4fd9 c17ff3f4
Loading
Loading
Loading
Loading
+44 −20
Original line number Diff line number Diff line
@@ -1014,7 +1014,7 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb,
                          const tBTA_GATTC_DATA* p_data) {
  if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return;

  if (p_data->api_read_multi.num_attr > GATT_MAX_READ_MULTI_HANDLES) {
  if (p_data->api_read_multi.handles.num_attr > GATT_MAX_READ_MULTI_HANDLES) {
    LOG(ERROR) << "api_read_multi.num_attr > GATT_MAX_READ_MULTI_HANDLES";
    return;
  }
@@ -1022,13 +1022,18 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb,
  tGATT_READ_PARAM read_param;
  memset(&read_param, 0, sizeof(tGATT_READ_PARAM));

  read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
  read_param.read_multiple.num_handles =
      p_data->api_read_multi.handles.num_attr;
  read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
  memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
         sizeof(uint16_t) * p_data->api_read_multi.num_attr);

  tGATT_STATUS status =
      GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
  read_param.read_multiple.variable_len = p_data->api_read_multi.variable_len;
  memcpy(&read_param.read_multiple.handles,
         p_data->api_read_multi.handles.handles,
         sizeof(uint16_t) * p_data->api_read_multi.handles.num_attr);

  tGATT_READ_TYPE read_type = (read_param.read_multiple.variable_len)
                                  ? GATT_READ_MULTIPLE_VAR_LEN
                                  : GATT_READ_MULTIPLE;
  tGATT_STATUS status = GATTC_Read(p_clcb->bta_conn_id, read_type, &read_param);
  /* read fail */
  if (status != GATT_SUCCESS) {
    /* Dequeue the data, if it was enqueued */
@@ -1110,11 +1115,14 @@ void bta_gattc_confirm(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
/** read complete */
static void bta_gattc_read_cmpl(tBTA_GATTC_CLCB* p_clcb,
                                const tBTA_GATTC_OP_CMPL* p_data) {
  void* my_cb_data;

  if (!p_clcb->p_q_cmd->api_read.is_multi_read) {
    GATT_READ_OP_CB cb = p_clcb->p_q_cmd->api_read.read_cb;
  void* my_cb_data = p_clcb->p_q_cmd->api_read.read_cb_data;
    my_cb_data = p_clcb->p_q_cmd->api_read.read_cb_data;

  /* if it was read by handle, return the handle requested, if read by UUID, use
   * handle returned from remote
    /* if it was read by handle, return the handle requested, if read by UUID,
     * use handle returned from remote
     */
    uint16_t handle = p_clcb->p_q_cmd->api_read.handle;
    if (handle == 0) handle = p_data->p_cmpl->att_value.handle;
@@ -1126,6 +1134,19 @@ static void bta_gattc_read_cmpl(tBTA_GATTC_CLCB* p_clcb,
         p_data->p_cmpl->att_value.len, p_data->p_cmpl->att_value.value,
         my_cb_data);
    }
  } else {
    GATT_READ_MULTI_OP_CB cb = p_clcb->p_q_cmd->api_read_multi.read_cb;
    my_cb_data = p_clcb->p_q_cmd->api_read_multi.read_cb_data;
    tBTA_GATTC_MULTI handles = p_clcb->p_q_cmd->api_read_multi.handles;

    osi_free_and_reset((void**)&p_clcb->p_q_cmd);

    if (cb) {
      cb(p_clcb->bta_conn_id, p_data->status, handles,
         p_data->p_cmpl->att_value.len, p_data->p_cmpl->att_value.value,
         my_cb_data);
    }
  }
}

/** write complete */
@@ -1223,9 +1244,12 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
  }

  if (p_clcb->p_q_cmd->hdr.event !=
      bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) {
          bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ] &&
      (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT ||
       op != GATTC_OPTYPE_READ)) {
    uint8_t mapped_op =
        p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ;

    if (mapped_op > GATTC_OPTYPE_INDICATION) mapped_op = 0;

    LOG(ERROR) << StringPrintf(
+17 −11
Original line number Diff line number Diff line
@@ -129,8 +129,8 @@ void BTA_GATTC_AppDeregister(tGATT_IF client_if) {
 *                  transport: Transport to be used for GATT connection
 *                             (BREDR/LE)
 *                  initiating_phys: LE PHY to use, optional
 *                  opportunistic: wether the connection shall be opportunistic,
 *                                 and don't impact the disconnection timer
 *                  opportunistic: whether the connection shall be
 *                  opportunistic, and don't impact the disconnection timer
 *
 ******************************************************************************/
void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda,
@@ -398,6 +398,7 @@ void BTA_GATTC_ReadCharacteristic(uint16_t conn_id, uint16_t handle,

  p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
  p_buf->hdr.layer_specific = conn_id;
  p_buf->is_multi_read = false;
  p_buf->auth_req = auth_req;
  p_buf->handle = handle;
  p_buf->read_cb = callback;
@@ -419,6 +420,7 @@ void BTA_GATTC_ReadUsingCharUuid(uint16_t conn_id, const Uuid& uuid,

  p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
  p_buf->hdr.layer_specific = conn_id;
  p_buf->is_multi_read = false;
  p_buf->auth_req = auth_req;
  p_buf->handle = 0;
  p_buf->uuid = uuid;
@@ -450,6 +452,7 @@ void BTA_GATTC_ReadCharDescr(uint16_t conn_id, uint16_t handle,

  p_buf->hdr.event = BTA_GATTC_API_READ_EVT;
  p_buf->hdr.layer_specific = conn_id;
  p_buf->is_multi_read = false;
  p_buf->auth_req = auth_req;
  p_buf->handle = handle;
  p_buf->read_cb = callback;
@@ -467,24 +470,27 @@ void BTA_GATTC_ReadCharDescr(uint16_t conn_id, uint16_t handle,
 *
 * Parameters       conn_id - connectino ID.
 *                  p_read_multi - pointer to the read multiple parameter.
 *                  variable_len - whether "read multi variable length" variant
 *                                 shall be used.
 *
 *
 * Returns          None
 *
 ******************************************************************************/
void BTA_GATTC_ReadMultiple(uint16_t conn_id, tBTA_GATTC_MULTI* p_read_multi,
                            tGATT_AUTH_REQ auth_req) {
void BTA_GATTC_ReadMultiple(uint16_t conn_id, tBTA_GATTC_MULTI& handles,
                            bool variable_len, tGATT_AUTH_REQ auth_req,
                            GATT_READ_MULTI_OP_CB callback, void* cb_data) {
  tBTA_GATTC_API_READ_MULTI* p_buf =
      (tBTA_GATTC_API_READ_MULTI*)osi_calloc(sizeof(tBTA_GATTC_API_READ_MULTI));

  p_buf->hdr.event = BTA_GATTC_API_READ_MULTI_EVT;
  p_buf->hdr.layer_specific = conn_id;
  p_buf->is_multi_read = true;
  p_buf->auth_req = auth_req;
  p_buf->num_attr = p_read_multi->num_attr;

  if (p_buf->num_attr > 0)
    memcpy(p_buf->handles, p_read_multi->handles,
           sizeof(uint16_t) * p_read_multi->num_attr);

  p_buf->handles = handles;
  p_buf->variable_len = variable_len;
  p_buf->read_cb = callback;
  p_buf->read_cb_data = cb_data;
  bta_sys_sendmsg(p_buf);
}

+16 −2
Original line number Diff line number Diff line
@@ -108,6 +108,12 @@ typedef struct {

typedef struct {
  BT_HDR_RIGID hdr;

  /* it is important that is_multi_read field stays at same position between
   * tBTA_GATTC_API_READ and tBTA_GATTC_API_READ_MULTI, as it is read from
   * parent union */
  uint8_t is_multi_read;

  tGATT_AUTH_REQ auth_req;

  // read by handle data
@@ -159,9 +165,17 @@ typedef struct {

typedef struct {
  BT_HDR_RIGID hdr;

  /* it is important that is_multi_read field stays at same position between
   * tBTA_GATTC_API_READ and tBTA_GATTC_API_READ_MULTI, as it is read from
   * parent union */
  uint8_t is_multi_read;

  tGATT_AUTH_REQ auth_req;
  uint8_t num_attr;
  uint16_t handles[GATT_MAX_READ_MULTI_HANDLES];
  tBTA_GATTC_MULTI handles;
  uint8_t variable_len;
  GATT_READ_MULTI_OP_CB read_cb;
  void* read_cb_data;
} tBTA_GATTC_API_READ_MULTI;

typedef struct {
+47 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ 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;
constexpr uint8_t GATT_READ_MULTI = 6;

struct gatt_read_op_data {
  GATT_READ_OP_CB cb;
@@ -112,6 +113,31 @@ void BtaGattQueue::gatt_configure_mtu_op_finished(uint16_t conn_id,
  }
}

struct gatt_read_multi_op_data {
  GATT_READ_MULTI_OP_CB cb;
  void* cb_data;
};

void BtaGattQueue::gatt_read_multi_op_finished(uint16_t conn_id,
                                               tGATT_STATUS status,
                                               tBTA_GATTC_MULTI& handles,
                                               uint16_t len, uint8_t* value,
                                               void* data) {
  gatt_read_multi_op_data* tmp = (gatt_read_multi_op_data*)data;
  GATT_READ_MULTI_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, handles, len, value, tmp_cb_data);
    return;
  }
}

void BtaGattQueue::gatt_execute_next_op(uint16_t conn_id) {
  LOG_VERBOSE("%s: conn_id=0x%x", __func__, conn_id);
  if (gatt_op_queue.empty()) {
@@ -177,6 +203,14 @@ void BtaGattQueue::gatt_execute_next_op(uint16_t conn_id) {
    BTA_GATTC_ConfigureMTU(conn_id, static_cast<uint16_t>(op.value[0] |
                                                          (op.value[1] << 8)),
                           gatt_configure_mtu_op_finished, data);
  } else if (op.type == GATT_READ_MULTI) {
    gatt_read_multi_op_data* data =
        (gatt_read_multi_op_data*)osi_malloc(sizeof(gatt_read_multi_op_data));
    data->cb = op.read_multi_cb;
    data->cb_data = op.read_cb_data;
    BTA_GATTC_ReadMultiple(conn_id, op.handles, op.variable_len,
                           GATT_AUTH_REQ_NONE, gatt_read_multi_op_finished,
                           data);
  }

  gatt_ops.pop_front();
@@ -239,3 +273,16 @@ void BtaGattQueue::ConfigureMtu(uint16_t conn_id, uint16_t mtu) {
                                    .value = std::move(value)});
  gatt_execute_next_op(conn_id);
}

void BtaGattQueue::ReadMultiCharacteristic(uint16_t conn_id,
                                           tBTA_GATTC_MULTI& handles,
                                           bool variable_len,
                                           GATT_READ_MULTI_OP_CB cb,
                                           void* cb_data) {
  gatt_op_queue[conn_id].push_back({.type = GATT_READ_MULTI,
                                    .handles = handles,
                                    .variable_len = variable_len,
                                    .read_multi_cb = cb,
                                    .read_cb_data = cb_data});
  gatt_execute_next_op(conn_id);
}
 No newline at end of file
+9 −4
Original line number Diff line number Diff line
@@ -621,7 +621,9 @@ typedef void (*GATT_WRITE_OP_CB)(uint16_t conn_id, tGATT_STATUS status,
                                 const uint8_t* value, void* data);
typedef void (*GATT_CONFIGURE_MTU_OP_CB)(uint16_t conn_id, tGATT_STATUS status,
                                         void* data);

typedef void (*GATT_READ_MULTI_OP_CB)(uint16_t conn_id, tGATT_STATUS status,
                                      tBTA_GATTC_MULTI& handles, uint16_t len,
                                      uint8_t* value, void* data);
/*******************************************************************************
 *
 * Function         BTA_GATTC_ReadCharacteristic
@@ -794,12 +796,15 @@ void BTA_GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute);
 *
 * Parameters       conn_id - connectino ID.
 *                  p_read_multi - read multiple parameters.
 *                  variable_len - whether "read multi variable length" variant
 *                                 shall be used.
 *
 * Returns          None
 *
 ******************************************************************************/
void BTA_GATTC_ReadMultiple(uint16_t conn_id, tBTA_GATTC_MULTI* p_read_multi,
                            tGATT_AUTH_REQ auth_req);
void BTA_GATTC_ReadMultiple(uint16_t conn_id, tBTA_GATTC_MULTI& p_read_multi,
                            bool variable_len, tGATT_AUTH_REQ auth_req,
                            GATT_READ_MULTI_OP_CB callback, void* cb_data);

/*******************************************************************************
 *
Loading