Merge "Add gd neighbor module"
diff --git a/gd/neighbor/Android.bp b/gd/neighbor/Android.bp
index 0b8b4da..bd69a3e 100644
--- a/gd/neighbor/Android.bp
+++ b/gd/neighbor/Android.bp
@@ -4,6 +4,7 @@
             "connectability.cc",
             "discoverability.cc",
             "inquiry.cc",
+            "name.cc",
             "page.cc",
             "scan.cc",
     ],
diff --git a/gd/neighbor/name.cc b/gd/neighbor/name.cc
new file mode 100644
index 0000000..34fa86b
--- /dev/null
+++ b/gd/neighbor/name.cc
@@ -0,0 +1,225 @@
+/*
+ * 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/name.h"
+
+#include <memory>
+#include <unordered_map>
+#include <utility>
+
+#include "common/bind.h"
+#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 ReadCallbackHandler {
+  ReadRemoteNameCallback callback;
+  os::Handler* handler;
+};
+
+struct CancelCallbackHandler {
+  CancelRemoteNameCallback callback;
+  os::Handler* handler;
+};
+
+constexpr std::array<uint8_t, 248> kEmptyName{};
+
+struct NameModule::impl {
+  void ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode,
+                             uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid,
+                             ReadRemoteNameCallback callback, os::Handler* handler);
+  void CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback, os::Handler* handler);
+
+  void Start();
+  void Stop();
+
+  impl(const NameModule& name_module);
+
+ private:
+  const NameModule& module_;
+
+  void EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command);
+  void EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command);
+
+  void OnCommandComplete(hci::CommandCompleteView view);
+  void OnCommandStatus(hci::CommandStatusView status);
+  void OnEvent(hci::EventPacketView view);
+
+  std::unordered_map<hci::Address, std::unique_ptr<ReadCallbackHandler>> read_callback_handler_map_;
+  std::unordered_map<hci::Address, std::unique_ptr<CancelCallbackHandler>> cancel_callback_handler_map_;
+
+  hci::HciLayer* hci_layer_;
+  os::Handler* handler_;
+};
+
+const ModuleFactory neighbor::NameModule::Factory = ModuleFactory([]() { return new neighbor::NameModule(); });
+
+neighbor::NameModule::impl::impl(const neighbor::NameModule& module) : module_(module) {}
+
+void neighbor::NameModule::impl::EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command) {
+  hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)),
+                             handler_);
+}
+
+void neighbor::NameModule::impl::EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command) {
+  hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)),
+                             handler_);
+}
+
+void neighbor::NameModule::impl::OnCommandComplete(hci::CommandCompleteView view) {
+  switch (view.GetCommandOpCode()) {
+    case hci::OpCode::REMOTE_NAME_REQUEST_CANCEL: {
+      auto packet = hci::RemoteNameRequestCancelCompleteView::Create(view);
+      ASSERT(packet.IsValid());
+      ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
+      hci::Address address = packet.GetBdAddr();
+      ASSERT(cancel_callback_handler_map_.find(address) != cancel_callback_handler_map_.end());
+      cancel_callback_handler_map_.erase(address);
+    } break;
+    default:
+      LOG_WARN("Unhandled command:%s", hci::OpCodeText(view.GetCommandOpCode()).c_str());
+      break;
+  }
+}
+
+void neighbor::NameModule::impl::OnCommandStatus(hci::CommandStatusView status) {
+  ASSERT(status.GetStatus() == hci::ErrorCode::SUCCESS);
+
+  switch (status.GetCommandOpCode()) {
+    case hci::OpCode::REMOTE_NAME_REQUEST: {
+      auto packet = hci::RemoteNameRequestStatusView::Create(status);
+      ASSERT(packet.IsValid());
+    } break;
+
+    default:
+      LOG_WARN("Unhandled command:%s", hci::OpCodeText(status.GetCommandOpCode()).c_str());
+      break;
+  }
+}
+
+void neighbor::NameModule::impl::OnEvent(hci::EventPacketView view) {
+  switch (view.GetEventCode()) {
+    case hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE: {
+      auto packet = hci::RemoteNameRequestCompleteView::Create(view);
+      ASSERT(packet.IsValid());
+      hci::Address address = packet.GetBdAddr();
+      ASSERT(read_callback_handler_map_.find(address) != read_callback_handler_map_.end());
+      auto read_callback_handler = std::move(read_callback_handler_map_[address]);
+      read_callback_handler->handler->Post(common::BindOnce(std::move(read_callback_handler->callback),
+                                                            packet.GetStatus(), address, packet.GetRemoteName()));
+      read_callback_handler_map_.erase(address);
+    } break;
+    default:
+      LOG_ERROR("Unhandled event:%s", hci::EventCodeText(view.GetEventCode()).c_str());
+      break;
+  }
+}
+
+void neighbor::NameModule::impl::Start() {
+  hci_layer_ = module_.GetDependency<hci::HciLayer>();
+  handler_ = module_.GetHandler();
+
+  hci_layer_->RegisterEventHandler(hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE,
+                                   common::Bind(&NameModule::impl::OnEvent, common::Unretained(this)), handler_);
+}
+
+void neighbor::NameModule::impl::Stop() {
+  hci_layer_->UnregisterEventHandler(hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE);
+}
+
+void neighbor::NameModule::impl::ReadRemoteNameRequest(hci::Address address,
+                                                       hci::PageScanRepetitionMode page_scan_repetition_mode,
+                                                       uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid,
+                                                       ReadRemoteNameCallback callback, os::Handler* handler) {
+  LOG_DEBUG("%s Start read remote name request for %s", __func__, address.ToString().c_str());
+
+  if (read_callback_handler_map_.find(address) != read_callback_handler_map_.end()) {
+    LOG_WARN("Ignoring duplicate read remote name request to:%s", address.ToString().c_str());
+    handler->Post(common::BindOnce(std::move(callback), hci::ErrorCode::UNSPECIFIED_ERROR, address, kEmptyName));
+    return;
+  }
+  read_callback_handler_map_[address] = std::unique_ptr<ReadCallbackHandler>(new ReadCallbackHandler{
+      .callback = std::move(callback),
+      .handler = handler,
+  });
+
+  EnqueueCommandStatus(
+      hci::RemoteNameRequestBuilder::Create(address, page_scan_repetition_mode, clock_offset, clock_offset_valid));
+}
+
+void neighbor::NameModule::impl::CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback callback,
+                                                         os::Handler* handler) {
+  LOG_DEBUG("%s Cancel remote name request for %s", __func__, address.ToString().c_str());
+
+  if (cancel_callback_handler_map_.find(address) != cancel_callback_handler_map_.end()) {
+    LOG_WARN("Ignoring duplicate cancel remote name request to:%s", address.ToString().c_str());
+    handler->Post(common::BindOnce(std::move(callback), hci::ErrorCode::UNSPECIFIED_ERROR, address));
+    return;
+  }
+  cancel_callback_handler_map_[address] = std::unique_ptr<CancelCallbackHandler>(new CancelCallbackHandler{
+      .callback = std::move(callback),
+      .handler = handler,
+  });
+  EnqueueCommandComplete(hci::RemoteNameRequestCancelBuilder::Create(address));
+}
+
+/**
+ * General API here
+ */
+neighbor::NameModule::NameModule() : pimpl_(std::make_unique<impl>(*this)) {}
+
+neighbor::NameModule::~NameModule() {
+  pimpl_.reset();
+}
+
+void neighbor::NameModule::ReadRemoteNameRequest(hci::Address address,
+                                                 hci::PageScanRepetitionMode page_scan_repetition_mode,
+                                                 uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid,
+                                                 ReadRemoteNameCallback callback, os::Handler* handler) {
+  GetHandler()->Post(common::BindOnce(&NameModule::impl::ReadRemoteNameRequest, common::Unretained(pimpl_.get()),
+                                      address, page_scan_repetition_mode, clock_offset, clock_offset_valid,
+                                      std::move(callback), handler));
+}
+
+void neighbor::NameModule::CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback callback,
+                                                   os::Handler* handler) {
+  GetHandler()->Post(common::BindOnce(&NameModule::impl::CancelRemoteNameRequest, common::Unretained(pimpl_.get()),
+                                      address, std::move(callback), handler));
+}
+
+/**
+ * Module methods here
+ */
+void neighbor::NameModule::ListDependencies(ModuleList* list) {
+  list->add<hci::HciLayer>();
+}
+
+void neighbor::NameModule::Start() {
+  pimpl_->Start();
+}
+
+void neighbor::NameModule::Stop() {
+  pimpl_->Stop();
+}
+
+}  // namespace neighbor
+}  // namespace bluetooth
diff --git a/gd/neighbor/name.h b/gd/neighbor/name.h
new file mode 100644
index 0000000..291e1de
--- /dev/null
+++ b/gd/neighbor/name.h
@@ -0,0 +1,59 @@
+/*
+ * 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 <array>
+#include <cstdint>
+#include <memory>
+
+#include "common/bind.h"
+#include "hci/address.h"
+#include "hci/hci_packets.h"
+#include "module.h"
+
+namespace bluetooth {
+namespace neighbor {
+
+using ReadRemoteNameCallback =
+    common::OnceCallback<void(hci::ErrorCode status, hci::Address address, std::array<uint8_t, 248> name)>;
+using CancelRemoteNameCallback = common::OnceCallback<void(hci::ErrorCode status, hci::Address address)>;
+
+class NameModule : public bluetooth::Module {
+ public:
+  void ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode,
+                             uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid,
+                             ReadRemoteNameCallback on_read_name, os::Handler* handler);
+  void CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback on_cancel, os::Handler* handler);
+
+  static const ModuleFactory Factory;
+
+  NameModule();
+  ~NameModule();
+
+ protected:
+  void ListDependencies(ModuleList* list) override;
+  void Start() override;
+  void Stop() override;
+
+ private:
+  struct impl;
+  std::unique_ptr<impl> pimpl_;
+
+  DISALLOW_COPY_AND_ASSIGN(NameModule);
+};
+
+}  // namespace neighbor
+}  // namespace bluetooth