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

Commit eba6d38e authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Automerger Merge Worker
Browse files

Merge "bta_gattc_api: Improve queueing messages" am: 3e6c5b1d

parents 4d5a2326 3e6c5b1d
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -716,7 +716,7 @@ void bta_gattc_restart_discover(tBTA_GATTC_CLCB* p_clcb,

/** Configure MTU size on the GATT connection */
void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
  if (!bta_gattc_enqueue(p_clcb, p_data)) return;
  if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return;

  tGATT_STATUS status =
      GATTC_ConfigureMTU(p_clcb->bta_conn_id, p_data->api_mtu.mtu);
@@ -728,6 +728,7 @@ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {

    bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status,
                           NULL);
    bta_gattc_continue(p_clcb);
  }
}

@@ -860,6 +861,8 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb,
     * referenced by p_clcb->p_q_cmd
     */
    if (p_q_cmd != p_clcb->p_q_cmd) osi_free_and_reset((void**)&p_q_cmd);
  } else {
    bta_gattc_continue(p_clcb);
  }

  if (p_clcb->p_rcb->p_cback) {
@@ -871,7 +874,7 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb,

/** Read an attribute */
void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
  if (!bta_gattc_enqueue(p_clcb, p_data)) return;
  if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return;

  tGATT_STATUS status;
  if (p_data->api_read.handle != 0) {
@@ -898,13 +901,14 @@ void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {

    bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status,
                           NULL);
    bta_gattc_continue(p_clcb);
  }
}

/** read multiple */
void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb,
                          const tBTA_GATTC_DATA* p_data) {
  if (!bta_gattc_enqueue(p_clcb, p_data)) return;
  if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return;

  tGATT_READ_PARAM read_param;
  memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
@@ -923,12 +927,13 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb,

    bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status,
                           NULL);
    bta_gattc_continue(p_clcb);
  }
}

/** Write an attribute */
void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
  if (!bta_gattc_enqueue(p_clcb, p_data)) return;
  if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return;

  tGATT_STATUS status = GATT_SUCCESS;
  tGATT_VALUE attr;
@@ -952,12 +957,13 @@ void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {

    bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status,
                           NULL);
    bta_gattc_continue(p_clcb);
  }
}

/** send execute write */
void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
  if (!bta_gattc_enqueue(p_clcb, p_data)) return;
  if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return;

  tGATT_STATUS status =
      GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
@@ -967,6 +973,7 @@ void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {

    bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status,
                           NULL);
    bta_gattc_continue(p_clcb);
  }
}

+12 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#define BTA_GATTC_INT_H

#include <cstdint>
#include <deque>

#include "bt_target.h"  // Must be first to define build configuration
#include "bta/gatt/database.h"
@@ -254,6 +255,7 @@ typedef struct {
  tBTA_GATTC_RCB* p_rcb;    /* pointer to the registration CB */
  tBTA_GATTC_SERV* p_srcb;  /* server cache CB */
  const tBTA_GATTC_DATA* p_q_cmd; /* command in queue waiting for execution */
  std::deque<const tBTA_GATTC_DATA*> p_q_cmd_queue;

// request during discover state
#define BTA_GATTC_DISCOVER_REQ_NONE 0
@@ -423,8 +425,16 @@ extern tBTA_GATTC_SERV* bta_gattc_find_scb_by_cid(uint16_t conn_id);
extern tBTA_GATTC_CLCB* bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA* p_msg);
extern tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg);

extern bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb,
enum BtaEnqueuedResult_t {
  ENQUEUED_READY_TO_SEND,
  ENQUEUED_FOR_LATER,
};

extern BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb,
                                             const tBTA_GATTC_DATA* p_data);
extern bool bta_gattc_is_data_queued(tBTA_GATTC_CLCB* p_clcb,
                                     const tBTA_GATTC_DATA* p_data);
extern void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb);

extern bool bta_gattc_check_notif_registry(tBTA_GATTC_RCB* p_clreg,
                                           tBTA_GATTC_SERV* p_srcb,
+1 −1
Original line number Diff line number Diff line
@@ -328,7 +328,7 @@ bool bta_gattc_sm_execute(tBTA_GATTC_CLCB* p_clcb, uint16_t event,
    action = state_table[event][i];
    if (action != BTA_GATTC_IGNORE) {
      (*bta_gattc_action[action])(p_clcb, p_data);
      if (p_clcb->p_q_cmd == p_data) {
      if (bta_gattc_is_data_queued(p_clcb, p_data)) {
        /* buffer is queued, don't free in the bta dispatcher.
         * we free it ourselves when a completion event is received.
         */
+62 −9
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@

#define LOG_TAG "bt_bta_gattc"

#include <base/logging.h>

#include <cstdint>

#include "bt_target.h"  // Must be first to define build configuration
@@ -31,12 +33,11 @@
#include "device/include/controller.h"
#include "gd/common/init_flags.h"
#include "osi/include/allocator.h"
#include "osi/include/log.h"
#include "types/bt_transport.h"
#include "types/hci_role.h"
#include "types/raw_address.h"

#include <base/logging.h>

static uint8_t ble_acceptlist_size() {
  const controller_t* controller = controller_get_interface();
  if (!controller->supports_ble()) {
@@ -218,10 +219,29 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) {
    p_srcb->gatt_database.Clear();
  }

  while (!p_clcb->p_q_cmd_queue.empty()) {
    auto p_q_cmd = p_clcb->p_q_cmd_queue.front();
    p_clcb->p_q_cmd_queue.pop_front();
    osi_free_and_reset((void**)&p_q_cmd);
  }

  if (p_clcb->p_q_cmd != NULL) {
    osi_free_and_reset((void**)&p_clcb->p_q_cmd);
  }
  memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));

  /* Clear p_clcb. Some of the fields are already reset e.g. p_q_cmd_queue and
   * p_q_cmd. */
  p_clcb->bta_conn_id = 0;
  p_clcb->bda = {};
  p_clcb->transport = 0;
  p_clcb->p_rcb = NULL;
  p_clcb->p_srcb = NULL;
  p_clcb->request_during_discovery = 0;
  p_clcb->auto_update = 0;
  p_clcb->disc_active = 0;
  p_clcb->in_use = 0;
  p_clcb->state = BTA_GATTC_IDLE_ST;
  p_clcb->status = GATT_SUCCESS;
}

/*******************************************************************************
@@ -318,24 +338,57 @@ tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda) {
  }
  return p_tcb;
}

void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb) {
  if (p_clcb->p_q_cmd != NULL) {
    LOG_INFO("Already scheduled another request for conn_id = 0x%04x",
             p_clcb->bta_conn_id);
    return;
  }

  if (p_clcb->p_q_cmd_queue.empty()) {
    LOG_INFO("Nothing to do for conn_id = 0x%04x", p_clcb->bta_conn_id);
    return;
  }

  const tBTA_GATTC_DATA* p_q_cmd = p_clcb->p_q_cmd_queue.front();
  p_clcb->p_q_cmd_queue.pop_front();
  bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
}

bool bta_gattc_is_data_queued(tBTA_GATTC_CLCB* p_clcb,
                              const tBTA_GATTC_DATA* p_data) {
  if (p_clcb->p_q_cmd == p_data) {
    return true;
  }

  auto it = std::find(p_clcb->p_q_cmd_queue.begin(),
                      p_clcb->p_q_cmd_queue.end(), p_data);
  return it != p_clcb->p_q_cmd_queue.end();
}
/*******************************************************************************
 *
 * Function         bta_gattc_enqueue
 *
 * Description      enqueue a client request in clcb.
 *
 * Returns          success or failure.
 * Returns          BtaEnqueuedResult_t
 *
 ******************************************************************************/
bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb,
                                      const tBTA_GATTC_DATA* p_data) {
  if (p_clcb->p_q_cmd == NULL) {
    p_clcb->p_q_cmd = p_data;
    return true;
    return ENQUEUED_READY_TO_SEND;
  }

  LOG(ERROR) << __func__ << ": already has a pending command";
  /* skip the callback now. ----- need to send callback ? */
  return false;
  LOG_INFO(
      "Already has a pending command to executer. Queuing for later %s conn "
      "id=0x%04x",
      p_clcb->bda.ToString().c_str(), p_clcb->bta_conn_id);
  p_clcb->p_q_cmd_queue.push_back(p_data);

  return ENQUEUED_FOR_LATER;
}

/*******************************************************************************