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

Commit 2481a025 authored by Rongxuan Liu's avatar Rongxuan Liu Committed by Gerrit Code Review
Browse files

Merge changes I721a66c9,I94bc4dba,I4228a47a,Id563b328 into main

* changes:
  Unify the callback trigger in check_status_with_id
  Divide long single gap data in le_advertising_manager
  Use raw payload for data raw commands builder
  Add new flag for divide long single gap data
parents 262cb292 5b3176a0
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -6,3 +6,10 @@ flag {
    description: "Enable support for the decryption of Encrypted Advertising Data"
    bug: "308855997"
}

flag {
    name: "divide_long_single_gap_data"
    namespace: "bluetooth"
    description: "Divide long single gap data if length is longer than HCI data length limit"
    bug: "310217895"
}
 No newline at end of file
+4 −2
Original line number Diff line number Diff line
@@ -47,7 +47,8 @@ LOCAL_host_libraries := \
	$(HOST_OUT_SHARED_LIBRARIES)/libprotobuf-cpp-full.so \
	$(HOST_OUT_SHARED_LIBRARIES)/libunwindstack.so \
	$(HOST_OUT_SHARED_LIBRARIES)/libutils.so \
	$(HOST_OUT_SHARED_LIBRARIES)/liblzma.so
	$(HOST_OUT_SHARED_LIBRARIES)/liblzma.so \
	$(HOST_OUT_SHARED_LIBRARIES)/server_configurable_flags.so

LOCAL_target_executables := \
	$(TARGET_OUT_EXECUTABLES)/bluetooth_stack_with_facade
@@ -72,7 +73,8 @@ LOCAL_target_libraries := \
	$(TARGET_OUT_SHARED_LIBRARIES)/libstatslog_bt.so \
	$(TARGET_OUT_SHARED_LIBRARIES)/libunwindstack.so \
	$(TARGET_OUT_SHARED_LIBRARIES)/libutils.so \
	$(TARGET_OUT_SHARED_LIBRARIES)/libz.so
	$(TARGET_OUT_SHARED_LIBRARIES)/libz.so \
	$(TARGET_OUT_SHARED_LIBRARIES)/server_configurable_flags.so
	# libclang_rt.asan-aarch64-android.so is only generated for ASAN build and included automatically
	# on devices
	# $(TARGET_OUT_SHARED_LIBRARIES)/libclang_rt.asan-aarch64-android.so \
+4 −0
Original line number Diff line number Diff line
@@ -305,6 +305,7 @@ cc_binary {
        "libgrpc_wrap",
        "libprotobuf-cpp-full",
        "libunwindstack",
        "server_configurable_flags",
    ],
    target: {
        android: {
@@ -424,12 +425,15 @@ cc_test {
        "libbt_shim_ffi",
        "libc++fs",
        "libchrome",
        "libflagtest",
        "libflatbuffers-cpp",
        "libgmock",
        "libosi",
    ],
    shared_libs: [
        "libbase",
        "libcrypto",
        "server_configurable_flags",
    ],
    sanitize: {
        address: true,
+3 −1
Original line number Diff line number Diff line
@@ -275,7 +275,9 @@ TEST(HciPacketsTest, testLeSetExtendedAdvertisingData) {
  std::vector<uint8_t> advertising_data{
      0x02, 0x01, 0x02, 0x0a, 0x09, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x33, 0x20, 0x58,
  };
  ASSERT_EQ(advertising_data, view.GetAdvertisingData());
  auto payload = view.GetPayload();
  std::vector<uint8_t> payload_data(payload.begin(), payload.end());
  ASSERT_EQ(advertising_data, payload_data);
}

std::vector<uint8_t> le_set_extended_advertising_parameters_set_0{
+211 −50
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
 */
#include "hci/le_advertising_manager.h"

#include <android_bluetooth_flags.h>

#include <iterator>
#include <memory>
#include <mutex>

@@ -32,6 +35,7 @@
#include "os/handler.h"
#include "os/log.h"
#include "os/system_properties.h"
#include "packet/fragmenting_inserter.h"

namespace bluetooth {
namespace hci {
@@ -776,6 +780,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
            module_handler_->BindOnceOn(
                this,
                &impl::check_status_with_id<LeSetAdvertisingParametersCompleteView>,
                true,
                advertiser_id));
      } break;
      case (AdvertisingApiType::ANDROID_HCI): {
@@ -792,7 +797,8 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
                config.filter_policy,
                advertiser_id,
                config.tx_power),
            module_handler_->BindOnceOn(this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, advertiser_id));
            module_handler_->BindOnceOn(
                this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, true, advertiser_id));
      } break;
      case (AdvertisingApiType::EXTENDED): {
        // sid must be in range 0x00 to 0x0F. Since no controller supports more than
@@ -906,10 +912,12 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb

  bool check_extended_advertising_data(std::vector<GapData> data, bool include_flag) {
    uint16_t data_len = 0;
    uint16_t data_limit = IS_FLAG_ENABLED(divide_long_single_gap_data) ? kLeMaximumGapDataLength
                                                                       : kLeMaximumFragmentLength;
    // check data size
    for (size_t i = 0; i < data.size(); i++) {
      if (data[i].size() > kLeMaximumFragmentLength) {
        LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength);
      if (data[i].size() > data_limit) {
        LOG_WARN("AD data len shall not greater than %d", data_limit);
        return false;
      }
      data_len += data[i].size();
@@ -972,31 +980,42 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
          le_advertising_interface_->EnqueueCommand(
              hci::LeSetScanResponseDataBuilder::Create(data),
              module_handler_->BindOnceOn(
                  this, &impl::check_status_with_id<LeSetScanResponseDataCompleteView>, advertiser_id));
                  this,
                  &impl::check_status_with_id<LeSetScanResponseDataCompleteView>,
                  true,
                  advertiser_id));
        } else {
          le_advertising_interface_->EnqueueCommand(
              hci::LeSetAdvertisingDataBuilder::Create(data),
              module_handler_->BindOnceOn(
                  this, &impl::check_status_with_id<LeSetAdvertisingDataCompleteView>, advertiser_id));
                  this,
                  &impl::check_status_with_id<LeSetAdvertisingDataCompleteView>,
                  true,
                  advertiser_id));
        }
      } break;
      case (AdvertisingApiType::ANDROID_HCI): {
        if (set_scan_rsp) {
          le_advertising_interface_->EnqueueCommand(
              hci::LeMultiAdvtSetScanRespBuilder::Create(data, advertiser_id),
              module_handler_->BindOnceOn(this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, advertiser_id));
              module_handler_->BindOnceOn(
                  this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, true, advertiser_id));
        } else {
          le_advertising_interface_->EnqueueCommand(
              hci::LeMultiAdvtSetDataBuilder::Create(data, advertiser_id),
              module_handler_->BindOnceOn(this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, advertiser_id));
              module_handler_->BindOnceOn(
                  this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, true, advertiser_id));
        }
      } break;
      case (AdvertisingApiType::EXTENDED): {
        uint16_t data_len = 0;
        bool divide_gap_flag = IS_FLAG_ENABLED(divide_long_single_gap_data);
        // check data size
        for (size_t i = 0; i < data.size(); i++) {
          if (data[i].size() > kLeMaximumFragmentLength) {
            LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength);
          uint16_t data_limit =
              divide_gap_flag ? kLeMaximumGapDataLength : kLeMaximumFragmentLength;
          if (data[i].size() > data_limit) {
            LOG_WARN("AD data len shall not greater than %d", data_limit);
            if (advertising_callbacks_ != nullptr) {
              if (set_scan_rsp) {
                advertising_callbacks_->OnScanResponseDataSet(
@@ -1034,6 +1053,24 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
          uint16_t sub_data_len = 0;
          Operation operation = Operation::FIRST_FRAGMENT;

          if (divide_gap_flag) {
            std::vector<std::unique_ptr<packet::RawBuilder>> fragments;
            packet::FragmentingInserter it(
                kLeMaximumFragmentLength, std::back_insert_iterator(fragments));
            for (auto gap_data : data) {
              gap_data.Serialize(it);
            }
            it.finalize();

            for (size_t i = 0; i < fragments.size(); i++) {
              send_data_fragment_with_raw_builder(
                  advertiser_id,
                  set_scan_rsp,
                  std::move(fragments[i]),
                  (i == fragments.size() - 1) ? Operation::LAST_FRAGMENT : operation);
              operation = Operation::INTERMEDIATE_FRAGMENT;
            }
          } else {
            for (size_t i = 0; i < data.size(); i++) {
              if (sub_data_len + data[i].size() > kLeMaximumFragmentLength) {
                send_data_fragment(advertiser_id, set_scan_rsp, sub_data, operation);
@@ -1046,23 +1083,56 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
            }
            send_data_fragment(advertiser_id, set_scan_rsp, sub_data, Operation::LAST_FRAGMENT);
          }
        }
      } break;
    }
  }

  void send_data_fragment(
      AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data, Operation operation) {
    if (IS_FLAG_ENABLED(divide_long_single_gap_data)) {
      // For first and intermediate fragment, do not trigger advertising_callbacks_.
      bool send_callback =
          (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT);
      if (set_scan_rsp) {
        le_advertising_interface_->EnqueueCommand(
            hci::LeSetExtendedScanResponseDataBuilder::Create(
                advertiser_id, operation, kFragment_preference, data),
            module_handler_->BindOnceOn(
                this,
                &impl::check_status_with_id<LeSetExtendedScanResponseDataCompleteView>,
                send_callback,
                advertiser_id));
      } else {
        le_advertising_interface_->EnqueueCommand(
            hci::LeSetExtendedAdvertisingDataBuilder::Create(
                advertiser_id, operation, kFragment_preference, data),
            module_handler_->BindOnceOn(
                this,
                &impl::check_status_with_id<LeSetExtendedAdvertisingDataCompleteView>,
                send_callback,
                advertiser_id));
      }
    } else {
      if (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT) {
        if (set_scan_rsp) {
          le_advertising_interface_->EnqueueCommand(
            hci::LeSetExtendedScanResponseDataBuilder::Create(advertiser_id, operation, kFragment_preference, data),
              hci::LeSetExtendedScanResponseDataBuilder::Create(
                  advertiser_id, operation, kFragment_preference, data),
              module_handler_->BindOnceOn(
                this, &impl::check_status_with_id<LeSetExtendedScanResponseDataCompleteView>, advertiser_id));
                  this,
                  &impl::check_status_with_id<LeSetExtendedScanResponseDataCompleteView>,
                  true,
                  advertiser_id));
        } else {
          le_advertising_interface_->EnqueueCommand(
            hci::LeSetExtendedAdvertisingDataBuilder::Create(advertiser_id, operation, kFragment_preference, data),
              hci::LeSetExtendedAdvertisingDataBuilder::Create(
                  advertiser_id, operation, kFragment_preference, data),
              module_handler_->BindOnceOn(
                this, &impl::check_status_with_id<LeSetExtendedAdvertisingDataCompleteView>, advertiser_id));
                  this,
                  &impl::check_status_with_id<LeSetExtendedAdvertisingDataCompleteView>,
                  true,
                  advertiser_id));
        }
      } else {
        // For first and intermediate fragment, do not trigger advertising_callbacks_.
@@ -1079,6 +1149,36 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
        }
      }
    }
  }

  void send_data_fragment_with_raw_builder(
      AdvertiserId advertiser_id,
      bool set_scan_rsp,
      std::unique_ptr<packet::RawBuilder> data,
      Operation operation) {
    // For first and intermediate fragment, do not trigger advertising_callbacks_.
    bool send_callback =
        (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT);
    if (set_scan_rsp) {
      le_advertising_interface_->EnqueueCommand(
          hci::LeSetExtendedScanResponseDataRawBuilder::Create(
              advertiser_id, operation, kFragment_preference, std::move(data)),
          module_handler_->BindOnceOn(
              this,
              &impl::check_status_with_id<LeSetExtendedScanResponseDataCompleteView>,
              send_callback,
              advertiser_id));
    } else {
      le_advertising_interface_->EnqueueCommand(
          hci::LeSetExtendedAdvertisingDataRawBuilder::Create(
              advertiser_id, operation, kFragment_preference, std::move(data)),
          module_handler_->BindOnceOn(
              this,
              &impl::check_status_with_id<LeSetExtendedAdvertisingDataCompleteView>,
              send_callback,
              advertiser_id));
    }
  }

  void enable_advertiser(
      AdvertiserId advertiser_id, bool enable, uint16_t duration, uint8_t max_extended_advertising_events) {
@@ -1155,15 +1255,18 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
        module_handler_->BindOnceOn(
            this,
            &impl::check_status_with_id<LeSetPeriodicAdvertisingParametersCompleteView>,
            true,
            advertiser_id));
  }

  void set_periodic_data(AdvertiserId advertiser_id, std::vector<GapData> data) {
    uint16_t data_len = 0;
    bool divide_gap_flag = IS_FLAG_ENABLED(divide_long_single_gap_data);
    // check data size
    for (size_t i = 0; i < data.size(); i++) {
      if (data[i].size() > kLeMaximumFragmentLength) {
        LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength);
      uint16_t data_limit = divide_gap_flag ? kLeMaximumGapDataLength : kLeMaximumFragmentLength;
      if (data[i].size() > data_limit) {
        LOG_WARN("AD data len shall not greater than %d", data_limit);
        if (advertising_callbacks_ != nullptr) {
          advertising_callbacks_->OnPeriodicAdvertisingDataSet(
              advertiser_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
@@ -1183,13 +1286,32 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
      return;
    }

    if (data_len <= kLeMaximumFragmentLength) {
    uint16_t data_fragment_limit =
        divide_gap_flag ? kLeMaximumPeriodicDataFragmentLength : kLeMaximumFragmentLength;
    if (data_len <= data_fragment_limit) {
      send_periodic_data_fragment(advertiser_id, data, Operation::COMPLETE_ADVERTISEMENT);
    } else {
      std::vector<GapData> sub_data;
      uint16_t sub_data_len = 0;
      Operation operation = Operation::FIRST_FRAGMENT;

      if (divide_gap_flag) {
        std::vector<std::unique_ptr<packet::RawBuilder>> fragments;
        packet::FragmentingInserter it(
            kLeMaximumPeriodicDataFragmentLength, std::back_insert_iterator(fragments));
        for (auto gap_data : data) {
          gap_data.Serialize(it);
        }
        it.finalize();

        for (size_t i = 0; i < fragments.size(); i++) {
          send_periodic_data_fragment_with_raw_builder(
              advertiser_id,
              std::move(fragments[i]),
              (i == fragments.size() - 1) ? Operation::LAST_FRAGMENT : operation);
          operation = Operation::INTERMEDIATE_FRAGMENT;
        }
      } else {
        for (size_t i = 0; i < data.size(); i++) {
          if (sub_data_len + data[i].size() > kLeMaximumFragmentLength) {
            send_periodic_data_fragment(advertiser_id, sub_data, operation);
@@ -1203,13 +1325,29 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
        send_periodic_data_fragment(advertiser_id, sub_data, Operation::LAST_FRAGMENT);
      }
    }
  }

  void send_periodic_data_fragment(AdvertiserId advertiser_id, std::vector<GapData> data, Operation operation) {
    if (IS_FLAG_ENABLED(divide_long_single_gap_data)) {
      // For first and intermediate fragment, do not trigger advertising_callbacks_.
      bool send_callback =
          (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT);
      le_advertising_interface_->EnqueueCommand(
          hci::LeSetPeriodicAdvertisingDataBuilder::Create(advertiser_id, operation, data),
          module_handler_->BindOnceOn(
              this,
              &impl::check_status_with_id<LeSetPeriodicAdvertisingDataCompleteView>,
              send_callback,
              advertiser_id));
    } else {
      if (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT) {
        le_advertising_interface_->EnqueueCommand(
            hci::LeSetPeriodicAdvertisingDataBuilder::Create(advertiser_id, operation, data),
            module_handler_->BindOnceOn(
              this, &impl::check_status_with_id<LeSetPeriodicAdvertisingDataCompleteView>, advertiser_id));
                this,
                &impl::check_status_with_id<LeSetPeriodicAdvertisingDataCompleteView>,
                true,
                advertiser_id));
      } else {
        // For first and intermediate fragment, do not trigger advertising_callbacks_.
        le_advertising_interface_->EnqueueCommand(
@@ -1217,6 +1355,22 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
            module_handler_->BindOnce(check_complete<LeSetPeriodicAdvertisingDataCompleteView>));
      }
    }
  }

  void send_periodic_data_fragment_with_raw_builder(
      AdvertiserId advertiser_id, std::unique_ptr<packet::RawBuilder> data, Operation operation) {
    // For first and intermediate fragment, do not trigger advertising_callbacks_.
    bool send_callback =
        (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT);
    le_advertising_interface_->EnqueueCommand(
        hci::LeSetPeriodicAdvertisingDataRawBuilder::Create(
            advertiser_id, operation, std::move(data)),
        module_handler_->BindOnceOn(
            this,
            &impl::check_status_with_id<LeSetPeriodicAdvertisingDataCompleteView>,
            send_callback,
            advertiser_id));
  }

  void enable_periodic_advertising(AdvertiserId advertiser_id, bool enable, bool include_adi) {
    if (!controller_->SupportsBlePeriodicAdvertising()) {
@@ -1552,7 +1706,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
  }

  template <class View>
  void check_status_with_id(AdvertiserId id, CommandCompleteView view) {
  void check_status_with_id(bool send_callback, AdvertiserId id, CommandCompleteView view) {
    ASSERT(view.IsValid());
    auto status_view = View::Create(view);
    ASSERT(status_view.IsValid());
@@ -1574,6 +1728,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
      return;
    }

    if (IS_FLAG_ENABLED(divide_long_single_gap_data)) {
      // Do not trigger callback if send_callback is false
      if (!send_callback) {
        return;
      }
    }

    OpCode opcode = view.GetCommandOpCode();

    switch (opcode) {
Loading