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

Commit 65b05a9b authored by Hansong Zhang's avatar Hansong Zhang
Browse files

Move rs_disc_pending from security to ACL

It's used by ACL.

Bug: 159815595
Tag: #refactor
Test: compile & verify basic functions working
Change-Id: Ia413ccfcf554a5d211c38b907ababf84e9140231
parent 4d345e1d
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -104,6 +104,11 @@ typedef struct {
  uint8_t lmp_version;
  uint8_t switch_role_failed_attempts;

#define BTM_SEC_RS_NOT_PENDING 0 /* Role Switch not in progress */
#define BTM_SEC_RS_PENDING 1     /* Role Switch in progress */
#define BTM_SEC_DISC_PENDING 2   /* Disconnect is pending */
  uint8_t rs_disc_pending = BTM_SEC_RS_NOT_PENDING;

 private:
  uint8_t switch_role_state_;

+33 −25
Original line number Diff line number Diff line
@@ -586,7 +586,7 @@ tBTM_STATUS BTM_SwitchRole(const RawAddress& remote_bd_addr, uint8_t new_role) {
    } else {
      btsnd_hcic_switch_role(remote_bd_addr, new_role);
      p_acl->set_switch_role_in_progress();
      if (p_dev_rec) p_dev_rec->rs_disc_pending = BTM_SEC_RS_PENDING;
      p_acl->rs_disc_pending = BTM_SEC_RS_PENDING;
    }
  }

@@ -609,7 +609,6 @@ void btm_acl_encrypt_change(uint16_t handle, uint8_t status,
                            uint8_t encr_enable) {
  tACL_CONN* p;
  uint8_t xx;
  tBTM_SEC_DEV_REC* p_dev_rec;

  xx = btm_handle_to_acl_index(handle);
  /* don't assume that we can never get a bad hci_handle */
@@ -630,9 +629,7 @@ void btm_acl_encrypt_change(uint16_t handle, uint8_t status,
    }

    btsnd_hcic_switch_role(p->remote_addr, (uint8_t)!p->link_role);
    p_dev_rec = btm_find_dev(p->remote_addr);
    if (p_dev_rec != NULL) p_dev_rec->rs_disc_pending = BTM_SEC_RS_PENDING;

    p->rs_disc_pending = BTM_SEC_RS_PENDING;
  }
  /* Finished enabling Encryption after role switch */
  else if (p->is_switch_role_encryption_on()) {
@@ -646,16 +643,11 @@ void btm_acl_encrypt_change(uint16_t handle, uint8_t status,

    /* If a disconnect is pending, issue it now that role switch has completed
     */
    p_dev_rec = btm_find_dev(p->remote_addr);
    if (p_dev_rec != NULL) {
      if (p_dev_rec->rs_disc_pending == BTM_SEC_DISC_PENDING) {
    if (p->rs_disc_pending == BTM_SEC_DISC_PENDING) {
      LOG_WARN("Issuing delayed HCI_Disconnect!!!");
      btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
    }
      LOG_WARN("tBTM_SEC_DEV:0x%x rs_disc_pending=%d", PTR_TO_UINT(p_dev_rec),
               p_dev_rec->rs_disc_pending);
      p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
    }
    p->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
  }
}

@@ -1463,15 +1455,12 @@ void StackAclBtmAcl::btm_acl_role_changed(tHCI_STATUS hci_status,
  BTA_dm_report_role_change(bd_addr, new_role, hci_status);

  /* If a disconnect is pending, issue it now that role switch has completed */
  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
  if (p_dev_rec != nullptr) {
    if (p_dev_rec->rs_disc_pending == BTM_SEC_DISC_PENDING) {
  if (p_acl->rs_disc_pending == BTM_SEC_DISC_PENDING) {
    LOG_WARN("peer %s Issuing delayed HCI_Disconnect!!!",
             bd_addr.ToString().c_str());
      btsnd_hcic_disconnect(p_dev_rec->hci_handle, HCI_ERR_PEER_USER);
    }
    p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
    btsnd_hcic_disconnect(p_acl->hci_handle, HCI_ERR_PEER_USER);
  }
  p_acl->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
}

void btm_acl_role_changed(tHCI_STATUS hci_status, const RawAddress& bd_addr,
@@ -2143,12 +2132,14 @@ void btm_read_link_quality_complete(uint8_t* p) {
tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
  uint16_t hci_handle = BTM_GetHCIConnHandle(bd_addr, transport);
  tBTM_STATUS status = BTM_SUCCESS;
  tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, transport);
  if (p_acl == nullptr) return BTM_UNKNOWN_ADDR;

  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);

  /* Role Switch is pending, postpone until completed */
  if (p_dev_rec && (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING)) {
    p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
  if (p_dev_rec && (p_acl->rs_disc_pending == BTM_SEC_RS_PENDING)) {
    p_acl->rs_disc_pending = BTM_SEC_DISC_PENDING;
  } else /* otherwise can disconnect right away */
  {
    if (hci_handle != HCI_INVALID_HANDLE && p_dev_rec &&
@@ -2208,7 +2199,7 @@ void btm_cont_rswitch(tACL_CONN* p, tBTM_SEC_DEV_REC* p_dev_rec) {
    {
      if (p->is_switch_role_mode_change()) {
        p->set_switch_role_in_progress();
        if (p_dev_rec) p_dev_rec->rs_disc_pending = BTM_SEC_RS_PENDING;
        p->rs_disc_pending = BTM_SEC_RS_PENDING;
        btsnd_hcic_switch_role(p->remote_addr, (uint8_t)!p->link_role);
      }
    }
@@ -2849,6 +2840,23 @@ void acl_disconnect(const RawAddress& bd_addr, tBT_TRANSPORT transport,
  btsnd_hcic_disconnect(p_acl->hci_handle, reason);
}

void acl_disconnect_after_role_switch(uint16_t conn_handle, uint16_t reason) {
  tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(conn_handle);

  /* If a role switch is in progress, delay the HCI Disconnect to avoid
   * controller problem */
  if (p_acl->rs_disc_pending == BTM_SEC_RS_PENDING) {
    BTM_TRACE_DEBUG(
        "RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect "
        "to delay disconnect");
    p_acl->rs_disc_pending = BTM_SEC_DISC_PENDING;
  }
  /* Tear down the HCI link */
  else {
    btsnd_hcic_disconnect(conn_handle, reason);
  }
}

constexpr uint16_t kDataPacketEventBrEdr = (BT_EVT_TO_LM_HCI_ACL);
constexpr uint16_t kDataPacketEventBle =
    (BT_EVT_TO_LM_HCI_ACL | LOCAL_BLE_CONTROLLER_ID);
+1 −25
Original line number Diff line number Diff line
@@ -1157,20 +1157,7 @@ static tBTM_STATUS btm_sec_send_hci_disconnect(tBTM_SEC_DEV_REC* p_dev_rec,
      break;
  }

  /* If a role switch is in progress, delay the HCI Disconnect to avoid
   * controller problem */
  if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING &&
      p_dev_rec->hci_handle == conn_handle) {
    BTM_TRACE_DEBUG(
        "RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect "
        "to delay disconnect");
    p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
    status = BTM_SUCCESS;
  }
  /* Tear down the HCI link */
  else {
    btsnd_hcic_disconnect(conn_handle, reason);
  }
  acl_disconnect_after_role_switch(conn_handle, reason);

  return status;
}
@@ -3419,7 +3406,6 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, uint8_t status,
              btm_sec_change_pairing_state(BTM_PAIR_STATE_IDLE);
            }
          }
          p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
          return;
        } else {
          l2cu_update_lcb_4_bonding(p_dev_rec->bd_addr, true);
@@ -3432,10 +3418,6 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, uint8_t status,

  p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;

  p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */

  p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */

  addr_matched = (btm_cb.pairing_bda == bda);

  if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) && addr_matched) {
@@ -3672,12 +3654,6 @@ void btm_sec_disconnected(uint16_t handle, tHCI_STATUS reason) {
  transport =
      (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR : BT_TRANSPORT_LE;

  p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */

  LOG_INFO("clearing pending flag handle:%d reason:%s", handle,
           hci_error_code_text(reason).c_str());
  p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */

  /* clear unused flags */
  p_dev_rec->sm4 &= BTM_SM4_TRUE;

+0 −14
Original line number Diff line number Diff line
@@ -356,18 +356,4 @@ typedef struct {
  tBTM_SEC_BLE ble;
  tBTM_LE_CONN_PRAMS conn_params;

#define BTM_SEC_RS_NOT_PENDING 0 /* Role Switch not in progress */
#define BTM_SEC_RS_PENDING 1     /* Role Switch in progress */
#define BTM_SEC_DISC_PENDING 2   /* Disconnect is pending */
  uint8_t rs_disc_pending;
  bool is_role_switch_idle() const {
    return rs_disc_pending == BTM_SEC_RS_NOT_PENDING;
  }
  bool is_role_switch_pending() const {
    return rs_disc_pending == BTM_SEC_RS_PENDING;
  }
  bool is_role_switch_disconnecting() const {
    return rs_disc_pending == BTM_SEC_DISC_PENDING;
  }

} tBTM_SEC_DEV_REC;
+2 −0
Original line number Diff line number Diff line
@@ -338,6 +338,8 @@ void btm_acl_removed(uint16_t handle);
void acl_disconnect(const RawAddress& bd_addr, tBT_TRANSPORT transport,
                    uint8_t reason);

void acl_disconnect_after_role_switch(uint16_t conn_handle, uint16_t reason);

bool acl_peer_supports_sniff_subrating(const RawAddress& remote_bda);

void btm_acl_set_paging(bool value);