[bt][gap] Distribute local identity information during pairing

LowEnergyConnectionManager now responds to local identity information
requests during the feature exchange and key distribution phases of SMP
pairing.

Bug: BT-243 #done
Test: 1. Run bt-pairing-tool, bt-le-battery-peripheral, and
         bt-le-peripheral -c -n <NAME> on Fuchsia. This will put Fuchsia
	 into LE peripheral mode with one GATT service that requires
	 security.
      2. Connect to Fuchsia from iOS using the nRF Connect app. This
         should trigger LE pairing. Respond to the authentication challenge
	 using bt-pairing-tool (local passkey entry on ToT). The battery
	 service characteristic should be readable and notifiable
	 without any errors.
      3. Pipe the output of bt-snoop-cli to Wireshark and confirm that:
         a. Fuchsia configured advertising using a random address.
	 b. Local IRK and identity address were distributed over SMP.
	 Check that the IRK matches what has been persisted in the
	 stash. Check that the identity address matches the address of
	 the active adapter (confirm via bt-cli).
      4. Reboot Fuchsia, repeat step #1. Connect again using nRF
         Connect. The battery service should be accessible without
	 additional pairing errors.
      5. Check the snoop logs to confirm that Fuchsia used a different
         RPA when advertising.
Change-Id: Ibb78b2de3049f9f351215ed4d878acfcca5569df
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/adapter.cc b/src/connectivity/bluetooth/core/bt-host/gap/adapter.cc
index e5faaf7..b4dbf84 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/adapter.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/adapter.cc
@@ -7,6 +7,13 @@
 #include <endian.h>
 #include <unistd.h>
 
+#include "bredr_connection_manager.h"
+#include "bredr_discovery_manager.h"
+#include "low_energy_address_manager.h"
+#include "low_energy_advertising_manager.h"
+#include "low_energy_connection_manager.h"
+#include "low_energy_discovery_manager.h"
+#include "remote_device.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/log.h"
 #include "src/connectivity/bluetooth/core/bt-host/common/random.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci/connection.h"
@@ -18,14 +25,6 @@
 #include "src/connectivity/bluetooth/core/bt-host/hci/util.h"
 #include "src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager.h"
 
-#include "bredr_connection_manager.h"
-#include "bredr_discovery_manager.h"
-#include "low_energy_address_manager.h"
-#include "low_energy_advertising_manager.h"
-#include "low_energy_connection_manager.h"
-#include "low_energy_discovery_manager.h"
-#include "remote_device.h"
-
 namespace bt {
 namespace gap {
 
@@ -241,7 +240,7 @@
 }
 
 void Adapter::SetDeviceClass(common::DeviceClass dev_class,
-                               hci::StatusCallback callback) {
+                             hci::StatusCallback callback) {
   auto write_dev_class = hci::CommandPacket::New(
       hci::kWriteClassOfDevice, sizeof(hci::WriteClassOfDeviceCommandParams));
   write_dev_class->mutable_view()
@@ -553,7 +552,8 @@
   le_discovery_manager_->set_directed_connectable_callback(
       fit::bind_member(this, &Adapter::OnLeAutoConnectRequest));
   le_connection_manager_ = std::make_unique<LowEnergyConnectionManager>(
-      hci_, hci_le_connector_.get(), &device_cache_, data_domain_, gatt_);
+      hci_, le_address_manager_.get(), hci_le_connector_.get(), &device_cache_,
+      data_domain_, gatt_);
   le_advertising_manager_ = std::make_unique<LowEnergyAdvertisingManager>(
       hci_le_advertiser_.get(), le_address_manager_.get());
 
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager.h b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager.h
index b70e79364..1c39df1 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager.h
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager.h
@@ -91,10 +91,9 @@
   // used.
   void EnablePrivacy(bool enabled);
 
-  // Returns the local address that should be used by the next LE procedure
-  // after refreshing the local random address. |callback| is run to report the
-  // address and may run either synchronously or asynchronously.
-  // LocalAddressDelegate override:
+  // LocalAddressDelegate overrides:
+  std::optional<common::UInt128> irk() const override { return irk_; }
+  common::DeviceAddress identity_address() const override { return public_; }
   void EnsureLocalAddress(AddressCallback callback) override;
 
  private:
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager_unittest.cc
index dde7b43..f298096 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_address_manager_unittest.cc
@@ -39,6 +39,8 @@
     addr_mgr_ = std::make_unique<LowEnergyAddressManager>(
         kPublic, [this] { return IsRandomAddressChangeAllowed(); },
         transport());
+    ASSERT_EQ(kPublic, addr_mgr()->identity_address());
+    ASSERT_FALSE(addr_mgr()->irk());
     StartTestDevice();
   }
 
@@ -107,6 +109,8 @@
       dispatcher());
 
   addr_mgr()->set_irk(kIrk);
+  ASSERT_TRUE(addr_mgr()->irk());
+  EXPECT_EQ(kIrk, *addr_mgr()->irk());
   addr_mgr()->EnablePrivacy(true);
 
   // Privacy is now considered enabled. Further requests to enable should not
@@ -126,6 +130,8 @@
   // Re-enable privacy with a new IRK. The latest IRK should be used.
   const UInt128 kIrk2{{15, 14, 14, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}};
   addr_mgr()->set_irk(kIrk2);
+  ASSERT_TRUE(addr_mgr()->irk());
+  EXPECT_EQ(kIrk2, *addr_mgr()->irk());
 
   // Returns the same address.
   EXPECT_EQ(addr, EnsureLocalAddress());
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.cc b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.cc
index a40b0bd..29ffd24 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.cc
@@ -13,6 +13,7 @@
 #include "src/connectivity/bluetooth/core/bt-host/gatt/local_service_manager.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci/defaults.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
+#include "src/connectivity/bluetooth/core/bt-host/hci/local_address_delegate.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci/transport.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci/util.h"
 #include "src/connectivity/bluetooth/core/bt-host/l2cap/channel_manager.h"
@@ -239,7 +240,17 @@
 
   // sm::PairingState::Delegate override:
   std::optional<sm::IdentityInfo> OnIdentityInformationRequest() override {
-    return std::nullopt;  // TODO(BT-243): Provide local identity information.
+    if (!conn_mgr_->local_address_delegate()->irk()) {
+      bt_log(SPEW, "gap-le", "no local identity information to exchange");
+      return std::nullopt;
+    }
+
+    bt_log(TRACE, "gap-le", "will distribute local identity information");
+    sm::IdentityInfo id_info;
+    id_info.irk = *conn_mgr_->local_address_delegate()->irk();
+    id_info.address = conn_mgr_->local_address_delegate()->identity_address();
+
+    return id_info;
   }
 
   // sm::PairingState::Delegate override:
@@ -380,9 +391,9 @@
 }
 
 LowEnergyConnectionManager::LowEnergyConnectionManager(
-    fxl::RefPtr<hci::Transport> hci, hci::LowEnergyConnector* connector,
-    RemoteDeviceCache* device_cache, fbl::RefPtr<data::Domain> data_domain,
-    fbl::RefPtr<gatt::GATT> gatt)
+    fxl::RefPtr<hci::Transport> hci, hci::LocalAddressDelegate* addr_delegate,
+    hci::LowEnergyConnector* connector, RemoteDeviceCache* device_cache,
+    fbl::RefPtr<data::Domain> data_domain, fbl::RefPtr<gatt::GATT> gatt)
     : hci_(hci),
       request_timeout_(kLECreateConnectionTimeout),
       dispatcher_(async_get_default_dispatcher()),
@@ -390,6 +401,7 @@
       data_domain_(data_domain),
       gatt_(gatt),
       connector_(connector),
+      local_address_delegate_(addr_delegate),
       weak_ptr_factory_(this) {
   ZX_DEBUG_ASSERT(dispatcher_);
   ZX_DEBUG_ASSERT(device_cache_);
@@ -397,6 +409,7 @@
   ZX_DEBUG_ASSERT(gatt_);
   ZX_DEBUG_ASSERT(hci_);
   ZX_DEBUG_ASSERT(connector_);
+  ZX_DEBUG_ASSERT(local_address_delegate_);
 
   auto self = weak_ptr_factory_.GetWeakPtr();
 
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.h b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.h
index 0ee2a17..fec6b83 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.h
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager.h
@@ -27,6 +27,7 @@
 namespace bt {
 
 namespace hci {
+class LocalAddressDelegate;
 class Transport;
 }  // namespace hci
 
@@ -87,7 +88,20 @@
 
 class LowEnergyConnectionManager final {
  public:
+  // |hci|: The HCI transport used to track link layer connection events from
+  //        the controller.
+  // |addr_delegate|: Used to obtain local identity information during pairing
+  //                  procedures.
+  // |connector|: Adapter object for initiating link layer connections. This
+  //              object abstracts the legacy and extended HCI command sets.
+  // |device_cache|: The cache that stores peer device data. The connection
+  //                 manager stores and retrieves pairing data and connection
+  //                 parameters to/from the cache. It also updates the
+  //                 connection and bonding state of a device via the cache.
+  // |data_domain|: Used to interact with the L2CAP layer.
+  // |gatt|: Used to interact with the GATT profile layer.
   LowEnergyConnectionManager(fxl::RefPtr<hci::Transport> hci,
+                             hci::LocalAddressDelegate* addr_delegate,
                              hci::LowEnergyConnector* connector,
                              RemoteDeviceCache* device_cache,
                              fbl::RefPtr<data::Domain> data_domain,
@@ -119,6 +133,9 @@
   bool Connect(DeviceId device_id, ConnectionResultCallback callback);
 
   RemoteDeviceCache* device_cache() { return device_cache_; }
+  hci::LocalAddressDelegate* local_address_delegate() const {
+    return local_address_delegate_;
+  }
 
   // Disconnects any existing LE connection to |device_id|, invalidating
   // all active LowEnergyConnectionRefs. Returns false if |device_id| is
@@ -356,6 +373,10 @@
   // out-live this connection manager.
   hci::LowEnergyConnector* connector_;  // weak
 
+  // Address manager is used to obtain local identity information during pairing
+  // procedures. Expected to outlive this instance.
+  hci::LocalAddressDelegate* local_address_delegate_;  // weak
+
   // Keep this as the last member to make sure that all weak pointers are
   // invalidated before other members get destroyed.
   fxl::WeakPtrFactory<LowEnergyConnectionManager> weak_ptr_factory_;
diff --git a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager_unittest.cc b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager_unittest.cc
index 815e60f..40d8db7 100644
--- a/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager_unittest.cc
+++ b/src/connectivity/bluetooth/core/bt-host/gap/low_energy_connection_manager_unittest.cc
@@ -14,6 +14,7 @@
 #include "src/connectivity/bluetooth/core/bt-host/gap/remote_device.h"
 #include "src/connectivity/bluetooth/core/bt-host/gap/remote_device_cache.h"
 #include "src/connectivity/bluetooth/core/bt-host/gatt/fake_layer.h"
+#include "src/connectivity/bluetooth/core/bt-host/hci/fake_local_address_delegate.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci/hci_constants.h"
 #include "src/connectivity/bluetooth/core/bt-host/hci/low_energy_connector.h"
 #include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_channel.h"
@@ -68,8 +69,8 @@
             this, &LowEnergyConnectionManagerTest::OnIncomingConnection));
 
     conn_mgr_ = std::make_unique<LowEnergyConnectionManager>(
-        transport(), connector_.get(), dev_cache_.get(), l2cap_,
-        gatt::testing::FakeLayer::Create());
+        transport(), &addr_delegate_, connector_.get(), dev_cache_.get(),
+        l2cap_, gatt::testing::FakeLayer::Create());
 
     test_device()->SetConnectionStateCallback(
         fit::bind_member(
@@ -144,6 +145,7 @@
 
   fbl::RefPtr<data::testing::FakeDomain> l2cap_;
 
+  hci::FakeLocalAddressDelegate addr_delegate_;
   std::unique_ptr<RemoteDeviceCache> dev_cache_;
   std::unique_ptr<hci::LowEnergyConnector> connector_;
   std::unique_ptr<LowEnergyConnectionManager> conn_mgr_;
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/fake_local_address_delegate.h b/src/connectivity/bluetooth/core/bt-host/hci/fake_local_address_delegate.h
index c7fc142..2b096c3 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/fake_local_address_delegate.h
+++ b/src/connectivity/bluetooth/core/bt-host/hci/fake_local_address_delegate.h
@@ -16,6 +16,8 @@
   FakeLocalAddressDelegate() = default;
   ~FakeLocalAddressDelegate() override = default;
 
+  std::optional<common::UInt128> irk() const override { return std::nullopt; }
+  common::DeviceAddress identity_address() const override { return {}; }
   void EnsureLocalAddress(AddressCallback callback) override;
 
   // If set to true EnsureLocalAddress runs its callback asynchronously.
diff --git a/src/connectivity/bluetooth/core/bt-host/hci/local_address_delegate.h b/src/connectivity/bluetooth/core/bt-host/hci/local_address_delegate.h
index a72d55d6..53291bd 100644
--- a/src/connectivity/bluetooth/core/bt-host/hci/local_address_delegate.h
+++ b/src/connectivity/bluetooth/core/bt-host/hci/local_address_delegate.h
@@ -7,7 +7,10 @@
 
 #include <lib/fit/function.h>
 
+#include <optional>
+
 #include "src/connectivity/bluetooth/core/bt-host/common/device_address.h"
+#include "src/connectivity/bluetooth/core/bt-host/common/uint128.h"
 
 namespace bt {
 namespace hci {
@@ -16,6 +19,12 @@
  public:
   virtual ~LocalAddressDelegate() = default;
 
+  // Returns the currently assigned IRK, if any.
+  virtual std::optional<common::UInt128> irk() const = 0;
+
+  // Returns the identity address.
+  virtual common::DeviceAddress identity_address() const = 0;
+
   // Asynchronously returns the local LE controller address used by all LE link
   // layer procedures with the exception of 5.0 advertising sets. These include:
   //   - Legacy and extended scan requests;