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

Commit fb5c1ae0 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Gerrit Code Review
Browse files

Merge "Add functions for checking controller capabilities"

parents 1b4acce8 1cb3493b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -80,25 +80,35 @@ typedef struct controller_t {
  bool (*supports_ble_periodic_advertising)(void);
  bool (*supports_ble_peripheral_initiated_feature_exchange)(void);
  bool (*supports_ble_connection_parameter_request)(void);
  bool (*supports_ble_periodic_advertising_sync_transfer_sender)(void);
  bool (*supports_ble_periodic_advertising_sync_transfer_recipient)(void);
  bool (*supports_ble_connected_isochronous_stream_master)(void);
  bool (*supports_ble_connected_isochronous_stream_slave)(void);
  bool (*supports_ble_isochronous_broadcaster)(void);
  bool (*supports_ble_synchronized_receiver)(void);

  // Get the cached acl data sizes for the controller.
  uint16_t (*get_acl_data_size_classic)(void);
  uint16_t (*get_acl_data_size_ble)(void);
  uint16_t (*get_iso_data_size)(void);

  // Get the cached acl packet sizes for the controller.
  // This is a convenience function for the respective
  // acl data size + size of the acl header.
  uint16_t (*get_acl_packet_size_classic)(void);
  uint16_t (*get_acl_packet_size_ble)(void);
  uint16_t (*get_iso_packet_size)(void);

  uint16_t (*get_ble_default_data_packet_length)(void);
  uint16_t (*get_ble_maximum_tx_data_length)(void);
  uint16_t (*get_ble_maxium_advertising_data_length)(void);
  uint8_t (*get_ble_number_of_supported_advertising_sets)(void);
  uint8_t (*get_ble_periodic_advertiser_list_size)(void);

  // Get the number of acl packets the controller can buffer.
  uint16_t (*get_acl_buffer_count_classic)(void);
  uint8_t (*get_acl_buffer_count_ble)(void);
  uint8_t (*get_iso_buffer_count)(void);

  uint8_t (*get_ble_white_list_size)(void);

+118 −13
Original line number Diff line number Diff line
@@ -30,15 +30,16 @@
#include "main/shim/controller.h"
#include "main/shim/shim.h"
#include "osi/include/future.h"
#include "osi/include/properties.h"
#include "stack/include/btm_ble_api.h"

const bt_event_mask_t BLE_EVENT_MASK = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
const bt_event_mask_t BLE_EVENT_MASK = {{0x00, 0x00, 0x00, 0x00, 0x7F, 0x02,
#if (BLE_PRIVACY_SPT == TRUE)
                                         0x1E,
                                         0xFE,
#else
                                         /* Disable "LE Enhanced Connection
                                            Complete" when privacy is off */
                                         0x1C,
                                         0xFC,
#endif
                                         0x7f}};

@@ -52,6 +53,7 @@ const uint8_t SCO_HOST_BUFFER_SIZE = 0xff;
#define BLE_SUPPORTED_STATES_SIZE 8
#define BLE_SUPPORTED_FEATURES_SIZE 8
#define MAX_LOCAL_SUPPORTED_CODECS_SIZE 8
#define LL_FEATURE_BIT_ISO_HOST_SUPPORT 32

static const hci_t* local_hci;
static const hci_packet_factory_t* packet_factory;
@@ -66,8 +68,11 @@ static uint8_t last_features_classic_page_index;

static uint16_t acl_data_size_classic;
static uint16_t acl_data_size_ble;
static uint16_t iso_data_size;

static uint16_t acl_buffer_count_classic;
static uint8_t acl_buffer_count_ble;
static uint8_t iso_buffer_count;

static uint8_t ble_white_list_size;
static uint8_t ble_resolving_list_max_size;
@@ -81,11 +86,13 @@ static uint16_t ble_supported_max_rx_time;

static uint16_t ble_maxium_advertising_data_length;
static uint8_t ble_number_of_supported_advertising_sets;
static uint8_t ble_periodic_advertiser_list_size;
static uint8_t local_supported_codecs[MAX_LOCAL_SUPPORTED_CODECS_SIZE];
static uint8_t number_of_local_supported_codecs = 0;

static bool readable;
static bool ble_supported;
static bool iso_supported;
static bool simple_pairing_supported;
static bool secure_connections_supported;

@@ -200,10 +207,29 @@ static future_t* start_up(void) {
    packet_parser->parse_ble_read_white_list_size_response(
        response, &ble_white_list_size);

    // Request the ble supported features next
    response =
        AWAIT_COMMAND(packet_factory->make_ble_read_local_supported_features());
    packet_parser->parse_ble_read_local_supported_features_response(
        response, &features_ble);

    iso_supported = HCI_LE_CIS_MASTER(features_ble.as_array) ||
                    HCI_LE_CIS_SLAVE(features_ble.as_array) ||
                    HCI_LE_ISO_BROADCASTER(features_ble.as_array);

    if (iso_supported) {
      // Request the ble buffer size next
      response = AWAIT_COMMAND(packet_factory->make_ble_read_buffer_size_v2());
      packet_parser->parse_ble_read_buffer_size_v2_response(
          response, &acl_data_size_ble, &acl_buffer_count_ble, &iso_data_size,
          &iso_buffer_count);

    } else {
      // Request the ble buffer size next
      response = AWAIT_COMMAND(packet_factory->make_ble_read_buffer_size());
      packet_parser->parse_ble_read_buffer_size_response(
          response, &acl_data_size_ble, &acl_buffer_count_ble);
    }

    // Response of 0 indicates ble has the same buffer size as classic
    if (acl_data_size_ble == 0) acl_data_size_ble = acl_data_size_classic;
@@ -213,12 +239,6 @@ static future_t* start_up(void) {
    packet_parser->parse_ble_read_supported_states_response(
        response, ble_supported_states, sizeof(ble_supported_states));

    // Request the ble supported features next
    response =
        AWAIT_COMMAND(packet_factory->make_ble_read_local_supported_features());
    packet_parser->parse_ble_read_local_supported_features_response(
        response, &features_ble);

    if (HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array)) {
      response =
          AWAIT_COMMAND(packet_factory->make_ble_read_resolving_list_size());
@@ -254,10 +274,24 @@ static future_t* start_up(void) {
      ble_maxium_advertising_data_length = 31;
    }

    if (HCI_LE_PERIODIC_ADVERTISING_SUPPORTED(features_ble.as_array)) {
      response = AWAIT_COMMAND(
          packet_factory->make_ble_read_periodic_advertiser_list_size());

      packet_parser->parse_ble_read_size_of_advertiser_list(
          response, &ble_periodic_advertiser_list_size);
    }

    // Set the ble event mask next
    response =
        AWAIT_COMMAND(packet_factory->make_ble_set_event_mask(&BLE_EVENT_MASK));
    packet_parser->parse_generic_command_complete(response);

    if (HCI_LE_SET_HOST_FEATURE_SUPPORTED(supported_commands)) {
      response = AWAIT_COMMAND(packet_factory->make_ble_set_host_features(
          LL_FEATURE_BIT_ISO_HOST_SUPPORT, 0x01));
      packet_parser->parse_generic_command_complete(response);
    }
  }

  if (simple_pairing_supported) {
@@ -550,6 +584,44 @@ static bool supports_ble_connection_parameter_request(void) {
  return HCI_LE_CONN_PARAM_REQ_SUPPORTED(features_ble.as_array);
}

static bool supports_ble_periodic_advertising_sync_transfer_sender(void) {
  CHECK(readable);
  CHECK(ble_supported);
  return HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER(
      features_ble.as_array);
}

static bool supports_ble_periodic_advertising_sync_transfer_recipient(void) {
  CHECK(readable);
  CHECK(ble_supported);
  return HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT(
      features_ble.as_array);
}

static bool supports_ble_connected_isochronous_stream_master(void) {
  CHECK(readable);
  CHECK(ble_supported);
  return HCI_LE_CIS_MASTER(features_ble.as_array);
}

static bool supports_ble_connected_isochronous_stream_slave(void) {
  CHECK(readable);
  CHECK(ble_supported);
  return HCI_LE_CIS_SLAVE(features_ble.as_array);
}

static bool supports_ble_isochronous_broadcaster(void) {
  CHECK(readable);
  CHECK(ble_supported);
  return HCI_LE_ISO_BROADCASTER(features_ble.as_array);
}

static bool supports_ble_synchronized_receiver(void) {
  CHECK(readable);
  CHECK(ble_supported);
  return HCI_LE_SYNCHRONIZED_RECEIVER(features_ble.as_array);
}

static uint16_t get_acl_data_size_classic(void) {
  CHECK(readable);
  return acl_data_size_classic;
@@ -561,6 +633,11 @@ static uint16_t get_acl_data_size_ble(void) {
  return acl_data_size_ble;
}

static uint16_t get_iso_data_size(void) {
  CHECK(readable);
  return iso_data_size;
}

static uint16_t get_acl_packet_size_classic(void) {
  CHECK(readable);
  return acl_data_size_classic + HCI_DATA_PREAMBLE_SIZE;
@@ -571,6 +648,11 @@ static uint16_t get_acl_packet_size_ble(void) {
  return acl_data_size_ble + HCI_DATA_PREAMBLE_SIZE;
}

static uint16_t get_iso_packet_size(void) {
  CHECK(readable);
  return iso_data_size + HCI_DATA_PREAMBLE_SIZE;
}

static uint16_t get_ble_suggested_default_data_length(void) {
  CHECK(readable);
  CHECK(ble_supported);
@@ -595,6 +677,12 @@ static uint8_t get_ble_number_of_supported_advertising_sets(void) {
  return ble_number_of_supported_advertising_sets;
}

static uint8_t get_ble_periodic_advertiser_list_size(void) {
  CHECK(readable);
  CHECK(ble_supported);
  return ble_periodic_advertiser_list_size;
}

static uint16_t get_acl_buffer_count_classic(void) {
  CHECK(readable);
  return acl_buffer_count_classic;
@@ -606,6 +694,12 @@ static uint8_t get_acl_buffer_count_ble(void) {
  return acl_buffer_count_ble;
}

static uint8_t get_iso_buffer_count(void) {
  CHECK(readable);
  CHECK(ble_supported);
  return iso_buffer_count;
}

static uint8_t get_ble_white_list_size(void) {
  CHECK(readable);
  CHECK(ble_supported);
@@ -688,19 +782,30 @@ static const controller_t interface = {
    supports_ble_periodic_advertising,
    supports_ble_peripheral_initiated_feature_exchange,
    supports_ble_connection_parameter_request,
    supports_ble_periodic_advertising_sync_transfer_sender,
    supports_ble_periodic_advertising_sync_transfer_recipient,
    supports_ble_connected_isochronous_stream_master,
    supports_ble_connected_isochronous_stream_slave,
    supports_ble_isochronous_broadcaster,
    supports_ble_synchronized_receiver,

    get_acl_data_size_classic,
    get_acl_data_size_ble,
    get_iso_data_size,

    get_acl_packet_size_classic,
    get_acl_packet_size_ble,
    get_iso_packet_size,

    get_ble_suggested_default_data_length,
    get_ble_maximum_tx_data_length,
    get_ble_maxium_advertising_data_length,
    get_ble_number_of_supported_advertising_sets,
    get_ble_periodic_advertiser_list_size,

    get_acl_buffer_count_classic,
    get_acl_buffer_count_ble,
    get_iso_buffer_count,

    get_ble_white_list_size,

+63 −6
Original line number Diff line number Diff line
@@ -59,8 +59,15 @@ struct Controller::impl {
    hci_->EnqueueCommand(ReadBufferSizeBuilder::Create(),
                         handler->BindOnceOn(this, &Controller::impl::read_buffer_size_complete_handler));

    hci_->EnqueueCommand(LeReadBufferSizeV1Builder::Create(),
    if (is_supported(OpCode::LE_READ_BUFFER_SIZE_V2)) {
      hci_->EnqueueCommand(
          LeReadBufferSizeV2Builder::Create(),
          handler->BindOnceOn(this, &Controller::impl::le_read_buffer_size_v2_handler));
    } else {
      hci_->EnqueueCommand(
          LeReadBufferSizeV1Builder::Create(),
          handler->BindOnceOn(this, &Controller::impl::le_read_buffer_size_handler));
    }

    hci_->EnqueueCommand(LeReadLocalSupportedFeaturesBuilder::Create(),
                         handler->BindOnceOn(this, &Controller::impl::le_read_local_supported_features_handler));
@@ -104,6 +111,11 @@ struct Controller::impl {
    } else {
      le_number_supported_advertising_sets_ = 1;
    }
    if (is_supported(OpCode::LE_READ_PERIODIC_ADVERTISING_LIST_SIZE)) {
      hci_->EnqueueCommand(
          LeReadPeriodicAdvertiserListSizeBuilder::Create(),
          handler->BindOnceOn(this, &Controller::impl::le_read_periodic_advertiser_list_size_handler));
    }

    hci_->EnqueueCommand(LeGetVendorCapabilitiesBuilder::Create(),
                         handler->BindOnceOn(this, &Controller::impl::le_get_vendor_capabilities_handler));
@@ -233,6 +245,23 @@ struct Controller::impl {
    }
  }

  void le_read_buffer_size_v2_handler(CommandCompleteView view) {
    auto complete_view = LeReadBufferSizeV2CompleteView::Create(view);
    ASSERT(complete_view.IsValid());
    ErrorCode status = complete_view.GetStatus();
    ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str());
    le_buffer_size_ = complete_view.GetLeBufferSize();
    iso_buffer_size_ = complete_view.GetIsoBufferSize();

    // If LE buffer size is zero, then buffers returned by Read_Buffer_Size are shared between BR/EDR and LE.
    if (le_buffer_size_.total_num_le_packets_ == 0) {
      ASSERT(acl_buffers_ != 0);
      le_buffer_size_.total_num_le_packets_ = acl_buffers_ / 2;
      acl_buffers_ -= le_buffer_size_.total_num_le_packets_;
      le_buffer_size_.le_data_packet_length_ = acl_buffer_length_;
    }
  }

  void le_read_local_supported_features_handler(CommandCompleteView view) {
    auto complete_view = LeReadLocalSupportedFeaturesCompleteView::Create(view);
    ASSERT(complete_view.IsValid());
@@ -297,6 +326,14 @@ struct Controller::impl {
    le_number_supported_advertising_sets_ = complete_view.GetNumberSupportedAdvertisingSets();
  }

  void le_read_periodic_advertiser_list_size_handler(CommandCompleteView view) {
    auto complete_view = LeReadPeriodicAdvertiserListSizeCompleteView::Create(view);
    ASSERT(complete_view.IsValid());
    ErrorCode status = complete_view.GetStatus();
    ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str());
    le_periodic_advertiser_list_size_ = complete_view.GetPeriodicAdvertiserListSize();
  }

  void le_get_vendor_capabilities_handler(CommandCompleteView view) {
    auto complete_view = LeGetVendorCapabilitiesCompleteView::Create(view);

@@ -746,6 +783,7 @@ struct Controller::impl {
  Address mac_address_;
  std::string local_name_;
  LeBufferSize le_buffer_size_;
  LeBufferSize iso_buffer_size_;
  uint64_t le_local_supported_features_;
  uint64_t le_supported_states_;
  uint8_t le_connect_list_size_;
@@ -754,6 +792,7 @@ struct Controller::impl {
  uint16_t le_maximum_advertising_data_length_;
  uint16_t le_suggested_default_data_length_;
  uint8_t le_number_supported_advertising_sets_;
  uint8_t le_periodic_advertiser_list_size_;
  VendorCapabilities vendor_capabilities_;
};  // namespace hci

@@ -819,15 +858,21 @@ LOCAL_FEATURE_ACCESSOR(SupportsBle, 0, 38)
    return GetLocalLeFeatures() & BIT(bit);  \
  }

LOCAL_LE_FEATURE_ACCESSOR(SupportsBlePrivacy, 6)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBlePacketExtension, 5)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBleConnectionParameterRequest, 1)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBleConnectionParametersRequest, 2)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBlePeripheralInitiatedFeatureExchange, 3)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBlePacketExtension, 5)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBlePrivacy, 6)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBle2mPhy, 8)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBleCodedPhy, 11)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBleExtendedAdvertising, 12)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBlePeriodicAdvertising, 13)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBlePeripheralInitiatedFeatureExchange, 3)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBleConnectionParameterRequest, 1)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBlePeriodicAdvertisingSyncTransferSender, 24)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBlePeriodicAdvertisingSyncTransferRecipient, 25)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBleConnectedIsochronousStreamMaster, 28)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBleConnectedIsochronousStreamSlave, 29)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBleIsochronousBroadcaster, 30)
LOCAL_LE_FEATURE_ACCESSOR(SupportsBleSynchronizedReceiver, 31)

uint64_t Controller::GetLocalFeatures(uint8_t page_number) const {
  if (page_number <= impl_->maximum_page_number_) {
@@ -938,6 +983,14 @@ uint64_t Controller::GetLocalLeFeatures() const {
  return impl_->le_local_supported_features_;
}

LeBufferSize Controller::GetControllerIsoBufferSize() const {
  return impl_->iso_buffer_size_;
}

uint64_t Controller::GetControllerLeLocalSupportedFeatures() const {
  return impl_->le_local_supported_features_;
}

uint64_t Controller::GetLeSupportedStates() const {
  return impl_->le_supported_states_;
}
@@ -970,6 +1023,10 @@ VendorCapabilities Controller::GetVendorCapabilities() const {
  return impl_->vendor_capabilities_;
}

uint8_t Controller::GetLePeriodicAdvertiserListSize() const {
  return impl_->le_periodic_advertiser_list_size_;
}

bool Controller::IsSupported(bluetooth::hci::OpCode op_code) const {
  return impl_->is_supported(op_code);
}
+12 −0
Original line number Diff line number Diff line
@@ -80,6 +80,12 @@ class Controller : public Module {
  virtual bool SupportsBlePeriodicAdvertising() const;
  virtual bool SupportsBlePeripheralInitiatedFeatureExchange() const;
  virtual bool SupportsBleConnectionParameterRequest() const;
  virtual bool SupportsBlePeriodicAdvertisingSyncTransferSender() const;
  virtual bool SupportsBlePeriodicAdvertisingSyncTransferRecipient() const;
  virtual bool SupportsBleConnectedIsochronousStreamMaster() const;
  virtual bool SupportsBleConnectedIsochronousStreamSlave() const;
  virtual bool SupportsBleIsochronousBroadcaster() const;
  virtual bool SupportsBleSynchronizedReceiver() const;

  virtual uint16_t GetAclPacketLength() const;

@@ -125,6 +131,10 @@ class Controller : public Module {

  virtual uint64_t GetLeSupportedStates() const;

  virtual LeBufferSize GetControllerIsoBufferSize() const;

  virtual uint64_t GetControllerLeLocalSupportedFeatures() const;

  virtual uint8_t GetLeConnectListSize() const;

  virtual uint8_t GetLeResolvingListSize() const;
@@ -137,6 +147,8 @@ class Controller : public Module {

  virtual uint8_t GetLeNumberOfSupportedAdverisingSets() const;

  virtual uint8_t GetLePeriodicAdvertiserListSize() const;

  virtual VendorCapabilities GetVendorCapabilities() const;

  virtual bool IsSupported(OpCode op_code) const;
+6 −3
Original line number Diff line number Diff line
@@ -3222,11 +3222,14 @@ packet LeRemoveDeviceFromPeriodicAdvertisingList : LeAdvertisingCommand (op_code
}

packet LeClearPeriodicAdvertisingList : LeAdvertisingCommand (op_code = LE_CLEAR_PERIODIC_ADVERTISING_LIST) {
  _payload_,  // placeholder (unimplemented)
}

packet LeReadPeriodicAdvertisingListSize : LeAdvertisingCommand (op_code = LE_READ_PERIODIC_ADVERTISING_LIST_SIZE) {
  _payload_,  // placeholder (unimplemented)
packet LeReadPeriodicAdvertiserListSize : CommandPacket (op_code = LE_READ_PERIODIC_ADVERTISING_LIST_SIZE) {
}

packet LeReadPeriodicAdvertiserListSizeComplete : CommandComplete (command_op_code = LE_READ_PERIODIC_ADVERTISING_LIST_SIZE) {
  status : ErrorCode,
  periodic_advertiser_list_size : 8,
}

packet LeReadTransmitPower : LeAdvertisingCommand (op_code = LE_READ_TRANSMIT_POWER) {
Loading