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

Commit 4f209389 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5975424 from b981c683 to rvc-release

Change-Id: I77f3236cf68864efe511ffd54b75a824825b0f95
parents d36b916d b981c683
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -2,13 +2,14 @@ filegroup {
    name: "BluetoothHciSources",
    srcs: [
        "acl_manager.cc",
        "classic_security_manager.cc",
        "controller.cc",
        "address.cc",
        "classic_security_manager.cc",
        "class_of_device.cc",
        "controller.cc",
        "device.cc",
        "device_database.cc",
        "hci_layer.cc",
        "le_advertising_manager.cc",
    ],
}

+139 −22
Original line number Diff line number Diff line
@@ -1802,8 +1802,7 @@ packet ReadExtendedInquiryResponseComplete : CommandComplete (command_op_code =
packet WriteExtendedInquiryResponse : CommandPacket (op_code = WRITE_EXTENDED_INQUIRY_RESPONSE) {
  fec_required : FecRequired,
  extended_inquiry_response : GapData[],
  //_payload_, // Zero padding to be 240 octets
  // Should it be GapData[240] ?
  _padding_[244], // Zero padding to be 240 octets (GapData[]) + 2 (opcode) + 1 (size) + 1 (FecRequired)
}

packet WriteExtendedInquiryResponseComplete : CommandComplete (command_op_code = WRITE_EXTENDED_INQUIRY_RESPONSE) {
@@ -2197,7 +2196,7 @@ packet LeReadLocalSupportedFeaturesComplete : CommandComplete (command_op_code =
  le_features : 64,
}

packet LeSetRandomAddress : CommandPacket (op_code = LE_SET_RANDOM_ADDRESS) {
packet LeSetRandomAddress : LeAdvertisingCommand (op_code = LE_SET_RANDOM_ADDRESS) {
  random_address : Address,
}

@@ -2220,7 +2219,7 @@ enum AdvertisingEventType : 8 {
  ADV_DIRECT_IND = 0x01,
  ADV_SCAN_IND = 0x02,
  ADV_NONCONN_IND = 0x03,
  SCAN_RSP = 0x04,
  ADV_DIRECT_IND_LOW = 0x04,
}

enum AddressType : 8 {
@@ -2231,15 +2230,14 @@ enum AddressType : 8 {
}

packet LeSetAdvertisingParameters : LeAdvertisingCommand (op_code = LE_SET_ADVERTISING_PARAMETERS) {
  advertising_interval_min : 16,
  advertising_interval_max : 16,
  advertising_type : AdvertisingEventType,
  interval_min : 16,
  interval_max : 16,
  type : AdvertisingEventType,
  own_address_type : AddressType,
  peer_address_type : PeerAddressType,
  peer_address : Address,
  advertising_channel_map : 8,
  connection_filter_policy : AdvertisingFilterPolicy,
  scan_filter_policy : AdvertisingFilterPolicy,
  channel_map : 8,
  filter_policy : AdvertisingFilterPolicy,
  _reserved_ : 6,
}

@@ -2258,7 +2256,7 @@ packet LeReadAdvertisingChannelTxPowerComplete : CommandComplete (command_op_cod
packet LeSetAdvertisingData : LeAdvertisingCommand (op_code = LE_SET_ADVERTISING_DATA) {
  _size_(advertising_data) : 8,
  advertising_data : GapData[],
  _payload_, // Zero padding to 31 bytes of advertising_data
  _padding_[31], // Zero padding to 31 bytes of advertising_data
}

packet LeSetAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_ADVERTISING_DATA) {
@@ -2268,7 +2266,7 @@ packet LeSetAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_
packet LeSetScanResponseData : LeAdvertisingCommand (op_code = LE_SET_SCAN_RESPONSE_DATA) {
  _size_(advertising_data) : 8,
  advertising_data : GapData[],
  _payload_, // Zero padding to 31 bytes of advertising_data
  _padding_[31], // Zero padding to 31 bytes of advertising_data
}

packet LeSetScanResponseDataComplete : CommandComplete (command_op_code = LE_SET_SCAN_RESPONSE_DATA) {
@@ -2730,16 +2728,85 @@ packet LeGetVendorCapabilitiesComplete098 : LeGetVendorCapabilitiesComplete096 {
  bluetooth_quality_report_support: 8
}

packet LeMultiAdvt : VendorCommand (op_code = LE_MULTI_ADVT) {
  _payload_,  // placeholder (unimplemented)
enum SubOcf : 8 {
  SET_ADVT_PARAM = 0x01,
  SET_ADVT_DATA = 0x02,
  SET_ADVT_SCAN_RESP = 0x03,
  SET_ADVT_RANDOM_ADDR = 0x04,
  SET_ADVT_ENABLE = 0x05,
}

packet LeMultiAdvt : LeAdvertisingCommand (op_code = LE_MULTI_ADVT) {
  sub_cmd : SubOcf,
  _body_,
}

packet LeMultiAdvtParamComplete : CommandComplete (command_op_code = LE_MULTI_ADVT) {
  status : ErrorCode,
  sub_cmd : SubOcf,
}

packet LeMultiAdvtParam : LeMultiAdvt (sub_cmd = SET_ADVT_PARAM) {
  interval_min : 16,
  interval_max : 16,
  type : AdvertisingEventType,
  own_address_type : AddressType,
  peer_address_type : PeerAddressType,
  peer_address : Address,
  channel_map : 8,
  filter_policy : AdvertisingFilterPolicy,
  _reserved_ : 6,
  instance : 8,
  tx_power : 8,
}

packet LeMultiAdvtParamSetData : LeMultiAdvt (sub_cmd = SET_ADVT_DATA) {
  _size_(advertising_data) : 8,
  advertising_data : GapData[],
  _padding_[31], // Zero padding to 31 bytes of advertising_data
  advertising_instance : 8,
}

packet LeMultiAdvtParamSetScanResp : LeMultiAdvt (sub_cmd = SET_ADVT_SCAN_RESP) {
  _size_(advertising_data) : 8,
  advertising_data : GapData[],
  _padding_[31], // Zero padding to 31 bytes of advertising_data
  advertising_instance : 8,
}

packet LeMultiAdvtParamSetRandomAddr : LeMultiAdvt (sub_cmd = SET_ADVT_RANDOM_ADDR) {
  random_address : Address,
  advertising_instance : 8,
}

packet LeMultiAdvtParamSetEnable : LeMultiAdvt (sub_cmd = SET_ADVT_ENABLE) {
  advertising_enable : Enable, // Default DISABLED
  advertising_instance : 8,
}

packet LeBatchScan : VendorCommand (op_code = LE_BATCH_SCAN) {
  _payload_,  // placeholder (unimplemented)
}

enum ApcfOpcode : 8 {
  ENABLE = 0x00,
  SET_FILTERING_PARAMETERS = 0x01,
  BROADCASTER_ADDRESS = 0x02,
  SERVICE_UUID = 0x03,
  SERVICE_SOLICITATION_UUID = 0x04,
  LOCAL_NAME = 0x05,
  MANUFACTURER_DATA = 0x06,
  SERVICE_DATA = 0x07,
}

packet LeAdvFilter : VendorCommand (op_code = LE_ADV_FILTER) {
  _payload_,  // placeholder (unimplemented)
  apcf_opcode : ApcfOpcode,
  _body_,
}

packet LeAdvFilterComplete : CommandComplete (command_op_code = LE_ADV_FILTER) {
  status : ErrorCode,
  apcf_opcode : ApcfOpcode,
}

packet LeTrackAdv : VendorCommand (op_code = LE_TRACK_ADV) {
@@ -3138,8 +3205,8 @@ struct LeAdvertisingReport {
}

packet LeAdvertisingReport : LeMetaEvent (subevent_code = ADVERTISING_REPORT) {
  _count_(le_advertising_reports) : 8,
  le_advertising_reports : LeAdvertisingReport[],
  _count_(advertising_reports) : 8,
  advertising_reports : LeAdvertisingReport[],
}

packet LeConnectionUpdateComplete : LeMetaEvent (subevent_code = CONNECTION_UPDATE_COMPLETE) {
@@ -3214,6 +3281,7 @@ enum DirectAdvertisingAddressType : 8 {
  RANDOM_DEVICE_ADDRESS = 0x01,
  PUBLIC_IDENTITY_ADDRESS = 0x02,
  RANDOM_IDENTITY_ADDRESS = 0x03,
  CONTROLLER_UNABLE_TO_RESOLVE = 0xFE,
  NO_ADDRESS = 0xFF,
}

@@ -3235,16 +3303,59 @@ struct LeDirectedAdvertisingReport {
}

packet LeDirectedAdvertisingReport : LeMetaEvent (subevent_code = DIRECTED_ADVERTISING_REPORT) {
  _count_(le_directed_advertising_reports) : 8,
  le_directed_advertising_reports : LeDirectedAdvertisingReport[],
  _count_(advertising_reports) : 8,
  advertising_reports : LeDirectedAdvertisingReport[],
}

packet LePhyUpdateComplete : LeMetaEvent (subevent_code = PHY_UPDATE_COMPLETE) {
  _payload_, // placeholder (unimplemented)
}

enum DataStatus : 2 {
  COMPLETE = 0x0,
  CONTINUING = 0x1,
  TRUNCATED = 0x2,
  RESERVED = 0x3,
}

enum PrimaryPhyType : 8 {
  LE_1M = 0x01,
  LE_CODED = 0x03,
}

enum SecondaryPhyType : 8 {
  NO_PACKETS = 0x00,
  LE_1M = 0x01,
  LE_2M = 0x02,
  LE_CODED = 0x03,
}


struct LeExtendedAdvertisingReport {
  connectable : 1,
  scannable : 1,
  directed : 1,
  scan_response : 1,
  data_status : DataStatus,
  _reserved_ : 10,
  address_type : DirectAdvertisingAddressType,
  address : Address,
  primary_phy : PrimaryPhyType,
  secondary_phy : SecondaryPhyType,
  advertising_sid : 4, // SID subfield in the ADI field
  _reserved_ : 4,
  tx_power : 8,
  rssi : 8, // -127 to +20 (0x7F means not available)
  periodic_advertising_interval : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
  direct_address_type : DirectAdvertisingAddressType,
  direct_address : Address,
  _size_(advertising_data) : 8,
  advertising_data : GapData[],
}

packet LeExtendedAdvertisingReport : LeMetaEvent (subevent_code = EXTENDED_ADVERTISING_REPORT) {
  _payload_, // placeholder (unimplemented)
  _count_(advertising_reports) : 8,
  advertising_reports : LeExtendedAdvertisingReport[],
}

packet LePeriodicAdvertisingSyncEstablished : LeMetaEvent (subevent_code = PERIODIC_ADVERTISING_SYNC_ESTABLISHED) {
@@ -3263,9 +3374,15 @@ packet LeScanTimeout : LeMetaEvent (subevent_code = SCAN_TIMEOUT) {
}

packet LeAdvertisingSetTerminated : LeMetaEvent (subevent_code = ADVERTISING_SET_TERMINATED) {
  _payload_, // placeholder (unimplemented)
  status : ErrorCode,
  advertising_handle : 8,
  connection_handle : 12,
  _reserved_ : 4,
  num_completed_extended_advertising_events : 8,
}

packet LeScanRequestReceived : LeMetaEvent (subevent_code = SCAN_REQUEST_RECEIVED) {
  _payload_, // placeholder (unimplemented)
  advertising_handle : 8,
  scanner_address_type : AddressType,
  scanner_address : Address,
}
+15 −2
Original line number Diff line number Diff line
@@ -229,13 +229,14 @@ std::vector<uint8_t> pixel_3_xl_write_extended_inquiry_response_no_uuids_just_ei
    pixel_3_xl_write_extended_inquiry_response_no_uuids.end()};

TEST(HciPacketsTest, testWriteExtendedInquiryResponse) {
  std::shared_ptr<std::vector<uint8_t>> packet_bytes =
  std::shared_ptr<std::vector<uint8_t>> view_bytes =
      std::make_shared<std::vector<uint8_t>>(pixel_3_xl_write_extended_inquiry_response);

  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
  PacketView<kLittleEndian> packet_bytes_view(view_bytes);
  auto view = WriteExtendedInquiryResponseView::Create(CommandPacketView::Create(packet_bytes_view));
  ASSERT_TRUE(view.IsValid());
  auto gap_data = view.GetExtendedInquiryResponse();
  ASSERT_GE(gap_data.size(), 4);
  ASSERT_EQ(gap_data[0].data_type_, GapDataType::COMPLETE_LOCAL_NAME);
  ASSERT_EQ(gap_data[0].data_.size(), 10);
  ASSERT_EQ(gap_data[1].data_type_, GapDataType::COMPLETE_LIST_16_BIT_UUIDS);
@@ -244,6 +245,18 @@ TEST(HciPacketsTest, testWriteExtendedInquiryResponse) {
  ASSERT_EQ(gap_data[2].data_.size(), 0);
  ASSERT_EQ(gap_data[3].data_type_, GapDataType::COMPLETE_LIST_128_BIT_UUIDS);
  ASSERT_EQ(gap_data[3].data_.size(), 128);

  std::vector<GapData> no_padding{gap_data.begin(), gap_data.begin() + 4};
  auto builder = WriteExtendedInquiryResponseBuilder::Create(view.GetFecRequired(), no_padding);

  std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
  BitInserter it(*packet_bytes);
  builder->Serialize(it);

  EXPECT_EQ(packet_bytes->size(), view_bytes->size());
  for (size_t i = 0; i < view_bytes->size(); i++) {
    ASSERT_EQ(packet_bytes->at(i), view_bytes->at(i));
  }
}

//  TODO: Revisit reflection tests for EIR
+1 −6
Original line number Diff line number Diff line
@@ -37,13 +37,8 @@ class LeAdvertisingInterface {
                              common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) = 0;

  static constexpr hci::SubeventCode LeAdvertisingEvents[] = {
      hci::SubeventCode::ADVERTISING_REPORT,
      hci::SubeventCode::DIRECTED_ADVERTISING_REPORT,
      hci::SubeventCode::EXTENDED_ADVERTISING_REPORT,
      hci::SubeventCode::PERIODIC_ADVERTISING_REPORT,
      hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED,
      hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST,
      hci::SubeventCode::SCAN_REQUEST_RECEIVED,
      hci::SubeventCode::ADVERTISING_SET_TERMINATED,
  };
};
}  // namespace hci
+262 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <memory>
#include <mutex>

#include "hci/controller.h"
#include "hci/hci_layer.h"
#include "hci/hci_packets.h"
#include "hci/le_advertising_interface.h"
#include "hci/le_advertising_manager.h"
#include "module.h"
#include "os/handler.h"
#include "os/log.h"

namespace bluetooth {
namespace hci {

const ModuleFactory LeAdvertisingManager::Factory = ModuleFactory([]() { return new LeAdvertisingManager(); });

struct Advertiser {
  os::Handler* handler;
  common::Callback<void(Address, AddressType)> scan_callback;
  common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback;
};

struct LeAdvertisingManager::impl {
  impl(Module* module, os::Handler* handler, hci::HciLayer* hci_layer, hci::Controller* controller)
      : registered_handler_(nullptr), module_(module), module_handler_(handler), hci_layer_(hci_layer),
        controller_(controller), le_advertising_interface_(nullptr), num_instances_(0) {}

  void start() {
    le_advertising_interface_ = hci_layer_->GetLeAdvertisingInterface(
        common::Bind(&LeAdvertisingManager::impl::handle_event, common::Unretained(this)), module_handler_);
    num_instances_ = controller_->GetControllerLeNumberOfSupportedAdverisingSets();
  }

  size_t GetNumberOfAdvertisingInstances() const {
    return num_instances_;
  }

  void handle_event(LeMetaEventView event) {
    switch (event.GetSubeventCode()) {
      case hci::SubeventCode::SCAN_REQUEST_RECEIVED:
        handle_scan_request(LeScanRequestReceivedView::Create(event));
        break;
      case hci::SubeventCode::ADVERTISING_SET_TERMINATED:
        handle_set_terminated(LeAdvertisingSetTerminatedView::Create(event));
        break;
      default:
        LOG_INFO("Unknown subevent in scanner %s", hci::SubeventCodeText(event.GetSubeventCode()).c_str());
    }
  }

  void handle_scan_request(LeScanRequestReceivedView event_view) {
    if (!event_view.IsValid()) {
      LOG_INFO("Dropping invalid scan request event");
      return;
    }
    registered_handler_->Post(
        common::BindOnce(scan_callback_, event_view.GetScannerAddress(), event_view.GetScannerAddressType()));
  }

  void handle_set_terminated(LeAdvertisingSetTerminatedView event_view) {
    if (!event_view.IsValid()) {
      LOG_INFO("Dropping invalid advertising event");
      return;
    }
    registered_handler_->Post(common::BindOnce(set_terminated_callback_, event_view.GetStatus(),
                                               event_view.GetAdvertisingHandle(),
                                               event_view.GetNumCompletedExtendedAdvertisingEvents()));
  }

  AdvertiserId allocate_advertiser() {
    AdvertiserId id = 0;
    {
      std::unique_lock lock(id_mutex_);
      while (id < num_instances_ && advertising_sets_.count(id) == 0) {
        id++;
      }
    }
    if (id == num_instances_) {
      return kInvalidId;
    }
    return id;
  }

  void remove_advertiser(AdvertiserId id) {
    std::unique_lock lock(id_mutex_);
    if (advertising_sets_.count(id) == 0) {
      return;
    }
    advertising_sets_.erase(id);
  }

  void create_advertiser(AdvertiserId id, const AdvertisingConfig& config,
                         const common::Callback<void(Address, AddressType)>& scan_callback,
                         const common::Callback<void(ErrorCode, uint8_t, uint8_t)>& set_terminated_callback,
                         os::Handler* handler) {
    advertising_sets_[id].scan_callback = scan_callback;
    advertising_sets_[id].set_terminated_callback = set_terminated_callback;
    advertising_sets_[id].handler = handler;
    if (!controller_->IsSupported(hci::OpCode::LE_MULTI_ADVT)) {
      le_advertising_interface_->EnqueueCommand(
          hci::LeSetAdvertisingParametersBuilder::Create(config.interval_min, config.interval_max, config.event_type,
                                                         config.address_type, config.peer_address_type,
                                                         config.peer_address, config.channel_map, config.filter_policy),
          common::BindOnce(impl::check_enable_status), module_handler_);
      le_advertising_interface_->EnqueueCommand(hci::LeSetAdvertisingDataBuilder::Create(config.advertisement),
                                                common::BindOnce(impl::check_enable_status), module_handler_);
      le_advertising_interface_->EnqueueCommand(hci::LeSetRandomAddressBuilder::Create(config.random_address),
                                                common::BindOnce(impl::check_enable_status), module_handler_);
      if (!config.scan_response.empty()) {
        le_advertising_interface_->EnqueueCommand(hci::LeSetScanResponseDataBuilder::Create(config.scan_response),
                                                  common::BindOnce(impl::check_enable_status), module_handler_);
      }
      le_advertising_interface_->EnqueueCommand(hci::LeSetAdvertisingDataBuilder::Create(config.advertisement),
                                                common::BindOnce(impl::check_enable_status), module_handler_);
      return;
    }
    le_advertising_interface_->EnqueueCommand(
        hci::LeMultiAdvtParamBuilder::Create(config.interval_min, config.interval_max, config.event_type,
                                             config.address_type, config.peer_address_type, config.peer_address,
                                             config.channel_map, config.filter_policy, id, config.tx_power),
        common::BindOnce(impl::check_enable_status), module_handler_);
    le_advertising_interface_->EnqueueCommand(hci::LeSetAdvertisingEnableBuilder::Create(Enable::ENABLED),
                                              common::BindOnce(impl::check_enable_status), module_handler_);
  }

  void create_extended_advertiser(AdvertiserId id, const ExtendedAdvertisingConfig& config,
                                  const common::Callback<void(Address, AddressType)>& scan_callback,
                                  const common::Callback<void(ErrorCode, uint8_t, uint8_t)>& set_terminated_callback,
                                  os::Handler* handler) {
    if (!controller_->IsSupported(hci::OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS)) {
      create_advertiser(id, config, scan_callback, set_terminated_callback, handler);
      return;
    } else {
      LOG_ALWAYS_FATAL("LE_SET_EXTENDED_ADVERTISING_PARAMETERS isn't implemented.");
    }

    /*
    le_advertising_interface_->EnqueueCommand(hci::LeSetExtendedAdvertisingParametersBuilder::Create(config.interval_min,
    config.interval_max, config.event_type, config.address_type, config.peer_address_type, config.peer_address,
    config.channel_map, config.filter_policy, id, config.tx_power), common::BindOnce(impl::check_enable_status),
    module_handler_);
     */
    advertising_sets_[id].scan_callback = scan_callback;
    advertising_sets_[id].set_terminated_callback = set_terminated_callback;
    advertising_sets_[id].handler = handler;
  }

  void stop_advertising(AdvertiserId advertising_set) {
    if (advertising_sets_.find(advertising_set) == advertising_sets_.end()) {
      LOG_INFO("Unknown advertising set %u", advertising_set);
      return;
    }
    le_advertising_interface_->EnqueueCommand(hci::LeSetAdvertisingEnableBuilder::Create(Enable::DISABLED),
                                              common::BindOnce(impl::check_enable_status), module_handler_);
    std::unique_lock lock(id_mutex_);
    advertising_sets_.erase(advertising_set);
  }

  common::Callback<void(Address, AddressType)> scan_callback_;
  common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback_;
  os::Handler* registered_handler_;
  Module* module_;
  os::Handler* module_handler_;
  hci::HciLayer* hci_layer_;
  hci::Controller* controller_;
  hci::LeAdvertisingInterface* le_advertising_interface_;
  std::map<AdvertiserId, Advertiser> advertising_sets_;

  std::mutex id_mutex_;
  size_t num_instances_;

  static void check_enable_status(CommandCompleteView view) {
    ASSERT(view.IsValid());
    auto status_view = LeSetAdvertisingEnableCompleteView::Create(view);
    ASSERT(status_view.IsValid());
    if (status_view.GetStatus() != ErrorCode::SUCCESS) {
      LOG_INFO("SetEnable returned status %s", ErrorCodeText(status_view.GetStatus()).c_str());
      return;
    }
  }
};

const AdvertiserId LeAdvertisingManager::kInvalidId = -1;

LeAdvertisingManager::LeAdvertisingManager() {
  pimpl_ = std::make_unique<impl>(this, GetHandler(), GetDependency<hci::HciLayer>(), GetDependency<hci::Controller>());
}

void LeAdvertisingManager::ListDependencies(ModuleList* list) {
  list->add<hci::HciLayer>();
  list->add<hci::Controller>();
}

void LeAdvertisingManager::Start() {
  pimpl_->start();
}

void LeAdvertisingManager::Stop() {
  pimpl_.reset();
}

size_t LeAdvertisingManager::GetNumberOfAdvertisingInstances() const {
  return pimpl_->GetNumberOfAdvertisingInstances();
}

AdvertiserId LeAdvertisingManager::CreateAdvertiser(
    const AdvertisingConfig& config, const common::Callback<void(Address, AddressType)>& scan_callback,
    const common::Callback<void(ErrorCode, uint8_t, uint8_t)>& set_terminated_callback, os::Handler* handler) {
  if (config.peer_address == Address::kEmpty) {
    if (config.address_type == hci::AddressType::PUBLIC_IDENTITY_ADDRESS ||
        config.address_type == hci::AddressType::RANDOM_IDENTITY_ADDRESS) {
      return kInvalidId;
    }
    if (config.event_type == hci::AdvertisingEventType::ADV_DIRECT_IND ||
        config.event_type == hci::AdvertisingEventType::ADV_DIRECT_IND_LOW) {
      return kInvalidId;
    }
  }
  AdvertiserId id = pimpl_->allocate_advertiser();
  if (id == kInvalidId) {
    return id;
  }
  GetHandler()->Post(common::BindOnce(&impl::create_advertiser, common::Unretained(pimpl_.get()), id, config,
                                      scan_callback, set_terminated_callback, handler));
  return id;
}

AdvertiserId LeAdvertisingManager::CreateAdvertiser(
    const ExtendedAdvertisingConfig& config, const common::Callback<void(Address, AddressType)>& scan_callback,
    const common::Callback<void(ErrorCode, uint8_t, uint8_t)>& set_terminated_callback, os::Handler* handler) {
  AdvertiserId id = pimpl_->allocate_advertiser();
  if (id == kInvalidId) {
    return id;
  }
  // Add error checking here
  GetHandler()->Post(common::BindOnce(&impl::create_extended_advertiser, common::Unretained(pimpl_.get()), id, config,
                                      scan_callback, set_terminated_callback, handler));
  return id;
}

void LeAdvertisingManager::RemoveAdvertiser(AdvertiserId id) {
  pimpl_->remove_advertiser(id);
}

}  // namespace hci
}  // namespace bluetooth
 No newline at end of file
Loading