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

Commit f269b85f authored by Hansong Zhang's avatar Hansong Zhang
Browse files

Remove remaining fixed channel code in bta_jv

Bug: 159815595
Tag: #refactor
Test: compile & verify basic functions working
Change-Id: I867225280fb535a8ad9ce2cd6a0318984ede39bf
parent 7a0b7f2e
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -526,20 +526,6 @@ void BTA_JvL2capStartServer(int conn_type, tBTA_SEC sec_mask, tBTA_JV_ROLE role,
                            tBTA_JV_L2CAP_CBACK* p_cback,
                            uint32_t l2cap_socket_id);

/*******************************************************************************
 *
 * Function         BTA_JvL2capStopServerLE
 *
 * Description      This function stops the LE L2CAP server. If the server has
 *                  an active connection, it would be closed.
 *
 * Returns          BTA_JV_SUCCESS, if the request is being processed.
 *                  BTA_JV_FAILURE, otherwise.
 *
 ******************************************************************************/
tBTA_JV_STATUS BTA_JvL2capStopServerLE(uint16_t local_chan,
                                       uint32_t l2cap_socket_id);

/*******************************************************************************
 *
 * Function         BTA_JvL2capStopServer
+0 −302
Original line number Diff line number Diff line
@@ -52,39 +52,6 @@ using bluetooth::Uuid;

tBTA_JV_CB bta_jv_cb;

/* one of these exists for each client */
struct fc_client {
  struct fc_client* next_all_list;
  struct fc_client* next_chan_list;
  RawAddress remote_addr;
  uint32_t id;
  tBTA_JV_L2CAP_CBACK* p_cback;
  uint32_t l2cap_socket_id;
  uint16_t handle;
  uint16_t chan;
  uint8_t sec_id;
  unsigned server : 1;
  unsigned init_called : 1;
};

/* one of these exists for each channel we're dealing with */
struct fc_channel {
  struct fc_channel* next;
  struct fc_client* clients;
  uint8_t has_server : 1;
  uint16_t chan;
};

static struct fc_client* fc_clients;
static struct fc_channel* fc_channels;
static uint32_t fc_next_id;

static void fcchan_conn_chng_cbk(uint16_t chan, const RawAddress& bd_addr,
                                 bool connected, uint16_t reason,
                                 tBT_TRANSPORT);
static void fcchan_data_cbk(uint16_t chan, const RawAddress& bd_addr,
                            BT_HDR* p_buf);

static tBTA_JV_PCB* bta_jv_add_rfc_port(tBTA_JV_RFC_CB* p_cb,
                                        tBTA_JV_PCB* p_pcb_open);
static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(uint32_t jv_handle);
@@ -1843,272 +1810,3 @@ static void bta_jv_pm_state_change(tBTA_JV_PM_CB* p_cb,
  }
}
/******************************************************************************/

static struct fc_channel* fcchan_get(uint16_t chan, char create) {
  struct fc_channel* t = fc_channels;
  static tL2CAP_FIXED_CHNL_REG fcr = {
      .pL2CA_FixedConn_Cb = fcchan_conn_chng_cbk,
      .pL2CA_FixedData_Cb = fcchan_data_cbk,
      .default_idle_tout = 0xffff,
  };

  while (t && t->chan != chan) t = t->next;

  if (t)
    return t;
  else if (!create)
    return NULL; /* we cannot alloc a struct if not asked to */

  t = static_cast<struct fc_channel*>(osi_calloc(sizeof(*t)));
  t->chan = chan;

  if (!L2CA_RegisterFixedChannel(chan, &fcr)) {
    osi_free(t);
    return NULL;
  }

  // link it in
  t->next = fc_channels;
  fc_channels = t;

  return t;
}

/* pass NULL to find servers */
static struct fc_client* fcclient_find_by_addr(struct fc_client* start,
                                               const RawAddress* addr) {
  struct fc_client* t = start;

  while (t) {
    /* match client if have addr */
    if (addr && addr == &t->remote_addr) break;

    /* match server if do not have addr */
    if (!addr && t->server) break;

    t = t->next_all_list;
  }

  return t;
}

static struct fc_client* fcclient_find_by_id(uint32_t id) {
  struct fc_client* t = fc_clients;

  while (t && t->id != id) t = t->next_all_list;

  return t;
}

static struct fc_client* fcclient_alloc(uint16_t chan, char server,
                                        const uint8_t* sec_id_to_use) {
  struct fc_channel* fc = fcchan_get(chan, true);
  struct fc_client* t;
  uint8_t sec_id;

  if (!fc) return NULL;

  if (fc->has_server && server)
    return NULL; /* no way to have multiple servers on same channel */

  if (sec_id_to_use)
    sec_id = *sec_id_to_use;
  else
    sec_id = bta_jv_alloc_sec_id();

  t = static_cast<fc_client*>(osi_calloc(sizeof(*t)));
  // Allocate it a unique ID
  do {
    t->id = ++fc_next_id;
  } while (!t->id || fcclient_find_by_id(t->id));

  // Populate some params
  t->chan = chan;
  t->server = server;

  // Get a security id
  t->sec_id = sec_id;

  // Link it in to global list
  t->next_all_list = fc_clients;
  fc_clients = t;

  // Link it in to channel list
  t->next_chan_list = fc->clients;
  fc->clients = t;

  // Update channel if needed
  if (server) fc->has_server = true;

  return t;
}

static void fcclient_free(struct fc_client* fc) {
  struct fc_client* t = fc_clients;
  struct fc_channel* tc = fcchan_get(fc->chan, false);

  // remove from global list
  while (t && t->next_all_list != fc) t = t->next_all_list;

  if (!t && fc != fc_clients) return; /* prevent double-free */

  if (t)
    t->next_all_list = fc->next_all_list;
  else
    fc_clients = fc->next_all_list;

  // remove from channel list
  if (tc) {
    t = tc->clients;

    while (t && t->next_chan_list != fc) t = t->next_chan_list;

    if (t)
      t->next_chan_list = fc->next_chan_list;
    else
      tc->clients = fc->next_chan_list;

    // if was server then channel no longer has a server
    if (fc->server) tc->has_server = false;
  }

  // free security id
  bta_jv_free_sec_id(&fc->sec_id);

  osi_free(fc);
}

static void fcchan_conn_chng_cbk(uint16_t chan, const RawAddress& bd_addr,
                                 bool connected, uint16_t reason,
                                 tBT_TRANSPORT transport) {
  tBTA_JV init_evt;
  tBTA_JV open_evt;
  struct fc_channel* tc;
  struct fc_client *t = NULL, *new_conn;
  tBTA_JV_L2CAP_CBACK* p_cback = NULL;
  char call_init = false;
  uint32_t l2cap_socket_id;

  tc = fcchan_get(chan, false);
  if (tc) {
    t = fcclient_find_by_addr(
        tc->clients,
        &bd_addr);  // try to find an open socked for that addr
    if (t) {
      p_cback = t->p_cback;
      l2cap_socket_id = t->l2cap_socket_id;
    } else {
      t = fcclient_find_by_addr(
          tc->clients,
          NULL);  // try to find a listening socked for that channel
      if (t) {
        // found: create a normal connection socket and assign the connection to
        // it
        new_conn = fcclient_alloc(chan, false, &t->sec_id);
        if (new_conn) {
          new_conn->remote_addr = bd_addr;
          new_conn->p_cback = NULL;     // for now
          new_conn->init_called = true; /*nop need to do it again */

          p_cback = t->p_cback;
          l2cap_socket_id = t->l2cap_socket_id;

          t = new_conn;
        }
      } else {
        // drop it
        return;
      }
    }
  }

  if (t) {
    if (!t->init_called) {
      call_init = true;
      t->init_called = true;

      init_evt.l2c_cl_init.handle = t->id;
      init_evt.l2c_cl_init.status = BTA_JV_SUCCESS;
      init_evt.l2c_cl_init.sec_id = t->sec_id;
    }

    open_evt.l2c_open.handle = t->id;
    open_evt.l2c_open.tx_mtu = 23; /* 23, why not ?*/
    memcpy(&open_evt.l2c_le_open.rem_bda, &t->remote_addr,
           sizeof(open_evt.l2c_le_open.rem_bda));
    // TODO: (apanicke) Change the way these functions work so that casting
    // isn't needed
    open_evt.l2c_le_open.p_p_cback = (void**)&t->p_cback;
    open_evt.l2c_le_open.p_user_data = (void**)&t->l2cap_socket_id;
    open_evt.l2c_le_open.status = BTA_JV_SUCCESS;

    if (connected) {
      open_evt.l2c_open.status = BTA_JV_SUCCESS;
    } else {
      fcclient_free(t);
      open_evt.l2c_open.status = BTA_JV_FAILURE;
    }
  }

  if (call_init) p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &init_evt, l2cap_socket_id);

  // call this with lock taken so socket does not disappear from under us */
  if (p_cback) {
    p_cback(BTA_JV_L2CAP_OPEN_EVT, &open_evt, l2cap_socket_id);
    if (!t->p_cback) /* no callback set, means they do not want this one... */
      fcclient_free(t);
  }
}

static void fcchan_data_cbk(uint16_t chan, const RawAddress& bd_addr,
                            BT_HDR* p_buf) {
  tBTA_JV evt_data;
  struct fc_channel* tc;
  struct fc_client* t = NULL;
  tBTA_JV_L2CAP_CBACK* sock_cback = NULL;
  uint32_t sock_id;

  tc = fcchan_get(chan, false);
  if (tc) {
    // try to find an open socked for that addr and channel
    t = fcclient_find_by_addr(tc->clients, &bd_addr);
  }
  if (!t) {
    // no socket -> drop it
    return;
  }


  sock_cback = t->p_cback;
  sock_id = t->l2cap_socket_id;
  evt_data.le_data_ind.handle = t->id;
  evt_data.le_data_ind.p_buf = p_buf;

  if (sock_cback) sock_cback(BTA_JV_L2CAP_DATA_IND_EVT, &evt_data, sock_id);
}

/* stops an LE L2CAP server */
void bta_jv_l2cap_stop_server_le(uint16_t local_chan) {
  struct fc_client* fcclient;

  tBTA_JV evt;
  evt.l2c_close.status = BTA_JV_FAILURE;
  evt.l2c_close.async = false;
  evt.l2c_close.handle = GAP_INVALID_HANDLE;

  struct fc_channel* fcchan = fcchan_get(local_chan, false);
  if (fcchan) {
    while ((fcclient = fcchan->clients)) {
      tBTA_JV_L2CAP_CBACK* p_cback = fcclient->p_cback;
      uint32_t l2cap_socket_id = fcclient->l2cap_socket_id;

      evt.l2c_close.handle = fcclient->id;
      evt.l2c_close.status = BTA_JV_SUCCESS;
      evt.l2c_close.async = false;

      fcclient_free(fcclient);

      if (p_cback) p_cback(BTA_JV_L2CAP_CLOSE_EVT, &evt, l2cap_socket_id);
    }
  }
}
+0 −19
Original line number Diff line number Diff line
@@ -307,25 +307,6 @@ tBTA_JV_STATUS BTA_JvL2capStopServer(uint16_t local_psm,
  return BTA_JV_SUCCESS;
}

/*******************************************************************************
 *
 * Function         BTA_JvL2capStopServerLE
 *
 * Description      This function stops the LE L2CAP server. If the server has
 *                  an active connection, it would be closed.
 *
 * Returns          BTA_JV_SUCCESS, if the request is being processed.
 *                  BTA_JV_FAILURE, otherwise.
 *
 ******************************************************************************/
tBTA_JV_STATUS BTA_JvL2capStopServerLE(uint16_t local_chan,
                                       uint32_t l2cap_socket_id) {
  VLOG(2) << __func__;

  do_in_main_thread(FROM_HERE, Bind(&bta_jv_l2cap_stop_server_le, local_chan));
  return BTA_JV_SUCCESS;
}

/*******************************************************************************
 *
 * Function         BTA_JvL2capRead