OSDN Git Service

Inquiry and page scan common module
authorChris Manton <cmanton@google.com>
Mon, 14 Oct 2019 23:14:30 +0000 (16:14 -0700)
committerChris Manton <cmanton@google.com>
Mon, 14 Oct 2019 23:27:08 +0000 (16:27 -0700)
Bug: 142061208
Test: Builds successfully
Change-Id: I0ca7afb996490fff71030bf949ea9647924fd458

gd/neighbor/scan.cc [new file with mode: 0644]
gd/neighbor/scan.h [new file with mode: 0644]

diff --git a/gd/neighbor/scan.cc b/gd/neighbor/scan.cc
new file mode 100644 (file)
index 0000000..99b868f
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * 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.
+ */
+#define LOG_TAG "bt_gd_neigh"
+
+#include "neighbor/scan.h"
+#include <memory>
+#include "hci/hci_layer.h"
+#include "hci/hci_packets.h"
+#include "module.h"
+#include "os/handler.h"
+#include "os/log.h"
+
+namespace bluetooth {
+namespace neighbor {
+
+struct ScanModule::impl {
+  impl(ScanModule& module);
+
+  void SetInquiryScan(bool enabled);
+  bool IsInquiryEnabled() const;
+
+  void SetPageScan(bool enabled);
+  bool IsPageEnabled() const;
+
+  void Start();
+  void Stop();
+
+ private:
+  ScanModule& module_;
+
+  bool inquiry_scan_enabled_;
+  bool page_scan_enabled_;
+
+  void WriteScanEnable();
+  void ReadScanEnable(hci::ScanEnable);
+
+  void OnCommandComplete(hci::CommandCompleteView status);
+
+  hci::HciLayer* hci_layer_;
+  os::Handler* handler_;
+};
+
+const ModuleFactory neighbor::ScanModule::Factory = ModuleFactory([]() { return new neighbor::ScanModule(); });
+
+neighbor::ScanModule::impl::impl(neighbor::ScanModule& module)
+    : module_(module), inquiry_scan_enabled_(false), page_scan_enabled_(false) {}
+
+void neighbor::ScanModule::impl::OnCommandComplete(hci::CommandCompleteView view) {
+  switch veiwstatus.GetCommandOpCode()) {
+      case hci::OpCode::READ_SCAN_ENABLE: {
+        auto packet = hci::ReadScanEnableCompleteView::Create(view);
+        ASSERT(packet.IsValid());
+        ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
+        ReadScanEnable(packet.GetScanEnable());
+      } break;
+
+      case hci::OpCode::WRITE_SCAN_ENABLE: {
+        auto packet = hci::WriteScanEnableCompleteView::Create(view);
+        ASSERT(packet.IsValid());
+        ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
+      } break;
+
+      default:
+        LOG_ERROR("Unhandled command %s", hci::OpCodeText(view.GetCommandOpCode()).c_str());
+        break;
+    }
+}
+
+void neighbor::ScanModule::impl::WriteScanEnable() {
+  hci::ScanEnable scan_enable;
+
+  if (inquiry_scan_enabled_ && !page_scan_enabled_) {
+    scan_enable = hci::ScanEnable::INQUIRY_SCAN_ONLY;
+  } else if (!inquiry_scan_enabled_ && page_scan_enabled_) {
+    scan_enable = hci::ScanEnable::PAGE_SCAN_ONLY;
+  } else if (inquiry_scan_enabled_ && page_scan_enabled_) {
+    scan_enable = hci::ScanEnable::INQUIRY_AND_PAGE_SCAN;
+  } else {
+    scan_enable = hci::ScanEnable::NO_SCANS;
+  }
+
+  {
+    std::unique_ptr<hci::WriteScanEnableBuilder> packet = hci::WriteScanEnableBuilder::Create(scan_enable);
+    hci_layer_->EnqueueCommand(std::move(packet), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)),
+                               handler_);
+  }
+
+  {
+    std::unique_ptr<hci::ReadScanEnableBuilder> packet = hci::ReadScanEnableBuilder::Create();
+    hci_layer_->EnqueueCommand(std::move(packet), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)),
+                               handler_);
+  }
+}
+
+void neighbor::ScanModule::impl::ReadScanEnable(hci::ScanEnable scan_enable) {
+  switch (scan_enable) {
+    case hci::ScanEnable::INQUIRY_SCAN_ONLY:
+      inquiry_scan_enabled_ = true;
+      page_scan_enabled_ = false;
+      break;
+
+    case hci::ScanEnable::PAGE_SCAN_ONLY:
+      inquiry_scan_enabled_ = false;
+      page_scan_enabled_ = true;
+      break;
+
+    case hci::ScanEnable::INQUIRY_AND_PAGE_SCAN:
+      inquiry_scan_enabled_ = true;
+      page_scan_enabled_ = true;
+      break;
+
+    default:
+      inquiry_scan_enabled_ = false;
+      page_scan_enabled_ = false;
+      break;
+  }
+}
+
+void neighbor::ScanModule::impl::SetInquiryScan(bool enabled) {
+  inquiry_scan_enabled_ = enabled;
+  WriteScanEnable();
+}
+
+void neighbor::ScanModule::impl::SetPageScan(bool enabled) {
+  page_scan_enabled_ = enabled;
+  WriteScanEnable();
+}
+
+bool neighbor::ScanModule::impl::IsInquiryEnabled() const {
+  return inquiry_scan_enabled_;
+}
+
+bool neighbor::ScanModule::impl::IsPageEnabled() const {
+  return page_scan_enabled_;
+}
+
+void neighbor::ScanModule::impl::Start() {
+  hci_layer_ = module_.GetDependency<hci::HciLayer>();
+  handler_ = module_.GetHandler();
+
+  std::unique_ptr<hci::ReadScanEnableBuilder> packet = hci::ReadScanEnableBuilder::Create();
+  hci_layer_->EnqueueCommand(std::move(packet), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)),
+                             handler_);
+}
+
+void neighbor::ScanModule::impl::Stop() {
+  LOG_DEBUG("inquiry scan enabled:%d page scan enabled:%d", inquiry_scan_enabled_, page_scan_enabled_);
+}
+
+neighbor::ScanModule::ScanModule() : pimpl_(std::make_unique<impl>(*this)) {}
+
+neighbor::ScanModule::~ScanModule() {
+  pimpl_.reset();
+}
+
+void neighbor::ScanModule::SetInquiryScan() {
+  pimpl_->SetInquiryScan(true);
+}
+
+void neighbor::ScanModule::ClearInquiryScan() {
+  pimpl_->SetInquiryScan(false);
+}
+
+void neighbor::ScanModule::SetPageScan() {
+  pimpl_->SetPageScan(true);
+}
+
+void neighbor::ScanModule::ClearPageScan() {
+  pimpl_->SetPageScan(false);
+}
+
+bool neighbor::ScanModule::IsInquiryEnabled() const {
+  return pimpl_->IsInquiryEnabled();
+}
+
+bool neighbor::ScanModule::IsPageEnabled() const {
+  return pimpl_->IsPageEnabled();
+}
+
+void neighbor::ScanModule::ListDependencies(ModuleList* list) {
+  list->add<hci::HciLayer>();
+}
+
+void neighbor::ScanModule::Start() {
+  pimpl_->Start();
+}
+
+void neighbor::ScanModule::Stop() {
+  pimpl_->Stop();
+}
+
+}  // namespace neighbor
+}  // namespace bluetooth
diff --git a/gd/neighbor/scan.h b/gd/neighbor/scan.h
new file mode 100644 (file)
index 0000000..b6499d3
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <memory>
+
+#include "module.h"
+
+namespace bluetooth {
+namespace neighbor {
+
+class ScanModule : public bluetooth::Module {
+ public:
+  ScanModule();
+  ~ScanModule();
+
+  void SetInquiryScan();
+  void ClearInquiryScan();
+  bool IsInquiryEnabled() const;
+
+  void SetPageScan();
+  void ClearPageScan();
+  bool IsPageEnabled() const;
+
+  static const ModuleFactory Factory;
+
+ protected:
+  void ListDependencies(ModuleList* list) override;
+  void Start() override;
+  void Stop() override;
+
+ private:
+  struct impl;
+  std::unique_ptr<impl> pimpl_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScanModule);
+};
+
+}  // namespace neighbor
+}  // namespace bluetooth