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

Commit 9f55f1c4 authored by Avish Shah's avatar Avish Shah Committed by Jakub Pawlowski
Browse files

Bluetooth 5: Update LE2M implementation through DM (3/3)

This patch moves LE2M implementation to the DM instead of tied to GATT.

Below are the reasons to make this change:
1) Per link setting usually be done under DM, such as link policy etc.
2) In the future, if LECOC is coming to use in more profile/apps,
   we can not rely on GATT API for these. Separate API should be required.
3) we could have multiple logical GATT user on top of the same link.
4) Also this will avoid duplicating all the APIs on GATTC and GATTS.

Bug: 37586939
Test: sl4a PhyTest passed
Change-Id: I7330be85d1bb98a4cc66b69462b01c23c9375362
parent 3245cae5
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -569,19 +569,20 @@ bt_status_t btif_gattc_conn_parameter_update(const bt_bdaddr_t* bd_addr,
           min_interval, max_interval, latency, timeout));
}

bt_status_t btif_gattc_set_preferred_phy(int conn_id, uint8_t tx_phy,
                                         uint8_t rx_phy, uint16_t phy_options) {
bt_status_t btif_gattc_set_preferred_phy(const bt_bdaddr_t& bd_addr,
                                         uint8_t tx_phy, uint8_t rx_phy,
                                         uint16_t phy_options) {
  CHECK_BTGATT_INIT();
  do_in_bta_thread(FROM_HERE, Bind(&GATTC_SetPreferredPHY, conn_id, tx_phy,
                                   rx_phy, phy_options));
  do_in_bta_thread(FROM_HERE,
                   Bind(&BTM_BleSetPhy, bd_addr, tx_phy, rx_phy, phy_options));
  return BT_STATUS_SUCCESS;
}

bt_status_t btif_gattc_read_phy(
    int conn_id,
    const bt_bdaddr_t& bd_addr,
    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
  CHECK_BTGATT_INIT();
  do_in_bta_thread(FROM_HERE, Bind(&GATTC_ReadPHY, conn_id,
  do_in_bta_thread(FROM_HERE, Bind(&BTM_BleReadPhy, bd_addr,
                                   jni_thread_wrapper(FROM_HERE, cb)));
  return BT_STATUS_SUCCESS;
}
+9 −9
Original line number Diff line number Diff line
@@ -425,20 +425,20 @@ static bt_status_t btif_gatts_send_response(int conn_id, int trans_id,
                               trans_id, status, *response));
}

static bt_status_t btif_gattc_set_preferred_phy(int conn_id, uint8_t tx_phy,
                                                uint8_t rx_phy,
static bt_status_t btif_gatts_set_preferred_phy(const bt_bdaddr_t& bd_addr,
                                                uint8_t tx_phy, uint8_t rx_phy,
                                                uint16_t phy_options) {
  CHECK_BTGATT_INIT();
  do_in_bta_thread(FROM_HERE, Bind(&GATTC_SetPreferredPHY, conn_id, tx_phy,
                                   rx_phy, phy_options));
  do_in_bta_thread(FROM_HERE,
                   Bind(&BTM_BleSetPhy, bd_addr, tx_phy, rx_phy, phy_options));
  return BT_STATUS_SUCCESS;
}

static bt_status_t btif_gattc_read_phy(
    int conn_id,
static bt_status_t btif_gatts_read_phy(
    const bt_bdaddr_t& bd_addr,
    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
  CHECK_BTGATT_INIT();
  do_in_bta_thread(FROM_HERE, Bind(&GATTC_ReadPHY, conn_id,
  do_in_bta_thread(FROM_HERE, Bind(&BTM_BleReadPhy, bd_addr,
                                   jni_thread_wrapper(FROM_HERE, cb)));
  return BT_STATUS_SUCCESS;
}
@@ -448,5 +448,5 @@ const btgatt_server_interface_t btgattServerInterface = {
    btif_gatts_open,           btif_gatts_close,
    btif_gatts_add_service,    btif_gatts_stop_service,
    btif_gatts_delete_service, btif_gatts_send_indication,
    btif_gatts_send_response,  btif_gattc_set_preferred_phy,
    btif_gattc_read_phy};
    btif_gatts_send_response,  btif_gatts_set_preferred_phy,
    btif_gatts_read_phy};
+165 −0
Original line number Diff line number Diff line
@@ -822,6 +822,171 @@ tBTM_STATUS BTM_SetBleDataLength(const bt_bdaddr_t& bd_addr,
  return BTM_SUCCESS;
}

void read_phy_cb(
    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb,
    uint8_t* data, uint16_t len) {
  uint8_t status, tx_phy, rx_phy;
  uint16_t handle;

  LOG_ASSERT(len == 5) << "Received bad response length: " << len;
  uint8_t* pp = data;
  STREAM_TO_UINT8(status, pp);
  STREAM_TO_UINT16(handle, pp);
  handle = handle & 0x0FFF;
  STREAM_TO_UINT8(tx_phy, pp);
  STREAM_TO_UINT8(rx_phy, pp);

  DVLOG(1) << __func__ << " Received read_phy_cb";
  cb.Run(tx_phy, rx_phy, status);
}

/*******************************************************************************
 *
 * Function         BTM_BleReadPhy
 *
 * Description      To read the current PHYs for specified LE connection
 *
 *
 * Returns          BTM_SUCCESS if command successfully sent to controller,
 *                  BTM_MODE_UNSUPPORTED if local controller doesn't support LE
 *                  2M or LE Coded PHY,
 *                  BTM_WRONG_MODE if Device in wrong mode for request.
 *
 ******************************************************************************/
void BTM_BleReadPhy(
    const bt_bdaddr_t& bd_addr,
    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
  BTM_TRACE_DEBUG("%s", __func__);

  tACL_CONN* p_acl = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE);

  if (p_acl == NULL) {
    BTM_TRACE_ERROR("%s: Wrong mode: no LE link exist or LE not supported",
                    __func__);
    cb.Run(0, 0, HCI_ERR_NO_CONNECTION);
    return;
  }

  // checking if local controller supports it!
  if (!controller_get_interface()->supports_ble_2m_phy() &&
      !controller_get_interface()->supports_ble_coded_phy()) {
    BTM_TRACE_ERROR("%s failed, request not supported in local controller!",
                    __func__);
    cb.Run(0, 0, HCI_ERR_ILLEGAL_COMMAND);
    return;
  }

  uint16_t handle = p_acl->hci_handle;

  const uint8_t len = HCIC_PARAM_SIZE_BLE_READ_PHY;
  uint8_t data[len];
  uint8_t* pp = data;
  UINT16_TO_STREAM(pp, handle);
  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_READ_PHY, data, len,
                            base::Bind(&read_phy_cb, std::move(cb)));
  return;
}

void doNothing(uint8_t* data, uint16_t len) {}

/*******************************************************************************
 *
 * Function         BTM_BleSetDefaultPhy
 *
 * Description      To set preferred PHY for ensuing LE connections
 *
 *
 * Returns          BTM_SUCCESS if command successfully sent to controller,
 *                  BTM_MODE_UNSUPPORTED if local controller doesn't support LE
 *                  2M or LE Coded PHY
 *
 ******************************************************************************/
tBTM_STATUS BTM_BleSetDefaultPhy(uint8_t all_phys, uint8_t tx_phys,
                                 uint8_t rx_phys) {
  BTM_TRACE_DEBUG("%s: all_phys = 0x%02x, tx_phys = 0x%02x, rx_phys = 0x%02x",
                  __func__, all_phys, tx_phys, rx_phys);

  // checking if local controller supports it!
  if (!controller_get_interface()->supports_ble_2m_phy() &&
      !controller_get_interface()->supports_ble_coded_phy()) {
    BTM_TRACE_ERROR("%s failed, request not supported in local controller!",
                    __func__);
    return BTM_MODE_UNSUPPORTED;
  }

  const uint8_t len = HCIC_PARAM_SIZE_BLE_SET_DEFAULT_PHY;
  uint8_t data[len];
  uint8_t* pp = data;
  UINT8_TO_STREAM(pp, all_phys);
  UINT8_TO_STREAM(pp, tx_phys);
  UINT8_TO_STREAM(pp, rx_phys);
  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_SET_DEFAULT_PHY, data, len,
                            base::Bind(doNothing));
  return BTM_SUCCESS;
}

/*******************************************************************************
 *
 * Function         BTM_BleSetPhy
 *
 * Description      To set PHY preferences for specified LE connection
 *
 *
 * Returns          BTM_SUCCESS if command successfully sent to controller,
 *                  BTM_MODE_UNSUPPORTED if local controller doesn't support LE
 *                  2M or LE Coded PHY,
 *                  BTM_ILLEGAL_VALUE if specified remote doesn't support LE 2M
 *                  or LE Coded PHY,
 *                  BTM_WRONG_MODE if Device in wrong mode for request.
 *
 ******************************************************************************/
void BTM_BleSetPhy(const bt_bdaddr_t& bd_addr, uint8_t tx_phys, uint8_t rx_phys,
                   uint16_t phy_options) {
  tACL_CONN* p_acl = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE);

  if (p_acl == NULL) {
    BTM_TRACE_ERROR("%s: Wrong mode: no LE link exist or LE not supported",
                    __func__);
    return;
  }

  uint8_t all_phys = 0;
  if (tx_phys == 0) all_phys &= 0x01;
  if (rx_phys == 0) all_phys &= 0x02;

  BTM_TRACE_DEBUG(
      "%s: all_phys = 0x%02x, tx_phys = 0x%02x, rx_phys = 0x%02x, phy_options "
      "= 0x%04x",
      __func__, all_phys, tx_phys, rx_phys, phy_options);

  // checking if local controller supports it!
  if (!controller_get_interface()->supports_ble_2m_phy() &&
      !controller_get_interface()->supports_ble_coded_phy()) {
    BTM_TRACE_ERROR("%s failed, request not supported in local controller!",
                    __func__);
    return;
  }

  if (!HCI_LE_2M_PHY_SUPPORTED(p_acl->peer_le_features) &&
      !HCI_LE_CODED_PHY_SUPPORTED(p_acl->peer_le_features)) {
    BTM_TRACE_ERROR("%s failed, peer does not support request", __func__);
    return;
  }

  uint16_t handle = p_acl->hci_handle;

  const uint8_t len = HCIC_PARAM_SIZE_BLE_SET_PHY;
  uint8_t data[len];
  uint8_t* pp = data;
  UINT16_TO_STREAM(pp, handle);
  UINT8_TO_STREAM(pp, all_phys);
  UINT8_TO_STREAM(pp, tx_phys);
  UINT8_TO_STREAM(pp, rx_phys);
  UINT16_TO_STREAM(pp, phy_options);
  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_SET_PHY, data, len,
                            base::Bind(doNothing));
}

/*******************************************************************************
 *
 * Function         btm_ble_determine_security_act
+1 −1
Original line number Diff line number Diff line
@@ -343,7 +343,7 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, BT_HDR* p_msg) {
          btu_ble_data_length_change_evt(p, hci_evt_len);
          break;

        case HCI_LE_PHY_UPDATE_COMPLETE_EVT:
        case HCI_BLE_PHY_UPDATE_COMPLETE_EVT:
          btm_ble_process_phy_update_pkt(ble_evt_len, p);
          break;

+0 −80
Original line number Diff line number Diff line
@@ -23,13 +23,11 @@
 ******************************************************************************/
#include "bt_target.h"

#include <base/bind.h>
#include <base/strings/stringprintf.h>
#include <stdio.h>
#include <string.h>
#include "bt_common.h"
#include "btm_int.h"
#include "btu.h"
#include "device/include/controller.h"
#include "gatt_api.h"
#include "gatt_int.h"
@@ -662,84 +660,6 @@ tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) {
                          (tGATT_CL_MSG*)&mtu);
}

void read_phy_cb(
    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb,
    uint8_t* data, uint16_t len) {
  uint8_t status, tx_phy, rx_phy;
  uint16_t handle;

  LOG_ASSERT(len == 5) << "Received bad response length: " << len;
  uint8_t* pp = data;
  STREAM_TO_UINT8(status, pp);
  STREAM_TO_UINT16(handle, pp);
  handle = handle & 0x0FFF;
  STREAM_TO_UINT8(tx_phy, pp);
  STREAM_TO_UINT8(rx_phy, pp);

  DVLOG(1) << __func__ << " Received read_phy_cb";
  cb.Run(tx_phy, rx_phy, status);
}

void GATTC_ReadPHY(
    uint16_t conn_id,
    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
  if (p_tcb == NULL) {
    LOG(ERROR) << __func__ << ": no p_tcb for conn_id " << +conn_id;
    cb.Run(0, 0, GATT_INVALID_HANDLE);
    return;
  }

  tACL_CONN* p_lcb = btm_bda_to_acl(p_tcb->peer_bda, BT_TRANSPORT_LE);
  if (p_lcb == NULL) {
    LOG(ERROR) << __func__ << ": no p_lcb for conn_id " << +conn_id;
    cb.Run(0, 0, GATT_INVALID_HANDLE);
    return;
  }
  uint16_t handle = p_lcb->hci_handle;

  const uint8_t len = 2;
  uint8_t data[len];
  uint8_t* pp = data;
  UINT16_TO_STREAM(pp, handle);
  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_LE_READ_PHY, data, len,
                            base::Bind(&read_phy_cb, std::move(cb)));
}

void doNothing(uint8_t* data, uint16_t len) {}

void GATTC_SetPreferredPHY(uint16_t conn_id, uint8_t tx_phy, uint8_t rx_phy,
                           uint16_t phy_options) {
  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
  if (p_tcb == NULL) {
    LOG(ERROR) << __func__ << ": no p_tcb for conn_id " << +conn_id;
    return;
  }

  tACL_CONN* p_lcb = btm_bda_to_acl(p_tcb->peer_bda, BT_TRANSPORT_LE);
  if (p_lcb == NULL) {
    LOG(ERROR) << __func__ << ": no p_lcb for conn_id " << +conn_id;
    return;
  }
  uint16_t handle = p_lcb->hci_handle;

  uint8_t all_phys = 0;
  if (tx_phy == 0) all_phys &= 0x01;
  if (rx_phy == 0) all_phys &= 0x02;

  const uint8_t len = 7;
  uint8_t data[len];
  uint8_t* pp = data;
  UINT16_TO_STREAM(pp, handle);
  UINT8_TO_STREAM(pp, all_phys);
  UINT8_TO_STREAM(pp, tx_phy);
  UINT8_TO_STREAM(pp, rx_phy);
  UINT16_TO_STREAM(pp, phy_options);
  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_LE_SET_PHY, data, len,
                            base::Bind(doNothing));
}

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