OSDN Git Service

gd: implement APIs of Advertising for Android HCI
authorChienyuan <chienyuanhuang@google.com>
Thu, 3 Dec 2020 08:41:01 +0000 (16:41 +0800)
committerChienyuan <chienyuanhuang@google.com>
Thu, 3 Dec 2020 08:43:42 +0000 (16:43 +0800)
Tag: #gd-refactor
Bug: 169125803
Test: cert/run --host
Test: atest --host bluetooth_test_gd
Change-Id: Iddb9d4838f1fde7f151bd491a3a3ffd3bebf2cdf

gd/hci/le_advertising_manager.cc
gd/hci/le_advertising_manager_test.cc

index 9b5665e..09ef9e5 100644 (file)
@@ -270,14 +270,16 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
         le_advertising_interface_->EnqueueCommand(
             hci::LeMultiAdvtSetRandomAddrBuilder::Create(advertising_sets_[id].current_address.GetAddress(), id),
             module_handler_->BindOnce(impl::check_status<LeMultiAdvtCompleteView>));
+        EnabledSet curr_set;
+        curr_set.advertising_handle_ = id;
+        enabled_sets_[id] = curr_set;
         if (!paused) {
+          std::vector<EnabledSet> enabled_sets = {curr_set};
           le_advertising_interface_->EnqueueCommand(
               hci::LeMultiAdvtSetEnableBuilder::Create(Enable::ENABLED, id),
-              module_handler_->BindOnce(impl::check_status<LeMultiAdvtCompleteView>));
+              module_handler_->BindOnceOn(
+                  this, &impl::on_set_advertising_enable_complete<LeMultiAdvtCompleteView>, true, enabled_sets));
         }
-        EnabledSet curr_set;
-        curr_set.advertising_handle_ = id;
-        enabled_sets_[id] = curr_set;
       } break;
       case (AdvertisingApiType::EXTENDED): {
         LOG_WARN("Unexpected AdvertisingApiType EXTENDED");
@@ -468,7 +470,19 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
                 this, &impl::check_status_with_id<LeSetAdvertisingParametersCompleteView>, advertiser_id));
       } break;
       case (AdvertisingApiType::ANDROID_HCI): {
-        // TODO
+        le_advertising_interface_->EnqueueCommand(
+            hci::LeMultiAdvtParamBuilder::Create(
+                config.interval_min,
+                config.interval_max,
+                config.advertising_type,
+                config.own_address_type,
+                config.peer_address_type,
+                config.peer_address,
+                config.channel_map,
+                config.filter_policy,
+                advertiser_id,
+                config.tx_power),
+            module_handler_->BindOnceOn(this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, advertiser_id));
       } break;
       case (AdvertisingApiType::EXTENDED): {
         // sid must be in range 0x00 to 0x0F. Since no controller supports more than
@@ -561,7 +575,15 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
         }
       } break;
       case (AdvertisingApiType::ANDROID_HCI): {
-        // TODO
+        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));
+        } else {
+          le_advertising_interface_->EnqueueCommand(
+              hci::LeMultiAdvtSetDataBuilder::Create(data, advertiser_id),
+              module_handler_->BindOnceOn(this, &impl::check_status_with_id<LeMultiAdvtCompleteView>, advertiser_id));
+        }
       } break;
       case (AdvertisingApiType::EXTENDED): {
         uint16_t data_len = 0;
@@ -661,7 +683,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
     switch (advertising_api_type_) {
       case (AdvertisingApiType::LEGACY): {
         le_advertising_interface_->EnqueueCommand(
-            hci::LeSetAdvertisingEnableBuilder::Create(Enable::DISABLED),
+            hci::LeSetAdvertisingEnableBuilder::Create(enable_value),
             module_handler_->BindOnceOn(
                 this,
                 &impl::on_set_advertising_enable_complete<LeSetAdvertisingEnableCompleteView>,
@@ -669,7 +691,10 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
                 enabled_sets));
       } break;
       case (AdvertisingApiType::ANDROID_HCI): {
-        // TODO
+        le_advertising_interface_->EnqueueCommand(
+            hci::LeMultiAdvtSetEnableBuilder::Create(enable_value, advertiser_id),
+            module_handler_->BindOnceOn(
+                this, &impl::on_set_advertising_enable_complete<LeMultiAdvtCompleteView>, enable, enabled_sets));
       } break;
       case (AdvertisingApiType::EXTENDED): {
         le_advertising_interface_->EnqueueCommand(
@@ -994,6 +1019,25 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
       case OpCode::LE_SET_PERIODIC_ADVERTISING_DATA:
         advertising_callbacks_->OnPeriodicAdvertisingDataSet(id, advertising_status);
         break;
+      case OpCode::LE_MULTI_ADVT: {
+        auto command_view = LeMultiAdvtCompleteView::Create(view);
+        ASSERT(command_view.IsValid());
+        auto sub_opcode = command_view.GetSubCmd();
+        switch (sub_opcode) {
+          case SubOcf::SET_PARAM:
+            advertising_callbacks_->OnAdvertisingParametersUpdated(
+                id, le_physical_channel_tx_power_, advertising_status);
+            break;
+          case SubOcf::SET_DATA:
+            advertising_callbacks_->OnAdvertisingDataSet(id, advertising_status);
+            break;
+          case SubOcf::SET_SCAN_RESP:
+            advertising_callbacks_->OnScanResponseDataSet(id, advertising_status);
+            break;
+          default:
+            LOG_WARN("Unexpected sub event type %s", SubOcfText(command_view.GetSubCmd()).c_str());
+        }
+      } break;
       default:
         LOG_WARN("Unexpected event type %s", OpCodeText(view.GetCommandOpCode()).c_str());
     }
index 5f45a6e..7fc77fb 100644 (file)
@@ -131,12 +131,12 @@ class TestHciLayer : public HciLayer {
     }
   }
 
-  std::future<size_t> GetSubCommandFuture(SubOcf sub_ocf) {
+  void SetSubCommandFuture(SubOcf sub_ocf) {
     ASSERT_LOG(command_promise_ == nullptr, "Promises promises ... Only one at a time");
     command_op_code_ = OpCode::LE_MULTI_ADVT;
     command_sub_ocf_ = sub_ocf;
     command_promise_ = std::make_unique<std::promise<size_t>>();
-    return command_promise_->get_future();
+    command_future_ = std::make_unique<std::future<size_t>>(command_promise_->get_future());
   }
 
   ConnectionManagementCommandView GetCommandPacket(OpCode op_code) {
@@ -436,6 +436,54 @@ class LeAndroidHciAdvertisingManagerTest : public LeAdvertisingManagerTest {
   }
 };
 
+class LeAndroidHciAdvertisingAPITest : public LeAndroidHciAdvertisingManagerTest {
+ protected:
+  void SetUp() override {
+    LeAndroidHciAdvertisingManagerTest::SetUp();
+
+    ExtendedAdvertisingConfig advertising_config{};
+    advertising_config.advertising_type = AdvertisingType::ADV_IND;
+    advertising_config.own_address_type = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
+    std::vector<GapData> gap_data{};
+    GapData data_item{};
+    data_item.data_type_ = GapDataType::FLAGS;
+    data_item.data_ = {0x34};
+    gap_data.push_back(data_item);
+    data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
+    data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
+    gap_data.push_back(data_item);
+    advertising_config.advertisement = gap_data;
+    advertising_config.scan_response = gap_data;
+
+    test_hci_layer_->SetSubCommandFuture(SubOcf::SET_PARAM);
+    advertiser_id_ = le_advertising_manager_->ExtendedCreateAdvertiser(
+        0x00, advertising_config, scan_callback, set_terminated_callback, client_handler_);
+    ASSERT_NE(LeAdvertisingManager::kInvalidId, advertiser_id_);
+    std::vector<SubOcf> sub_ocf = {
+        SubOcf::SET_PARAM,
+        SubOcf::SET_DATA,
+        SubOcf::SET_SCAN_RESP,
+        SubOcf::SET_RANDOM_ADDR,
+        SubOcf::SET_ENABLE,
+    };
+    EXPECT_CALL(
+        mock_advertising_callback_,
+        OnAdvertisingSetStarted(0, advertiser_id_, 0, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+    for (size_t i = 0; i < sub_ocf.size(); i++) {
+      auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT);
+      auto sub_packet = LeMultiAdvtView::Create(LeAdvertisingCommandView::Create(packet));
+      ASSERT_TRUE(sub_packet.IsValid());
+      test_hci_layer_->IncomingEvent(LeMultiAdvtCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, sub_ocf[i]));
+      if ((i + 1) < sub_ocf.size()) {
+        test_hci_layer_->SetSubCommandFuture(sub_ocf[i + 1]);
+      }
+    }
+    sync_client_handler();
+  }
+
+  AdvertiserId advertiser_id_;
+};
+
 class LeExtendedAdvertisingManagerTest : public LeAdvertisingManagerTest {
  protected:
   void SetUp() override {
@@ -573,30 +621,32 @@ TEST_F(LeAndroidHciAdvertisingManagerTest, create_advertiser_test) {
   advertising_config.advertisement = gap_data;
   advertising_config.scan_response = gap_data;
 
-  auto next_command_future = test_hci_layer_->GetSubCommandFuture(SubOcf::SET_ENABLE);
+  test_hci_layer_->SetSubCommandFuture(SubOcf::SET_PARAM);
   auto id = le_advertising_manager_->ExtendedCreateAdvertiser(
       0x00, advertising_config, scan_callback, set_terminated_callback, client_handler_);
   ASSERT_NE(LeAdvertisingManager::kInvalidId, id);
   std::vector<SubOcf> sub_ocf = {
       SubOcf::SET_PARAM, SubOcf::SET_DATA, SubOcf::SET_SCAN_RESP, SubOcf::SET_RANDOM_ADDR, SubOcf::SET_ENABLE,
   };
-  auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
-  ASSERT_EQ(std::future_status::ready, result);
-  size_t num_commands = next_command_future.get();
+  EXPECT_CALL(
+      mock_advertising_callback_, OnAdvertisingSetStarted(0, id, 0, AdvertisingCallback::AdvertisingStatus::SUCCESS));
   for (size_t i = 0; i < sub_ocf.size(); i++) {
     auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT);
     auto sub_packet = LeMultiAdvtView::Create(LeAdvertisingCommandView::Create(packet));
     ASSERT_TRUE(sub_packet.IsValid());
     test_hci_layer_->IncomingEvent(LeMultiAdvtCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, sub_ocf[i]));
-    num_commands -= 1;
+    if ((i + 1) < sub_ocf.size()) {
+      test_hci_layer_->SetSubCommandFuture(sub_ocf[i + 1]);
+    }
   }
-  ASSERT_EQ(0, num_commands);
+  sync_client_handler();
+
   // Disable the advertiser
-  next_command_future = test_hci_layer_->GetSubCommandFuture(SubOcf::SET_ENABLE);
+  test_hci_layer_->SetSubCommandFuture(SubOcf::SET_ENABLE);
   le_advertising_manager_->RemoveAdvertiser(id);
-  result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
-  ASSERT_EQ(std::future_status::ready, result);
+  test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT);
   test_hci_layer_->IncomingEvent(LeMultiAdvtSetEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+  sync_client_handler();
 }
 
 TEST_F(LeExtendedAdvertisingManagerTest, create_advertiser_test) {
@@ -657,6 +707,8 @@ TEST_F(LeExtendedAdvertisingManagerTest, create_advertiser_test) {
 
 TEST_F(LeAdvertisingAPITest, startup_teardown) {}
 
+TEST_F(LeAndroidHciAdvertisingAPITest, startup_teardown) {}
+
 TEST_F(LeExtendedAdvertisingAPITest, startup_teardown) {}
 
 TEST_F(LeAdvertisingAPITest, set_parameter) {
@@ -680,6 +732,27 @@ TEST_F(LeAdvertisingAPITest, set_parameter) {
   sync_client_handler();
 }
 
+TEST_F(LeAndroidHciAdvertisingAPITest, set_parameter) {
+  ExtendedAdvertisingConfig advertising_config{};
+  advertising_config.advertising_type = AdvertisingType::ADV_IND;
+  advertising_config.own_address_type = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
+  std::vector<GapData> gap_data{};
+  GapData data_item{};
+  data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
+  data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
+  gap_data.push_back(data_item);
+  advertising_config.advertisement = gap_data;
+  advertising_config.channel_map = 1;
+  test_hci_layer_->SetSubCommandFuture(SubOcf::SET_PARAM);
+  le_advertising_manager_->SetParameters(advertiser_id_, advertising_config);
+  test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnAdvertisingParametersUpdated(advertiser_id_, 0x00, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(LeMultiAdvtCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, SubOcf::SET_PARAM));
+  sync_client_handler();
+}
+
 TEST_F(LeExtendedAdvertisingAPITest, set_parameter) {
   ExtendedAdvertisingConfig advertising_config{};
   advertising_config.advertising_type = AdvertisingType::ADV_IND;
@@ -769,6 +842,39 @@ TEST_F(LeExtendedAdvertisingAPITest, set_data_test) {
   sync_client_handler();
 }
 
+TEST_F(LeAndroidHciAdvertisingAPITest, set_data_test) {
+  // Set advertising data
+  std::vector<GapData> advertising_data{};
+  GapData data_item{};
+  data_item.data_type_ = GapDataType::TX_POWER_LEVEL;
+  data_item.data_ = {0x00};
+  advertising_data.push_back(data_item);
+  test_hci_layer_->SetSubCommandFuture(SubOcf::SET_DATA);
+  le_advertising_manager_->SetData(advertiser_id_, false, advertising_data);
+  test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnAdvertisingDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(LeMultiAdvtCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, SubOcf::SET_DATA));
+  sync_client_handler();
+
+  // Set scan response data
+  std::vector<GapData> response_data{};
+  GapData data_item2{};
+  data_item2.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
+  data_item2.data_ = {'t', 'e', 's', 't', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
+  response_data.push_back(data_item2);
+  test_hci_layer_->SetSubCommandFuture(SubOcf::SET_SCAN_RESP);
+  le_advertising_manager_->SetData(advertiser_id_, true, response_data);
+  test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnScanResponseDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(
+      LeMultiAdvtCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, SubOcf::SET_SCAN_RESP));
+  sync_client_handler();
+}
+
 TEST_F(LeExtendedAdvertisingAPITest, set_data_fragments_test) {
   // Set advertising data
   std::vector<GapData> advertising_data{};
@@ -921,6 +1027,30 @@ TEST_F(LeAdvertisingAPITest, disable_enable_advertiser_test) {
   sync_client_handler();
 }
 
+TEST_F(LeAndroidHciAdvertisingAPITest, disable_enable_advertiser_test) {
+  // disable advertiser
+  test_hci_layer_->SetSubCommandFuture(SubOcf::SET_ENABLE);
+  le_advertising_manager_->EnableAdvertiser(advertiser_id_, false, 0x00, 0x00);
+  test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnAdvertisingEnabled(advertiser_id_, false, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(
+      LeMultiAdvtCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, SubOcf::SET_ENABLE));
+  sync_client_handler();
+
+  // enable advertiser
+  test_hci_layer_->SetSubCommandFuture(SubOcf::SET_ENABLE);
+  le_advertising_manager_->EnableAdvertiser(advertiser_id_, true, 0x00, 0x00);
+  test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnAdvertisingEnabled(advertiser_id_, true, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(
+      LeMultiAdvtCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, SubOcf::SET_ENABLE));
+  sync_client_handler();
+}
+
 TEST_F(LeExtendedAdvertisingAPITest, disable_enable_advertiser_test) {
   // disable advertiser
   test_hci_layer_->SetCommandFuture();