Integrate name module into legacy stack

Bug: 142570089
Test: Start pairing in Gd mode

Change-Id: Iebbab317ce194e833006a24ce512f671e3e15066
diff --git a/main/shim/btm.cc b/main/shim/btm.cc
index 35f5f43..7ebbf90 100644
--- a/main/shim/btm.cc
+++ b/main/shim/btm.cc
@@ -17,6 +17,7 @@
 #define LOG_TAG "bt_shim_btm"
 
 #include <algorithm>
+#include <cstring>
 
 #include "main/shim/btm.h"
 #include "main/shim/entry.h"
@@ -34,12 +35,16 @@
 static constexpr uint8_t kInquiryResultWithRssiMode = 1;
 static constexpr uint8_t kExtendedInquiryResultMode = 2;
 
+static constexpr size_t kRemoteDeviceNameLength = 248;
+
 extern void btm_process_cancel_complete(uint8_t status, uint8_t mode);
 extern void btm_process_inq_complete(uint8_t status, uint8_t result_type);
 extern void btm_process_inq_results(uint8_t* p, uint8_t result_mode);
 
+using BtmRemoteDeviceName = tBTM_REMOTE_DEV_NAME;
+
 /**
- * Inquiry
+ *
  */
 void bluetooth::shim::Btm::OnInquiryResult(std::vector<const uint8_t> result) {
   CHECK(result.size() < kMaxInquiryResultSize);
@@ -194,7 +199,7 @@
 }
 
 /**
- * Periodic Inquiry
+ * Periodic
  */
 bool bluetooth::shim::Btm::StartPeriodicInquiry(
     uint8_t mode, uint8_t duration, uint8_t max_responses, uint16_t max_delay,
@@ -343,3 +348,85 @@
   LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
   return state;
 }
+
+bool bluetooth::shim::Btm::IsLeAclConnected(
+    const RawAddress& raw_address) const {
+  // TODO(cmanton) Check current acl's for this address and indicate if there is
+  // an LE option.  For now ignore and default to classic.
+  LOG_INFO(LOG_TAG, "%s Le acl connection check is temporarily unsupported",
+           __func__);
+  return false;
+}
+
+bluetooth::shim::BtmStatus bluetooth::shim::Btm::ReadClassicRemoteDeviceName(
+    const RawAddress& raw_address, tBTM_CMPL_CB* callback) {
+  if (!CheckClassicAclLink(raw_address)) {
+    return bluetooth::shim::BTM_UNKNOWN_ADDR;
+  }
+
+  if (!classic_read_remote_name_.Start(raw_address)) {
+    LOG_INFO(LOG_TAG, "%s Read remote name is currently busy address:%s",
+             __func__, raw_address.ToString().c_str());
+    return bluetooth::shim::BTM_BUSY;
+  }
+
+  LOG_DEBUG(LOG_TAG, "%s Start read name from address:%s", __func__,
+            raw_address.ToString().c_str());
+  bluetooth::shim::GetName()->ReadRemoteNameRequest(
+      classic_read_remote_name_.AddressString(),
+      [this, callback](
+          std::string address_string, uint8_t hci_status,
+          std::array<uint8_t, kRemoteDeviceNameLength> remote_name) {
+        RawAddress raw_address;
+        RawAddress::FromString(address_string, raw_address);
+
+        BtmRemoteDeviceName name{
+            .status = (hci_status == 0) ? (BTM_SUCCESS) : (BTM_BAD_VALUE_RET),
+            .bd_addr = raw_address,
+            .length = kRemoteDeviceNameLength,
+        };
+        std::copy(remote_name.begin(), remote_name.end(), name.remote_bd_name);
+        LOG_DEBUG(LOG_TAG, "%s Finish read name from address:%s name:%s",
+                  __func__, address_string.c_str(), name.remote_bd_name);
+        callback(&name);
+        classic_read_remote_name_.Stop();
+      });
+  return bluetooth::shim::BTM_CMD_STARTED;
+}
+
+bluetooth::shim::BtmStatus bluetooth::shim::Btm::ReadLeRemoteDeviceName(
+    const RawAddress& raw_address, tBTM_CMPL_CB* callback) {
+  if (!CheckLeAclLink(raw_address)) {
+    return bluetooth::shim::BTM_UNKNOWN_ADDR;
+  }
+
+  if (!le_read_remote_name_.Start(raw_address)) {
+    return bluetooth::shim::BTM_BUSY;
+  }
+
+  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s need access to GATT module", __func__);
+  return bluetooth::shim::BTM_UNKNOWN_ADDR;
+}
+
+bluetooth::shim::BtmStatus
+bluetooth::shim::Btm::CancelAllReadRemoteDeviceName() {
+  if (classic_read_remote_name_.IsInProgress() ||
+      le_read_remote_name_.IsInProgress()) {
+    if (classic_read_remote_name_.IsInProgress()) {
+      bluetooth::shim::GetName()->CancelRemoteNameRequest(
+          classic_read_remote_name_.AddressString(),
+          [this](std::string address_string, uint8_t status) {
+            classic_read_remote_name_.Stop();
+          });
+    }
+    if (le_read_remote_name_.IsInProgress()) {
+      LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s need access to GATT module",
+               __func__);
+    }
+    return bluetooth::shim::BTM_UNKNOWN_ADDR;
+  }
+  LOG_INFO(LOG_TAG,
+           "%s Cancelling classic remote device name without one in progress",
+           __func__);
+  return bluetooth::shim::BTM_WRONG_MODE;
+}
diff --git a/main/shim/btm.h b/main/shim/btm.h
index aa92bf6..6f9c00b 100644
--- a/main/shim/btm.h
+++ b/main/shim/btm.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <cstdint>
+#include <mutex>
 #include <unordered_map>
 #include <vector>
 
@@ -62,6 +63,62 @@
 namespace bluetooth {
 namespace shim {
 
+using BtmStatus = enum : uint16_t {
+  BTM_SUCCESS = 0,         /* 0  Command succeeded                 */
+  BTM_CMD_STARTED,         /* 1  Command started OK.               */
+  BTM_BUSY,                /* 2  Device busy with another command  */
+  BTM_NO_RESOURCES,        /* 3  No resources to issue command     */
+  BTM_MODE_UNSUPPORTED,    /* 4  Request for 1 or more unsupported modes */
+  BTM_ILLEGAL_VALUE,       /* 5  Illegal parameter value           */
+  BTM_WRONG_MODE,          /* 6  Device in wrong mode for request  */
+  BTM_UNKNOWN_ADDR,        /* 7  Unknown remote BD address         */
+  BTM_DEVICE_TIMEOUT,      /* 8  Device timeout                    */
+  BTM_BAD_VALUE_RET,       /* 9  A bad value was received from HCI */
+  BTM_ERR_PROCESSING,      /* 10 Generic error                     */
+  BTM_NOT_AUTHORIZED,      /* 11 Authorization failed              */
+  BTM_DEV_RESET,           /* 12 Device has been reset             */
+  BTM_CMD_STORED,          /* 13 request is stored in control block */
+  BTM_ILLEGAL_ACTION,      /* 14 state machine gets illegal command */
+  BTM_DELAY_CHECK,         /* 15 delay the check on encryption */
+  BTM_SCO_BAD_LENGTH,      /* 16 Bad SCO over HCI data length */
+  BTM_SUCCESS_NO_SECURITY, /* 17 security passed, no security set  */
+  BTM_FAILED_ON_SECURITY,  /* 18 security failed                   */
+  BTM_REPEATED_ATTEMPTS,   /* 19 repeated attempts for LE security requests */
+  BTM_MODE4_LEVEL4_NOT_SUPPORTED, /* 20 Secure Connections Only Mode can't be
+                                     supported */
+  BTM_DEV_BLACKLISTED             /* 21 The device is Blacklisted */
+};
+
+class ReadRemoteName {
+ public:
+  bool Start(RawAddress raw_address) {
+    std::unique_lock<std::mutex> lock(mutex_);
+    if (in_progress_) {
+      return false;
+    }
+    raw_address_ = raw_address;
+    in_progress_ = true;
+    return true;
+  }
+
+  void Stop() {
+    std::unique_lock<std::mutex> lock(mutex_);
+    raw_address_ = RawAddress::kEmpty;
+    in_progress_ = false;
+  }
+
+  bool IsInProgress() const { return in_progress_; }
+
+  std::string AddressString() const { return raw_address_.ToString(); }
+
+  ReadRemoteName() : in_progress_{false}, raw_address_(RawAddress::kEmpty) {}
+
+ private:
+  bool in_progress_;
+  RawAddress raw_address_;
+  std::mutex mutex_;
+};
+
 class Btm {
  public:
   Btm();
@@ -120,16 +177,21 @@
   void SetLeConnectibleOff();
   ConnectabilityState GetLeConnectabilityState() const;
 
+  bool IsLeAclConnected(const RawAddress& raw_address) const;
+
+  // Remote device name
+  BtmStatus ReadClassicRemoteDeviceName(const RawAddress& raw_address,
+                                        tBTM_CMPL_CB* callback);
+  BtmStatus ReadLeRemoteDeviceName(const RawAddress& raw_address,
+                                   tBTM_CMPL_CB* callback);
+  BtmStatus CancelAllReadRemoteDeviceName();
+
  private:
-  //  DiscoverabilityState classic_;
-  //  DiscoverabilityState le_;
-
-  //  ConnectabilityState classic_connectibility_state_;
-  //  ConnectabilityState le_connectibility_state_;
-
-  //  bool DoSetEventFilter();
-  //  void DoSetDiscoverability();
-  //  bool DoSetInquiryMode();
+  ReadRemoteName le_read_remote_name_;
+  ReadRemoteName classic_read_remote_name_;
+  // TODO(cmanton) abort if there is no classic acl link up
+  bool CheckClassicAclLink(const RawAddress& raw_address) { return true; }
+  bool CheckLeAclLink(const RawAddress& raw_address) { return true; }
 };
 
 }  // namespace shim
diff --git a/main/shim/btm_api.cc b/main/shim/btm_api.cc
index ee3b0cf..a8adee8 100644
--- a/main/shim/btm_api.cc
+++ b/main/shim/btm_api.cc
@@ -493,15 +493,23 @@
  *
  ******************************************************************************/
 tBTM_STATUS bluetooth::shim::BTM_ReadRemoteDeviceName(
-    const RawAddress& remote_bda, tBTM_CMPL_CB* p_cb, tBT_TRANSPORT transport) {
-  if (transport == BT_TRANSPORT_LE) {
-    LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
-    return BTM_NO_RESOURCES;
-  }
+    const RawAddress& raw_address, tBTM_CMPL_CB* callback,
+    tBT_TRANSPORT transport) {
+  CHECK(callback != nullptr);
+  tBTM_STATUS status = BTM_NO_RESOURCES;
 
-  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
-  return BTM_NO_RESOURCES;
-  CHECK(p_cb != nullptr);
+  switch (transport) {
+    case BT_TRANSPORT_LE:
+      status = shim_btm.ReadLeRemoteDeviceName(raw_address, callback);
+      break;
+    case BT_TRANSPORT_BR_EDR:
+      status = shim_btm.ReadClassicRemoteDeviceName(raw_address, callback);
+      break;
+    default:
+      LOG_WARN(LOG_TAG, "%s Unspecified transport:%d", __func__, transport);
+      break;
+  }
+  return status;
 }
 
 /*******************************************************************************
@@ -523,8 +531,7 @@
  *
  ******************************************************************************/
 tBTM_STATUS bluetooth::shim::BTM_CancelRemoteDeviceName(void) {
-  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
-  return BTM_NO_RESOURCES;
+  return shim_btm.CancelAllReadRemoteDeviceName();
 }
 
 /*******************************************************************************
@@ -1155,9 +1162,8 @@
  * Returns          true to use LE, false use BR/EDR.
  *
  ******************************************************************************/
-bool bluetooth::shim::BTM_UseLeLink(const RawAddress& bd_addr) {
-  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
-  return false;
+bool bluetooth::shim::BTM_UseLeLink(const RawAddress& raw_address) {
+  return shim_btm.IsLeAclConnected(raw_address);
 }
 
 /*******************************************************************************
diff --git a/main/shim/entry.cc b/main/shim/entry.cc
index 8768818..4655219 100644
--- a/main/shim/entry.cc
+++ b/main/shim/entry.cc
@@ -54,6 +54,10 @@
   return GetGabeldorscheStack()->GetL2cap();
 }
 
+bluetooth::shim::IName* bluetooth::shim::GetName() {
+  return GetGabeldorscheStack()->GetName();
+}
+
 bluetooth::shim::IPage* bluetooth::shim::GetPage() {
   return GetGabeldorscheStack()->GetPage();
 }
diff --git a/main/shim/entry.h b/main/shim/entry.h
index a4d4cf4..2ffd2e5 100644
--- a/main/shim/entry.h
+++ b/main/shim/entry.h
@@ -44,6 +44,7 @@
 bluetooth::shim::IInquiry* GetInquiry();
 bluetooth::shim::IHciLayer* GetHciLayer();
 bluetooth::shim::IL2cap* GetL2cap();
+bluetooth::shim::IName* GetName();
 bluetooth::shim::IPage* GetPage();
 
 }  // namespace shim