OSDN Git Service

gd: implement APIs of Advertising for Legacy
authorChienyuan <chienyuanhuang@google.com>
Tue, 24 Nov 2020 11:54:14 +0000 (19:54 +0800)
committerChienyuan <chienyuanhuang@google.com>
Tue, 24 Nov 2020 11:58:40 +0000 (19:58 +0800)
Tag: #gd-refactor
Bug: 169125803
Test: cert/run --host
Test: atest --host bluetooth_test_gd
Change-Id: I317b75c93619f99df6ff40b46fbb44c23e21f437

gd/hci/le_advertising_manager.cc
gd/hci/le_advertising_manager_test.cc
main/shim/hci_layer.cc

index 13c7901..046440c 100644 (file)
@@ -451,7 +451,18 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
   void set_parameters(AdvertiserId advertiser_id, ExtendedAdvertisingConfig config) {
     switch (advertising_api_type_) {
       case (AdvertisingApiType::LEGACY): {
-        // TODO
+        le_advertising_interface_->EnqueueCommand(
+            hci::LeSetAdvertisingParametersBuilder::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),
+            module_handler_->BindOnceOn(
+                this, &impl::check_status_with_id<LeSetAdvertisingParametersCompleteView>, advertiser_id));
       } break;
       case (AdvertisingApiType::ANDROID_HCI): {
         // TODO
@@ -534,7 +545,17 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
   void set_data(AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data) {
     switch (advertising_api_type_) {
       case (AdvertisingApiType::LEGACY): {
-        // TODO
+        if (set_scan_rsp) {
+          le_advertising_interface_->EnqueueCommand(
+              hci::LeSetScanResponseDataBuilder::Create(data),
+              module_handler_->BindOnceOn(
+                  this, &impl::check_status_with_id<LeSetScanResponseDataCompleteView>, advertiser_id));
+        } else {
+          le_advertising_interface_->EnqueueCommand(
+              hci::LeSetAdvertisingDataBuilder::Create(data),
+              module_handler_->BindOnceOn(
+                  this, &impl::check_status_with_id<LeSetAdvertisingDataCompleteView>, advertiser_id));
+        }
       } break;
       case (AdvertisingApiType::ANDROID_HCI): {
         // TODO
@@ -636,7 +657,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
 
     switch (advertising_api_type_) {
       case (AdvertisingApiType::LEGACY): {
-        // TODO
+        le_advertising_interface_->EnqueueCommand(
+            hci::LeSetAdvertisingEnableBuilder::Create(Enable::DISABLED),
+            module_handler_->BindOnceOn(
+                this,
+                &impl::on_set_advertising_enable_complete<LeSetAdvertisingEnableCompleteView>,
+                enable,
+                enabled_sets));
       } break;
       case (AdvertisingApiType::ANDROID_HCI): {
         // TODO
@@ -826,11 +853,20 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
       return;
     }
     for (EnabledSet enabled_set : enabled_sets) {
+      bool started = advertising_sets_[enabled_set.advertising_handle_].started;
       uint8_t id = enabled_set.advertising_handle_;
       if (id == kInvalidHandle) {
         continue;
       }
-      advertising_callbacks_->OnAdvertisingEnabled(id, enable, advertising_status);
+
+      if (started) {
+        advertising_callbacks_->OnAdvertisingEnabled(id, enable, advertising_status);
+      } else {
+        int reg_id = id_map_[id];
+        advertising_sets_[enabled_set.advertising_handle_].started = true;
+        // TODO read tx power
+        advertising_callbacks_->OnAdvertisingSetStarted(reg_id, id, 0x00, advertising_status);
+      }
     }
   }
 
@@ -928,6 +964,10 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
     OpCode opcode = view.GetCommandOpCode();
 
     switch (opcode) {
+      case OpCode::LE_SET_ADVERTISING_PARAMETERS:
+        // TODO read tx power
+        advertising_callbacks_->OnAdvertisingParametersUpdated(id, 0x00, advertising_status);
+        break;
       case OpCode::LE_SET_ADVERTISING_DATA:
       case OpCode::LE_SET_EXTENDED_ADVERTISING_DATA:
         advertising_callbacks_->OnAdvertisingDataSet(id, advertising_status);
index 97ccc79..5789fd5 100644 (file)
@@ -354,6 +354,55 @@ class LeAdvertisingManagerTest : public ::testing::Test {
   } mock_advertising_callback_;
 };
 
+class LeAdvertisingAPITest : public LeAdvertisingManagerTest {
+ protected:
+  void SetUp() override {
+    LeAdvertisingManagerTest::SetUp();
+
+    // start advertising set
+    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;
+
+    auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_ENABLE);
+    advertiser_id_ = le_advertising_manager_->ExtendedCreateAdvertiser(
+        0x00, advertising_config, scan_callback, set_terminated_callback, client_handler_);
+    ASSERT_NE(LeAdvertisingManager::kInvalidId, advertiser_id_);
+    EXPECT_CALL(
+        mock_advertising_callback_,
+        OnAdvertisingSetStarted(0x00, advertiser_id_, 0x00, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+    std::vector<OpCode> adv_opcodes = {
+        OpCode::LE_SET_ADVERTISING_PARAMETERS,
+        OpCode::LE_SET_SCAN_RESPONSE_DATA,
+        OpCode::LE_SET_ADVERTISING_DATA,
+        OpCode::LE_SET_ADVERTISING_ENABLE,
+    };
+    auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+    std::vector<uint8_t> success_vector{static_cast<uint8_t>(ErrorCode::SUCCESS)};
+    ASSERT_EQ(std::future_status::ready, result);
+    for (size_t i = 0; i < adv_opcodes.size(); i++) {
+      auto packet_view = test_hci_layer_->GetCommandPacket(adv_opcodes[i]);
+      CommandPacketView command_packet_view = CommandPacketView::Create(packet_view);
+      auto command = ConnectionManagementCommandView::Create(AclCommandView::Create(command_packet_view));
+      test_hci_layer_->IncomingEvent(
+          CommandCompleteBuilder::Create(uint8_t{1}, adv_opcodes[i], std::make_unique<RawBuilder>(success_vector)));
+    }
+    sync_client_handler();
+  }
+
+  AdvertiserId advertiser_id_;
+};
+
 class LeAndroidHciAdvertisingManagerTest : public LeAdvertisingManagerTest {
  protected:
   void SetUp() override {
@@ -460,7 +509,8 @@ TEST_F(LeAdvertisingManagerTest, create_advertiser_test) {
       OpCode::LE_SET_ADVERTISING_ENABLE,
   };
   EXPECT_CALL(
-      mock_advertising_callback_, OnAdvertisingEnabled(id, true, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+      mock_advertising_callback_,
+      OnAdvertisingSetStarted(0x00, id, 0x00, AdvertisingCallback::AdvertisingStatus::SUCCESS));
 
   std::vector<uint8_t> success_vector{static_cast<uint8_t>(ErrorCode::SUCCESS)};
   auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
@@ -578,8 +628,32 @@ TEST_F(LeExtendedAdvertisingManagerTest, create_advertiser_test) {
   sync_client_handler();
 }
 
+TEST_F(LeAdvertisingAPITest, startup_teardown) {}
+
 TEST_F(LeExtendedAdvertisingAPITest, startup_teardown) {}
 
+TEST_F(LeAdvertisingAPITest, 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;
+  le_advertising_manager_->SetParameters(advertiser_id_, advertising_config);
+  auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_PARAMETERS);
+  auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+  ASSERT_EQ(std::future_status::ready, result);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnAdvertisingParametersUpdated(advertiser_id_, 0x00, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(LeSetAdvertisingParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+  sync_client_handler();
+}
+
 TEST_F(LeExtendedAdvertisingAPITest, set_parameter) {
   ExtendedAdvertisingConfig advertising_config{};
   advertising_config.advertising_type = AdvertisingType::ADV_IND;
@@ -605,6 +679,40 @@ TEST_F(LeExtendedAdvertisingAPITest, set_parameter) {
   sync_client_handler();
 }
 
+TEST_F(LeAdvertisingAPITest, 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);
+  le_advertising_manager_->SetData(advertiser_id_, false, advertising_data);
+  auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_DATA);
+  auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+  ASSERT_EQ(std::future_status::ready, result);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnAdvertisingDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(LeSetAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+  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);
+  le_advertising_manager_->SetData(advertiser_id_, true, response_data);
+  last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_SCAN_RESPONSE_DATA);
+  result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+  ASSERT_EQ(std::future_status::ready, result);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnScanResponseDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(LeSetScanResponseDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+  sync_client_handler();
+}
+
 TEST_F(LeExtendedAdvertisingAPITest, set_data_test) {
   // Set advertising data
   std::vector<GapData> advertising_data{};
@@ -723,7 +831,7 @@ TEST_F(LeExtendedAdvertisingAPITest, set_scan_response_fragments_test) {
   sync_client_handler();
 }
 
-TEST_F(LeExtendedAdvertisingAPITest, send_data_with_invalid_ad_structure) {
+TEST_F(LeExtendedAdvertisingAPITest, set_data_with_invalid_ad_structure) {
   // Set advertising data with AD structure that length greater than 251
   std::vector<GapData> advertising_data{};
   GapData data_item{};
@@ -749,7 +857,7 @@ TEST_F(LeExtendedAdvertisingAPITest, send_data_with_invalid_ad_structure) {
   sync_client_handler();
 }
 
-TEST_F(LeExtendedAdvertisingAPITest, send_data_with_invalid_length) {
+TEST_F(LeExtendedAdvertisingAPITest, set_data_with_invalid_length) {
   // Set advertising data with data that greater than le_maximum_advertising_data_length_
   std::vector<GapData> advertising_data{};
   for (uint8_t i = 0; i < 10; i++) {
@@ -776,6 +884,30 @@ TEST_F(LeExtendedAdvertisingAPITest, send_data_with_invalid_length) {
   sync_client_handler();
 }
 
+TEST_F(LeAdvertisingAPITest, disable_enable_advertiser_test) {
+  // disable advertiser
+  le_advertising_manager_->EnableAdvertiser(advertiser_id_, false, 0x00, 0x00);
+  auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_ENABLE);
+  auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+  ASSERT_EQ(std::future_status::ready, result);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnAdvertisingEnabled(advertiser_id_, false, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(LeSetAdvertisingEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+  sync_client_handler();
+
+  // enable advertiser
+  le_advertising_manager_->EnableAdvertiser(advertiser_id_, true, 0x00, 0x00);
+  last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_ENABLE);
+  result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+  ASSERT_EQ(std::future_status::ready, result);
+  EXPECT_CALL(
+      mock_advertising_callback_,
+      OnAdvertisingEnabled(advertiser_id_, true, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+  test_hci_layer_->IncomingEvent(LeSetAdvertisingEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+  sync_client_handler();
+}
+
 TEST_F(LeExtendedAdvertisingAPITest, disable_enable_advertiser_test) {
   // disable advertiser
   le_advertising_manager_->EnableAdvertiser(advertiser_id_, false, 0x00, 0x00);
index 9a8b11b..a6816ac 100644 (file)
@@ -266,11 +266,13 @@ static bool subevent_already_registered_in_le_hci_layer(
     case bluetooth::hci::SubeventCode::PHY_UPDATE_COMPLETE:
     case bluetooth::hci::SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST:
       return bluetooth::shim::is_gd_acl_enabled() ||
-             bluetooth::shim::is_gd_l2cap_enabled();
+             bluetooth::shim::is_gd_l2cap_enabled() ||
+             bluetooth::shim::is_gd_advertising_enabled();
     case bluetooth::hci::SubeventCode::ADVERTISING_SET_TERMINATED:
     case bluetooth::hci::SubeventCode::SCAN_REQUEST_RECEIVED:
       return bluetooth::shim::is_gd_acl_enabled() ||
-             bluetooth::shim::is_gd_l2cap_enabled();
+             bluetooth::shim::is_gd_l2cap_enabled() ||
+             bluetooth::shim::is_gd_advertising_enabled();
     case bluetooth::hci::SubeventCode::ADVERTISING_REPORT:
     case bluetooth::hci::SubeventCode::DIRECTED_ADVERTISING_REPORT:
     case bluetooth::hci::SubeventCode::EXTENDED_ADVERTISING_REPORT: