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

Commit 1924b53d authored by Jakub Pawłowski's avatar Jakub Pawłowski Committed by Automerger Merge Worker
Browse files

Merge "Consolidate existing LE connection after pairing" into tm-qpr-dev am: 463ea77b

parents 2f474320 463ea77b
Loading
Loading
Loading
Loading
+23 −6
Original line number Diff line number Diff line
@@ -1607,13 +1607,30 @@ void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk,
  BTM_TRACE_ERROR("key size = %d", p_rec->ble.keys.key_size);
  if (use_stk) {
    btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, stk);
  } else /* calculate LTK using peer device  */
  {
    if (p_rec->ble.key_type & BTM_LE_KEY_LENC)
    return;
  }
  /* calculate LTK using peer device  */
  if (p_rec->ble.key_type & BTM_LE_KEY_LENC) {
    btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p_rec->ble.keys.lltk);
    else
    return;
  }

  p_rec = btm_find_dev_with_lenc(bda);
  if (!p_rec) {
    btsnd_hcic_ble_ltk_req_neg_reply(btm_cb.enc_handle);
    return;
  }

  LOG_INFO("Found second sec_dev_rec for device that have LTK");
  /* This can happen when remote established LE connection using RPA to this
   * device, but then pair with us using Classing transport while still keeping
   * LE connection. If remote attempts to encrypt the LE connection, we might
   * end up here. We will eventually consolidate both entries, this is to avoid
   * race conditions. */

  LOG_ASSERT(p_rec->ble.key_type & BTM_LE_KEY_LENC);
  p_cb->key_size = p_rec->ble.keys.key_size;
  btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p_rec->ble.keys.lltk);
}

/*******************************************************************************
+84 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <string.h>

#include "btm_api.h"
#include "btm_ble_int.h"
#include "device/include/controller.h"
#include "l2c_api.h"
#include "main/shim/btm_api.h"
@@ -372,6 +373,32 @@ tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr) {
  return NULL;
}

static bool has_lenc_and_address_is_equal(void* data, void* context) {
  tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data);
  if (!(p_dev_rec->ble.key_type & BTM_LE_KEY_LENC)) return false;

  return is_address_equal(data, context);
}

/*******************************************************************************
 *
 * Function         btm_find_dev_with_lenc
 *
 * Description      Look for the record in the device database with LTK and
 *                  specified BD address
 *
 * Returns          Pointer to the record or NULL
 *
 ******************************************************************************/
tBTM_SEC_DEV_REC* btm_find_dev_with_lenc(const RawAddress& bd_addr) {
  if (btm_cb.sec_dev_rec == nullptr) return nullptr;

  list_node_t* n = list_foreach(btm_cb.sec_dev_rec, has_lenc_and_address_is_equal,
                                (void*)&bd_addr);
  if (n) return static_cast<tBTM_SEC_DEV_REC*>(list_node(n));

  return NULL;
}
/*******************************************************************************
 *
 * Function         btm_consolidate_dev
@@ -429,6 +456,63 @@ void btm_consolidate_dev(tBTM_SEC_DEV_REC* p_target_rec) {
  }
}

/* combine security records of established LE connections after Classic pairing
 * succeeded. */
void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr) {
  tBTM_SEC_DEV_REC* p_target_rec = btm_find_dev(bd_addr);
  if (!p_target_rec) {
    LOG_ERROR("No security record for just bonded device!?!?");
    return;
  }

  if (p_target_rec->ble_hci_handle != HCI_INVALID_HANDLE) {
    LOG_INFO("Not consolidating - already have LE connection");
    return;
  }

  LOG_INFO("%s", PRIVATE_ADDRESS(bd_addr));

  list_node_t* end = list_end(btm_cb.sec_dev_rec);
  list_node_t* node = list_begin(btm_cb.sec_dev_rec);
  while (node != end) {
    tBTM_SEC_DEV_REC* p_dev_rec =
        static_cast<tBTM_SEC_DEV_REC*>(list_node(node));

    // we do list_remove in some cases, must grab next before removing
    node = list_next(node);

    if (p_target_rec == p_dev_rec) continue;

    /* an RPA device entry is a duplicate of the target record */
    if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec)) {
      if (p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE) {
        LOG_INFO("already disconnected - erasing entry %s",
                 PRIVATE_ADDRESS(p_dev_rec->bd_addr));
        wipe_secrets_and_remove(p_dev_rec);
        continue;
      }

      LOG_INFO(
          "Found existing LE connection to just bonded device on %s handle 0x%04x",
          PRIVATE_ADDRESS(p_dev_rec->bd_addr), p_dev_rec->ble_hci_handle);

      RawAddress ble_conn_addr = p_dev_rec->bd_addr;
      p_target_rec->ble_hci_handle = p_dev_rec->ble_hci_handle;

      /* remove the old LE record */
      wipe_secrets_and_remove(p_dev_rec);

      /* To avoid race conditions between central/peripheral starting encryption
       * at same time, initiate it just from central. */
      if (L2CA_GetBleConnRole(ble_conn_addr) == HCI_ROLE_CENTRAL) {
        LOG_INFO("Will encrypt existing connection");
        BTM_SetEncryption(ble_conn_addr, BT_TRANSPORT_LE, nullptr, nullptr,
                          BTM_BLE_SEC_ENCRYPT);
      }
    }
  }
}

/*******************************************************************************
 *
 * Function         btm_find_or_alloc_dev
+27 −1
Original line number Diff line number Diff line
@@ -109,10 +109,22 @@ bool is_address_equal(void* data, void* context);
 ******************************************************************************/
tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr);

/*******************************************************************************
 *
 * Function         btm_find_dev_with_lenc
 *
 * Description      Look for the record in the device database with LTK and
 *                  specified BD address
 *
 * Returns          Pointer to the record or NULL
 *
 ******************************************************************************/
tBTM_SEC_DEV_REC* btm_find_dev_with_lenc(const RawAddress& bd_addr);

/*******************************************************************************
 *
 * Function         btm_consolidate_dev
5**
 *
 * Description      combine security records if identified as same peer
 *
 * Returns          none
@@ -120,6 +132,20 @@ tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr);
 ******************************************************************************/
void btm_consolidate_dev(tBTM_SEC_DEV_REC* p_target_rec);

/*******************************************************************************
 *
 * Function         btm_consolidate_dev
 *
 * Description      When pairing is finished (i.e. on BR/EDR), this function
 *                  checks if there are existing LE connections to same device
 *                  that can now be encrypted and used for profiles requiring
 *                  encryption.
 *
 * Returns          none
 *
 ******************************************************************************/
void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr);

/*******************************************************************************
 *
 * Function         btm_find_or_alloc_dev
+1 −1
Original line number Diff line number Diff line
@@ -1042,7 +1042,7 @@ void smp_proc_id_addr(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  tBTM_LE_KEY_VALUE pid_key = {
      .pid_key = {},
  };
  ;

  STREAM_TO_UINT8(pid_key.pid_key.identity_addr_type, p);
  STREAM_TO_BDADDR(pid_key.pid_key.identity_addr, p);
  pid_key.pid_key.irk = p_cb->tk;
+6 −0
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@
#include "stack/include/stack_metrics_logging.h"
#include "types/raw_address.h"

void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr);

#define SMP_PAIRING_REQ_SIZE 7
#define SMP_CONFIRM_CMD_SIZE (OCTET16_LEN + 1)
#define SMP_RAND_CMD_SIZE (OCTET16_LEN + 1)
@@ -978,6 +980,10 @@ void smp_proc_pairing_cmpl(tSMP_CB* p_cb) {
                           smp_status_text(evt_data.cmplt.reason).c_str()));
  }

  if (p_cb->status == SMP_SUCCESS && p_cb->smp_over_br) {
    btm_dev_consolidate_existing_connections(pairing_bda);
  }

  smp_reset_control_value(p_cb);

  if (p_callback) (*p_callback)(SMP_COMPLT_EVT, pairing_bda, &evt_data);
Loading