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

Commit 6be03c0d authored by Jack He's avatar Jack He Committed by Gerrit Code Review
Browse files

Merge "[ DUP ] prevent sending LE create connection twice"

parents 1a8baed3 a70c15a2
Loading
Loading
Loading
Loading
+86 −66
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@
#include <unordered_set>
#include <unordered_set>


#include "common/bind.h"
#include "common/bind.h"
#include "common/init_flags.h"
#include "crypto_toolbox/crypto_toolbox.h"
#include "crypto_toolbox/crypto_toolbox.h"
#include "hci/acl_manager/assembler.h"
#include "hci/acl_manager/assembler.h"
#include "hci/acl_manager/le_connection_management_callbacks.h"
#include "hci/acl_manager/le_connection_management_callbacks.h"
@@ -272,9 +273,9 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
    auto connecting_addr_with_type = connecting_le_.find(address_with_type);
    auto connecting_addr_with_type = connecting_le_.find(address_with_type);
    if (connecting_addr_with_type == connecting_le_.end()) {
    if (connecting_addr_with_type == connecting_le_.end()) {
      LOG_WARN("No prior connection request for %s", address_with_type.ToString().c_str());
      LOG_WARN("No prior connection request for %s", address_with_type.ToString().c_str());
    } else {
      connecting_le_.erase(connecting_addr_with_type);
    }
    }
    connecting_le_.clear();

    if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) {
    if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) {
      create_connection_timeout_alarms_.at(address_with_type).Cancel();
      create_connection_timeout_alarms_.at(address_with_type).Cancel();
      create_connection_timeout_alarms_.erase(address_with_type);
      create_connection_timeout_alarms_.erase(address_with_type);
@@ -620,68 +621,9 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
          connectability_state_machine_text(connectability_state_).c_str());
          connectability_state_machine_text(connectability_state_).c_str());
      return;
      return;
    }
    }
    connectability_state_ = ConnectabilityState::ARMING;
    AddressWithType empty(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS);
    AddressWithType empty(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS);
    create_le_connection(empty, false, false);
    connectability_state_ = ConnectabilityState::ARMING;
  }
    connecting_le_ = connect_list;

  void disarm_connectability() {
    if (connectability_state_ != ConnectabilityState::ARMED && connectability_state_ != ConnectabilityState::ARMING) {
      LOG_ERROR(
          "Attempting to disarm le connection state machine in unexpected state:%s",
          connectability_state_machine_text(connectability_state_).c_str());
      return;
    }
    connectability_state_ = ConnectabilityState::DISARMING;
    le_acl_connection_interface_->EnqueueCommand(
        LeCreateConnectionCancelBuilder::Create(),
        handler_->BindOnce(&le_impl::on_create_connection_cancel_complete, common::Unretained(this)));
  }

  void create_le_connection(AddressWithType address_with_type, bool add_to_connect_list, bool is_direct) {
    if (le_client_callbacks_ == nullptr) {
      LOG_ERROR("No callbacks to call");
      return;
    }

    if (connections.alreadyConnected(address_with_type)) {
      LOG_INFO("Device already connected, return");
      return;
    }

    // TODO: Configure default LE connection parameters?
    if (add_to_connect_list) {
      add_device_to_connect_list(address_with_type);
      if (is_direct) {
        direct_connections_.insert(address_with_type);
        if (create_connection_timeout_alarms_.find(address_with_type) == create_connection_timeout_alarms_.end()) {
          create_connection_timeout_alarms_.emplace(
              std::piecewise_construct,
              std::forward_as_tuple(address_with_type.GetAddress(), address_with_type.GetAddressType()),
              std::forward_as_tuple(handler_));
          create_connection_timeout_alarms_.at(address_with_type)
              .Schedule(
                  common::BindOnce(&le_impl::on_create_connection_timeout, common::Unretained(this), address_with_type),
                  kCreateConnectionTimeoutMs);
        }
      }
    }

    if (!address_manager_registered) {
      auto policy = le_address_manager_->Register(this);
      address_manager_registered = true;

      // Pause connection, wait for set random address complete
      if (policy == LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS ||
          policy == LeAddressManager::AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
        pause_connection = true;
      }
    }

    if (pause_connection) {
      canceled_connections_.insert(address_with_type);
      return;
    }


    uint16_t le_scan_interval = kScanIntervalSlow;
    uint16_t le_scan_interval = kScanIntervalSlow;
    uint16_t le_scan_window = kScanWindowSlow;
    uint16_t le_scan_window = kScanWindowSlow;
@@ -703,9 +645,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
    uint16_t supervision_timeout = 0x001f4;
    uint16_t supervision_timeout = 0x001f4;
    ASSERT(check_connection_parameters(conn_interval_min, conn_interval_max, conn_latency, supervision_timeout));
    ASSERT(check_connection_parameters(conn_interval_min, conn_interval_max, conn_latency, supervision_timeout));


    connecting_le_.insert(address_with_type);
    AddressWithType address_with_type = connection_peer_address_with_type_;
    connectability_state_ = ConnectabilityState::ARMING;

    if (initiator_filter_policy == InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST) {
    if (initiator_filter_policy == InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST) {
      address_with_type = AddressWithType();
      address_with_type = AddressWithType();
    }
    }
@@ -779,6 +719,85 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
    }
    }
  }
  }


  void disarm_connectability() {
    if (connectability_state_ != ConnectabilityState::ARMED && connectability_state_ != ConnectabilityState::ARMING) {
      LOG_ERROR(
          "Attempting to disarm le connection state machine in unexpected state:%s",
          connectability_state_machine_text(connectability_state_).c_str());
      return;
    }
    connectability_state_ = ConnectabilityState::DISARMING;
    le_acl_connection_interface_->EnqueueCommand(
        LeCreateConnectionCancelBuilder::Create(),
        handler_->BindOnce(&le_impl::on_create_connection_cancel_complete, common::Unretained(this)));
  }

  void create_le_connection(AddressWithType address_with_type, bool add_to_connect_list, bool is_direct) {
    if (le_client_callbacks_ == nullptr) {
      LOG_ERROR("No callbacks to call");
      return;
    }

    if (connections.alreadyConnected(address_with_type)) {
      LOG_INFO("Device already connected, return");
      return;
    }

    // TODO: Configure default LE connection parameters?
    if (add_to_connect_list) {
      add_device_to_connect_list(address_with_type);
      if (is_direct) {
        direct_connections_.insert(address_with_type);
        if (create_connection_timeout_alarms_.find(address_with_type) == create_connection_timeout_alarms_.end()) {
          create_connection_timeout_alarms_.emplace(
              std::piecewise_construct,
              std::forward_as_tuple(address_with_type.GetAddress(), address_with_type.GetAddressType()),
              std::forward_as_tuple(handler_));
          create_connection_timeout_alarms_.at(address_with_type)
              .Schedule(
                  common::BindOnce(&le_impl::on_create_connection_timeout, common::Unretained(this), address_with_type),
                  kCreateConnectionTimeoutMs);
        }
      }
    }

    if (!address_manager_registered) {
      auto policy = le_address_manager_->Register(this);
      address_manager_registered = true;

      // Pause connection, wait for set random address complete
      if (policy == LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS ||
          policy == LeAddressManager::AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
        pause_connection = true;
      }
    }

    if (pause_connection) {
      canceled_connections_.insert(address_with_type);
      return;
    }

    switch (connectability_state_) {
      case ConnectabilityState::ARMED:
      case ConnectabilityState::ARMING:
        // Ignored, if we add new device to the filter accept list, create connection command will be sent by OnResume.
        LOG_DEBUG(
            "Deferred until filter accept list updated create connection state %s",
            connectability_state_machine_text(connectability_state_).c_str());
        break;
      default:
        // If we added to filter accept list then the arming of the le state machine
        // must wait until the filter accept list command as completed
        if (add_to_connect_list) {
          canceled_connections_.insert(address_with_type);
          LOG_DEBUG("Deferred until filter accept list has completed");
        } else {
          handler_->CallOn(this, &le_impl::arm_connectability);
        }
        break;
    }
  }

  void on_create_connection_timeout(AddressWithType address_with_type) {
  void on_create_connection_timeout(AddressWithType address_with_type) {
    LOG_INFO("on_create_connection_timeout, address: %s", address_with_type.ToString().c_str());
    LOG_INFO("on_create_connection_timeout, address: %s", address_with_type.ToString().c_str());
    if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) {
    if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) {
@@ -951,6 +970,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
  // Set of devices that will not be removed from connect list after direct connect timeout
  // Set of devices that will not be removed from connect list after direct connect timeout
  std::unordered_set<AddressWithType> background_connections_;
  std::unordered_set<AddressWithType> background_connections_;
  std::unordered_set<AddressWithType> connect_list;
  std::unordered_set<AddressWithType> connect_list;
  AddressWithType connection_peer_address_with_type_;  // Direct peer address UNSUPPORTEDD
  bool address_manager_registered = false;
  bool address_manager_registered = false;
  bool ready_to_unregister = false;
  bool ready_to_unregister = false;
  bool pause_connection = false;
  bool pause_connection = false;