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

Commit 3afede77 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Use White List for direct connection establishment to multiple devices

Currently, we implement GAP Direct Connect procedure exactly as the spec
says: we attempt connection to just one device.

This means that an app doing Direct Connection can take over the ability
to establish connections, and if it repeats the request, can cause other
devices to not connect.

From now on, we will use White List for both Background and Direct
connections. When there is at least one direct connection, we will
increase the scan parameters used for connection.

Bug: 112827989
Test: added unittests, also sl4a GattConnectTest
Change-Id: Ic0b2f631e3c84d5e8e0f4683b0148f031bfd5639
parent 29d85a29
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -279,7 +279,6 @@ void btif_gattc_open_impl(int client_if, RawAddress address, bool is_direct,
        return;
      }
    }
    BTA_DmBleStartAutoConn();
  }

  // Determine transport
@@ -304,6 +303,10 @@ void btif_gattc_open_impl(int client_if, RawAddress address, bool is_direct,
    }
  }

  if (transport == GATT_TRANSPORT_LE) {
    BTA_DmBleStartAutoConn();
  }

  // Connect!
  BTIF_TRACE_DEBUG("%s Transport=%d, device type=%d, phy=%d", __func__,
                   transport, device_type, initiating_phys);
+52 −0
Original line number Diff line number Diff line
#pragma once
#include <memory>

struct alarm_t;

class AlarmMock {
 public:
  MOCK_METHOD1(AlarmNew, alarm_t*(const char*));
  MOCK_METHOD1(AlarmFree, void(alarm_t*));
  MOCK_METHOD1(AlarmCancel, void(alarm_t*));
  MOCK_METHOD4(AlarmSetOnMloop, void(alarm_t* alarm, uint64_t interval_ms,
                                     alarm_callback_t cb, void* data));

  alarm_t* AlarmNewImpl(const char* name) {
    AlarmNew(name);
    // We must return something from alarm_new in tests, if we just return null,
    // unique_ptr will misbehave. Just reserve few bits they will be freed in
    // AlarmFreeImpl
    return (alarm_t*)new uint8_t[30];
  }

  void AlarmFreeImpl(alarm_t* alarm) {
    uint8_t* ptr = (uint8_t*)alarm;
    delete[] ptr;
    return AlarmFree(alarm);
  }

  static inline AlarmMock* Get() {
    if (!localAlarmMock) {
      localAlarmMock = std::make_unique<AlarmMock>();
    }
    return localAlarmMock.get();
  }

  static inline void Reset() { localAlarmMock = std::make_unique<AlarmMock>(); }

 private:
  static std::unique_ptr<AlarmMock> localAlarmMock;
};

std::unique_ptr<AlarmMock> AlarmMock::localAlarmMock;

alarm_t* alarm_new(const char* name) {
  return AlarmMock::Get()->AlarmNewImpl(name);
}

void alarm_free(alarm_t* alarm) { AlarmMock::Get()->AlarmFreeImpl(alarm); }

void alarm_set_on_mloop(alarm_t* alarm, uint64_t interval_ms,
                        alarm_callback_t cb, void* data) {
  AlarmMock::Get()->AlarmSetOnMloop(alarm, interval_ms, cb, data);
}
+2 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "stack/crypto_toolbox/crypto_toolbox.h"
#include "stack/gatt/connection_manager.h"

extern void gatt_notify_phy_updated(uint8_t status, uint16_t handle,
                                    uint8_t tx_phy, uint8_t rx_phy);
@@ -1957,6 +1958,7 @@ void btm_ble_conn_complete(uint8_t* p, UNUSED_ATTR uint16_t evt_len,
    }
#endif

    gatt::connection_manager::on_connection_complete(bda);
    btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type,
                      match);

+26 −0
Original line number Diff line number Diff line
@@ -351,6 +351,32 @@ void btm_send_hci_create_connection(
  }
}

bool BTM_SetLeConnectionModeToFast() {
  VLOG(2) << __func__;
  tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
  if ((p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF &&
       p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ||
      (p_cb->scan_int == BTM_BLE_SCAN_SLOW_INT_1 &&
       p_cb->scan_win == BTM_BLE_SCAN_SLOW_WIN_1)) {
    p_cb->scan_int = BTM_BLE_SCAN_FAST_INT;
    p_cb->scan_win = BTM_BLE_SCAN_FAST_WIN;
    return true;
  }
  return false;
}

void BTM_SetLeConnectionModeToSlow() {
  VLOG(2) << __func__;
  tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
  if ((p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF &&
       p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ||
      (p_cb->scan_int == BTM_BLE_SCAN_FAST_INT &&
       p_cb->scan_win == BTM_BLE_SCAN_FAST_WIN)) {
    p_cb->scan_int = BTM_BLE_SCAN_SLOW_INT_1;
    p_cb->scan_win = BTM_BLE_SCAN_SLOW_WIN_1;
  }
}

/** This function is to start auto connection procedure */
bool btm_ble_start_auto_conn() {
  tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
+11 −0
Original line number Diff line number Diff line
@@ -30,3 +30,14 @@ extern void BTM_WhiteListRemove(const RawAddress& address);

/** Clear the whitelist, end any pending whitelist connections */
extern void BTM_WhiteListClear();

/* Use fast scan window/interval for LE connection establishment.
 * This does not send any requests to controller, instead it changes the
 * parameters that will be used after next add/remove request.
 * Returns true, if the change is scheduled, false otherwise. */
extern bool BTM_SetLeConnectionModeToFast();

/* Use slow scan window/interval for LE connection establishment.
 * This does not send any requests to controller, instead it changes the
 * parameters that will be used after next add/remove request */
extern void BTM_SetLeConnectionModeToSlow();
 No newline at end of file
Loading