OSDN Git Service

gd: add shim layer for LE advertising manager
authorChienyuan <chienyuanhuang@google.com>
Tue, 15 Sep 2020 12:05:42 +0000 (20:05 +0800)
committerChienyuan <chienyuanhuang@google.com>
Wed, 16 Sep 2020 08:01:30 +0000 (16:01 +0800)
Tag: #refactor
Bug: 159815595
Test: manual
Change-Id: Ib969d1ffe17c97b326d5553da3b054461e1039af

btif/src/btif_ble_advertiser.cc
gd/common/init_flags.cc
main/shim/Android.bp
main/shim/hci_layer.cc
main/shim/le_advertising_manager.cc [new file with mode: 0644]
main/shim/le_advertising_manager.h [new file with mode: 0644]
main/shim/shim.cc
main/shim/stack.cc

index d1923bd..8a57731 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "ble_advertiser.h"
 #include "btif_common.h"
+#include "main/shim/le_advertising_manager.h"
+#include "main/shim/shim.h"
 #include "stack/include/btu.h"
 
 using base::Bind;
@@ -253,8 +255,12 @@ BleAdvertiserInterface* btLeAdvertiserInstance = nullptr;
 }  // namespace
 
 BleAdvertiserInterface* get_ble_advertiser_instance() {
-  if (btLeAdvertiserInstance == nullptr)
+  if (bluetooth::shim::is_gd_advertising_enabled()) {
+    LOG(INFO) << __func__ << " use gd le advertiser";
+    return bluetooth::shim::get_ble_advertiser_instance();
+  } else if (btLeAdvertiserInstance == nullptr) {
     btLeAdvertiserInstance = new BleAdvertiserInterfaceImpl();
+  }
 
   return btLeAdvertiserInstance;
 }
index ea5a1f1..fdb732c 100644 (file)
@@ -52,7 +52,8 @@ void InitFlags::Load(const char** flags) {
     if (kGdCoreFlag == *flags) {
       gd_core_enabled = true;
     } else if (kGdAdvertisingFlag == *flags) {
-      gd_advertising_enabled = true;
+      // TODO enable when module ready
+      // gd_advertising_enabled = true;
     } else if (kGdSecurityFlag == *flags) {
       gd_security_enabled = true;
     } else if (kGdAclFlag == *flags) {
index 9e6624e..ceac7a6 100644 (file)
@@ -12,6 +12,7 @@ filegroup {
         "hci_layer.cc",
         "l2c_api.cc",
         "l2cap.cc",
+        "le_advertising_manager.cc",
         "shim.cc",
         "stack.cc",
     ]
index b50b385..dff6cc7 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "hci/hci_packets.h"
 #include "hci/include/packet_fragmenter.h"
+#include "hci/le_acl_connection_interface.h"
 #include "main/shim/hci_layer.h"
 #include "main/shim/shim.h"
 #include "osi/include/allocator.h"
@@ -187,25 +188,12 @@ static bool event_already_registered_in_hci_layer(
 
 static bool event_already_registered_in_le_advertising_manager(
     bluetooth::hci::EventCode event_code) {
-  switch (event_code) {
-    case bluetooth::hci::EventCode::CONNECTION_PACKET_TYPE_CHANGED:
-    case bluetooth::hci::EventCode::ROLE_CHANGE:
-    case bluetooth::hci::EventCode::CONNECTION_COMPLETE:
-    case bluetooth::hci::EventCode::CONNECTION_REQUEST:
-    case bluetooth::hci::EventCode::AUTHENTICATION_COMPLETE:
-    case bluetooth::hci::EventCode::READ_CLOCK_OFFSET_COMPLETE:
-    case bluetooth::hci::EventCode::MODE_CHANGE:
-    case bluetooth::hci::EventCode::QOS_SETUP_COMPLETE:
-    case bluetooth::hci::EventCode::FLOW_SPECIFICATION_COMPLETE:
-    case bluetooth::hci::EventCode::FLUSH_OCCURRED:
-    case bluetooth::hci::EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE:
-    case bluetooth::hci::EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE:
-    case bluetooth::hci::EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE:
-    case bluetooth::hci::EventCode::LINK_SUPERVISION_TIMEOUT_CHANGED:
+  for (auto event : bluetooth::hci::AclConnectionEvents) {
+    if (event == event_code) {
       return bluetooth::shim::is_gd_advertising_enabled();
-    default:
-      return false;
+    }
   }
+  return false;
 }
 
 std::unique_ptr<bluetooth::packet::RawBuilder> MakeUniquePacket(
diff --git a/main/shim/le_advertising_manager.cc b/main/shim/le_advertising_manager.cc
new file mode 100644 (file)
index 0000000..908601f
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#define LOG_TAG "bt_shim_advertiser"
+
+#include "le_advertising_manager.h"
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_gatt.h>
+
+#include <vector>
+#include "gd/common/init_flags.h"
+#include "gd/hci/acl_manager.h"
+#include "gd/hci/controller.h"
+#include "gd/hci/le_advertising_manager.h"
+#include "gd/packet/packet_view.h"
+#include "main/shim/entry.h"
+
+#include "ble_advertiser.h"
+#include "btif_common.h"
+#include "btm_api.h"
+#include "btu.h"
+
+using bluetooth::hci::Address;
+using bluetooth::hci::AddressType;
+using bluetooth::hci::ErrorCode;
+using bluetooth::hci::GapData;
+using bluetooth::hci::OwnAddressType;
+using std::vector;
+
+class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface,
+                                   public bluetooth::hci::AdvertisingCallback {
+ public:
+  ~BleAdvertiserInterfaceImpl() override{};
+
+  void Init() {
+    // Register callback
+    bluetooth::shim::GetAdvertising()->RegisterAdvertisingCallback(this);
+
+    if (!bluetooth::common::InitFlags::GdSecurityEnabled()) {
+      // Set private policy
+      auto address = bluetooth::shim::GetController()->GetMacAddress();
+      bluetooth::hci::AddressWithType address_with_type(
+          address, bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS);
+      bluetooth::crypto_toolbox::Octet16 irk = {};
+      auto minimum_rotation_time = std::chrono::milliseconds(7 * 60 * 1000);
+      auto maximum_rotation_time = std::chrono::milliseconds(15 * 60 * 1000);
+      bluetooth::shim::GetAclManager()->SetPrivacyPolicyForInitiatorAddress(
+          bluetooth::hci::LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS,
+          address_with_type, irk, minimum_rotation_time, maximum_rotation_time);
+    }
+  }
+
+  // nobody use this function
+  void RegisterAdvertiser(IdStatusCallback cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  void Unregister(uint8_t advertiser_id) override {
+    LOG(INFO) << __func__ << " in shim layer";
+    bluetooth::shim::GetAdvertising()->RemoveAdvertiser(advertiser_id);
+  }
+
+  // only for PTS test
+  void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
+                     ParametersCallback cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
+               StatusCallback cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
+              uint16_t duration, uint8_t maxExtAdvEvents,
+              StatusCallback timeout_cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  // nobody use this function
+  void StartAdvertising(uint8_t advertiser_id, StatusCallback cb,
+                        AdvertiseParameters params,
+                        std::vector<uint8_t> advertise_data,
+                        std::vector<uint8_t> scan_response_data, int timeout_s,
+                        MultiAdvCb timeout_cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  void StartAdvertisingSet(IdTxPowerStatusCallback cb,
+                           AdvertiseParameters params,
+                           std::vector<uint8_t> advertise_data,
+                           std::vector<uint8_t> scan_response_data,
+                           PeriodicAdvertisingParameters periodic_params,
+                           std::vector<uint8_t> periodic_data,
+                           uint16_t duration, uint8_t maxExtAdvEvents,
+                           IdStatusCallback timeout_cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+
+    bluetooth::hci::ExtendedAdvertisingConfig config{};
+    config.connectable = params.advertising_event_properties & 0x01;
+    config.scannable = params.advertising_event_properties & 0x02;
+    config.legacy_pdus = params.advertising_event_properties & 0x10;
+    config.anonymous = params.advertising_event_properties & 0x20;
+    config.include_tx_power = params.advertising_event_properties & 0x40;
+    config.interval_min = params.min_interval;
+    config.interval_max = params.max_interval;
+    config.channel_map = params.channel_map;
+    config.tx_power = params.tx_power;
+    config.use_le_coded_phy = params.primary_advertising_phy == 0x03;
+    config.secondary_advertising_phy =
+        static_cast<bluetooth::hci::SecondaryPhyType>(
+            params.secondary_advertising_phy);
+    config.enable_scan_request_notifications =
+        static_cast<bluetooth::hci::Enable>(
+            params.scan_request_notification_enable);
+
+    if (bluetooth::shim::BTM_BleLocalPrivacyEnabled()) {
+      config.own_address_type = OwnAddressType::RANDOM_DEVICE_ADDRESS;
+    } else {
+      config.own_address_type = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
+    }
+
+    if (!bluetooth::common::InitFlags::GdSecurityEnabled()) {
+      // use public address for testing
+      config.own_address_type = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
+    }
+
+    size_t offset = 0;
+
+    while (offset < advertise_data.size()) {
+      GapData gap_data;
+      uint8_t len = advertise_data[offset];
+      auto begin = advertise_data.begin() + offset;
+      auto end = begin + len + 1;  // 1 byte for len
+      auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end);
+      bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet(
+          data_copy);
+      GapData::Parse(&gap_data, packet.begin());
+      config.advertisement.push_back(gap_data);
+      offset += len + 1;  // 1 byte for len
+    }
+
+    offset = 0;
+    while (offset < scan_response_data.size()) {
+      GapData gap_data;
+      uint8_t len = scan_response_data[offset];
+      auto begin = scan_response_data.begin() + offset;
+      auto end = begin + len + 1;  // 1 byte for len
+      auto data_copy = std::make_shared<std::vector<uint8_t>>(begin, end);
+      bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> packet(
+          data_copy);
+      GapData::Parse(&gap_data, packet.begin());
+      config.scan_response.push_back(gap_data);
+      offset += len + 1;  // 1 byte for len
+    }
+
+    // TODO check advertising data size
+    config.operation = bluetooth::hci::Operation::COMPLETE_ADVERTISEMENT;
+
+    power_status_callback_ = cb;
+
+    bluetooth::hci::AdvertiserId id =
+        bluetooth::shim::GetAdvertising()->ExtendedCreateAdvertiser(
+            config, scan_callback, set_terminated_callback,
+            bluetooth::shim::GetGdShimHandler());
+
+    LOG(INFO) << " CYDBG id" << (uint16_t)id;
+  }
+
+  void SetPeriodicAdvertisingParameters(
+      int advertiser_id, PeriodicAdvertisingParameters periodic_params,
+      StatusCallback cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  void SetPeriodicAdvertisingData(int advertiser_id, std::vector<uint8_t> data,
+                                  StatusCallback cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
+                                    StatusCallback cb) override {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  void on_scan(Address address, AddressType address_type) {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  void on_set_terminated(ErrorCode error_code, uint8_t, uint8_t) {
+    LOG(INFO) << __func__ << " in shim layer";
+  }
+
+  const bluetooth::common::Callback<void(Address, AddressType)> scan_callback =
+      bluetooth::common::Bind(&BleAdvertiserInterfaceImpl::on_scan,
+                              bluetooth::common::Unretained(this));
+
+  const bluetooth::common::Callback<void(ErrorCode, uint8_t, uint8_t)>
+      set_terminated_callback = bluetooth::common::Bind(
+          &BleAdvertiserInterfaceImpl::on_set_terminated,
+          bluetooth::common::Unretained(this));
+
+  // AdvertisingCallback
+  void OnAdvertisingSetStarted(uint8_t advertiser_id, int8_t tx_power,
+                               AdvertisingStatus status) override {
+    do_in_jni_thread(FROM_HERE,
+                     base::Bind(power_status_callback_, advertiser_id, tx_power,
+                                (uint8_t)status));
+  }
+
+  void onAdvertisingEnabled(uint8_t advertiser_id, bool enable,
+                            uint8_t status) {
+    // TODO
+  }
+
+  IdTxPowerStatusCallback power_status_callback_;
+};
+
+BleAdvertiserInterfaceImpl* bt_le_advertiser_instance = nullptr;
+
+BleAdvertiserInterface* bluetooth::shim::get_ble_advertiser_instance() {
+  if (bt_le_advertiser_instance == nullptr) {
+    bt_le_advertiser_instance = new BleAdvertiserInterfaceImpl();
+  }
+  return bt_le_advertiser_instance;
+};
+
+void bluetooth::shim::init_advertising_manager() {
+  bt_le_advertiser_instance->Init();
+}
diff --git a/main/shim/le_advertising_manager.h b/main/shim/le_advertising_manager.h
new file mode 100644 (file)
index 0000000..d53c795
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 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.
+ */
+
+/**
+ * Gd shim layer to legacy le advertiser
+ */
+#pragma once
+
+#include "ble_advertiser.h"
+#include "include/hardware/ble_advertiser.h"
+
+namespace bluetooth {
+namespace shim {
+
+BleAdvertiserInterface* get_ble_advertiser_instance();
+void init_advertising_manager();
+
+}  // namespace shim
+}  // namespace bluetooth
\ No newline at end of file
index d7360c2..f191ea6 100644 (file)
@@ -55,7 +55,9 @@ EXPORT_SYMBOL extern const module_t gd_shim_module = {
     .dependencies = {kUnusedModuleDependencies}};
 
 bool bluetooth::shim::is_gd_advertising_enabled() {
-  return bluetooth::common::InitFlags::GdAdvertisingEnabled();
+  // TODO enable when module ready
+  // return bluetooth::common::InitFlags::GdAdvertisingEnabled();
+  return false;
 }
 
 bool bluetooth::shim::is_gd_security_enabled() {
index 286d1f1..a0b55c8 100644 (file)
@@ -40,6 +40,7 @@
 #include "gd/storage/storage_module.h"
 
 #include "main/shim/hci_layer.h"
+#include "main/shim/le_advertising_manager.h"
 #include "main/shim/stack.h"
 
 namespace bluetooth {
@@ -118,6 +119,10 @@ void Stack::StartEverything() {
   if (!common::InitFlags::GdCoreEnabled()) {
     bluetooth::shim::hci_on_reset_complete();
   }
+
+  if (common::InitFlags::GdAdvertisingEnabled()) {
+    bluetooth::shim::init_advertising_manager();
+  }
 }
 
 void Stack::Start(ModuleList* modules) {